From 55e4139c45a8e746596ea69e75d23ae9c00cc75a Mon Sep 17 00:00:00 2001 From: Carl Kyrillos Date: Wed, 16 Aug 2023 10:31:45 -0400 Subject: [PATCH 1/2] THREESCALE-7836 Added documentation around env vars --- doc/development.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/doc/development.md b/doc/development.md index 8cf908072..9914416b1 100644 --- a/doc/development.md +++ b/doc/development.md @@ -7,6 +7,7 @@ * [Run 3scale Operator](#run-3scale-operator) * [Run 3scale Operator Locally](#run-3scale-operator-locally) * [Deploy custom 3scale Operator using OLM](#deploy-custom-3scale-operator-using-olm) + * [Environment Variables](#3scale-operator-environment-variables) * [Run tests](#run-tests) * [Run all tests](#run-all-tests) * [Run unit tests](#run-unit-tests) @@ -116,6 +117,15 @@ It will take a few minutes for the operator to become visible under the _OperatorHub_ section of the OpenShift console _Catalog_. It can be easily found by filtering the provider type to _Custom_. +### 3scale Operator Environment Variables +There are a few environment variables that may be used to aid in development. Refer to the table below for details: + +| Variable | Options | Type | Default | Details | +|-----------------------------|------------|:--------:|---------|------------------------------------------------------------------------------------------------------------------------------------------------------------| +| THREESCALE_DEBUG | `1` or `0` | Optional | `0` | If `1`, sets the porta client logging to be more verbose. | +| INSECURE_SKIP_VERIFY_CLIENT | `1` or `0` | Optional | `0` | If `1`, sets the porta client to _not_ verify the server's certificate chain and host name. **NOTE:** this should only be used during development/testing. | +| + ### Run tests #### Run all tests From e5c98b17614944d9655734b918c7eb7fdb9f27a7 Mon Sep 17 00:00:00 2001 From: Carl Kyrillos Date: Thu, 17 Aug 2023 16:29:59 -0400 Subject: [PATCH 2/2] THREESCALE-7836 Refactor TLS InsecureSkipVerify logic to use annotations --- .../capabilities/activedoc_controller.go | 3 +- .../capabilities/application_controller.go | 3 +- .../capabilities/backend_controller.go | 6 ++-- .../custompolicydefinition_controller.go | 3 +- .../developeraccount_controller.go | 6 ++-- .../capabilities/developeruser_controller.go | 6 ++-- .../capabilities/product_controller.go | 6 ++-- .../proxyconfigpromote_controller.go | 3 +- controllers/capabilities/tenant_controller.go | 3 +- doc/development.md | 4 +-- doc/operator-user-guide.md | 12 ++++++++ pkg/controller/helper/threescale_api.go | 30 +++++++++++-------- pkg/controller/helper/threescale_api_test.go | 10 +++---- 13 files changed, 61 insertions(+), 34 deletions(-) diff --git a/controllers/capabilities/activedoc_controller.go b/controllers/capabilities/activedoc_controller.go index 1d4a5f4f1..7bc8cd5a5 100644 --- a/controllers/capabilities/activedoc_controller.go +++ b/controllers/capabilities/activedoc_controller.go @@ -144,7 +144,8 @@ func (r *ActiveDocReconciler) reconcileSpec(activeDocCR *capabilitiesv1beta1.Act return statusReconciler, err } - threescaleAPIClient, err := controllerhelper.PortaClient(providerAccount) + insecureSkipVerify := controllerhelper.GetInsecureSkipVerifyAnnotation(activeDocCR.GetAnnotations()) + threescaleAPIClient, err := controllerhelper.PortaClient(providerAccount, insecureSkipVerify) if err != nil { statusReconciler := NewActiveDocStatusReconciler(r.BaseReconciler, activeDocCR, providerAccount.AdminURLStr, nil, err) return statusReconciler, err diff --git a/controllers/capabilities/application_controller.go b/controllers/capabilities/application_controller.go index 1387f1dc6..15f3a1a8d 100644 --- a/controllers/capabilities/application_controller.go +++ b/controllers/capabilities/application_controller.go @@ -103,7 +103,8 @@ func (r *ApplicationReconciler) Reconcile(ctx context.Context, req ctrl.Request) return ctrl.Result{}, err } - threescaleAPIClient, err := controllerhelper.PortaClient(providerAccount) + insecureSkipVerify := controllerhelper.GetInsecureSkipVerifyAnnotation(application.GetAnnotations()) + threescaleAPIClient, err := controllerhelper.PortaClient(providerAccount, insecureSkipVerify) if err != nil { return ctrl.Result{}, err } diff --git a/controllers/capabilities/backend_controller.go b/controllers/capabilities/backend_controller.go index 17d5d669e..f11804388 100644 --- a/controllers/capabilities/backend_controller.go +++ b/controllers/capabilities/backend_controller.go @@ -207,7 +207,8 @@ func (r *BackendReconciler) reconcile(backendResource *capabilitiesv1beta1.Backe return statusReconciler, err } - threescaleAPIClient, err := controllerhelper.PortaClient(providerAccount) + insecureSkipVerify := controllerhelper.GetInsecureSkipVerifyAnnotation(backendResource.GetAnnotations()) + threescaleAPIClient, err := controllerhelper.PortaClient(providerAccount, insecureSkipVerify) if err != nil { statusReconciler := NewBackendStatusReconciler(r.BaseReconciler, backendResource, nil, providerAccount.AdminURLStr, err) return statusReconciler, err @@ -298,7 +299,8 @@ func (r *BackendReconciler) removeBackendFrom3scale(backend *capabilitiesv1beta1 return err } - threescaleAPIClient, err := controllerhelper.PortaClient(providerAccount) + insecureSkipVerify := controllerhelper.GetInsecureSkipVerifyAnnotation(backend.GetAnnotations()) + threescaleAPIClient, err := controllerhelper.PortaClient(providerAccount, insecureSkipVerify) if err != nil { return err } diff --git a/controllers/capabilities/custompolicydefinition_controller.go b/controllers/capabilities/custompolicydefinition_controller.go index eca5c204d..afc4c0822 100644 --- a/controllers/capabilities/custompolicydefinition_controller.go +++ b/controllers/capabilities/custompolicydefinition_controller.go @@ -115,7 +115,8 @@ func (r *CustomPolicyDefinitionReconciler) reconcileSpec(customPolicyDefinitionC return statusReconciler, err } - threescaleAPIClient, err := controllerhelper.PortaClient(providerAccount) + insecureSkipVerify := controllerhelper.GetInsecureSkipVerifyAnnotation(customPolicyDefinitionCR.GetAnnotations()) + threescaleAPIClient, err := controllerhelper.PortaClient(providerAccount, insecureSkipVerify) if err != nil { statusReconciler := NewCustomPolicyDefinitionStatusReconciler(r.BaseReconciler, customPolicyDefinitionCR, providerAccount.AdminURLStr, nil, err) return statusReconciler, err diff --git a/controllers/capabilities/developeraccount_controller.go b/controllers/capabilities/developeraccount_controller.go index ae51cf7b6..e25e6df71 100644 --- a/controllers/capabilities/developeraccount_controller.go +++ b/controllers/capabilities/developeraccount_controller.go @@ -189,7 +189,8 @@ func (r *DeveloperAccountReconciler) reconcileSpec(accountCR *capabilitiesv1beta return statusReconciler, err } - threescaleAPIClient, err := controllerhelper.PortaClient(providerAccount) + insecureSkipVerify := controllerhelper.GetInsecureSkipVerifyAnnotation(accountCR.GetAnnotations()) + threescaleAPIClient, err := controllerhelper.PortaClient(providerAccount, insecureSkipVerify) if err != nil { statusReconciler := NewDeveloperAccountStatusReconciler(r.BaseReconciler, accountCR, providerAccount.AdminURLStr, nil, err) return statusReconciler, err @@ -240,7 +241,8 @@ func (r *DeveloperAccountReconciler) removeDeveloperAccountFrom3scale(developerA return err } - threescaleAPIClient, err := controllerhelper.PortaClient(developerAccount) + insecureSkipVerify := controllerhelper.GetInsecureSkipVerifyAnnotation(developerAccountCR.GetAnnotations()) + threescaleAPIClient, err := controllerhelper.PortaClient(developerAccount, insecureSkipVerify) if err != nil { return err } diff --git a/controllers/capabilities/developeruser_controller.go b/controllers/capabilities/developeruser_controller.go index 21351e51f..4b2a45aae 100644 --- a/controllers/capabilities/developeruser_controller.go +++ b/controllers/capabilities/developeruser_controller.go @@ -202,7 +202,8 @@ func (r *DeveloperUserReconciler) reconcileSpec(userCR *capabilitiesv1beta1.Deve return statusReconciler, err } - threescaleAPIClient, err := controllerhelper.PortaClient(providerAccount) + insecureSkipVerify := controllerhelper.GetInsecureSkipVerifyAnnotation(userCR.GetAnnotations()) + threescaleAPIClient, err := controllerhelper.PortaClient(providerAccount, insecureSkipVerify) if err != nil { statusReconciler := NewDeveloperUserStatusReconciler(r.BaseReconciler, userCR, parentAccountCR, providerAccount.AdminURLStr, nil, err) return statusReconciler, err @@ -298,7 +299,8 @@ func (r *DeveloperUserReconciler) removeDeveloperUserFrom3scale(developerUser *c return err } - threescaleAPIClient, err := controllerhelper.PortaClient(providerAccount) + insecureSkipVerify := controllerhelper.GetInsecureSkipVerifyAnnotation(developerUser.GetAnnotations()) + threescaleAPIClient, err := controllerhelper.PortaClient(providerAccount, insecureSkipVerify) if err != nil { return err } diff --git a/controllers/capabilities/product_controller.go b/controllers/capabilities/product_controller.go index fd0aea871..b146dadd3 100644 --- a/controllers/capabilities/product_controller.go +++ b/controllers/capabilities/product_controller.go @@ -207,7 +207,8 @@ func (r *ProductReconciler) reconcile(productResource *capabilitiesv1beta1.Produ return statusReconciler, err } - threescaleAPIClient, err := controllerhelper.PortaClient(providerAccount) + insecureSkipVerify := controllerhelper.GetInsecureSkipVerifyAnnotation(productResource.GetAnnotations()) + threescaleAPIClient, err := controllerhelper.PortaClient(providerAccount, insecureSkipVerify) if err != nil { statusReconciler := NewProductStatusReconciler(r.BaseReconciler, productResource, nil, providerAccount.AdminURLStr, err) return statusReconciler, err @@ -400,7 +401,8 @@ func (r *ProductReconciler) removeProductFrom3scale(product *capabilitiesv1beta1 return err } - threescaleAPIClient, err := controllerhelper.PortaClient(providerAccount) + insecureSkipVerify := controllerhelper.GetInsecureSkipVerifyAnnotation(product.GetAnnotations()) + threescaleAPIClient, err := controllerhelper.PortaClient(providerAccount, insecureSkipVerify) if err != nil { return err } diff --git a/controllers/capabilities/proxyconfigpromote_controller.go b/controllers/capabilities/proxyconfigpromote_controller.go index ea3513a8b..0c91a8b64 100644 --- a/controllers/capabilities/proxyconfigpromote_controller.go +++ b/controllers/capabilities/proxyconfigpromote_controller.go @@ -90,7 +90,8 @@ func (r *ProxyConfigPromoteReconciler) Reconcile(ctx context.Context, req ctrl.R } // connect to the 3scale porta client - threescaleAPIClient, err := controllerhelper.PortaClient(providerAccount) + insecureSkipVerify := controllerhelper.GetInsecureSkipVerifyAnnotation(proxyConfigPromote.GetAnnotations()) + threescaleAPIClient, err := controllerhelper.PortaClient(providerAccount, insecureSkipVerify) if err != nil { return ctrl.Result{}, err } diff --git a/controllers/capabilities/tenant_controller.go b/controllers/capabilities/tenant_controller.go index a8aa66302..977e95b6b 100644 --- a/controllers/capabilities/tenant_controller.go +++ b/controllers/capabilities/tenant_controller.go @@ -98,7 +98,8 @@ func (r *TenantReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctr return ctrl.Result{}, err } - portaClient, err := controllerhelper.PortaClientFromURLString(tenantR.Spec.SystemMasterUrl, masterAccessToken) + insecureSkipVerify := controllerhelper.GetInsecureSkipVerifyAnnotation(tenantR.GetAnnotations()) + portaClient, err := controllerhelper.PortaClientFromURLString(tenantR.Spec.SystemMasterUrl, masterAccessToken, insecureSkipVerify) if err != nil { reqLogger.Error(err, "Error creating porta client object") // Error reading the object - requeue the request. diff --git a/doc/development.md b/doc/development.md index 9914416b1..de0e5da4a 100644 --- a/doc/development.md +++ b/doc/development.md @@ -118,13 +118,11 @@ the _OperatorHub_ section of the OpenShift console _Catalog_. It can be easily found by filtering the provider type to _Custom_. ### 3scale Operator Environment Variables -There are a few environment variables that may be used to aid in development. Refer to the table below for details: +There are environment variables that may be used to aid in development. Refer to the table below for details: | Variable | Options | Type | Default | Details | |-----------------------------|------------|:--------:|---------|------------------------------------------------------------------------------------------------------------------------------------------------------------| | THREESCALE_DEBUG | `1` or `0` | Optional | `0` | If `1`, sets the porta client logging to be more verbose. | -| INSECURE_SKIP_VERIFY_CLIENT | `1` or `0` | Optional | `0` | If `1`, sets the porta client to _not_ verify the server's certificate chain and host name. **NOTE:** this should only be used during development/testing. | -| ### Run tests diff --git a/doc/operator-user-guide.md b/doc/operator-user-guide.md index 9a2cb8ad7..fc1003d3c 100644 --- a/doc/operator-user-guide.md +++ b/doc/operator-user-guide.md @@ -22,6 +22,7 @@ * [Setting custom TopologySpreadConstraints](#setting-custom-topologyspreadconstraints) * [Setting custom labels](#setting-custom-labels) * [Setting custom Annotations](#setting-custom-annotations) + * [Setting porta client to skip certificate verification](#setting-porta-client-to-skip-certificate-verification) * [Reconciliation](#reconciliation) * [Resources](#resources) * [Backend replicas](#backend-replicas) @@ -815,6 +816,17 @@ spec: anno-sample2: anno2 ``` +#### Setting porta client to skip certificate verification +Whenever a controller reconciles an object it creates a new porta client to make API calls. That client is configured to verify the server's certificate chain by default. For development/testing purposes, you may want the client to skip certificate verification when reconciling an object. This can be done using the annotation `insecure_skip_verify: true`, which can be added to the following objects: +* ActiveDoc +* Application +* Backend +* CustomPolicyDefinition +* DeveloperAccount +* DeveloperUser +* Product +* ProxyConfigPromote +* Tenant ### Reconciliation After 3scale API Management solution has been installed, 3scale Operator enables updating a given set diff --git a/pkg/controller/helper/threescale_api.go b/pkg/controller/helper/threescale_api.go index c8daa7fce..515aeeb01 100644 --- a/pkg/controller/helper/threescale_api.go +++ b/pkg/controller/helper/threescale_api.go @@ -11,8 +11,7 @@ import ( ) const ( - HTTP_VERBOSE_ENVVAR = "THREESCALE_DEBUG" - INSECURE_SKIP_VERIFY_ENVVAR = "INSECURE_SKIP_VERIFY_CLIENT" + HTTP_VERBOSE_ENVVAR = "THREESCALE_DEBUG" ) type ProviderAccount struct { @@ -20,31 +19,27 @@ type ProviderAccount struct { Token string } -// PortaClient instantiate porta_client.ThreeScaleClient from ProviderAccount object -func PortaClient(providerAccount *ProviderAccount) (*threescaleapi.ThreeScaleClient, error) { - return PortaClientFromURLString(providerAccount.AdminURLStr, providerAccount.Token) +// PortaClient instantiates porta_client.ThreeScaleClient from ProviderAccount object +func PortaClient(providerAccount *ProviderAccount, insecureSkipVerify bool) (*threescaleapi.ThreeScaleClient, error) { + return PortaClientFromURLString(providerAccount.AdminURLStr, providerAccount.Token, insecureSkipVerify) } -func PortaClientFromURLString(adminURLStr, token string) (*threescaleapi.ThreeScaleClient, error) { +// PortaClientFromURLString instantiates porta_client.ThreeScaleClient from url string +func PortaClientFromURLString(adminURLStr, token string, insecureSkipVerify bool) (*threescaleapi.ThreeScaleClient, error) { adminURL, err := url.Parse(adminURLStr) if err != nil { return nil, err } - return PortaClientFromURL(adminURL, token) + return PortaClientFromURL(adminURL, token, insecureSkipVerify) } // PortaClientFromURL instantiates porta_client.ThreeScaleClient from admin url object -func PortaClientFromURL(url *url.URL, token string) (*threescaleapi.ThreeScaleClient, error) { +func PortaClientFromURL(url *url.URL, token string, insecureSkipVerify bool) (*threescaleapi.ThreeScaleClient, error) { adminPortal, err := threescaleapi.NewAdminPortal(url.Scheme, url.Hostname(), helper.PortFromURL(url)) if err != nil { return nil, err } - insecureSkipVerify := false - if helper.GetEnvVar(INSECURE_SKIP_VERIFY_ENVVAR, "0") == "1" { - insecureSkipVerify = true - } - // Activated by some env var or Spec param var transport http.RoundTripper = &http.Transport{ Proxy: http.ProxyFromEnvironment, @@ -57,3 +52,12 @@ func PortaClientFromURL(url *url.URL, token string) (*threescaleapi.ThreeScaleCl return threescaleapi.NewThreeScale(adminPortal, token, &http.Client{Transport: transport}), nil } + +// GetInsecureSkipVerifyAnnotation extracts the insecure_skip_verify annotation from an object +func GetInsecureSkipVerifyAnnotation(annotations map[string]string) bool { + insecureSkipVerify, ok := annotations["insecure_skip_verify"] + if ok && insecureSkipVerify == "true" { + return true + } + return false +} diff --git a/pkg/controller/helper/threescale_api_test.go b/pkg/controller/helper/threescale_api_test.go index aceb8e0a3..bad6ded7a 100644 --- a/pkg/controller/helper/threescale_api_test.go +++ b/pkg/controller/helper/threescale_api_test.go @@ -7,28 +7,28 @@ import ( func TestPortaClientInvalidURL(t *testing.T) { providerAccount := &ProviderAccount{AdminURLStr: ":foo", Token: "some token"} - _, err := PortaClient(providerAccount) + _, err := PortaClient(providerAccount, false) assert(t, err != nil, "error should not be nil") } func TestPortaClient(t *testing.T) { providerAccount := &ProviderAccount{AdminURLStr: "http://somedomain.example.com", Token: "some token"} - _, err := PortaClient(providerAccount) + _, err := PortaClient(providerAccount, false) ok(t, err) } func TestPortaClientFromURLStringInvalidURL(t *testing.T) { - _, err := PortaClientFromURLString(":foo", "some token") + _, err := PortaClientFromURLString(":foo", "some token", false) assert(t, err != nil, "error should not be nil") } func TestPortaClientFromURLString(t *testing.T) { - _, err := PortaClientFromURLString("http://somedomain.example.com", "some token") + _, err := PortaClientFromURLString("http://somedomain.example.com", "some token", false) ok(t, err) } func TestPortaClientFromURL(t *testing.T) { url := &url.URL{} - _, err := PortaClientFromURL(url, "some token") + _, err := PortaClientFromURL(url, "some token", false) assert(t, err != nil, "error should not be nil") }