diff --git a/README.md b/README.md index b5a1b0a..95dd897 100644 --- a/README.md +++ b/README.md @@ -59,7 +59,7 @@ Certificatee uses the HAProxy Data Plane API to update certificates at runtime w - **Basic authentication**: Authenticate using username/password credentials - **Automatic retries**: Connections are retried with exponential backoff (default: 3 retries, 1-30s delays) - **Graceful degradation**: If one HAProxy instance is unreachable, the tool continues updating reachable instances -- **REST API**: Certificates are managed via the `/v3/services/haproxy/runtime/certs` endpoints +- **REST API**: Certificates are managed via the `/v2/services/haproxy/runtime/certs` endpoints ### HAProxy Data Plane API Configuration diff --git a/pkg/haproxy/client.go b/pkg/haproxy/client.go index 9aebbcb..f97a1a5 100644 --- a/pkg/haproxy/client.go +++ b/pkg/haproxy/client.go @@ -304,7 +304,7 @@ func (c *Client) ListCertificates() ([]string, error) { // ListCertificateRefs returns a list of certificate references with both display names and file paths func (c *Client) ListCertificateRefs() ([]CertificateRef, error) { // Use storage API endpoint for listing SSL certificates - resp, err := c.doRequest("GET", "/v3/services/haproxy/storage/ssl_certificates", nil, "") + resp, err := c.doRequest("GET", "/v2/services/haproxy/storage/ssl_certificates", nil, "") if err != nil { return nil, err } @@ -348,7 +348,7 @@ func (c *Client) GetCertificateInfo(certName string) (*CertInfo, error) { func (c *Client) GetCertificateInfoByPath(filePath, displayName string) (*CertInfo, error) { // URL-encode the file path for the API request encodedPath := url.PathEscape(filePath) - path := fmt.Sprintf("/v3/services/haproxy/storage/ssl_certificates/%s", encodedPath) + path := fmt.Sprintf("/v2/services/haproxy/storage/ssl_certificates/%s", encodedPath) resp, err := c.doRequest("GET", path, nil, "") if err != nil { return nil, err @@ -454,7 +454,7 @@ func (c *Client) UpdateCertificate(certName, pemData string) error { } // Send PUT request to replace certificate - path := fmt.Sprintf("/v3/services/haproxy/runtime/certs/%s", certName) + path := fmt.Sprintf("/v2/services/haproxy/runtime/certs/%s", certName) resp, err := c.doRequestWithBodyBuffer("PUT", path, buf.Bytes(), writer.FormDataContentType()) if err != nil { return err @@ -490,7 +490,7 @@ func (c *Client) CreateCertificate(certName, pemData string) error { } // Send POST request to create certificate - resp, err := c.doRequestWithBodyBuffer("POST", "/v3/services/haproxy/runtime/certs", buf.Bytes(), writer.FormDataContentType()) + resp, err := c.doRequestWithBodyBuffer("POST", "/v2/services/haproxy/runtime/certs", buf.Bytes(), writer.FormDataContentType()) if err != nil { return err } @@ -507,7 +507,7 @@ func (c *Client) CreateCertificate(certName, pemData string) error { // DeleteCertificate deletes a certificate entry via Data Plane API func (c *Client) DeleteCertificate(certName string) error { - path := fmt.Sprintf("/v3/services/haproxy/runtime/certs/%s", certName) + path := fmt.Sprintf("/v2/services/haproxy/runtime/certs/%s", certName) resp, err := c.doRequest("DELETE", path, nil, "") if err != nil { return err diff --git a/pkg/haproxy/client_test.go b/pkg/haproxy/client_test.go index 4e99c8f..30865a8 100644 --- a/pkg/haproxy/client_test.go +++ b/pkg/haproxy/client_test.go @@ -408,7 +408,7 @@ func newMockDataPlaneAPI(t *testing.T) *mockDataPlaneAPI { return } - // Try prefix matching for dynamic paths (e.g., /v3/services/haproxy/runtime/certs/example.com.pem) + // Try prefix matching for dynamic paths (e.g., /v2/services/haproxy/runtime/certs/example.com.pem) for pattern, handler := range m.handlers { if strings.HasPrefix(key, pattern) { handler(w, r) @@ -506,7 +506,7 @@ func TestListCertificates(t *testing.T) { mock := newMockDataPlaneAPI(t) defer mock.Close() - mock.SetHandler("GET", "/v3/services/haproxy/storage/ssl_certificates", func(w http.ResponseWriter, r *http.Request) { + mock.SetHandler("GET", "/v2/services/haproxy/storage/ssl_certificates", func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(tt.statusCode) if tt.response != nil { @@ -616,7 +616,7 @@ kF7B68QUswmVK4Icz6zBgmo= mock := newMockDataPlaneAPI(t) defer mock.Close() - mock.SetHandler("GET", "/v3/services/haproxy/storage/ssl_certificates/"+tt.certPath, func(w http.ResponseWriter, r *http.Request) { + mock.SetHandler("GET", "/v2/services/haproxy/storage/ssl_certificates/"+tt.certPath, func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(tt.statusCode) if tt.statusCode == http.StatusOK { _, _ = w.Write([]byte(tt.pemData)) @@ -689,7 +689,7 @@ func TestUpdateCertificate(t *testing.T) { mock := newMockDataPlaneAPI(t) defer mock.Close() - mock.SetHandler("PUT", "/v3/services/haproxy/runtime/certs/"+tt.certName, func(w http.ResponseWriter, r *http.Request) { + mock.SetHandler("PUT", "/v2/services/haproxy/runtime/certs/"+tt.certName, func(w http.ResponseWriter, r *http.Request) { // Verify content type is multipart contentType := r.Header.Get("Content-Type") if !strings.Contains(contentType, "multipart/form-data") { @@ -776,7 +776,7 @@ func TestCreateCertificate(t *testing.T) { mock := newMockDataPlaneAPI(t) defer mock.Close() - mock.SetHandler("POST", "/v3/services/haproxy/runtime/certs", func(w http.ResponseWriter, r *http.Request) { + mock.SetHandler("POST", "/v2/services/haproxy/runtime/certs", func(w http.ResponseWriter, r *http.Request) { // Verify content type is multipart contentType := r.Header.Get("Content-Type") if !strings.Contains(contentType, "multipart/form-data") { @@ -861,7 +861,7 @@ func TestDeleteCertificate(t *testing.T) { mock := newMockDataPlaneAPI(t) defer mock.Close() - mock.SetHandler("DELETE", "/v3/services/haproxy/runtime/certs/"+tt.certName, func(w http.ResponseWriter, r *http.Request) { + mock.SetHandler("DELETE", "/v2/services/haproxy/runtime/certs/"+tt.certName, func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(tt.statusCode) }) @@ -890,7 +890,7 @@ func TestBasicAuth(t *testing.T) { defer mock.Close() mock.SetAuth("admin", "secret") - mock.SetHandler("GET", "/v3/services/haproxy/storage/ssl_certificates", func(w http.ResponseWriter, r *http.Request) { + mock.SetHandler("GET", "/v2/services/haproxy/storage/ssl_certificates", func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) _ = json.NewEncoder(w).Encode([]SSLCertificateEntry{}) diff --git a/test/integration/run-tests.sh b/test/integration/run-tests.sh index ede8840..14fae4c 100755 --- a/test/integration/run-tests.sh +++ b/test/integration/run-tests.sh @@ -199,7 +199,7 @@ EOF # Wait for API to be ready local retries=30 - while ! curl -sf http://127.0.0.1:5555/v3/services/haproxy/runtime/info -u admin:adminpwd > /dev/null 2>&1; do + while ! curl -sf http://127.0.0.1:5555/v2/services/haproxy/runtime/info -u admin:adminpwd > /dev/null 2>&1; do retries=$((retries - 1)) if [[ ${retries} -le 0 ]]; then log_error "Data Plane API failed to start. Logs:" @@ -301,25 +301,25 @@ test_api_connectivity() { # First, check API info endpoint log_info "Checking API info..." local info - info=$(curl -s http://127.0.0.1:5555/v3/info -u admin:adminpwd) || true + info=$(curl -s http://127.0.0.1:5555/v2/info -u admin:adminpwd) || true echo "API Info: ${info}" # Check available endpoints log_info "Checking runtime info..." local runtime_info - runtime_info=$(curl -s http://127.0.0.1:5555/v3/services/haproxy/runtime/info -u admin:adminpwd) || true + runtime_info=$(curl -s http://127.0.0.1:5555/v2/services/haproxy/runtime/info -u admin:adminpwd) || true echo "Runtime Info: ${runtime_info}" # Try to list certificates via storage endpoint log_info "Checking storage certs endpoint..." local storage_certs - storage_certs=$(curl -s http://127.0.0.1:5555/v3/services/haproxy/storage/ssl_certificates -u admin:adminpwd) || true + storage_certs=$(curl -s http://127.0.0.1:5555/v2/services/haproxy/storage/ssl_certificates -u admin:adminpwd) || true echo "Storage Certs: ${storage_certs}" # Check runtime certs endpoint log_info "Checking runtime certs endpoint..." local runtime_certs - runtime_certs=$(curl -s http://127.0.0.1:5555/v3/services/haproxy/runtime/certs -u admin:adminpwd) || true + runtime_certs=$(curl -s http://127.0.0.1:5555/v2/services/haproxy/runtime/certs -u admin:adminpwd) || true echo "Runtime Certs: ${runtime_certs}" if echo "${runtime_certs}" | grep -q "404"; then