From fa99f9abf7b8532cde8310df05de94ea1a0bfc8a Mon Sep 17 00:00:00 2001 From: Roi Vazquez Date: Thu, 21 Dec 2023 16:40:59 +0100 Subject: [PATCH 1/8] Rework options framework ExternalSecrets are now dynamically generated only when required. This is important to remove the dependency of saas dev environments from external-secrets operator and vault. --- api/v1alpha1/common_types.go | 2 +- api/v1alpha1/system_types.go | 7 +- api/v1alpha1/zz_generated.deepcopy.go | 11 +- .../saas-operator.clusterserviceversion.yaml | 84 ++- .../manifests/saas.3scale.net_backends.yaml | 12 +- .../saas.3scale.net_corsproxies.yaml | 2 +- .../saas.3scale.net_mappingservices.yaml | 2 +- bundle/manifests/saas.3scale.net_systems.yaml | 98 ++- bundle/manifests/saas.3scale.net_zyncs.yaml | 10 +- .../crd/bases/saas.3scale.net_backends.yaml | 12 +- .../bases/saas.3scale.net_corsproxies.yaml | 2 +- .../saas.3scale.net_mappingservices.yaml | 2 +- config/crd/bases/saas.3scale.net_systems.yaml | 98 ++- config/crd/bases/saas.3scale.net_zyncs.yaml | 10 +- .../saas-operator.clusterserviceversion.yaml | 84 ++- controllers/system_controller_suite_test.go | 2 +- go.mod | 3 + go.sum | 35 ++ pkg/generators/apicast/config/options.go | 36 +- pkg/generators/apicast/deployment.go | 2 +- pkg/generators/apicast/generator.go | 3 +- pkg/generators/autossl/config/options.go | 50 +- pkg/generators/autossl/deployment.go | 2 +- pkg/generators/autossl/generator.go | 3 +- pkg/generators/backend/config/cron_options.go | 40 +- .../backend/config/listener_options.go | 68 +-- .../backend/config/worker_options.go | 65 +- pkg/generators/backend/cron_deployment.go | 2 +- pkg/generators/backend/generator.go | 28 +- pkg/generators/backend/listener_deployment.go | 2 +- pkg/generators/backend/worker_deployment.go | 2 +- pkg/generators/corsproxy/config/options.go | 15 +- pkg/generators/corsproxy/deployment.go | 2 +- pkg/generators/corsproxy/generator.go | 13 +- .../mappingservice/config/options.go | 27 +- pkg/generators/mappingservice/deployment.go | 2 +- pkg/generators/mappingservice/generator.go | 13 +- pkg/generators/sentinel/config/options.go | 13 - pkg/generators/sentinel/generator.go | 6 +- pkg/generators/system/app_deployment.go | 4 +- pkg/generators/system/config/options.go | 255 +++----- pkg/generators/system/console_statefulset.go | 3 +- pkg/generators/system/generator.go | 59 +- pkg/generators/system/sidekiq_deployment.go | 13 +- pkg/generators/system/tekton_task.go | 22 +- pkg/generators/zync/api_deployment.go | 14 +- pkg/generators/zync/config/api_options.go | 52 +- pkg/generators/zync/config/que_options.go | 47 +- pkg/generators/zync/console_statefulset.go | 14 +- pkg/generators/zync/generator.go | 19 +- pkg/generators/zync/que_deployment.go | 14 +- .../externalsecret/resource.go | 33 + pkg/resource_builders/pod/environment.go | 235 +++++-- pkg/resource_builders/pod/environment_test.go | 576 +++++++++++++----- pkg/resource_builders/pod/externalsecrets.go | 95 --- .../pod/externalsecrets_test.go | 281 --------- pkg/resource_builders/twemproxy/options.go | 25 +- pkg/resource_builders/twemproxy/util.go | 2 +- .../deployment/deployment_based_workload.go | 14 +- .../deployment_based_workload_test.go | 43 -- 60 files changed, 1120 insertions(+), 1570 deletions(-) delete mode 100644 pkg/generators/sentinel/config/options.go create mode 100644 pkg/resource_builders/externalsecret/resource.go delete mode 100644 pkg/resource_builders/pod/externalsecrets.go delete mode 100644 pkg/resource_builders/pod/externalsecrets_test.go diff --git a/api/v1alpha1/common_types.go b/api/v1alpha1/common_types.go index ec394032..d278aac5 100644 --- a/api/v1alpha1/common_types.go +++ b/api/v1alpha1/common_types.go @@ -559,7 +559,7 @@ func (spec *ExternalSecret) Default() { // SecretReference is a reference to a secret stored in some secrets engine type SecretReference struct { - // VaultSecretReference is a reference to a secret stored in a Hashicorp Vault + // FromVault is a reference to a secret key/value stored in a Hashicorp Vault // +operator-sdk:csv:customresourcedefinitions:type=spec // +optional FromVault *VaultSecretReference `json:"fromVault,omitempty"` diff --git a/api/v1alpha1/system_types.go b/api/v1alpha1/system_types.go index 7f795cb8..d5c49ae2 100644 --- a/api/v1alpha1/system_types.go +++ b/api/v1alpha1/system_types.go @@ -471,14 +471,9 @@ type SystemConfig struct { // Mapping Service access token // +operator-sdk:csv:customresourcedefinitions:type=spec MappingServiceAccessToken SecretReference `json:"mappingServiceAccessToken"` - // Zync authentication token - // +operator-sdk:csv:customresourcedefinitions:type=spec - // +optional - ZyncAuthToken *SecretReference `json:"zyncAuthToken,omitempty"` // Zync has configuration options for system to contact zync // +operator-sdk:csv:customresourcedefinitions:type=spec - // +optional - Zync *SystemZyncSpec `json:"zync,omitempty"` + Zync SystemZyncSpec `json:"zync,omitempty"` // Backend has configuration options for system to contact backend // +operator-sdk:csv:customresourcedefinitions:type=spec Backend SystemBackendSpec `json:"backend"` diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index f00fe25e..f2902046 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -3151,16 +3151,7 @@ func (in *SystemConfig) DeepCopyInto(out *SystemConfig) { out.Redis = in.Redis in.SMTP.DeepCopyInto(&out.SMTP) in.MappingServiceAccessToken.DeepCopyInto(&out.MappingServiceAccessToken) - if in.ZyncAuthToken != nil { - in, out := &in.ZyncAuthToken, &out.ZyncAuthToken - *out = new(SecretReference) - (*in).DeepCopyInto(*out) - } - if in.Zync != nil { - in, out := &in.Zync, &out.Zync - *out = new(SystemZyncSpec) - (*in).DeepCopyInto(*out) - } + in.Zync.DeepCopyInto(&out.Zync) in.Backend.DeepCopyInto(&out.Backend) in.Assets.DeepCopyInto(&out.Assets) } diff --git a/bundle/manifests/saas-operator.clusterserviceversion.yaml b/bundle/manifests/saas-operator.clusterserviceversion.yaml index 699d34a8..cbe584fe 100644 --- a/bundle/manifests/saas-operator.clusterserviceversion.yaml +++ b/bundle/manifests/saas-operator.clusterserviceversion.yaml @@ -1308,7 +1308,7 @@ spec: key displayName: Error Monitoring Key path: config.errorMonitoringKey - - description: VaultSecretReference is a reference to a secret stored in a Hashicorp + - description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault displayName: From Vault path: config.errorMonitoringKey.fromVault @@ -1325,7 +1325,7 @@ spec: service displayName: Error Monitoring Service path: config.errorMonitoringService - - description: VaultSecretReference is a reference to a secret stored in a Hashicorp + - description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault displayName: From Vault path: config.errorMonitoringService.fromVault @@ -1358,7 +1358,7 @@ spec: - description: A reference to the secret holding the backend-internal-api password displayName: Internal APIPassword path: config.internalAPIPassword - - description: VaultSecretReference is a reference to a secret stored in a Hashicorp + - description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault displayName: From Vault path: config.internalAPIPassword.fromVault @@ -1374,7 +1374,7 @@ spec: - description: A reference to the secret holding the backend-internal-api user displayName: Internal APIUser path: config.internalAPIUser - - description: VaultSecretReference is a reference to a secret stored in a Hashicorp + - description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault displayName: From Vault path: config.internalAPIUser.fromVault @@ -1403,7 +1403,7 @@ spec: password displayName: System Events Hook Password path: config.systemEventsHookPassword - - description: VaultSecretReference is a reference to a secret stored in a Hashicorp + - description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault displayName: From Vault path: config.systemEventsHookPassword.fromVault @@ -1420,7 +1420,7 @@ spec: URL displayName: System Events Hook URL path: config.systemEventsHookURL - - description: VaultSecretReference is a reference to a secret stored in a Hashicorp + - description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault displayName: From Vault path: config.systemEventsHookURL.fromVault @@ -1940,7 +1940,7 @@ spec: - description: System database connection string displayName: System Database DSN path: config.systemDatabaseDSN - - description: VaultSecretReference is a reference to a secret stored in a Hashicorp + - description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault displayName: From Vault path: config.systemDatabaseDSN.fromVault @@ -2293,7 +2293,7 @@ spec: - description: A reference to the secret holding the system admin token displayName: System Admin Token path: config.systemAdminToken - - description: VaultSecretReference is a reference to a secret stored in a Hashicorp + - description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault displayName: From Vault path: config.systemAdminToken.fromVault @@ -2794,7 +2794,7 @@ spec: - description: AccessCode to protect admin urls displayName: Access Code path: config.accessCode - - description: VaultSecretReference is a reference to a secret stored in a Hashicorp + - description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault displayName: From Vault path: config.accessCode.fromVault @@ -2810,7 +2810,7 @@ spec: - description: AWS access key displayName: Access Key path: config.assets.accessKey - - description: VaultSecretReference is a reference to a secret stored in a Hashicorp + - description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault displayName: From Vault path: config.assets.accessKey.fromVault @@ -2835,7 +2835,7 @@ spec: - description: AWS secret access key displayName: Secret Key path: config.assets.secretKey - - description: VaultSecretReference is a reference to a secret stored in a Hashicorp + - description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault displayName: From Vault path: config.assets.secretKey.fromVault @@ -2857,7 +2857,7 @@ spec: - description: Internal API password displayName: Internal APIPassword path: config.backend.internalAPIPassword - - description: VaultSecretReference is a reference to a secret stored in a Hashicorp + - description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault displayName: From Vault path: config.backend.internalAPIPassword.fromVault @@ -2873,7 +2873,7 @@ spec: - description: Internal API user displayName: Internal APIUser path: config.backend.internalAPIUser - - description: VaultSecretReference is a reference to a secret stored in a Hashicorp + - description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault displayName: From Vault path: config.backend.internalAPIUser.fromVault @@ -2898,7 +2898,7 @@ spec: - description: API key displayName: APIKey path: config.bugsnag.apiKey - - description: VaultSecretReference is a reference to a secret stored in a Hashicorp + - description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault displayName: From Vault path: config.bugsnag.apiKey.fromVault @@ -2921,7 +2921,7 @@ spec: - description: DSN of system's main database displayName: Database DSN path: config.databaseDSN - - description: VaultSecretReference is a reference to a secret stored in a Hashicorp + - description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault displayName: From Vault path: config.databaseDSN.fromVault @@ -2937,7 +2937,7 @@ spec: - description: Database secret displayName: Database Secret path: config.databaseSecret - - description: VaultSecretReference is a reference to a secret stored in a Hashicorp + - description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault displayName: From Vault path: config.databaseSecret.fromVault @@ -2953,7 +2953,7 @@ spec: - description: EventsSharedSecret displayName: Events Shared Secret path: config.eventsSharedSecret - - description: VaultSecretReference is a reference to a secret stored in a Hashicorp + - description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault displayName: From Vault path: config.eventsSharedSecret.fromVault @@ -2992,7 +2992,7 @@ spec: - description: Client ID displayName: Client ID path: config.github.clientID - - description: VaultSecretReference is a reference to a secret stored in a Hashicorp + - description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault displayName: From Vault path: config.github.clientID.fromVault @@ -3008,7 +3008,7 @@ spec: - description: Client secret displayName: Client Secret path: config.github.clientSecret - - description: VaultSecretReference is a reference to a secret stored in a Hashicorp + - description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault displayName: From Vault path: config.github.clientSecret.fromVault @@ -3024,7 +3024,7 @@ spec: - description: Mapping Service access token displayName: Mapping Service Access Token path: config.mappingServiceAccessToken - - description: VaultSecretReference is a reference to a secret stored in a Hashicorp + - description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault displayName: From Vault path: config.mappingServiceAccessToken.fromVault @@ -3058,7 +3058,7 @@ spec: - description: Private key displayName: Private Key path: config.recaptcha.privateKey - - description: VaultSecretReference is a reference to a secret stored in a Hashicorp + - description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault displayName: From Vault path: config.recaptcha.privateKey.fromVault @@ -3074,7 +3074,7 @@ spec: - description: Public key displayName: Public Key path: config.recaptcha.publicKey - - description: VaultSecretReference is a reference to a secret stored in a Hashicorp + - description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault displayName: From Vault path: config.recaptcha.publicKey.fromVault @@ -3093,7 +3093,7 @@ spec: - description: Client ID displayName: Client ID path: config.redhatCustomerPortal.clientID - - description: VaultSecretReference is a reference to a secret stored in a Hashicorp + - description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault displayName: From Vault path: config.redhatCustomerPortal.clientID.fromVault @@ -3109,7 +3109,7 @@ spec: - description: Client secret displayName: Client Secret path: config.redhatCustomerPortal.clientSecret - - description: VaultSecretReference is a reference to a secret stored in a Hashicorp + - description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault displayName: From Vault path: config.redhatCustomerPortal.clientSecret.fromVault @@ -3149,7 +3149,7 @@ spec: - description: SecretKeyBase displayName: Secret Key Base path: config.secretKeyBase - - description: VaultSecretReference is a reference to a secret stored in a Hashicorp + - description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault displayName: From Vault path: config.secretKeyBase.fromVault @@ -3168,7 +3168,7 @@ spec: - description: Deletion token displayName: Deletion Token path: config.segment.deletionToken - - description: VaultSecretReference is a reference to a secret stored in a Hashicorp + - description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault displayName: From Vault path: config.segment.deletionToken.fromVault @@ -3187,7 +3187,7 @@ spec: - description: Write key displayName: Write Key path: config.segment.writeKey - - description: VaultSecretReference is a reference to a secret stored in a Hashicorp + - description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault displayName: From Vault path: config.segment.writeKey.fromVault @@ -3215,7 +3215,7 @@ spec: - description: Password displayName: Password path: config.smtp.password - - description: VaultSecretReference is a reference to a secret stored in a Hashicorp + - description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault displayName: From Vault path: config.smtp.password.fromVault @@ -3240,7 +3240,7 @@ spec: - description: User displayName: User path: config.smtp.user - - description: VaultSecretReference is a reference to a secret stored in a Hashicorp + - description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault displayName: From Vault path: config.smtp.user.fromVault @@ -3268,7 +3268,7 @@ spec: - description: Zync authentication token displayName: Auth Token path: config.zync.authToken - - description: VaultSecretReference is a reference to a secret stored in a Hashicorp + - description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault displayName: From Vault path: config.zync.authToken.fromVault @@ -3284,22 +3284,6 @@ spec: - description: Zync endpoint displayName: Endpoint path: config.zync.endpoint - - description: Zync authentication token - displayName: Zync Auth Token - path: config.zyncAuthToken - - description: VaultSecretReference is a reference to a secret stored in a Hashicorp - Vault - displayName: From Vault - path: config.zyncAuthToken.fromVault - - description: The Vault key of the secret - displayName: Key - path: config.zyncAuthToken.fromVault.key - - description: The Vault path where the secret is located - displayName: Path - path: config.zyncAuthToken.fromVault.path - - description: Override allows to directly specify a string value. - displayName: Override - path: config.zyncAuthToken.override - description: Console specific configuration options displayName: Console path: console @@ -4171,7 +4155,7 @@ spec: - description: API key displayName: APIKey path: config.bugsnag.apiKey - - description: VaultSecretReference is a reference to a secret stored in a Hashicorp + - description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault displayName: From Vault path: config.bugsnag.apiKey.fromVault @@ -4190,7 +4174,7 @@ spec: - description: A reference to the secret holding the database DSN displayName: Database DSN path: config.databaseDSN - - description: VaultSecretReference is a reference to a secret stored in a Hashicorp + - description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault displayName: From Vault path: config.databaseDSN.fromVault @@ -4235,7 +4219,7 @@ spec: - description: A reference to the secret holding the secret-key-base displayName: Secret Key Base path: config.secretKeyBase - - description: VaultSecretReference is a reference to a secret stored in a Hashicorp + - description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault displayName: From Vault path: config.secretKeyBase.fromVault @@ -4251,7 +4235,7 @@ spec: - description: A reference to the secret holding the zync authentication token displayName: Zync Auth Token path: config.zyncAuthToken - - description: VaultSecretReference is a reference to a secret stored in a Hashicorp + - description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault displayName: From Vault path: config.zyncAuthToken.fromVault diff --git a/bundle/manifests/saas.3scale.net_backends.yaml b/bundle/manifests/saas.3scale.net_backends.yaml index 732ef3a5..734a589d 100644 --- a/bundle/manifests/saas.3scale.net_backends.yaml +++ b/bundle/manifests/saas.3scale.net_backends.yaml @@ -42,7 +42,7 @@ spec: key properties: fromVault: - description: VaultSecretReference is a reference to a secret + description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault properties: key: @@ -65,7 +65,7 @@ spec: service properties: fromVault: - description: VaultSecretReference is a reference to a secret + description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault properties: key: @@ -107,7 +107,7 @@ spec: password properties: fromVault: - description: VaultSecretReference is a reference to a secret + description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault properties: key: @@ -130,7 +130,7 @@ spec: user properties: fromVault: - description: VaultSecretReference is a reference to a secret + description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault properties: key: @@ -166,7 +166,7 @@ spec: password properties: fromVault: - description: VaultSecretReference is a reference to a secret + description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault properties: key: @@ -189,7 +189,7 @@ spec: URL properties: fromVault: - description: VaultSecretReference is a reference to a secret + description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault properties: key: diff --git a/bundle/manifests/saas.3scale.net_corsproxies.yaml b/bundle/manifests/saas.3scale.net_corsproxies.yaml index a604e494..3faa2d86 100644 --- a/bundle/manifests/saas.3scale.net_corsproxies.yaml +++ b/bundle/manifests/saas.3scale.net_corsproxies.yaml @@ -60,7 +60,7 @@ spec: description: System database connection string properties: fromVault: - description: VaultSecretReference is a reference to a secret + description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault properties: key: diff --git a/bundle/manifests/saas.3scale.net_mappingservices.yaml b/bundle/manifests/saas.3scale.net_mappingservices.yaml index 27c865cf..b4238b4a 100644 --- a/bundle/manifests/saas.3scale.net_mappingservices.yaml +++ b/bundle/manifests/saas.3scale.net_mappingservices.yaml @@ -70,7 +70,7 @@ spec: token properties: fromVault: - description: VaultSecretReference is a reference to a secret + description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault properties: key: diff --git a/bundle/manifests/saas.3scale.net_systems.yaml b/bundle/manifests/saas.3scale.net_systems.yaml index 87f10e70..2c2adee9 100644 --- a/bundle/manifests/saas.3scale.net_systems.yaml +++ b/bundle/manifests/saas.3scale.net_systems.yaml @@ -657,7 +657,7 @@ spec: description: AccessCode to protect admin urls properties: fromVault: - description: VaultSecretReference is a reference to a secret + description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault properties: key: @@ -683,8 +683,8 @@ spec: description: AWS access key properties: fromVault: - description: VaultSecretReference is a reference to a - secret stored in a Hashicorp Vault + description: FromVault is a reference to a secret key/value + stored in a Hashicorp Vault properties: key: description: The Vault key of the secret @@ -714,8 +714,8 @@ spec: description: AWS secret access key properties: fromVault: - description: VaultSecretReference is a reference to a - secret stored in a Hashicorp Vault + description: FromVault is a reference to a secret key/value + stored in a Hashicorp Vault properties: key: description: The Vault key of the secret @@ -749,8 +749,8 @@ spec: description: Internal API password properties: fromVault: - description: VaultSecretReference is a reference to a - secret stored in a Hashicorp Vault + description: FromVault is a reference to a secret key/value + stored in a Hashicorp Vault properties: key: description: The Vault key of the secret @@ -771,8 +771,8 @@ spec: description: Internal API user properties: fromVault: - description: VaultSecretReference is a reference to a - secret stored in a Hashicorp Vault + description: FromVault is a reference to a secret key/value + stored in a Hashicorp Vault properties: key: description: The Vault key of the secret @@ -809,8 +809,8 @@ spec: description: API key properties: fromVault: - description: VaultSecretReference is a reference to a - secret stored in a Hashicorp Vault + description: FromVault is a reference to a secret key/value + stored in a Hashicorp Vault properties: key: description: The Vault key of the secret @@ -841,7 +841,7 @@ spec: description: DSN of system's main database properties: fromVault: - description: VaultSecretReference is a reference to a secret + description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault properties: key: @@ -863,7 +863,7 @@ spec: description: Database secret properties: fromVault: - description: VaultSecretReference is a reference to a secret + description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault properties: key: @@ -885,7 +885,7 @@ spec: description: EventsSharedSecret properties: fromVault: - description: VaultSecretReference is a reference to a secret + description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault properties: key: @@ -932,8 +932,8 @@ spec: description: Client ID properties: fromVault: - description: VaultSecretReference is a reference to a - secret stored in a Hashicorp Vault + description: FromVault is a reference to a secret key/value + stored in a Hashicorp Vault properties: key: description: The Vault key of the secret @@ -954,8 +954,8 @@ spec: description: Client secret properties: fromVault: - description: VaultSecretReference is a reference to a - secret stored in a Hashicorp Vault + description: FromVault is a reference to a secret key/value + stored in a Hashicorp Vault properties: key: description: The Vault key of the secret @@ -980,7 +980,7 @@ spec: description: Mapping Service access token properties: fromVault: - description: VaultSecretReference is a reference to a secret + description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault properties: key: @@ -1029,8 +1029,8 @@ spec: description: Private key properties: fromVault: - description: VaultSecretReference is a reference to a - secret stored in a Hashicorp Vault + description: FromVault is a reference to a secret key/value + stored in a Hashicorp Vault properties: key: description: The Vault key of the secret @@ -1051,8 +1051,8 @@ spec: description: Public key properties: fromVault: - description: VaultSecretReference is a reference to a - secret stored in a Hashicorp Vault + description: FromVault is a reference to a secret key/value + stored in a Hashicorp Vault properties: key: description: The Vault key of the secret @@ -1080,8 +1080,8 @@ spec: description: Client ID properties: fromVault: - description: VaultSecretReference is a reference to a - secret stored in a Hashicorp Vault + description: FromVault is a reference to a secret key/value + stored in a Hashicorp Vault properties: key: description: The Vault key of the secret @@ -1102,8 +1102,8 @@ spec: description: Client secret properties: fromVault: - description: VaultSecretReference is a reference to a - secret stored in a Hashicorp Vault + description: FromVault is a reference to a secret key/value + stored in a Hashicorp Vault properties: key: description: The Vault key of the secret @@ -1158,7 +1158,7 @@ spec: description: SecretKeyBase properties: fromVault: - description: VaultSecretReference is a reference to a secret + description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault properties: key: @@ -1183,8 +1183,8 @@ spec: description: Deletion token properties: fromVault: - description: VaultSecretReference is a reference to a - secret stored in a Hashicorp Vault + description: FromVault is a reference to a secret key/value + stored in a Hashicorp Vault properties: key: description: The Vault key of the secret @@ -1208,8 +1208,8 @@ spec: description: Write key properties: fromVault: - description: VaultSecretReference is a reference to a - secret stored in a Hashicorp Vault + description: FromVault is a reference to a secret key/value + stored in a Hashicorp Vault properties: key: description: The Vault key of the secret @@ -1247,8 +1247,8 @@ spec: description: Password properties: fromVault: - description: VaultSecretReference is a reference to a - secret stored in a Hashicorp Vault + description: FromVault is a reference to a secret key/value + stored in a Hashicorp Vault properties: key: description: The Vault key of the secret @@ -1279,8 +1279,8 @@ spec: description: User properties: fromVault: - description: VaultSecretReference is a reference to a - secret stored in a Hashicorp Vault + description: FromVault is a reference to a secret key/value + stored in a Hashicorp Vault properties: key: description: The Vault key of the secret @@ -1322,8 +1322,8 @@ spec: description: Zync authentication token properties: fromVault: - description: VaultSecretReference is a reference to a - secret stored in a Hashicorp Vault + description: FromVault is a reference to a secret key/value + stored in a Hashicorp Vault properties: key: description: The Vault key of the secret @@ -1347,28 +1347,6 @@ spec: - authToken - endpoint type: object - zyncAuthToken: - description: Zync authentication token - properties: - fromVault: - description: VaultSecretReference is a reference to a secret - stored in a Hashicorp Vault - properties: - key: - description: The Vault key of the secret - type: string - path: - description: The Vault path where the secret is located - type: string - required: - - key - - path - type: object - override: - description: Override allows to directly specify a string - value. - type: string - type: object required: - assets - backend diff --git a/bundle/manifests/saas.3scale.net_zyncs.yaml b/bundle/manifests/saas.3scale.net_zyncs.yaml index 9349f16e..963c9ed2 100644 --- a/bundle/manifests/saas.3scale.net_zyncs.yaml +++ b/bundle/manifests/saas.3scale.net_zyncs.yaml @@ -579,8 +579,8 @@ spec: description: API key properties: fromVault: - description: VaultSecretReference is a reference to a - secret stored in a Hashicorp Vault + description: FromVault is a reference to a secret key/value + stored in a Hashicorp Vault properties: key: description: The Vault key of the secret @@ -607,7 +607,7 @@ spec: description: A reference to the secret holding the database DSN properties: fromVault: - description: VaultSecretReference is a reference to a secret + description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault properties: key: @@ -670,7 +670,7 @@ spec: description: A reference to the secret holding the secret-key-base properties: fromVault: - description: VaultSecretReference is a reference to a secret + description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault properties: key: @@ -693,7 +693,7 @@ spec: token properties: fromVault: - description: VaultSecretReference is a reference to a secret + description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault properties: key: diff --git a/config/crd/bases/saas.3scale.net_backends.yaml b/config/crd/bases/saas.3scale.net_backends.yaml index 9f5a8fa7..9280e3b0 100644 --- a/config/crd/bases/saas.3scale.net_backends.yaml +++ b/config/crd/bases/saas.3scale.net_backends.yaml @@ -43,7 +43,7 @@ spec: key properties: fromVault: - description: VaultSecretReference is a reference to a secret + description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault properties: key: @@ -66,7 +66,7 @@ spec: service properties: fromVault: - description: VaultSecretReference is a reference to a secret + description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault properties: key: @@ -108,7 +108,7 @@ spec: password properties: fromVault: - description: VaultSecretReference is a reference to a secret + description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault properties: key: @@ -131,7 +131,7 @@ spec: user properties: fromVault: - description: VaultSecretReference is a reference to a secret + description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault properties: key: @@ -167,7 +167,7 @@ spec: password properties: fromVault: - description: VaultSecretReference is a reference to a secret + description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault properties: key: @@ -190,7 +190,7 @@ spec: URL properties: fromVault: - description: VaultSecretReference is a reference to a secret + description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault properties: key: diff --git a/config/crd/bases/saas.3scale.net_corsproxies.yaml b/config/crd/bases/saas.3scale.net_corsproxies.yaml index a34bd65c..bb23409c 100644 --- a/config/crd/bases/saas.3scale.net_corsproxies.yaml +++ b/config/crd/bases/saas.3scale.net_corsproxies.yaml @@ -61,7 +61,7 @@ spec: description: System database connection string properties: fromVault: - description: VaultSecretReference is a reference to a secret + description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault properties: key: diff --git a/config/crd/bases/saas.3scale.net_mappingservices.yaml b/config/crd/bases/saas.3scale.net_mappingservices.yaml index ef40d3f0..71649581 100644 --- a/config/crd/bases/saas.3scale.net_mappingservices.yaml +++ b/config/crd/bases/saas.3scale.net_mappingservices.yaml @@ -71,7 +71,7 @@ spec: token properties: fromVault: - description: VaultSecretReference is a reference to a secret + description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault properties: key: diff --git a/config/crd/bases/saas.3scale.net_systems.yaml b/config/crd/bases/saas.3scale.net_systems.yaml index ee24eeb0..f332151c 100644 --- a/config/crd/bases/saas.3scale.net_systems.yaml +++ b/config/crd/bases/saas.3scale.net_systems.yaml @@ -658,7 +658,7 @@ spec: description: AccessCode to protect admin urls properties: fromVault: - description: VaultSecretReference is a reference to a secret + description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault properties: key: @@ -684,8 +684,8 @@ spec: description: AWS access key properties: fromVault: - description: VaultSecretReference is a reference to a - secret stored in a Hashicorp Vault + description: FromVault is a reference to a secret key/value + stored in a Hashicorp Vault properties: key: description: The Vault key of the secret @@ -715,8 +715,8 @@ spec: description: AWS secret access key properties: fromVault: - description: VaultSecretReference is a reference to a - secret stored in a Hashicorp Vault + description: FromVault is a reference to a secret key/value + stored in a Hashicorp Vault properties: key: description: The Vault key of the secret @@ -750,8 +750,8 @@ spec: description: Internal API password properties: fromVault: - description: VaultSecretReference is a reference to a - secret stored in a Hashicorp Vault + description: FromVault is a reference to a secret key/value + stored in a Hashicorp Vault properties: key: description: The Vault key of the secret @@ -772,8 +772,8 @@ spec: description: Internal API user properties: fromVault: - description: VaultSecretReference is a reference to a - secret stored in a Hashicorp Vault + description: FromVault is a reference to a secret key/value + stored in a Hashicorp Vault properties: key: description: The Vault key of the secret @@ -810,8 +810,8 @@ spec: description: API key properties: fromVault: - description: VaultSecretReference is a reference to a - secret stored in a Hashicorp Vault + description: FromVault is a reference to a secret key/value + stored in a Hashicorp Vault properties: key: description: The Vault key of the secret @@ -842,7 +842,7 @@ spec: description: DSN of system's main database properties: fromVault: - description: VaultSecretReference is a reference to a secret + description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault properties: key: @@ -864,7 +864,7 @@ spec: description: Database secret properties: fromVault: - description: VaultSecretReference is a reference to a secret + description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault properties: key: @@ -886,7 +886,7 @@ spec: description: EventsSharedSecret properties: fromVault: - description: VaultSecretReference is a reference to a secret + description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault properties: key: @@ -933,8 +933,8 @@ spec: description: Client ID properties: fromVault: - description: VaultSecretReference is a reference to a - secret stored in a Hashicorp Vault + description: FromVault is a reference to a secret key/value + stored in a Hashicorp Vault properties: key: description: The Vault key of the secret @@ -955,8 +955,8 @@ spec: description: Client secret properties: fromVault: - description: VaultSecretReference is a reference to a - secret stored in a Hashicorp Vault + description: FromVault is a reference to a secret key/value + stored in a Hashicorp Vault properties: key: description: The Vault key of the secret @@ -981,7 +981,7 @@ spec: description: Mapping Service access token properties: fromVault: - description: VaultSecretReference is a reference to a secret + description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault properties: key: @@ -1030,8 +1030,8 @@ spec: description: Private key properties: fromVault: - description: VaultSecretReference is a reference to a - secret stored in a Hashicorp Vault + description: FromVault is a reference to a secret key/value + stored in a Hashicorp Vault properties: key: description: The Vault key of the secret @@ -1052,8 +1052,8 @@ spec: description: Public key properties: fromVault: - description: VaultSecretReference is a reference to a - secret stored in a Hashicorp Vault + description: FromVault is a reference to a secret key/value + stored in a Hashicorp Vault properties: key: description: The Vault key of the secret @@ -1081,8 +1081,8 @@ spec: description: Client ID properties: fromVault: - description: VaultSecretReference is a reference to a - secret stored in a Hashicorp Vault + description: FromVault is a reference to a secret key/value + stored in a Hashicorp Vault properties: key: description: The Vault key of the secret @@ -1103,8 +1103,8 @@ spec: description: Client secret properties: fromVault: - description: VaultSecretReference is a reference to a - secret stored in a Hashicorp Vault + description: FromVault is a reference to a secret key/value + stored in a Hashicorp Vault properties: key: description: The Vault key of the secret @@ -1159,7 +1159,7 @@ spec: description: SecretKeyBase properties: fromVault: - description: VaultSecretReference is a reference to a secret + description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault properties: key: @@ -1184,8 +1184,8 @@ spec: description: Deletion token properties: fromVault: - description: VaultSecretReference is a reference to a - secret stored in a Hashicorp Vault + description: FromVault is a reference to a secret key/value + stored in a Hashicorp Vault properties: key: description: The Vault key of the secret @@ -1209,8 +1209,8 @@ spec: description: Write key properties: fromVault: - description: VaultSecretReference is a reference to a - secret stored in a Hashicorp Vault + description: FromVault is a reference to a secret key/value + stored in a Hashicorp Vault properties: key: description: The Vault key of the secret @@ -1248,8 +1248,8 @@ spec: description: Password properties: fromVault: - description: VaultSecretReference is a reference to a - secret stored in a Hashicorp Vault + description: FromVault is a reference to a secret key/value + stored in a Hashicorp Vault properties: key: description: The Vault key of the secret @@ -1280,8 +1280,8 @@ spec: description: User properties: fromVault: - description: VaultSecretReference is a reference to a - secret stored in a Hashicorp Vault + description: FromVault is a reference to a secret key/value + stored in a Hashicorp Vault properties: key: description: The Vault key of the secret @@ -1323,8 +1323,8 @@ spec: description: Zync authentication token properties: fromVault: - description: VaultSecretReference is a reference to a - secret stored in a Hashicorp Vault + description: FromVault is a reference to a secret key/value + stored in a Hashicorp Vault properties: key: description: The Vault key of the secret @@ -1348,28 +1348,6 @@ spec: - authToken - endpoint type: object - zyncAuthToken: - description: Zync authentication token - properties: - fromVault: - description: VaultSecretReference is a reference to a secret - stored in a Hashicorp Vault - properties: - key: - description: The Vault key of the secret - type: string - path: - description: The Vault path where the secret is located - type: string - required: - - key - - path - type: object - override: - description: Override allows to directly specify a string - value. - type: string - type: object required: - assets - backend diff --git a/config/crd/bases/saas.3scale.net_zyncs.yaml b/config/crd/bases/saas.3scale.net_zyncs.yaml index 62e8d2c4..a1d75180 100644 --- a/config/crd/bases/saas.3scale.net_zyncs.yaml +++ b/config/crd/bases/saas.3scale.net_zyncs.yaml @@ -580,8 +580,8 @@ spec: description: API key properties: fromVault: - description: VaultSecretReference is a reference to a - secret stored in a Hashicorp Vault + description: FromVault is a reference to a secret key/value + stored in a Hashicorp Vault properties: key: description: The Vault key of the secret @@ -608,7 +608,7 @@ spec: description: A reference to the secret holding the database DSN properties: fromVault: - description: VaultSecretReference is a reference to a secret + description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault properties: key: @@ -671,7 +671,7 @@ spec: description: A reference to the secret holding the secret-key-base properties: fromVault: - description: VaultSecretReference is a reference to a secret + description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault properties: key: @@ -694,7 +694,7 @@ spec: token properties: fromVault: - description: VaultSecretReference is a reference to a secret + description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault properties: key: diff --git a/config/manifests/bases/saas-operator.clusterserviceversion.yaml b/config/manifests/bases/saas-operator.clusterserviceversion.yaml index 3676c55b..f4122de3 100644 --- a/config/manifests/bases/saas-operator.clusterserviceversion.yaml +++ b/config/manifests/bases/saas-operator.clusterserviceversion.yaml @@ -849,7 +849,7 @@ spec: key displayName: Error Monitoring Key path: config.errorMonitoringKey - - description: VaultSecretReference is a reference to a secret stored in a Hashicorp + - description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault displayName: From Vault path: config.errorMonitoringKey.fromVault @@ -866,7 +866,7 @@ spec: service displayName: Error Monitoring Service path: config.errorMonitoringService - - description: VaultSecretReference is a reference to a secret stored in a Hashicorp + - description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault displayName: From Vault path: config.errorMonitoringService.fromVault @@ -899,7 +899,7 @@ spec: - description: A reference to the secret holding the backend-internal-api password displayName: Internal APIPassword path: config.internalAPIPassword - - description: VaultSecretReference is a reference to a secret stored in a Hashicorp + - description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault displayName: From Vault path: config.internalAPIPassword.fromVault @@ -915,7 +915,7 @@ spec: - description: A reference to the secret holding the backend-internal-api user displayName: Internal APIUser path: config.internalAPIUser - - description: VaultSecretReference is a reference to a secret stored in a Hashicorp + - description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault displayName: From Vault path: config.internalAPIUser.fromVault @@ -944,7 +944,7 @@ spec: password displayName: System Events Hook Password path: config.systemEventsHookPassword - - description: VaultSecretReference is a reference to a secret stored in a Hashicorp + - description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault displayName: From Vault path: config.systemEventsHookPassword.fromVault @@ -961,7 +961,7 @@ spec: URL displayName: System Events Hook URL path: config.systemEventsHookURL - - description: VaultSecretReference is a reference to a secret stored in a Hashicorp + - description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault displayName: From Vault path: config.systemEventsHookURL.fromVault @@ -1481,7 +1481,7 @@ spec: - description: System database connection string displayName: System Database DSN path: config.systemDatabaseDSN - - description: VaultSecretReference is a reference to a secret stored in a Hashicorp + - description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault displayName: From Vault path: config.systemDatabaseDSN.fromVault @@ -1834,7 +1834,7 @@ spec: - description: A reference to the secret holding the system admin token displayName: System Admin Token path: config.systemAdminToken - - description: VaultSecretReference is a reference to a secret stored in a Hashicorp + - description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault displayName: From Vault path: config.systemAdminToken.fromVault @@ -2335,7 +2335,7 @@ spec: - description: AccessCode to protect admin urls displayName: Access Code path: config.accessCode - - description: VaultSecretReference is a reference to a secret stored in a Hashicorp + - description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault displayName: From Vault path: config.accessCode.fromVault @@ -2351,7 +2351,7 @@ spec: - description: AWS access key displayName: Access Key path: config.assets.accessKey - - description: VaultSecretReference is a reference to a secret stored in a Hashicorp + - description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault displayName: From Vault path: config.assets.accessKey.fromVault @@ -2376,7 +2376,7 @@ spec: - description: AWS secret access key displayName: Secret Key path: config.assets.secretKey - - description: VaultSecretReference is a reference to a secret stored in a Hashicorp + - description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault displayName: From Vault path: config.assets.secretKey.fromVault @@ -2398,7 +2398,7 @@ spec: - description: Internal API password displayName: Internal APIPassword path: config.backend.internalAPIPassword - - description: VaultSecretReference is a reference to a secret stored in a Hashicorp + - description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault displayName: From Vault path: config.backend.internalAPIPassword.fromVault @@ -2414,7 +2414,7 @@ spec: - description: Internal API user displayName: Internal APIUser path: config.backend.internalAPIUser - - description: VaultSecretReference is a reference to a secret stored in a Hashicorp + - description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault displayName: From Vault path: config.backend.internalAPIUser.fromVault @@ -2439,7 +2439,7 @@ spec: - description: API key displayName: APIKey path: config.bugsnag.apiKey - - description: VaultSecretReference is a reference to a secret stored in a Hashicorp + - description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault displayName: From Vault path: config.bugsnag.apiKey.fromVault @@ -2462,7 +2462,7 @@ spec: - description: DSN of system's main database displayName: Database DSN path: config.databaseDSN - - description: VaultSecretReference is a reference to a secret stored in a Hashicorp + - description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault displayName: From Vault path: config.databaseDSN.fromVault @@ -2478,7 +2478,7 @@ spec: - description: Database secret displayName: Database Secret path: config.databaseSecret - - description: VaultSecretReference is a reference to a secret stored in a Hashicorp + - description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault displayName: From Vault path: config.databaseSecret.fromVault @@ -2494,7 +2494,7 @@ spec: - description: EventsSharedSecret displayName: Events Shared Secret path: config.eventsSharedSecret - - description: VaultSecretReference is a reference to a secret stored in a Hashicorp + - description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault displayName: From Vault path: config.eventsSharedSecret.fromVault @@ -2533,7 +2533,7 @@ spec: - description: Client ID displayName: Client ID path: config.github.clientID - - description: VaultSecretReference is a reference to a secret stored in a Hashicorp + - description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault displayName: From Vault path: config.github.clientID.fromVault @@ -2549,7 +2549,7 @@ spec: - description: Client secret displayName: Client Secret path: config.github.clientSecret - - description: VaultSecretReference is a reference to a secret stored in a Hashicorp + - description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault displayName: From Vault path: config.github.clientSecret.fromVault @@ -2565,7 +2565,7 @@ spec: - description: Mapping Service access token displayName: Mapping Service Access Token path: config.mappingServiceAccessToken - - description: VaultSecretReference is a reference to a secret stored in a Hashicorp + - description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault displayName: From Vault path: config.mappingServiceAccessToken.fromVault @@ -2599,7 +2599,7 @@ spec: - description: Private key displayName: Private Key path: config.recaptcha.privateKey - - description: VaultSecretReference is a reference to a secret stored in a Hashicorp + - description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault displayName: From Vault path: config.recaptcha.privateKey.fromVault @@ -2615,7 +2615,7 @@ spec: - description: Public key displayName: Public Key path: config.recaptcha.publicKey - - description: VaultSecretReference is a reference to a secret stored in a Hashicorp + - description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault displayName: From Vault path: config.recaptcha.publicKey.fromVault @@ -2634,7 +2634,7 @@ spec: - description: Client ID displayName: Client ID path: config.redhatCustomerPortal.clientID - - description: VaultSecretReference is a reference to a secret stored in a Hashicorp + - description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault displayName: From Vault path: config.redhatCustomerPortal.clientID.fromVault @@ -2650,7 +2650,7 @@ spec: - description: Client secret displayName: Client Secret path: config.redhatCustomerPortal.clientSecret - - description: VaultSecretReference is a reference to a secret stored in a Hashicorp + - description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault displayName: From Vault path: config.redhatCustomerPortal.clientSecret.fromVault @@ -2690,7 +2690,7 @@ spec: - description: SecretKeyBase displayName: Secret Key Base path: config.secretKeyBase - - description: VaultSecretReference is a reference to a secret stored in a Hashicorp + - description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault displayName: From Vault path: config.secretKeyBase.fromVault @@ -2709,7 +2709,7 @@ spec: - description: Deletion token displayName: Deletion Token path: config.segment.deletionToken - - description: VaultSecretReference is a reference to a secret stored in a Hashicorp + - description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault displayName: From Vault path: config.segment.deletionToken.fromVault @@ -2728,7 +2728,7 @@ spec: - description: Write key displayName: Write Key path: config.segment.writeKey - - description: VaultSecretReference is a reference to a secret stored in a Hashicorp + - description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault displayName: From Vault path: config.segment.writeKey.fromVault @@ -2756,7 +2756,7 @@ spec: - description: Password displayName: Password path: config.smtp.password - - description: VaultSecretReference is a reference to a secret stored in a Hashicorp + - description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault displayName: From Vault path: config.smtp.password.fromVault @@ -2781,7 +2781,7 @@ spec: - description: User displayName: User path: config.smtp.user - - description: VaultSecretReference is a reference to a secret stored in a Hashicorp + - description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault displayName: From Vault path: config.smtp.user.fromVault @@ -2809,7 +2809,7 @@ spec: - description: Zync authentication token displayName: Auth Token path: config.zync.authToken - - description: VaultSecretReference is a reference to a secret stored in a Hashicorp + - description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault displayName: From Vault path: config.zync.authToken.fromVault @@ -2825,22 +2825,6 @@ spec: - description: Zync endpoint displayName: Endpoint path: config.zync.endpoint - - description: Zync authentication token - displayName: Zync Auth Token - path: config.zyncAuthToken - - description: VaultSecretReference is a reference to a secret stored in a Hashicorp - Vault - displayName: From Vault - path: config.zyncAuthToken.fromVault - - description: The Vault key of the secret - displayName: Key - path: config.zyncAuthToken.fromVault.key - - description: The Vault path where the secret is located - displayName: Path - path: config.zyncAuthToken.fromVault.path - - description: Override allows to directly specify a string value. - displayName: Override - path: config.zyncAuthToken.override - description: Console specific configuration options displayName: Console path: console @@ -3712,7 +3696,7 @@ spec: - description: API key displayName: APIKey path: config.bugsnag.apiKey - - description: VaultSecretReference is a reference to a secret stored in a Hashicorp + - description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault displayName: From Vault path: config.bugsnag.apiKey.fromVault @@ -3731,7 +3715,7 @@ spec: - description: A reference to the secret holding the database DSN displayName: Database DSN path: config.databaseDSN - - description: VaultSecretReference is a reference to a secret stored in a Hashicorp + - description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault displayName: From Vault path: config.databaseDSN.fromVault @@ -3776,7 +3760,7 @@ spec: - description: A reference to the secret holding the secret-key-base displayName: Secret Key Base path: config.secretKeyBase - - description: VaultSecretReference is a reference to a secret stored in a Hashicorp + - description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault displayName: From Vault path: config.secretKeyBase.fromVault @@ -3792,7 +3776,7 @@ spec: - description: A reference to the secret holding the zync authentication token displayName: Zync Auth Token path: config.zyncAuthToken - - description: VaultSecretReference is a reference to a secret stored in a Hashicorp + - description: FromVault is a reference to a secret key/value stored in a Hashicorp Vault displayName: From Vault path: config.zyncAuthToken.fromVault diff --git a/controllers/system_controller_suite_test.go b/controllers/system_controller_suite_test.go index c97af4d8..1211fcbe 100644 --- a/controllers/system_controller_suite_test.go +++ b/controllers/system_controller_suite_test.go @@ -104,7 +104,7 @@ var _ = Describe("System controller", func() { STARTTLS: util.Pointer(false), }, MappingServiceAccessToken: saasv1alpha1.SecretReference{Override: util.Pointer("override")}, - Zync: &saasv1alpha1.SystemZyncSpec{ + Zync: saasv1alpha1.SystemZyncSpec{ AuthToken: saasv1alpha1.SecretReference{Override: util.Pointer("override")}, Endpoint: "value", }, diff --git a/go.mod b/go.mod index 6565c6c9..f0a07dc3 100644 --- a/go.mod +++ b/go.mod @@ -41,6 +41,8 @@ require ( sigs.k8s.io/yaml v1.3.0 ) +require github.com/huandu/go-clone v1.6.0 // indirect + // For local dev uncomment this and point it to the correct path in your system // replace github.com/3scale-ops/basereconciler => /home/roi/github.com/3scale/basereconciler @@ -91,6 +93,7 @@ require ( github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect + github.com/huandu/go-clone/generic v1.7.2 github.com/imdario/mergo v0.3.13 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect diff --git a/go.sum b/go.sum index 98a959bc..07216148 100644 --- a/go.sum +++ b/go.sum @@ -39,11 +39,17 @@ github.com/3scale-ops/basereconciler v0.4.0 h1:p4xpxwqWnCybHu6uxb6KxW9tKvpgk5+ry github.com/3scale-ops/basereconciler v0.4.0/go.mod h1:QuHsnYMbPQYKZjXjKX93efNI2VH2jVio4emJVJy7sRg= github.com/3scale-ops/marin3r v0.12.2 h1:sU4N7RZ5AQzfejrfP0KgpagmL/XD8a5NdSIv1qvaAnU= github.com/3scale-ops/marin3r v0.12.2/go.mod h1:BOU7EFv58PgPMgKgJFDd4ingfBhH6KC2AGJoD7i9SaU= +github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= +github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= +github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= +github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= +github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ= github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= +github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= @@ -102,6 +108,7 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ= github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= +github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= github.com/blendle/zapdriver v1.3.1 h1:C3dydBOWYRiOk+B8X9IVZ5IOe+7cl+tGOexN4QqHfpE= github.com/blendle/zapdriver v1.3.1/go.mod h1:mdXfREi6u5MArG4j9fewC+FGnXaBR+T4Ox4J2u4eHCc= github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= @@ -126,6 +133,8 @@ github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWH github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4 h1:/inchEIKaYC1Akx+H+gqO04wryn5h75LSazbRlnya1k= github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/dave/dst v0.26.2/go.mod h1:UMDJuIRPfyUCC78eFuB+SV/WI8oDeyFDvM/JR6NI3IU= github.com/dave/gopackages v0.0.0-20170318123100-46e7023ec56e/go.mod h1:i00+b/gKdIDIxuLDFob7ustLAVqhsZRk2qVZrArELGQ= @@ -139,6 +148,7 @@ github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/r github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153 h1:yUdfgN0XgIJw7foRItutHYUIhlcKzcSf5vDpdhQAKTc= github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= @@ -166,6 +176,7 @@ github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2Vvl github.com/external-secrets/external-secrets v0.8.1 h1:LI7lYmR04Zi2gMVdgifTtyGKfBtYrCA380ePgds2gsY= github.com/external-secrets/external-secrets v0.8.1/go.mod h1:N5TxTxHLbCK2vVmcUAbUUorwuZiKxJqd/j8I65+44Zc= github.com/flowstack/go-jsonschema v0.1.1/go.mod h1:yL7fNggx1o8rm9RlgXv7hTBWxdBM0rVwpMwimd3F3N0= +github.com/form3tech-oss/jwt-go v3.2.3+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= @@ -259,6 +270,7 @@ github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= github.com/google/gnostic v0.5.7-v3refs/go.mod h1:73MKFl6jIHelAJNaBGFzt3SPtZULs9dYrGFt8OiIsHQ= github.com/google/gnostic v0.6.9 h1:ZK/5VhkoX835RikCHpSUJV9a+S3e1zLh59YnyWeBW+0= github.com/google/gnostic v0.6.9/go.mod h1:Nm8234We1lq6iB9OmlgNv3nH91XLLVZHCDayfA3xq+E= @@ -309,6 +321,9 @@ github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB7 github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/grafana-operator/grafana-operator/v4 v4.10.0 h1:+AVEPP/wflmx5ySdzt1mIw+q63ZYVInxQhF3XKNhJv4= github.com/grafana-operator/grafana-operator/v4 v4.10.0/go.mod h1:k69wJcXVrqAcZBoGuh5LSqz0ak8LlVOxxqp0W3f/4V8= +github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= +github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.14.6/go.mod h1:zdiPV4Yse/1gnckTHtghG4GkDEdKCRJduHpTxT3/jcw= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks= @@ -323,12 +338,19 @@ github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/huandu/go-assert v1.1.5/go.mod h1:yOLvuqZwmcHIC5rIzrBhT7D3Q9c3GFnd0JrPVhn/06U= +github.com/huandu/go-clone v1.6.0 h1:HMo5uvg4wgfiy5FoGOqlFLQED/VGRm2D9Pi8g1FXPGc= +github.com/huandu/go-clone v1.6.0/go.mod h1:ReGivhG6op3GYr+UY3lS6mxjKp7MIGTknuU5TbTVaXE= +github.com/huandu/go-clone/generic v1.7.2 h1:47pQphxs1Xc9cVADjOHN+Bm5D0hNagwH9UXErbxgVKA= +github.com/huandu/go-clone/generic v1.7.2/go.mod h1:xgd9ZebcMsBWWcBx5mVMCoqMX24gLWr5lQicr+nVXNs= +github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk= github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= +github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= @@ -367,6 +389,7 @@ github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJ github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/moby/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8= github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= @@ -388,8 +411,10 @@ github.com/nsf/jsondiff v0.0.0-20230430225905-43f6cf3098c1 h1:dOYG7LS/WK00RWZc8X github.com/nsf/jsondiff v0.0.0-20230430225905-43f6cf3098c1/go.mod h1:mpRZBD8SJ55OIICQ3iWH0Yz3cjzA61JdqMLoWXeB2+8= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/ohler55/ojg v1.20.3 h1:Z+fnElsA/GbI5oiT726qJaG4Ca9q5l7UO68Qd0PtkD4= github.com/ohler55/ojg v1.20.3/go.mod h1:uHcD1ErbErC27Zhb5Df2jUjbseLLcmOCo6oxSr3jZxo= +github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -409,6 +434,7 @@ github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3I github.com/openshift/api v0.0.0-20220715133027-dab5b363ebd1 h1:FzCXZdnkGLus4hHu7/d/utr3ELPiwNt2ffAqSspi6U8= github.com/openshift/api v0.0.0-20220715133027-dab5b363ebd1/go.mod h1:LEnw1IVscIxyDnltE3Wi7bQb/QzIM8BfPNKoGA1Qlxw= github.com/openshift/build-machinery-go v0.0.0-20211213093930-7e33a7eb4ce3/go.mod h1:b1BuldmJlbA/xYtdZvKi+7j5YGB44qJUJDZ9zwiNCfE= +github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5 h1:Ii+DKncOVM8Cu1Hc+ETb5K+23HdAMvESYE3ZJ5b5cMI= github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -450,14 +476,17 @@ github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzG github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/samber/lo v1.39.0 h1:4gTz1wUhNYLhFSKl6O+8peW0v2F4BCY034GRpU9WnuA= github.com/samber/lo v1.39.0/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= +github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= +github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4= github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= @@ -478,15 +507,18 @@ github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY= github.com/tektoncd/pipeline v0.49.0 h1:LxpgoPZvIDiOvPj6vtInnGG0uzuQ5CPA+h8FdJdklh4= github.com/tektoncd/pipeline v0.49.0/go.mod h1:R3Qn/oTTf1SCLrj+rCg4sqUbpx7vE+6D8Z81+zKUdqQ= +github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= +github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= @@ -546,6 +578,7 @@ golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHl golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= @@ -861,6 +894,7 @@ gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= gopkg.in/src-d/go-billy.v4 v4.3.0/go.mod h1:tm33zBoOwxjYHZIE+OV8bxTWFMJLrconzFMd38aARFk= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= @@ -879,6 +913,7 @@ gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/pkg/generators/apicast/config/options.go b/pkg/generators/apicast/config/options.go index 77604a7b..9a4bca28 100644 --- a/pkg/generators/apicast/config/options.go +++ b/pkg/generators/apicast/config/options.go @@ -1,35 +1,21 @@ package config import ( - "fmt" - saasv1alpha1 "github.com/3scale-ops/saas-operator/api/v1alpha1" "github.com/3scale-ops/saas-operator/pkg/resource_builders/pod" ) -// EnvOptions holds configuration for the apicasts pods -type EnvOptions struct { - ApicastConfigurationLoader pod.EnvVarValue `env:"APICAST_CONFIGURATION_LOADER"` - ApicastConfigurationCache pod.EnvVarValue `env:"APICAST_CONFIGURATION_CACHE"` - ApicastExtendedMetrics pod.EnvVarValue `env:"APICAST_EXTENDED_METRICS"` - ThreeScaleDeploymentEnv pod.EnvVarValue `env:"THREESCALE_DEPLOYMENT_ENV"` - ThreescalePortalEndpoint pod.EnvVarValue `env:"THREESCALE_PORTAL_ENDPOINT"` - ApicastLogLevel pod.EnvVarValue `env:"APICAST_LOG_LEVEL"` - ApicastOIDCLogLevel pod.EnvVarValue `env:"APICAST_OIDC_LOG_LEVEL"` - ApicastResponseCodes pod.EnvVarValue `env:"APICAST_RESPONSE_CODES"` -} +func NewEnvOptions(spec saasv1alpha1.ApicastEnvironmentSpec, env string) pod.Options { + opts := pod.Options{} + + opts.Unpack("lazy").IntoEnvvar("APICAST_CONFIGURATION_LOADER") + opts.Unpack(spec.Config.ConfigurationCache).IntoEnvvar("APICAST_CONFIGURATION_CACHE") + opts.Unpack("true").IntoEnvvar("APICAST_EXTENDED_METRICS") + opts.Unpack(env).IntoEnvvar("THREESCALE_DEPLOYMENT_ENV") + opts.Unpack(spec.Config.ThreescalePortalEndpoint).IntoEnvvar("THREESCALE_PORTAL_ENDPOINT") + opts.Unpack(spec.Config.LogLevel).IntoEnvvar("APICAST_LOG_LEVEL") + opts.Unpack(spec.Config.OIDCLogLevel).IntoEnvvar("APICAST_OIDC_LOG_LEVEL") + opts.Unpack("true").IntoEnvvar("APICAST_RESPONSE_CODES") -// NewEnvOptions returns an Options struct for the given saasv1alpha1.ApicastEnvironmentSpec -func NewEnvOptions(spec saasv1alpha1.ApicastEnvironmentSpec, env string) EnvOptions { - opts := EnvOptions{ - ApicastConfigurationLoader: &pod.ClearTextValue{Value: "lazy"}, - ApicastConfigurationCache: &pod.ClearTextValue{Value: fmt.Sprintf("%d", spec.Config.ConfigurationCache)}, - ApicastExtendedMetrics: &pod.ClearTextValue{Value: "true"}, - ThreeScaleDeploymentEnv: &pod.ClearTextValue{Value: env}, - ThreescalePortalEndpoint: &pod.ClearTextValue{Value: spec.Config.ThreescalePortalEndpoint}, - ApicastLogLevel: &pod.ClearTextValue{Value: *spec.Config.LogLevel}, - ApicastOIDCLogLevel: &pod.ClearTextValue{Value: *spec.Config.OIDCLogLevel}, - ApicastResponseCodes: &pod.ClearTextValue{Value: "true"}, - } return opts } diff --git a/pkg/generators/apicast/deployment.go b/pkg/generators/apicast/deployment.go index 498edcb5..84d5bcf4 100644 --- a/pkg/generators/apicast/deployment.go +++ b/pkg/generators/apicast/deployment.go @@ -40,7 +40,7 @@ func (gen *EnvGenerator) deployment() *appsv1.Deployment { pod.ContainerPortTCP("management", 8090), pod.ContainerPortTCP("metrics", 9421), ), - Env: pod.BuildEnvironment(gen.Options), + Env: gen.Options.BuildEnvironment(), Resources: corev1.ResourceRequirements(*gen.Spec.Resources), LivenessProbe: pod.TCPProbe(intstr.FromString("gateway"), *gen.Spec.LivenessProbe), ReadinessProbe: pod.HTTPProbe("/status/ready", intstr.FromString("management"), corev1.URISchemeHTTP, *gen.Spec.ReadinessProbe), diff --git a/pkg/generators/apicast/generator.go b/pkg/generators/apicast/generator.go index 39d2e1ea..1e4d199c 100644 --- a/pkg/generators/apicast/generator.go +++ b/pkg/generators/apicast/generator.go @@ -10,6 +10,7 @@ import ( "github.com/3scale-ops/saas-operator/pkg/generators/apicast/config" descriptor "github.com/3scale-ops/saas-operator/pkg/resource_builders/envoyconfig/descriptor" "github.com/3scale-ops/saas-operator/pkg/resource_builders/grafanadashboard" + "github.com/3scale-ops/saas-operator/pkg/resource_builders/pod" "github.com/3scale-ops/saas-operator/pkg/resource_builders/podmonitor" operatorutil "github.com/3scale-ops/saas-operator/pkg/util" deployment_workload "github.com/3scale-ops/saas-operator/pkg/workloads/deployment" @@ -167,7 +168,7 @@ func (gen *Generator) Resources() ([]resource.TemplateInterface, error) { type EnvGenerator struct { generators.BaseOptionsV2 Spec saasv1alpha1.ApicastEnvironmentSpec - Options config.EnvOptions + Options pod.Options Traffic bool } diff --git a/pkg/generators/autossl/config/options.go b/pkg/generators/autossl/config/options.go index b8d57575..a29b9283 100644 --- a/pkg/generators/autossl/config/options.go +++ b/pkg/generators/autossl/config/options.go @@ -1,7 +1,6 @@ package config import ( - "fmt" "strings" saasv1alpha1 "github.com/3scale-ops/saas-operator/api/v1alpha1" @@ -12,39 +11,24 @@ const ( leACMEStagingEndpoint = "https://acme-staging-v02.api.letsencrypt.org/directory" ) -// Options holds configuration for the autossl pods -type Options struct { - ACMEStaging pod.EnvVarValue `env:"ACME_STAGING"` - ContactEmail pod.EnvVarValue `env:"CONTACT_EMAIL"` - ProxyEndpoint pod.EnvVarValue `env:"PROXY_ENDPOINT"` - StorageAdapter pod.EnvVarValue `env:"STORAGE_ADAPTER"` - RedisHost pod.EnvVarValue `env:"REDIS_HOST"` - RedisPort pod.EnvVarValue `env:"REDIS_PORT"` - VerificationEndpoint pod.EnvVarValue `env:"VERIFICATION_ENDPOINT"` - LogLevel pod.EnvVarValue `env:"LOG_LEVEL"` - DomainWhitelist pod.EnvVarValue `env:"DOMAIN_WHITELIST"` - DomainBlacklist pod.EnvVarValue `env:"DOMAIN_BLACKLIST"` -} +func NewOptions(spec saasv1alpha1.AutoSSLSpec) pod.Options { + opts := pod.Options{} -// NewOptions returns an Options struct for the given saasv1alpha1.AutoSSLSpec -func NewOptions(spec saasv1alpha1.AutoSSLSpec) Options { - opts := Options{ - ACMEStaging: &pod.ClearTextValue{Value: func() string { - if *spec.Config.ACMEStaging { - return leACMEStagingEndpoint - } - return "" - }()}, - ContactEmail: &pod.ClearTextValue{Value: spec.Config.ContactEmail}, - ProxyEndpoint: &pod.ClearTextValue{Value: spec.Config.ProxyEndpoint}, - StorageAdapter: &pod.ClearTextValue{Value: "redis"}, - RedisHost: &pod.ClearTextValue{Value: spec.Config.RedisHost}, - RedisPort: &pod.ClearTextValue{Value: fmt.Sprintf("%v", *spec.Config.RedisPort)}, - VerificationEndpoint: &pod.ClearTextValue{Value: spec.Config.VerificationEndpoint}, - LogLevel: &pod.ClearTextValue{Value: *spec.Config.LogLevel}, - DomainWhitelist: &pod.ClearTextValue{Value: strings.Join(spec.Config.DomainWhitelist, ",")}, - DomainBlacklist: &pod.ClearTextValue{Value: strings.Join(spec.Config.DomainBlacklist, ",")}, - } + opts.Unpack(func() string { + if *spec.Config.ACMEStaging { + return leACMEStagingEndpoint + } + return "" + }()).IntoEnvvar("ACME_STAGING") + opts.Unpack(spec.Config.ContactEmail).IntoEnvvar("CONTACT_EMAIL") + opts.Unpack(spec.Config.ProxyEndpoint).IntoEnvvar("PROXY_ENDPOINT") + opts.Unpack("redis").IntoEnvvar("STORAGE_ADAPTER") + opts.Unpack(spec.Config.RedisHost).IntoEnvvar("REDIS_HOST") + opts.Unpack(spec.Config.RedisPort).IntoEnvvar("REDIS_PORT") + opts.Unpack(spec.Config.VerificationEndpoint).IntoEnvvar("VERIFICATION_ENDPOINT") + opts.Unpack(spec.Config.LogLevel).IntoEnvvar("LOG_LEVEL") + opts.Unpack(strings.Join(spec.Config.DomainWhitelist, ",")).IntoEnvvar("DOMAIN_WHITELIST") + opts.Unpack(strings.Join(spec.Config.DomainBlacklist, ",")).IntoEnvvar("DOMAIN_BLACKLIST") return opts } diff --git a/pkg/generators/autossl/deployment.go b/pkg/generators/autossl/deployment.go index 8a04b22b..a022a339 100644 --- a/pkg/generators/autossl/deployment.go +++ b/pkg/generators/autossl/deployment.go @@ -54,7 +54,7 @@ func (gen *Generator) deployment() *appsv1.Deployment { pod.ContainerPortTCP("https-no-pp", 8443), pod.ContainerPortTCP("metrics", 9145), ), - Env: pod.BuildEnvironment(gen.Options), + Env: gen.Options.BuildEnvironment(), Resources: corev1.ResourceRequirements(*gen.Spec.Resources), ImagePullPolicy: *gen.Spec.Image.PullPolicy, VolumeMounts: []corev1.VolumeMount{ diff --git a/pkg/generators/autossl/generator.go b/pkg/generators/autossl/generator.go index cfb77ec5..00271745 100644 --- a/pkg/generators/autossl/generator.go +++ b/pkg/generators/autossl/generator.go @@ -10,6 +10,7 @@ import ( "github.com/3scale-ops/saas-operator/pkg/generators" "github.com/3scale-ops/saas-operator/pkg/generators/autossl/config" "github.com/3scale-ops/saas-operator/pkg/resource_builders/grafanadashboard" + "github.com/3scale-ops/saas-operator/pkg/resource_builders/pod" "github.com/3scale-ops/saas-operator/pkg/resource_builders/podmonitor" operatorutil "github.com/3scale-ops/saas-operator/pkg/util" deployment_workload "github.com/3scale-ops/saas-operator/pkg/workloads/deployment" @@ -26,7 +27,7 @@ const ( type Generator struct { generators.BaseOptionsV2 Spec saasv1alpha1.AutoSSLSpec - Options config.Options + Options pod.Options Canary *Generator Traffic bool } diff --git a/pkg/generators/backend/config/cron_options.go b/pkg/generators/backend/config/cron_options.go index 33f990ad..cf724805 100644 --- a/pkg/generators/backend/config/cron_options.go +++ b/pkg/generators/backend/config/cron_options.go @@ -5,35 +5,19 @@ import ( "github.com/3scale-ops/saas-operator/pkg/resource_builders/pod" ) -// CronOptions holds configuration for the cron pods -type CronOptions struct { - RackEnv pod.EnvVarValue `env:"RACK_ENV"` - ConfigRedisProxy pod.EnvVarValue `env:"CONFIG_REDIS_PROXY"` - ConfigRedisSentinelHosts pod.EnvVarValue `env:"CONFIG_REDIS_SENTINEL_HOSTS"` - ConfigRedisSentinelRole pod.EnvVarValue `env:"CONFIG_REDIS_SENTINEL_ROLE"` - ConfigQueuesMasterName pod.EnvVarValue `env:"CONFIG_QUEUES_MASTER_NAME"` - ConfigQueuesSentinelHosts pod.EnvVarValue `env:"CONFIG_QUEUES_SENTINEL_HOSTS"` - ConfigQueuesSentinelRole pod.EnvVarValue `env:"CONFIG_QUEUES_SENTINEL_ROLE"` - ConfigHoptoadService pod.EnvVarValue `env:"CONFIG_HOPTOAD_SERVICE" secret:"backend-error-monitoring"` - ConfigHoptoadAPIKey pod.EnvVarValue `env:"CONFIG_HOPTOAD_API_KEY" secret:"backend-error-monitoring"` -} - -// NewCronOptions returns a CronOptions struct for the given saasv1alpha1.BackendSpec -func NewCronOptions(spec saasv1alpha1.BackendSpec) CronOptions { - opts := CronOptions{ - RackEnv: &pod.ClearTextValue{Value: *spec.Config.RackEnv}, - ConfigRedisProxy: &pod.ClearTextValue{Value: spec.Config.RedisStorageDSN}, - ConfigRedisSentinelHosts: &pod.ClearTextValue{Value: ""}, - ConfigRedisSentinelRole: &pod.ClearTextValue{Value: ""}, - ConfigQueuesMasterName: &pod.ClearTextValue{Value: spec.Config.RedisQueuesDSN}, - ConfigQueuesSentinelHosts: &pod.ClearTextValue{Value: ""}, - ConfigQueuesSentinelRole: &pod.ClearTextValue{Value: ""}, - } +// NewCronOptions returns cron options for the given saasv1alpha1.BackendSpec +func NewCronOptions(spec saasv1alpha1.BackendSpec) pod.Options { + opts := pod.Options{} - if spec.Config.ErrorMonitoringService != nil && spec.Config.ErrorMonitoringKey != nil { - opts.ConfigHoptoadService = &pod.SecretValue{Value: *spec.Config.ErrorMonitoringService} - opts.ConfigHoptoadAPIKey = &pod.SecretValue{Value: *spec.Config.ErrorMonitoringKey} - } + opts.Unpack(spec.Config.RackEnv).IntoEnvvar("RACK_ENV") + opts.Unpack(spec.Config.RedisStorageDSN).IntoEnvvar("CONFIG_REDIS_PROXY") + opts.Unpack("").IntoEnvvar("CONFIG_REDIS_SENTINEL_HOSTS") + opts.Unpack("").IntoEnvvar("CONFIG_REDIS_SENTINEL_ROLE") + opts.Unpack(spec.Config.RedisQueuesDSN).IntoEnvvar("CONFIG_QUEUES_MASTER_NAME") + opts.Unpack("").IntoEnvvar("CONFIG_QUEUES_SENTINEL_HOSTS") + opts.Unpack("").IntoEnvvar("CONFIG_QUEUES_SENTINEL_ROLE") + opts.Unpack(spec.Config.ErrorMonitoringService).IntoEnvvar("CONFIG_HOPTOAD_SERVICE").AsSecretRef("backend-error-monitoring") + opts.Unpack(spec.Config.ErrorMonitoringKey).IntoEnvvar("CONFIG_HOPTOAD_API_KEY").AsSecretRef("backend-error-monitoring") return opts } diff --git a/pkg/generators/backend/config/listener_options.go b/pkg/generators/backend/config/listener_options.go index 147b5722..834b04bb 100644 --- a/pkg/generators/backend/config/listener_options.go +++ b/pkg/generators/backend/config/listener_options.go @@ -1,59 +1,31 @@ package config import ( - "fmt" - "strconv" - saasv1alpha1 "github.com/3scale-ops/saas-operator/api/v1alpha1" "github.com/3scale-ops/saas-operator/pkg/resource_builders/pod" ) -// ListenerOptions holds configuration for the listener pods -type ListenerOptions struct { - RackEnv pod.EnvVarValue `env:"RACK_ENV"` - ConfigRedisProxy pod.EnvVarValue `env:"CONFIG_REDIS_PROXY"` - ConfigRedisSentinelHosts pod.EnvVarValue `env:"CONFIG_REDIS_SENTINEL_HOSTS"` - ConfigRedisSentinelRole pod.EnvVarValue `env:"CONFIG_REDIS_SENTINEL_ROLE"` - ConfigQueuesMasterName pod.EnvVarValue `env:"CONFIG_QUEUES_MASTER_NAME"` - ConfigQueuesSentinelHosts pod.EnvVarValue `env:"CONFIG_QUEUES_SENTINEL_HOSTS"` - ConfigQueuesSentinelRole pod.EnvVarValue `env:"CONFIG_QUEUES_SENTINEL_ROLE"` - ConfigMasterServiceID pod.EnvVarValue `env:"CONFIG_MASTER_SERVICE_ID"` - ConfigRequestLoggers pod.EnvVarValue `env:"CONFIG_REQUEST_LOGGERS"` - ConfigRedisAsync pod.EnvVarValue `env:"CONFIG_REDIS_ASYNC"` - ListenerWorkers pod.EnvVarValue `env:"LISTENER_WORKERS"` - ConfigLegacyReferrerFilters pod.EnvVarValue `env:"CONFIG_LEGACY_REFERRER_FILTERS"` - ConfigListenerPrometheusMetricsEnabled pod.EnvVarValue `env:"CONFIG_LISTENER_PROMETHEUS_METRICS_ENABLED"` - ConfigInternalAPIUser pod.EnvVarValue `env:"CONFIG_INTERNAL_API_USER" secret:"backend-internal-api"` - ConfigInternalAPIPassword pod.EnvVarValue `env:"CONFIG_INTERNAL_API_PASSWORD" secret:"backend-internal-api"` - ConfigHoptoadService pod.EnvVarValue `env:"CONFIG_HOPTOAD_SERVICE" secret:"backend-error-monitoring"` - ConfigHoptoadAPIKey pod.EnvVarValue `env:"CONFIG_HOPTOAD_API_KEY" secret:"backend-error-monitoring"` -} - -// NewListenerOptions returns an Options struct for the given saasv1alpha1.BackendSpec -func NewListenerOptions(spec saasv1alpha1.BackendSpec) ListenerOptions { - opts := ListenerOptions{ - RackEnv: &pod.ClearTextValue{Value: *spec.Config.RackEnv}, - ConfigRedisProxy: &pod.ClearTextValue{Value: spec.Config.RedisStorageDSN}, - ConfigRedisSentinelHosts: &pod.ClearTextValue{Value: ""}, - ConfigRedisSentinelRole: &pod.ClearTextValue{Value: ""}, - ConfigQueuesMasterName: &pod.ClearTextValue{Value: spec.Config.RedisQueuesDSN}, - ConfigQueuesSentinelHosts: &pod.ClearTextValue{Value: ""}, - ConfigQueuesSentinelRole: &pod.ClearTextValue{Value: ""}, - ConfigMasterServiceID: &pod.ClearTextValue{Value: fmt.Sprintf("%d", *spec.Config.MasterServiceID)}, - ConfigRequestLoggers: &pod.ClearTextValue{Value: *spec.Listener.Config.LogFormat}, - ConfigRedisAsync: &pod.ClearTextValue{Value: strconv.FormatBool(*spec.Listener.Config.RedisAsync)}, - ListenerWorkers: &pod.ClearTextValue{Value: fmt.Sprintf("%d", *spec.Listener.Config.ListenerWorkers)}, - ConfigLegacyReferrerFilters: &pod.ClearTextValue{Value: strconv.FormatBool(*spec.Listener.Config.LegacyReferrerFilters)}, - ConfigListenerPrometheusMetricsEnabled: &pod.ClearTextValue{Value: "true"}, - - ConfigInternalAPIUser: &pod.SecretValue{Value: spec.Config.InternalAPIUser}, - ConfigInternalAPIPassword: &pod.SecretValue{Value: spec.Config.InternalAPIPassword}, - } +// NewListenerOptions returns listener options for the given saasv1alpha1.BackendSpec +func NewListenerOptions(spec saasv1alpha1.BackendSpec) pod.Options { + opts := pod.Options{} - if spec.Config.ErrorMonitoringService != nil && spec.Config.ErrorMonitoringKey != nil { - opts.ConfigHoptoadService = &pod.SecretValue{Value: *spec.Config.ErrorMonitoringService} - opts.ConfigHoptoadAPIKey = &pod.SecretValue{Value: *spec.Config.ErrorMonitoringKey} - } + opts.Unpack(spec.Config.RackEnv).IntoEnvvar("RACK_ENV") + opts.Unpack(spec.Config.RedisStorageDSN).IntoEnvvar("CONFIG_REDIS_PROXY") + opts.Unpack("").IntoEnvvar("CONFIG_REDIS_SENTINEL_HOSTS") + opts.Unpack("").IntoEnvvar("CONFIG_REDIS_SENTINEL_ROLE") + opts.Unpack(spec.Config.RedisQueuesDSN).IntoEnvvar("CONFIG_QUEUES_MASTER_NAME") + opts.Unpack("").IntoEnvvar("CONFIG_QUEUES_SENTINEL_HOSTS") + opts.Unpack("").IntoEnvvar("CONFIG_QUEUES_SENTINEL_ROLE") + opts.Unpack(spec.Config.MasterServiceID).IntoEnvvar("CONFIG_MASTER_SERVICE_ID") + opts.Unpack(spec.Listener.Config.LogFormat).IntoEnvvar("CONFIG_REQUEST_LOGGERS") + opts.Unpack(spec.Listener.Config.RedisAsync).IntoEnvvar("CONFIG_REDIS_ASYNC") + opts.Unpack(spec.Listener.Config.ListenerWorkers).IntoEnvvar("LISTENER_WORKERS") + opts.Unpack(spec.Listener.Config.LegacyReferrerFilters).IntoEnvvar("CONFIG_LEGACY_REFERRER_FILTERS") + opts.Unpack("true").IntoEnvvar("CONFIG_LISTENER_PROMETHEUS_METRICS_ENABLED") + opts.Unpack(spec.Config.InternalAPIUser).IntoEnvvar("CONFIG_INTERNAL_API_USER").AsSecretRef("backend-internal-api") + opts.Unpack(spec.Config.InternalAPIPassword).IntoEnvvar("CONFIG_INTERNAL_API_PASSWORD").AsSecretRef("backend-internal-api") + opts.Unpack(spec.Config.ErrorMonitoringService).IntoEnvvar("CONFIG_HOPTOAD_SERVICE").AsSecretRef("backend-error-monitoring") + opts.Unpack(spec.Config.ErrorMonitoringKey).IntoEnvvar("CONFIG_HOPTOAD_API_KEY").AsSecretRef("backend-error-monitoring") return opts } diff --git a/pkg/generators/backend/config/worker_options.go b/pkg/generators/backend/config/worker_options.go index 36563846..1a49bec6 100644 --- a/pkg/generators/backend/config/worker_options.go +++ b/pkg/generators/backend/config/worker_options.go @@ -1,57 +1,30 @@ package config import ( - "fmt" - "strconv" - saasv1alpha1 "github.com/3scale-ops/saas-operator/api/v1alpha1" "github.com/3scale-ops/saas-operator/pkg/resource_builders/pod" ) -// WorkerOptions holds configuration for the worker pods -type WorkerOptions struct { - RackEnv pod.EnvVarValue `env:"RACK_ENV"` - ConfigRedisProxy pod.EnvVarValue `env:"CONFIG_REDIS_PROXY"` - ConfigRedisSentinelHosts pod.EnvVarValue `env:"CONFIG_REDIS_SENTINEL_HOSTS"` - ConfigRedisSentinelRole pod.EnvVarValue `env:"CONFIG_REDIS_SENTINEL_ROLE"` - ConfigQueuesMasterName pod.EnvVarValue `env:"CONFIG_QUEUES_MASTER_NAME"` - ConfigQueuesSentinelHosts pod.EnvVarValue `env:"CONFIG_QUEUES_SENTINEL_HOSTS"` - ConfigQueuesSentinelRole pod.EnvVarValue `env:"CONFIG_QUEUES_SENTINEL_ROLE"` - ConfigMasterServiceID pod.EnvVarValue `env:"CONFIG_MASTER_SERVICE_ID"` - ConfigRedisAsync pod.EnvVarValue `env:"CONFIG_REDIS_ASYNC"` - ConfigWorkersLoggerFormatter pod.EnvVarValue `env:"CONFIG_WORKERS_LOGGER_FORMATTER"` - ConfigWorkerPrometheusMetricsEnabled pod.EnvVarValue `env:"CONFIG_WORKER_PROMETHEUS_METRICS_ENABLED"` - ConfigWorkerPrometheusMetricsPort pod.EnvVarValue `env:"CONFIG_WORKER_PROMETHEUS_METRICS_PORT"` - ConfigEventsHook pod.EnvVarValue `env:"CONFIG_EVENTS_HOOK" secret:"backend-system-events-hook"` - ConfigEventsHookSharedSecret pod.EnvVarValue `env:"CONFIG_EVENTS_HOOK_SHARED_SECRET" secret:"backend-system-events-hook"` - ConfigHoptoadService pod.EnvVarValue `env:"CONFIG_HOPTOAD_SERVICE" secret:"backend-error-monitoring"` - ConfigHoptoadAPIKey pod.EnvVarValue `env:"CONFIG_HOPTOAD_API_KEY" secret:"backend-error-monitoring"` -} - -// NewWorkerOptions returns an Options struct for the given saasv1alpha1.BackedSpec -func NewWorkerOptions(spec saasv1alpha1.BackendSpec) WorkerOptions { - opts := WorkerOptions{ - RackEnv: &pod.ClearTextValue{Value: *spec.Config.RackEnv}, - ConfigRedisProxy: &pod.ClearTextValue{Value: spec.Config.RedisStorageDSN}, - ConfigRedisSentinelHosts: &pod.ClearTextValue{Value: ""}, - ConfigRedisSentinelRole: &pod.ClearTextValue{Value: ""}, - ConfigQueuesMasterName: &pod.ClearTextValue{Value: spec.Config.RedisQueuesDSN}, - ConfigQueuesSentinelHosts: &pod.ClearTextValue{Value: ""}, - ConfigQueuesSentinelRole: &pod.ClearTextValue{Value: ""}, - ConfigMasterServiceID: &pod.ClearTextValue{Value: fmt.Sprintf("%d", *spec.Config.MasterServiceID)}, - ConfigRedisAsync: &pod.ClearTextValue{Value: strconv.FormatBool(*spec.Worker.Config.RedisAsync)}, - ConfigWorkersLoggerFormatter: &pod.ClearTextValue{Value: *spec.Worker.Config.LogFormat}, - ConfigWorkerPrometheusMetricsEnabled: &pod.ClearTextValue{Value: "true"}, - ConfigWorkerPrometheusMetricsPort: &pod.ClearTextValue{Value: "9421"}, - - ConfigEventsHook: &pod.SecretValue{Value: spec.Config.SystemEventsHookURL}, - ConfigEventsHookSharedSecret: &pod.SecretValue{Value: spec.Config.SystemEventsHookPassword}, - } +// NewWorkerOptions returns worker options for the given saasv1alpha1.BackedSpec +func NewWorkerOptions(spec saasv1alpha1.BackendSpec) pod.Options { + opts := pod.Options{} - if spec.Config.ErrorMonitoringService != nil && spec.Config.ErrorMonitoringKey != nil { - opts.ConfigHoptoadService = &pod.SecretValue{Value: *spec.Config.ErrorMonitoringService} - opts.ConfigHoptoadAPIKey = &pod.SecretValue{Value: *spec.Config.ErrorMonitoringKey} - } + opts.Unpack(spec.Config.RackEnv).IntoEnvvar("RACK_ENV") + opts.Unpack(spec.Config.RedisStorageDSN).IntoEnvvar("CONFIG_REDIS_PROXY") + opts.Unpack("").IntoEnvvar("CONFIG_REDIS_SENTINEL_HOSTS") + opts.Unpack("").IntoEnvvar("CONFIG_REDIS_SENTINEL_ROLE") + opts.Unpack(spec.Config.RedisQueuesDSN).IntoEnvvar("CONFIG_QUEUES_MASTER_NAME") + opts.Unpack("").IntoEnvvar("CONFIG_QUEUES_SENTINEL_HOSTS") + opts.Unpack("").IntoEnvvar("CONFIG_QUEUES_SENTINEL_ROLE") + opts.Unpack(spec.Config.MasterServiceID).IntoEnvvar("CONFIG_MASTER_SERVICE_ID") + opts.Unpack(spec.Worker.Config.RedisAsync).IntoEnvvar("CONFIG_REDIS_ASYNC") + opts.Unpack(spec.Worker.Config.LogFormat).IntoEnvvar("CONFIG_WORKERS_LOGGER_FORMATTER") + opts.Unpack("true").IntoEnvvar("CONFIG_WORKER_PROMETHEUS_METRICS_ENABLED") + opts.Unpack("9421").IntoEnvvar("CONFIG_WORKER_PROMETHEUS_METRICS_PORT") + opts.Unpack(spec.Config.SystemEventsHookURL).IntoEnvvar("CONFIG_EVENTS_HOOK").AsSecretRef("backend-system-events-hook") + opts.Unpack(spec.Config.SystemEventsHookPassword).IntoEnvvar("CONFIG_EVENTS_HOOK_SHARED_SECRET").AsSecretRef("backend-system-events-hook") + opts.Unpack(spec.Config.ErrorMonitoringService).IntoEnvvar("CONFIG_HOPTOAD_SERVICE").AsSecretRef("backend-error-monitoring") + opts.Unpack(spec.Config.ErrorMonitoringKey).IntoEnvvar("CONFIG_HOPTOAD_API_KEY").AsSecretRef("backend-error-monitoring") return opts } diff --git a/pkg/generators/backend/cron_deployment.go b/pkg/generators/backend/cron_deployment.go index e55e49d4..a7d5ca64 100644 --- a/pkg/generators/backend/cron_deployment.go +++ b/pkg/generators/backend/cron_deployment.go @@ -29,7 +29,7 @@ func (gen *CronGenerator) deployment() *appsv1.Deployment { Name: strings.Join([]string{component, cron}, "-"), Image: pod.Image(gen.Image), Args: []string{"backend-cron"}, - Env: pod.BuildEnvironment(gen.Options), + Env: gen.Options.BuildEnvironment(), Resources: corev1.ResourceRequirements(*gen.CronSpec.Resources), ImagePullPolicy: *gen.Image.PullPolicy, }, diff --git a/pkg/generators/backend/generator.go b/pkg/generators/backend/generator.go index 00aa6ef6..cfa767dd 100644 --- a/pkg/generators/backend/generator.go +++ b/pkg/generators/backend/generator.go @@ -176,30 +176,18 @@ func (gen *Generator) Resources() ([]resource.TemplateInterface, error) { return nil, err } + externalsecrets := pod.Union(gen.Listener.Options, gen.Worker.Options, gen.Cron.Options). + GenerateExternalSecrets(gen.GetKey().Namespace, gen.GetLabels(), + *gen.config.ExternalSecret.SecretStoreRef.Name, *gen.config.ExternalSecret.SecretStoreRef.Kind, *gen.config.ExternalSecret.RefreshInterval) + misc := []resource.TemplateInterface{ // GrafanaDashboard resource.NewTemplate( grafanadashboard.New(gen.GetKey(), gen.GetLabels(), gen.grafanaDashboardSpec, "dashboards/backend.json.gtpl")). WithEnabled(!gen.grafanaDashboardSpec.IsDeactivated()), - // ExternalSecrets - resource.NewTemplate( - pod.GenerateExternalSecretFn("backend-system-events-hook", gen.GetNamespace(), - *gen.config.ExternalSecret.SecretStoreRef.Name, *gen.config.ExternalSecret.SecretStoreRef.Kind, - *gen.config.ExternalSecret.RefreshInterval, gen.GetLabels(), gen.Worker.Options), - ), - resource.NewTemplate( - pod.GenerateExternalSecretFn("backend-internal-api", gen.GetNamespace(), - *gen.config.ExternalSecret.SecretStoreRef.Name, *gen.config.ExternalSecret.SecretStoreRef.Kind, - *gen.config.ExternalSecret.RefreshInterval, gen.GetLabels(), gen.Listener.Options), - ), - resource.NewTemplate( - pod.GenerateExternalSecretFn("backend-error-monitoring", gen.GetNamespace(), - *gen.config.ExternalSecret.SecretStoreRef.Name, *gen.config.ExternalSecret.SecretStoreRef.Kind, - *gen.config.ExternalSecret.RefreshInterval, gen.GetLabels(), gen.Listener.Options)). - WithEnabled(gen.config.ErrorMonitoringKey != nil), } - return operatorutil.ConcatSlices(listener_resources, worker_resources, cron_resources, misc), nil + return operatorutil.ConcatSlices(listener_resources, worker_resources, cron_resources, externalsecrets, misc), nil } // ListenerGenerator has methods to generate resources for a @@ -208,7 +196,7 @@ type ListenerGenerator struct { generators.BaseOptionsV2 Image saasv1alpha1.ImageSpec ListenerSpec saasv1alpha1.ListenerSpec - Options config.ListenerOptions + Options pod.Options Traffic bool TwemproxySpec *saasv1alpha1.TwemproxySpec } @@ -272,7 +260,7 @@ type WorkerGenerator struct { generators.BaseOptionsV2 Image saasv1alpha1.ImageSpec WorkerSpec saasv1alpha1.WorkerSpec - Options config.WorkerOptions + Options pod.Options TwemproxySpec *saasv1alpha1.TwemproxySpec } @@ -307,7 +295,7 @@ type CronGenerator struct { generators.BaseOptionsV2 Image saasv1alpha1.ImageSpec CronSpec saasv1alpha1.CronSpec - Options config.CronOptions + Options pod.Options } // Validate that CronGenerator implements deployment_workload.DeploymentWorkload interface diff --git a/pkg/generators/backend/listener_deployment.go b/pkg/generators/backend/listener_deployment.go index 5e087793..6fe884ce 100644 --- a/pkg/generators/backend/listener_deployment.go +++ b/pkg/generators/backend/listener_deployment.go @@ -43,7 +43,7 @@ func (gen *ListenerGenerator) deployment() *appsv1.Deployment { pod.ContainerPortTCP("http", 3000), pod.ContainerPortTCP("metrics", 9394), ), - Env: pod.BuildEnvironment(gen.Options), + Env: gen.Options.BuildEnvironment(), Resources: corev1.ResourceRequirements(*gen.ListenerSpec.Resources), ImagePullPolicy: *gen.Image.PullPolicy, LivenessProbe: pod.TCPProbe(intstr.FromString("http"), *gen.ListenerSpec.LivenessProbe), diff --git a/pkg/generators/backend/worker_deployment.go b/pkg/generators/backend/worker_deployment.go index 16a0e8ba..94f6aaa1 100644 --- a/pkg/generators/backend/worker_deployment.go +++ b/pkg/generators/backend/worker_deployment.go @@ -33,7 +33,7 @@ func (gen *WorkerGenerator) deployment() *appsv1.Deployment { Ports: pod.ContainerPorts( pod.ContainerPortTCP("metrics", 9421), ), - Env: pod.BuildEnvironment(gen.Options), + Env: gen.Options.BuildEnvironment(), Resources: corev1.ResourceRequirements(*gen.WorkerSpec.Resources), ImagePullPolicy: *gen.Image.PullPolicy, LivenessProbe: pod.HTTPProbe("/metrics", intstr.FromString("metrics"), corev1.URISchemeHTTP, *gen.WorkerSpec.LivenessProbe), diff --git a/pkg/generators/corsproxy/config/options.go b/pkg/generators/corsproxy/config/options.go index fe8db3d2..ac5aaee0 100644 --- a/pkg/generators/corsproxy/config/options.go +++ b/pkg/generators/corsproxy/config/options.go @@ -5,14 +5,9 @@ import ( "github.com/3scale-ops/saas-operator/pkg/resource_builders/pod" ) -// Options holds configuration for the cors-proxy pod -type Options struct { - DatabaseURL pod.EnvVarValue `env:"DATABASE_URL" secret:"cors-proxy-system-database"` -} - -// NewOptions returns an Options struct for the given saasv1alpha1.CORSProxySpec -func NewOptions(spec saasv1alpha1.CORSProxySpec) Options { - return Options{ - DatabaseURL: &pod.SecretValue{Value: spec.Config.SystemDatabaseDSN}, - } +// NewOptions returns cors-proxy options the given saasv1alpha1.CORSProxySpec +func NewOptions(spec saasv1alpha1.CORSProxySpec) pod.Options { + opts := pod.Options{} + opts.Unpack(spec.Config.SystemDatabaseDSN).IntoEnvvar("DATABASE_URL").AsSecretRef("cors-proxy-system-database") + return opts } diff --git a/pkg/generators/corsproxy/deployment.go b/pkg/generators/corsproxy/deployment.go index e4cf667b..afe711b6 100644 --- a/pkg/generators/corsproxy/deployment.go +++ b/pkg/generators/corsproxy/deployment.go @@ -37,7 +37,7 @@ func (gen *Generator) deployment() *appsv1.Deployment { pod.ContainerPortTCP("http", 8080), pod.ContainerPortTCP("metrics", 9145), ), - Env: pod.BuildEnvironment(gen.Options), + Env: gen.Options.BuildEnvironment(), Resources: corev1.ResourceRequirements(*gen.Spec.Resources), ImagePullPolicy: *gen.Spec.Image.PullPolicy, LivenessProbe: pod.HTTPProbe("/healthz", intstr.FromString("metrics"), corev1.URISchemeHTTP, *gen.Spec.LivenessProbe), diff --git a/pkg/generators/corsproxy/generator.go b/pkg/generators/corsproxy/generator.go index 76a593e3..c8906530 100644 --- a/pkg/generators/corsproxy/generator.go +++ b/pkg/generators/corsproxy/generator.go @@ -27,7 +27,7 @@ const ( type Generator struct { generators.BaseOptionsV2 Spec saasv1alpha1.CORSProxySpec - Options config.Options + Options pod.Options Traffic bool } @@ -61,16 +61,17 @@ func (gen *Generator) Resources() ([]resource.TemplateInterface, error) { if err != nil { return nil, err } + + externalsecrets := gen.Options.GenerateExternalSecrets(gen.GetKey().Namespace, gen.GetLabels(), + *gen.Spec.Config.ExternalSecret.SecretStoreRef.Name, *gen.Spec.Config.ExternalSecret.SecretStoreRef.Kind, + *gen.Spec.Config.ExternalSecret.RefreshInterval) + misc := []resource.TemplateInterface{ - resource.NewTemplate( - pod.GenerateExternalSecretFn("cors-proxy-system-database", gen.GetNamespace(), - *gen.Spec.Config.ExternalSecret.SecretStoreRef.Name, *gen.Spec.Config.ExternalSecret.SecretStoreRef.Kind, - *gen.Spec.Config.ExternalSecret.RefreshInterval, gen.GetLabels(), gen.Options)), resource.NewTemplate( grafanadashboard.New(gen.GetKey(), gen.GetLabels(), *gen.Spec.GrafanaDashboard, "dashboards/cors-proxy.json.gtpl")). WithEnabled(!gen.Spec.GrafanaDashboard.IsDeactivated()), } - return operatorutil.ConcatSlices(workload, misc), nil + return operatorutil.ConcatSlices(workload, externalsecrets, misc), nil } func (gen *Generator) Services() []*resource.Template[*corev1.Service] { diff --git a/pkg/generators/mappingservice/config/options.go b/pkg/generators/mappingservice/config/options.go index 04c9394c..17bc90b1 100644 --- a/pkg/generators/mappingservice/config/options.go +++ b/pkg/generators/mappingservice/config/options.go @@ -5,26 +5,15 @@ import ( "github.com/3scale-ops/saas-operator/pkg/resource_builders/pod" ) -// Options holds configuration for the mapping-service pod -type Options struct { - MasterAccessToken pod.EnvVarValue `env:"MASTER_ACCESS_TOKEN" secret:"mapping-service-system-master-access-token"` - APIHost pod.EnvVarValue `env:"API_HOST"` - ApicastConfigurationLoader pod.EnvVarValue `env:"APICAST_CONFIGURATION_LOADER"` - ApicastLogLevel pod.EnvVarValue `env:"APICAST_LOG_LEVEL"` - PreviewBaseDomain pod.EnvVarValue `env:"PREVIEW_BASE_DOMAIN"` -} +// NewOptions returns mapping-service options for the given saasv1alpha1.CORSProxySpec +func NewOptions(spec saasv1alpha1.MappingServiceSpec) pod.Options { + opts := pod.Options{} -// NewOptions returns an Options struct for the given saasv1alpha1.CORSProxySpec -func NewOptions(spec saasv1alpha1.MappingServiceSpec) Options { - opts := Options{ - MasterAccessToken: &pod.SecretValue{Value: spec.Config.SystemAdminToken}, - APIHost: &pod.ClearTextValue{Value: spec.Config.APIHost}, - ApicastConfigurationLoader: &pod.ClearTextValue{Value: "lazy"}, - ApicastLogLevel: &pod.ClearTextValue{Value: *spec.Config.LogLevel}, - } - if spec.Config.PreviewBaseDomain != nil { - opts.PreviewBaseDomain = &pod.ClearTextValue{Value: *spec.Config.PreviewBaseDomain} - } + opts.Unpack(spec.Config.SystemAdminToken).IntoEnvvar("MASTER_ACCESS_TOKEN").AsSecretRef("mapping-service-system-master-access-token") + opts.Unpack(spec.Config.APIHost).IntoEnvvar("API_HOST") + opts.Unpack("lazy").IntoEnvvar("APICAST_CONFIGURATION_LOADER") + opts.Unpack(spec.Config.LogLevel).IntoEnvvar("APICAST_LOG_LEVEL") + opts.Unpack(spec.Config.PreviewBaseDomain).IntoEnvvar("PREVIEW_BASE_DOMAIN") return opts } diff --git a/pkg/generators/mappingservice/deployment.go b/pkg/generators/mappingservice/deployment.go index e4276eb8..2b03bd26 100644 --- a/pkg/generators/mappingservice/deployment.go +++ b/pkg/generators/mappingservice/deployment.go @@ -38,7 +38,7 @@ func (gen *Generator) deployment() *appsv1.Deployment { pod.ContainerPortTCP("management", 8090), pod.ContainerPortTCP("metrics", 9421), ), - Env: pod.BuildEnvironment(gen.Options), + Env: gen.Options.BuildEnvironment(), Resources: corev1.ResourceRequirements(*gen.Spec.Resources), ImagePullPolicy: *gen.Spec.Image.PullPolicy, LivenessProbe: pod.TCPProbe(intstr.FromString("mapping"), *gen.Spec.LivenessProbe), diff --git a/pkg/generators/mappingservice/generator.go b/pkg/generators/mappingservice/generator.go index 2163ab34..72338b33 100644 --- a/pkg/generators/mappingservice/generator.go +++ b/pkg/generators/mappingservice/generator.go @@ -27,7 +27,7 @@ const ( type Generator struct { generators.BaseOptionsV2 Spec saasv1alpha1.MappingServiceSpec - Options config.Options + Options pod.Options Traffic bool } @@ -61,16 +61,17 @@ func (gen *Generator) Resources() ([]resource.TemplateInterface, error) { if err != nil { return nil, err } + + externalsecrets := gen.Options.GenerateExternalSecrets(gen.GetKey().Namespace, gen.GetLabels(), + *gen.Spec.Config.ExternalSecret.SecretStoreRef.Name, *gen.Spec.Config.ExternalSecret.SecretStoreRef.Kind, + *gen.Spec.Config.ExternalSecret.RefreshInterval) + misc := []resource.TemplateInterface{ resource.NewTemplate( grafanadashboard.New(gen.GetKey(), gen.GetLabels(), *gen.Spec.GrafanaDashboard, "dashboards/mapping-service.json.gtpl")). WithEnabled(!gen.Spec.GrafanaDashboard.IsDeactivated()), - resource.NewTemplate( - pod.GenerateExternalSecretFn("mapping-service-system-master-access-token", gen.GetNamespace(), - *gen.Spec.Config.ExternalSecret.SecretStoreRef.Name, *gen.Spec.Config.ExternalSecret.SecretStoreRef.Kind, - *gen.Spec.Config.ExternalSecret.RefreshInterval, gen.GetLabels(), gen.Options)), } - return operatorutil.ConcatSlices(workload, misc), nil + return operatorutil.ConcatSlices(workload, externalsecrets, misc), nil } func (gen *Generator) Services() []*resource.Template[*corev1.Service] { diff --git a/pkg/generators/sentinel/config/options.go b/pkg/generators/sentinel/config/options.go deleted file mode 100644 index 9ee67f19..00000000 --- a/pkg/generators/sentinel/config/options.go +++ /dev/null @@ -1,13 +0,0 @@ -package config - -import ( - saasv1alpha1 "github.com/3scale-ops/saas-operator/api/v1alpha1" -) - -// Options holds configuration for the pods -type Options struct{} - -// NewOptions returns an Options struct for the given saasv1alpha1.SentinelSpec -func NewOptions(spec saasv1alpha1.SentinelSpec) Options { - return Options{} -} diff --git a/pkg/generators/sentinel/generator.go b/pkg/generators/sentinel/generator.go index 4578c84e..9151f1ff 100644 --- a/pkg/generators/sentinel/generator.go +++ b/pkg/generators/sentinel/generator.go @@ -11,9 +11,9 @@ import ( "github.com/3scale-ops/basereconciler/resource" saasv1alpha1 "github.com/3scale-ops/saas-operator/api/v1alpha1" "github.com/3scale-ops/saas-operator/pkg/generators" - "github.com/3scale-ops/saas-operator/pkg/generators/sentinel/config" "github.com/3scale-ops/saas-operator/pkg/resource_builders/grafanadashboard" "github.com/3scale-ops/saas-operator/pkg/resource_builders/pdb" + "github.com/3scale-ops/saas-operator/pkg/resource_builders/pod" operatorutils "github.com/3scale-ops/saas-operator/pkg/util" corev1 "k8s.io/api/core/v1" ) @@ -26,7 +26,7 @@ const ( type Generator struct { generators.BaseOptionsV2 Spec saasv1alpha1.SentinelSpec - Options config.Options + Options pod.Options } // NewGenerator returns a new Options struct @@ -42,7 +42,7 @@ func NewGenerator(instance, namespace string, spec saasv1alpha1.SentinelSpec) Ge }, }, Spec: spec, - Options: config.NewOptions(spec), + Options: pod.Options{}, } } diff --git a/pkg/generators/system/app_deployment.go b/pkg/generators/system/app_deployment.go index 6a4e43a8..902a54cd 100644 --- a/pkg/generators/system/app_deployment.go +++ b/pkg/generators/system/app_deployment.go @@ -32,7 +32,7 @@ func (gen *AppGenerator) deployment() *appsv1.Deployment { Args: []string{ "bundle", "exec", "rake", "k8s:deploy", }, - Env: pod.BuildEnvironment(gen.Options), + Env: gen.Options.BuildEnvironment(), ImagePullPolicy: *gen.Image.PullPolicy, }, }, @@ -50,7 +50,7 @@ func (gen *AppGenerator) deployment() *appsv1.Deployment { "-c", "config/unicorn.rb", }, - Env: pod.BuildEnvironment(gen.Options), + Env: gen.Options.BuildEnvironment(), Ports: pod.ContainerPorts( pod.ContainerPortTCP("ui-api", 3000), pod.ContainerPortTCP("metrics", 9394), diff --git a/pkg/generators/system/config/options.go b/pkg/generators/system/config/options.go index 6eb641fd..1d9d7ca9 100644 --- a/pkg/generators/system/config/options.go +++ b/pkg/generators/system/config/options.go @@ -1,191 +1,84 @@ package config import ( - "fmt" - - "github.com/3scale-ops/basereconciler/util" saasv1alpha1 "github.com/3scale-ops/saas-operator/api/v1alpha1" "github.com/3scale-ops/saas-operator/pkg/resource_builders/pod" ) -// Options holds configuration for system app and sidekiq pods -type Options struct { - ForceSSL pod.EnvVarValue `env:"FORCE_SSL"` - ProviderPlan pod.EnvVarValue `env:"PROVIDER_PLAN"` - SSLCertDir pod.EnvVarValue `env:"SSL_CERT_DIR"` - SandboxProxyOpensslVerifyMode pod.EnvVarValue `env:"THREESCALE_SANDBOX_PROXY_OPENSSL_VERIFY_MODE"` - Superdomain pod.EnvVarValue `env:"THREESCALE_SUPERDOMAIN"` - - RailsEnvironment pod.EnvVarValue `env:"RAILS_ENV"` - RailsLogLevel pod.EnvVarValue `env:"RAILS_LOG_LEVEL"` - RailsLogToStdout pod.EnvVarValue `env:"RAILS_LOG_TO_STDOUT"` - - SearchServerAddress pod.EnvVarValue `env:"THINKING_SPHINX_ADDRESS"` - SearchServerPort pod.EnvVarValue `env:"THINKING_SPHINX_PORT"` - SearchServerBatchSize pod.EnvVarValue `env:"THINKING_SPHINX_BATCH_SIZE"` - - DatabaseURL pod.EnvVarValue `env:"DATABASE_URL" secret:"system-database"` - - MemcachedServers pod.EnvVarValue `env:"MEMCACHE_SERVERS"` - - RecaptchaPublicKey pod.EnvVarValue `env:"RECAPTCHA_PUBLIC_KEY" secret:"system-recaptcha"` - RecaptchaPrivateKey pod.EnvVarValue `env:"RECAPTCHA_PRIVATE_KEY" secret:"system-recaptcha"` - - EventsHookPassword pod.EnvVarValue `env:"EVENTS_SHARED_SECRET" secret:"system-events-hook"` - - RedisURL pod.EnvVarValue `env:"REDIS_URL"` - RedisNamespace pod.EnvVarValue `env:"REDIS_NAMESPACE"` - RedisSentinelHosts pod.EnvVarValue `env:"REDIS_SENTINEL_HOSTS"` - RedisSentinelRole pod.EnvVarValue `env:"REDIS_SENTINEL_ROLE"` - - SMTPAddress pod.EnvVarValue `env:"SMTP_ADDRESS"` - SMTPUserName pod.EnvVarValue `env:"SMTP_USER_NAME" secret:"system-smtp"` - SMTPPassword pod.EnvVarValue `env:"SMTP_PASSWORD" secret:"system-smtp"` - SMTPPort pod.EnvVarValue `env:"SMTP_PORT"` - SMTPAuthentication pod.EnvVarValue `env:"SMTP_AUTHENTICATION"` - SMTPOpensslVerifyMode pod.EnvVarValue `env:"SMTP_OPENSSL_VERIFY_MODE"` - SMTPSTARTTLS pod.EnvVarValue `env:"SMTP_STARTTLS"` - SMTPSTARTTLSAuto pod.EnvVarValue `env:"SMTP_STARTTLS_AUTO"` - - MappingServiceAccessToken pod.EnvVarValue `env:"APICAST_ACCESS_TOKEN" secret:"system-master-apicast"` - - ZyncEndpoint pod.EnvVarValue `env:"ZYNC_ENDPOINT"` - ZyncAuthenticationToken pod.EnvVarValue `env:"ZYNC_AUTHENTICATION_TOKEN" secret:"system-zync"` - - BackendRedisURL pod.EnvVarValue `env:"BACKEND_REDIS_URL"` - BackendRedisSentinelHosts pod.EnvVarValue `env:"BACKEND_REDIS_SENTINEL_HOSTS"` - BackendRedisSentinelRole pod.EnvVarValue `env:"BACKEND_REDIS_SENTINEL_ROLE"` - BackendRoute pod.EnvVarValue `env:"BACKEND_ROUTE"` // DEPRECATED - BackendURL pod.EnvVarValue `env:"BACKEND_URL"` - BackendPublicURL pod.EnvVarValue `env:"BACKEND_PUBLIC_URL"` - BackendInternalAPIUser pod.EnvVarValue `env:"CONFIG_INTERNAL_API_USER" secret:"system-backend"` - BackendInternalAPIPassword pod.EnvVarValue `env:"CONFIG_INTERNAL_API_PASSWORD" secret:"system-backend"` - - AssetsAWSAccessKeyID pod.EnvVarValue `env:"AWS_ACCESS_KEY_ID" secret:"system-multitenant-assets-s3"` - AssetsAWSSecretAccessKey pod.EnvVarValue `env:"AWS_SECRET_ACCESS_KEY" secret:"system-multitenant-assets-s3"` - AssetsAWSBucket pod.EnvVarValue `env:"AWS_BUCKET"` - AssetsAWSRegion pod.EnvVarValue `env:"AWS_REGION"` - AssetsHost pod.EnvVarValue `env:"RAILS_ASSET_HOST"` - - AppSecretKeyBase pod.EnvVarValue `env:"SECRET_KEY_BASE" secret:"system-app"` - AccessCode pod.EnvVarValue `env:"ACCESS_CODE" secret:"system-app"` - SegmentDeletionToken pod.EnvVarValue `env:"SEGMENT_DELETION_TOKEN" secret:"system-app"` - SegmentDeletionWorkspace pod.EnvVarValue `env:"SEGMENT_DELETION_WORKSPACE"` - SegmentWriteKey pod.EnvVarValue `env:"SEGMENT_WRITE_KEY" secret:"system-app"` - GithubClientID pod.EnvVarValue `env:"GITHUB_CLIENT_ID" secret:"system-app"` - GithubClientSecret pod.EnvVarValue `env:"GITHUB_CLIENT_SECRET" secret:"system-app"` - RedHatCustomerPortalClientID pod.EnvVarValue `env:"RH_CUSTOMER_PORTAL_CLIENT_ID" secret:"system-app"` - RedHatCustomerPortalClientSecret pod.EnvVarValue `env:"RH_CUSTOMER_PORTAL_CLIENT_SECRET" secret:"system-app"` - RedHatCustomerPortalRealm pod.EnvVarValue `env:"RH_CUSTOMER_PORTAL_REALM"` - BugsnagAPIKey pod.EnvVarValue `env:"BUGSNAG_API_KEY" secret:"system-app"` - BugsnagReleaseStage pod.EnvVarValue `env:"BUGSNAG_RELEASE_STAGE"` - DatabaseSecret pod.EnvVarValue `env:"DB_SECRET" secret:"system-app"` -} - -// NewOptions returns an Options struct for the given saasv1alpha1.SystemSpec -func NewOptions(spec saasv1alpha1.SystemSpec) Options { - opts := Options{ - ForceSSL: &pod.ClearTextValue{Value: fmt.Sprintf("%t", *spec.Config.ForceSSL)}, - ProviderPlan: &pod.ClearTextValue{Value: *spec.Config.ThreescaleProviderPlan}, - SSLCertDir: &pod.ClearTextValue{Value: *spec.Config.SSLCertsDir}, - SandboxProxyOpensslVerifyMode: &pod.ClearTextValue{Value: *spec.Config.SandboxProxyOpensslVerifyMode}, - Superdomain: &pod.ClearTextValue{Value: *spec.Config.ThreescaleSuperdomain}, - - RailsEnvironment: &pod.ClearTextValue{Value: *spec.Config.Rails.Environment}, - RailsLogLevel: &pod.ClearTextValue{Value: *spec.Config.Rails.LogLevel}, - RailsLogToStdout: &pod.ClearTextValue{Value: "true"}, - - SearchServerAddress: &pod.ClearTextValue{Value: *spec.Config.SearchServer.Host}, - SearchServerPort: &pod.ClearTextValue{Value: fmt.Sprintf("%d", *spec.Config.SearchServer.Port)}, - SearchServerBatchSize: &pod.ClearTextValue{Value: fmt.Sprintf("%d", *spec.Config.SearchServer.BatchSize)}, - - DatabaseURL: &pod.SecretValue{Value: spec.Config.DatabaseDSN}, - - MemcachedServers: &pod.ClearTextValue{Value: spec.Config.MemcachedServers}, - - RecaptchaPublicKey: &pod.SecretValue{Value: spec.Config.Recaptcha.PublicKey}, - RecaptchaPrivateKey: &pod.SecretValue{Value: spec.Config.Recaptcha.PrivateKey}, - - EventsHookPassword: &pod.SecretValue{Value: spec.Config.EventsSharedSecret}, - - RedisURL: &pod.ClearTextValue{Value: spec.Config.Redis.QueuesDSN}, - RedisNamespace: &pod.ClearTextValue{Value: ""}, - RedisSentinelHosts: &pod.ClearTextValue{Value: ""}, - RedisSentinelRole: &pod.ClearTextValue{Value: ""}, - - SMTPAddress: &pod.ClearTextValue{Value: spec.Config.SMTP.Address}, - SMTPUserName: &pod.SecretValue{Value: spec.Config.SMTP.User}, - SMTPPassword: &pod.SecretValue{Value: spec.Config.SMTP.Password}, - SMTPPort: &pod.ClearTextValue{Value: fmt.Sprintf("%d", spec.Config.SMTP.Port)}, - SMTPAuthentication: &pod.ClearTextValue{Value: spec.Config.SMTP.AuthProtocol}, - SMTPOpensslVerifyMode: &pod.ClearTextValue{Value: spec.Config.SMTP.OpenSSLVerifyMode}, - - MappingServiceAccessToken: &pod.SecretValue{Value: spec.Config.MappingServiceAccessToken}, - - BackendRedisURL: &pod.ClearTextValue{Value: spec.Config.Backend.RedisDSN}, - BackendRedisSentinelHosts: &pod.ClearTextValue{Value: ""}, - BackendRedisSentinelRole: &pod.ClearTextValue{Value: ""}, - BackendRoute: &pod.ClearTextValue{Value: spec.Config.Backend.InternalEndpoint}, // DEPRECATED - BackendURL: &pod.ClearTextValue{Value: spec.Config.Backend.InternalEndpoint}, - BackendPublicURL: &pod.ClearTextValue{Value: spec.Config.Backend.ExternalEndpoint}, - BackendInternalAPIUser: &pod.SecretValue{Value: spec.Config.Backend.InternalAPIUser}, - BackendInternalAPIPassword: &pod.SecretValue{Value: spec.Config.Backend.InternalAPIPassword}, - - AssetsAWSAccessKeyID: &pod.SecretValue{Value: spec.Config.Assets.AccessKey}, - AssetsAWSSecretAccessKey: &pod.SecretValue{Value: spec.Config.Assets.SecretKey}, - AssetsAWSBucket: &pod.ClearTextValue{Value: spec.Config.Assets.Bucket}, - AssetsAWSRegion: &pod.ClearTextValue{Value: spec.Config.Assets.Region}, - - AppSecretKeyBase: &pod.SecretValue{Value: spec.Config.SecretKeyBase}, - SegmentDeletionToken: &pod.SecretValue{Value: spec.Config.Segment.DeletionToken}, - SegmentDeletionWorkspace: &pod.ClearTextValue{Value: spec.Config.Segment.DeletionWorkspace}, - SegmentWriteKey: &pod.SecretValue{Value: spec.Config.Segment.WriteKey}, - GithubClientID: &pod.SecretValue{Value: spec.Config.Github.ClientID}, - GithubClientSecret: &pod.SecretValue{Value: spec.Config.Github.ClientSecret}, - RedHatCustomerPortalClientID: &pod.SecretValue{Value: spec.Config.RedHatCustomerPortal.ClientID}, - RedHatCustomerPortalClientSecret: &pod.SecretValue{Value: spec.Config.RedHatCustomerPortal.ClientSecret}, - DatabaseSecret: &pod.SecretValue{Value: spec.Config.DatabaseSecret}, - } - - if spec.Config.Bugsnag.Enabled() { - opts.BugsnagAPIKey = &pod.SecretValue{Value: spec.Config.Bugsnag.APIKey} - - if spec.Config.Bugsnag.ReleaseStage != nil { - opts.BugsnagReleaseStage = &pod.ClearTextValue{Value: *spec.Config.Bugsnag.ReleaseStage} - } - - } else { - opts.BugsnagAPIKey = &pod.SecretValue{Value: saasv1alpha1.SecretReference{Override: util.Pointer("")}} - } - - if spec.Config.Assets.Host == nil { - opts.AssetsHost = &pod.ClearTextValue{Value: ""} - } else { - opts.AssetsHost = &pod.ClearTextValue{Value: *spec.Config.Assets.Host} - } - - if spec.Config.AccessCode != nil { - opts.AccessCode = &pod.SecretValue{Value: *spec.Config.AccessCode} - } - - if spec.Config.RedHatCustomerPortal.Realm != nil { - opts.RedHatCustomerPortalRealm = &pod.ClearTextValue{Value: *spec.Config.RedHatCustomerPortal.Realm} - } - - if spec.Config.SMTP.STARTTLS != nil { - opts.SMTPSTARTTLS = &pod.ClearTextValue{Value: fmt.Sprintf("%t", *spec.Config.SMTP.STARTTLS)} - } - - if spec.Config.SMTP.STARTTLSAuto != nil { - opts.SMTPSTARTTLSAuto = &pod.ClearTextValue{Value: fmt.Sprintf("%t", *spec.Config.SMTP.STARTTLSAuto)} - } - - if spec.Config.Zync != nil { - opts.ZyncEndpoint = &pod.ClearTextValue{Value: spec.Config.Zync.Endpoint} - opts.ZyncAuthenticationToken = &pod.SecretValue{Value: spec.Config.Zync.AuthToken} - } else { - opts.ZyncAuthenticationToken = &pod.SecretValue{Value: *spec.Config.ZyncAuthToken} - } +// cat | grep secret: | sed -r 's/.*`env:"(\w*)"(\s*secret:"([0-9a-zA-Z\-]*)")?`/Unpack().IntoEnvvar("\1").AsSecretRef("\3"),/gm' +func NewOptions(spec saasv1alpha1.SystemSpec) pod.Options { + opts := pod.Options{} + + opts.Unpack(spec.Config.ForceSSL).IntoEnvvar("FORCE_SSL") + opts.Unpack(spec.Config.ThreescaleProviderPlan).IntoEnvvar("PROVIDER_PLAN") + opts.Unpack(spec.Config.SSLCertsDir).IntoEnvvar("SSL_CERT_DIR") + opts.Unpack(spec.Config.SandboxProxyOpensslVerifyMode).IntoEnvvar("THREESCALE_SANDBOX_PROXY_OPENSSL_VERIFY_MODE") + opts.Unpack(spec.Config.ThreescaleSuperdomain).IntoEnvvar("THREESCALE_SUPERDOMAIN") + + opts.Unpack(spec.Config.Rails.Environment).IntoEnvvar("RAILS_ENV") + opts.Unpack(spec.Config.Rails.LogLevel).IntoEnvvar("RAILS_LOG_LEVEL") + opts.Unpack("true").IntoEnvvar("RAILS_LOG_TO_STDOUT") + + opts.Unpack(spec.Config.SearchServer.Host).IntoEnvvar("THINKING_SPHINX_ADDRESS") + opts.Unpack(spec.Config.SearchServer.Port).IntoEnvvar("THINKING_SPHINX_PORT") + opts.Unpack(spec.Config.SearchServer.BatchSize).IntoEnvvar("THINKING_SPHINX_BATCH_SIZE") + + opts.Unpack(spec.Config.DatabaseDSN).IntoEnvvar("DATABASE_URL").AsSecretRef("system-database") + + opts.Unpack(spec.Config.MemcachedServers).IntoEnvvar("MEMCACHE_SERVERS") + + opts.Unpack(spec.Config.Recaptcha.PublicKey).IntoEnvvar("RECAPTCHA_PUBLIC_KEY").AsSecretRef("system-recaptcha") + opts.Unpack(spec.Config.Recaptcha.PrivateKey).IntoEnvvar("RECAPTCHA_PRIVATE_KEY").AsSecretRef("system-recaptcha") + + opts.Unpack(spec.Config.EventsSharedSecret).IntoEnvvar("EVENTS_SHARED_SECRET").AsSecretRef("system-events-hook") + + opts.Unpack(spec.Config.Redis.QueuesDSN).IntoEnvvar("REDIS_URL") + opts.Unpack("").IntoEnvvar("REDIS_NAMESPACE") + opts.Unpack("").IntoEnvvar("REDIS_SENTINEL_HOSTS") + opts.Unpack("").IntoEnvvar("REDIS_SENTINEL_ROLE") + + opts.Unpack(spec.Config.SMTP.Address).IntoEnvvar("SMTP_ADDRESS") + opts.Unpack(spec.Config.SMTP.User).IntoEnvvar("SMTP_USER_NAME").AsSecretRef("system-smtp") + opts.Unpack(spec.Config.SMTP.Password).IntoEnvvar("SMTP_PASSWORD").AsSecretRef("system-smtp") + opts.Unpack(spec.Config.SMTP.Port).IntoEnvvar("SMTP_PORT") + opts.Unpack(spec.Config.SMTP.AuthProtocol).IntoEnvvar("SMTP_AUTHENTICATION") + opts.Unpack(spec.Config.SMTP.OpenSSLVerifyMode).IntoEnvvar("SMTP_OPENSSL_VERIFY_MODE") + opts.Unpack(spec.Config.SMTP.STARTTLS).IntoEnvvar("SMTP_STARTTLS") + opts.Unpack(spec.Config.SMTP.STARTTLSAuto).IntoEnvvar("SMTP_STARTTLS_AUTO") + + opts.Unpack(spec.Config.MappingServiceAccessToken).IntoEnvvar("APICAST_ACCESS_TOKEN").AsSecretRef("system-master-apicast") + + opts.Unpack(spec.Config.Zync.Endpoint).IntoEnvvar("ZYNC_ENDPOINT") + opts.Unpack(spec.Config.Zync.AuthToken).IntoEnvvar("ZYNC_AUTHENTICATION_TOKEN").AsSecretRef("system-zync") + + opts.Unpack(spec.Config.Backend.RedisDSN).IntoEnvvar("BACKEND_REDIS_URL") + opts.Unpack("").IntoEnvvar("BACKEND_REDIS_SENTINEL_HOSTS") + opts.Unpack("").IntoEnvvar("BACKEND_REDIS_SENTINEL_ROLE") + opts.Unpack(spec.Config.Backend.InternalEndpoint).IntoEnvvar("BACKEND_ROUTE") // DEPRECATED + opts.Unpack(spec.Config.Backend.InternalEndpoint).IntoEnvvar("BACKEND_URL") + opts.Unpack(spec.Config.Backend.ExternalEndpoint).IntoEnvvar("BACKEND_PUBLIC_URL") + opts.Unpack(spec.Config.Backend.InternalAPIUser).IntoEnvvar("CONFIG_INTERNAL_API_USER").AsSecretRef("system-backend") + opts.Unpack(spec.Config.Backend.InternalAPIPassword).IntoEnvvar("CONFIG_INTERNAL_API_PASSWORD").AsSecretRef("system-backend") + + opts.Unpack(spec.Config.Assets.AccessKey).IntoEnvvar("AWS_ACCESS_KEY_ID").AsSecretRef("system-multitenant-assets-s3") + opts.Unpack(spec.Config.Assets.SecretKey).IntoEnvvar("AWS_SECRET_ACCESS_KEY").AsSecretRef("system-multitenant-assets-s3") + opts.Unpack(spec.Config.Assets.Bucket).IntoEnvvar("AWS_BUCKET") + opts.Unpack(spec.Config.Assets.Region).IntoEnvvar("AWS_REGION") + opts.Unpack(spec.Config.Assets.Host).IntoEnvvar("RAILS_ASSET_HOST") + + opts.Unpack(spec.Config.SecretKeyBase).IntoEnvvar("SECRET_KEY_BASE").AsSecretRef("system-app") + opts.Unpack(spec.Config.AccessCode).IntoEnvvar("ACCESS_CODE").AsSecretRef("system-app") + opts.Unpack(spec.Config.Segment.DeletionToken).IntoEnvvar("SEGMENT_DELETION_TOKEN").AsSecretRef("system-app") + opts.Unpack(spec.Config.Segment.DeletionWorkspace).IntoEnvvar("SEGMENT_DELETION_WORKSPACE") + opts.Unpack(spec.Config.Segment.WriteKey).IntoEnvvar("SEGMENT_WRITE_KEY").AsSecretRef("system-app") + opts.Unpack(spec.Config.Github.ClientID).IntoEnvvar("GITHUB_CLIENT_ID").AsSecretRef("system-app") + opts.Unpack(spec.Config.Github.ClientSecret).IntoEnvvar("GITHUB_CLIENT_SECRET").AsSecretRef("system-app") + opts.Unpack(spec.Config.RedHatCustomerPortal.ClientID).IntoEnvvar("RH_CUSTOMER_PORTAL_CLIENT_ID").AsSecretRef("system-app") + opts.Unpack(spec.Config.RedHatCustomerPortal.ClientSecret).IntoEnvvar("RH_CUSTOMER_PORTAL_CLIENT_SECRET").AsSecretRef("system-app") + opts.Unpack(spec.Config.RedHatCustomerPortal.Realm).IntoEnvvar("RH_CUSTOMER_PORTAL_REALM") + opts.Unpack(spec.Config.Bugsnag.APIKey).IntoEnvvar("BUGSNAG_API_KEY").AsSecretRef("system-app").EmptyIf(!spec.Config.Bugsnag.Enabled()) + opts.Unpack(spec.Config.Bugsnag.ReleaseStage).IntoEnvvar("BUGSNAG_RELEASE_STAGE") + opts.Unpack(spec.Config.DatabaseSecret).IntoEnvvar("DB_SECRET").AsSecretRef("system-app") return opts } diff --git a/pkg/generators/system/console_statefulset.go b/pkg/generators/system/console_statefulset.go index 59aed072..5f4942f7 100644 --- a/pkg/generators/system/console_statefulset.go +++ b/pkg/generators/system/console_statefulset.go @@ -5,7 +5,6 @@ import ( "strings" "github.com/3scale-ops/basereconciler/util" - "github.com/3scale-ops/saas-operator/pkg/resource_builders/pod" "github.com/3scale-ops/saas-operator/pkg/resource_builders/twemproxy" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" @@ -45,7 +44,7 @@ func (gen *ConsoleGenerator) statefulset() *appsv1.StatefulSet { "sleep", "infinity", }, - Env: pod.BuildEnvironment(gen.Options), + Env: gen.Options.BuildEnvironment(), Ports: nil, Resources: corev1.ResourceRequirements(*gen.Spec.Resources), ImagePullPolicy: *gen.Image.PullPolicy, diff --git a/pkg/generators/system/generator.go b/pkg/generators/system/generator.go index 26573c77..fed2aaf2 100644 --- a/pkg/generators/system/generator.go +++ b/pkg/generators/system/generator.go @@ -6,7 +6,6 @@ import ( "github.com/3scale-ops/basereconciler/mutators" "github.com/3scale-ops/basereconciler/resource" - "github.com/3scale-ops/basereconciler/util" saasv1alpha1 "github.com/3scale-ops/saas-operator/api/v1alpha1" "github.com/3scale-ops/saas-operator/pkg/generators" "github.com/3scale-ops/saas-operator/pkg/generators/system/config" @@ -48,7 +47,7 @@ type Generator struct { Config saasv1alpha1.SystemConfig GrafanaDashboardSpec saasv1alpha1.GrafanaDashboardSpec ConfigFilesSecret string - Options config.Options + Options pod.Options Tekton []SystemTektonGenerator } @@ -330,22 +329,15 @@ func (gen *Generator) Resources() ([]resource.TemplateInterface, error) { return nil, err } + externalsecrets := gen.Options.GenerateExternalSecrets(gen.GetKey().Namespace, gen.GetLabels(), + *gen.Config.ExternalSecret.SecretStoreRef.Name, *gen.Config.ExternalSecret.SecretStoreRef.Kind, *gen.Config.ExternalSecret.RefreshInterval) + misc := []resource.TemplateInterface{ resource.NewTemplate( grafanadashboard.New(gen.GetKey(), gen.GetLabels(), gen.GrafanaDashboardSpec, "dashboards/system.json.gtpl")). WithEnabled(!gen.GrafanaDashboardSpec.IsDeactivated()), } - for _, es := range getSystemSecrets() { - misc = append( - misc, - resource.NewTemplate( - pod.GenerateExternalSecretFn(es, gen.GetNamespace(), - *gen.Config.ExternalSecret.SecretStoreRef.Name, *gen.Config.ExternalSecret.SecretStoreRef.Kind, - *gen.Config.ExternalSecret.RefreshInterval, gen.GetLabels(), gen.Options, - ), - ), - ) - } + for _, tr := range gen.Tekton { // NewTemplateFromObjectFunction receives a function with a pointer receiver so we must // copy the value into a new variable to avoid referencing directly the loop variable, which @@ -364,42 +356,17 @@ func (gen *Generator) Resources() ([]resource.TemplateInterface, error) { sidekiq_low_resources, gen.Searchd.StatefulSetWithTraffic(), gen.Console.StatefulSet(), + externalsecrets, misc, ), nil } -func getSystemSecrets() []string { - return []string{ - "system-app", - "system-backend", - "system-database", - "system-events-hook", - "system-master-apicast", - "system-multitenant-assets-s3", - "system-recaptcha", - "system-smtp", - "system-zync", - } -} - -func getSystemSecretsRolloutTriggers(additionalSecrets ...string) []resource.TemplateMutationFunction { - secrets := append(getSystemSecrets(), additionalSecrets...) - triggers := make([]resource.TemplateMutationFunction, 0, len(secrets)) - for _, secret := range secrets { - triggers = append( - triggers, - mutators.RolloutTrigger{Name: secret, SecretName: util.Pointer(secret)}.Add(), - ) - } - return triggers -} - // AppGenerator has methods to generate resources for system-app type AppGenerator struct { generators.BaseOptionsV2 Spec saasv1alpha1.SystemAppSpec - Options config.Options + Options pod.Options Image saasv1alpha1.ImageSpec ConfigFilesSecret string Traffic bool @@ -427,7 +394,7 @@ func (gen *AppGenerator) TrafficSelector() map[string]string { func (gen *AppGenerator) Deployment() *resource.Template[*appsv1.Deployment] { return resource.NewTemplateFromObjectFunction(gen.deployment). - WithMutations(getSystemSecretsRolloutTriggers(gen.ConfigFilesSecret)). + WithMutations(gen.Options.GenerateRolloutTriggers(gen.ConfigFilesSecret)). WithMutation(mutators.SetDeploymentReplicas(gen.Spec.HPA.IsDeactivated())) } @@ -456,7 +423,7 @@ var _ deployment_workload.DeploymentWorkload = &SidekiqGenerator{} type SidekiqGenerator struct { generators.BaseOptionsV2 Spec saasv1alpha1.SystemSidekiqSpec - Options config.Options + Options pod.Options Image saasv1alpha1.ImageSpec ConfigFilesSecret string TwemproxySpec *saasv1alpha1.TwemproxySpec @@ -464,7 +431,7 @@ type SidekiqGenerator struct { func (gen *SidekiqGenerator) Deployment() *resource.Template[*appsv1.Deployment] { return resource.NewTemplateFromObjectFunction(gen.deployment). - WithMutations(getSystemSecretsRolloutTriggers(gen.ConfigFilesSecret)). + WithMutations(gen.Options.GenerateRolloutTriggers(gen.ConfigFilesSecret)). WithMutation(mutators.SetDeploymentReplicas(gen.Spec.HPA.IsDeactivated())) } @@ -509,7 +476,7 @@ func (gen *SearchdGenerator) StatefulSetWithTraffic() []resource.TemplateInterfa type ConsoleGenerator struct { generators.BaseOptionsV2 Spec saasv1alpha1.SystemRailsConsoleSpec - Options config.Options + Options pod.Options Image saasv1alpha1.ImageSpec ConfigFilesSecret string Enabled bool @@ -520,7 +487,7 @@ func (gen *ConsoleGenerator) StatefulSet() []resource.TemplateInterface { return []resource.TemplateInterface{ resource.NewTemplateFromObjectFunction(gen.statefulset). WithEnabled(gen.Enabled). - WithMutations(getSystemSecretsRolloutTriggers(gen.ConfigFilesSecret)), + WithMutations(gen.Options.GenerateRolloutTriggers(gen.ConfigFilesSecret)), } } @@ -528,7 +495,7 @@ func (gen *ConsoleGenerator) StatefulSet() []resource.TemplateInterface { type SystemTektonGenerator struct { generators.BaseOptionsV2 Spec saasv1alpha1.SystemTektonTaskSpec - Options config.Options + Options pod.Options Image saasv1alpha1.ImageSpec ConfigFilesSecret string TwemproxySpec *saasv1alpha1.TwemproxySpec diff --git a/pkg/generators/system/sidekiq_deployment.go b/pkg/generators/system/sidekiq_deployment.go index 94484974..f0156b35 100644 --- a/pkg/generators/system/sidekiq_deployment.go +++ b/pkg/generators/system/sidekiq_deployment.go @@ -36,16 +36,9 @@ func (gen *SidekiqGenerator) deployment() *appsv1.Deployment { } return args }(gen.Spec.Config.Queues), - Env: func() []corev1.EnvVar { - envVars := pod.BuildEnvironment(gen.Options) - envVars = append(envVars, - corev1.EnvVar{ - Name: "RAILS_MAX_THREADS", - Value: fmt.Sprintf("%d", *gen.Spec.Config.MaxThreads), - }, - ) - return envVars - }(), + Env: gen.Options. + WithExtraEnv([]corev1.EnvVar{{Name: "RAILS_MAX_THREADS", Value: fmt.Sprintf("%d", *gen.Spec.Config.MaxThreads)}}). + BuildEnvironment(), Ports: pod.ContainerPorts( pod.ContainerPortTCP("metrics", 9394), ), diff --git a/pkg/generators/system/tekton_task.go b/pkg/generators/system/tekton_task.go index 9e93b50d..e3988049 100644 --- a/pkg/generators/system/tekton_task.go +++ b/pkg/generators/system/tekton_task.go @@ -4,7 +4,6 @@ import ( "fmt" "github.com/3scale-ops/basereconciler/util" - "github.com/3scale-ops/saas-operator/pkg/resource_builders/pod" "github.com/3scale-ops/saas-operator/pkg/resource_builders/twemproxy" pipelinev1beta1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1" corev1 "k8s.io/api/core/v1" @@ -43,26 +42,7 @@ func (gen *SystemTektonGenerator) task() *pipelinev1beta1.Task { }, StepTemplate: &pipelinev1beta1.StepTemplate{ Image: "$(params.container-image):$(params.container-tag)", - Env: func(base, extra []corev1.EnvVar) []corev1.EnvVar { - if len(extra) == 0 { - return base - } - envVars := base - for _, extraEnvVar := range extra { - found := false - for ev, envVar := range envVars { - if extraEnvVar.Name == envVar.Name { - found = true - envVars[ev].Value = extraEnvVar.Value - envVars[ev].ValueFrom = extraEnvVar.ValueFrom - } - } - if !found { - envVars = append(envVars, extraEnvVar) - } - } - return envVars - }(pod.BuildEnvironment(gen.Options), gen.Spec.Config.ExtraEnv), + Env: gen.Options.WithExtraEnv(gen.Spec.Config.ExtraEnv).BuildEnvironment(), }, Steps: []pipelinev1beta1.Step{ { diff --git a/pkg/generators/zync/api_deployment.go b/pkg/generators/zync/api_deployment.go index e2b02a71..effdfb88 100644 --- a/pkg/generators/zync/api_deployment.go +++ b/pkg/generators/zync/api_deployment.go @@ -37,10 +37,9 @@ func (gen *APIGenerator) deployment() *appsv1.Deployment { pod.ContainerPortTCP("http", 8080), pod.ContainerPortTCP("metrics", 9393), ), - Env: func() []corev1.EnvVar { - envVars := pod.BuildEnvironment(gen.Options) - envVars = append(envVars, - corev1.EnvVar{ + Env: gen.Options.WithExtraEnv( + []corev1.EnvVar{ + { Name: "POD_NAME", ValueFrom: &corev1.EnvVarSource{ FieldRef: &corev1.ObjectFieldSelector{ @@ -49,7 +48,7 @@ func (gen *APIGenerator) deployment() *appsv1.Deployment { }, }, }, - corev1.EnvVar{ + { Name: "POD_NAMESPACE", ValueFrom: &corev1.EnvVarSource{ FieldRef: &corev1.ObjectFieldSelector{ @@ -58,9 +57,8 @@ func (gen *APIGenerator) deployment() *appsv1.Deployment { }, }, }, - ) - return envVars - }(), + }, + ).BuildEnvironment(), Resources: corev1.ResourceRequirements(*gen.APISpec.Resources), ImagePullPolicy: *gen.Image.PullPolicy, LivenessProbe: pod.HTTPProbe("/status/live", intstr.FromString("http"), corev1.URISchemeHTTP, *gen.APISpec.LivenessProbe), diff --git a/pkg/generators/zync/config/api_options.go b/pkg/generators/zync/config/api_options.go index 60aa10ab..6eb853bd 100644 --- a/pkg/generators/zync/config/api_options.go +++ b/pkg/generators/zync/config/api_options.go @@ -1,49 +1,23 @@ package config import ( - "fmt" - - "github.com/3scale-ops/basereconciler/util" saasv1alpha1 "github.com/3scale-ops/saas-operator/api/v1alpha1" "github.com/3scale-ops/saas-operator/pkg/resource_builders/pod" ) -// APIOptions holds configuration for the api pods -type APIOptions struct { - RailsEnvironment pod.EnvVarValue `env:"RAILS_ENV"` - RailsLogLevel pod.EnvVarValue `env:"RAILS_LOG_LEVEL"` - RailsLogToStdOut pod.EnvVarValue `env:"RAILS_LOG_TO_STDOUT"` - RailsMaxThreads pod.EnvVarValue `env:"RAILS_MAX_THREADS"` - DatabaseURL pod.EnvVarValue `env:"DATABASE_URL" secret:"zync"` - SecretKeyBase pod.EnvVarValue `env:"SECRET_KEY_BASE" secret:"zync"` - ZyncAuthenticationToken pod.EnvVarValue `env:"ZYNC_AUTHENTICATION_TOKEN" secret:"zync"` - BugsnagAPIKey pod.EnvVarValue `env:"BUGSNAG_API_KEY" secret:"zync"` - BugsnagReleaseStage pod.EnvVarValue `env:"BUGSNAG_RELEASE_STAGE"` -} - -// NewAPIOptions returns an Options struct for the given saasv1alpha1.ZyncSpec -func NewAPIOptions(spec saasv1alpha1.ZyncSpec) APIOptions { - opts := APIOptions{ - RailsEnvironment: &pod.ClearTextValue{Value: *spec.Config.Rails.Environment}, - RailsLogLevel: &pod.ClearTextValue{Value: *spec.Config.Rails.LogLevel}, - RailsLogToStdOut: &pod.ClearTextValue{Value: "true"}, - RailsMaxThreads: &pod.ClearTextValue{Value: fmt.Sprintf("%d", *spec.Config.Rails.MaxThreads)}, - - DatabaseURL: &pod.SecretValue{Value: spec.Config.DatabaseDSN}, - SecretKeyBase: &pod.SecretValue{Value: spec.Config.SecretKeyBase}, - ZyncAuthenticationToken: &pod.SecretValue{Value: spec.Config.ZyncAuthToken}, - } - - if spec.Config.Bugsnag.Enabled() { - opts.BugsnagAPIKey = &pod.SecretValue{Value: spec.Config.Bugsnag.APIKey} - - if spec.Config.Bugsnag.ReleaseStage != nil { - opts.BugsnagReleaseStage = &pod.ClearTextValue{Value: *spec.Config.Bugsnag.ReleaseStage} - } - - } else { - opts.BugsnagAPIKey = &pod.SecretValue{Value: saasv1alpha1.SecretReference{Override: util.Pointer("")}} - } +// NewAPIOptions returns Zync API options given saasv1alpha1.ZyncSpec +func NewAPIOptions(spec saasv1alpha1.ZyncSpec) pod.Options { + opts := pod.Options{} + + opts.Unpack(spec.Config.Rails.Environment).IntoEnvvar("RAILS_ENV") + opts.Unpack(spec.Config.Rails.LogLevel).IntoEnvvar("RAILS_LOG_LEVEL") + opts.Unpack("true").IntoEnvvar("RAILS_LOG_TO_STDOUT") + opts.Unpack(spec.Config.Rails.MaxThreads).IntoEnvvar("RAILS_MAX_THREADS") + opts.Unpack(spec.Config.DatabaseDSN).IntoEnvvar("DATABASE_URL").AsSecretRef("zync") + opts.Unpack(spec.Config.SecretKeyBase).IntoEnvvar("SECRET_KEY_BASE").AsSecretRef("zync") + opts.Unpack(spec.Config.ZyncAuthToken).IntoEnvvar("ZYNC_AUTHENTICATION_TOKEN").AsSecretRef("zync") + opts.Unpack(spec.Config.Bugsnag.APIKey).IntoEnvvar("BUGSNAG_API_KEY").AsSecretRef("zync").EmptyIf(!spec.Config.Bugsnag.Enabled()) + opts.Unpack(spec.Config.Bugsnag.ReleaseStage).IntoEnvvar("BUGSNAG_RELEASE_STAGE") return opts } diff --git a/pkg/generators/zync/config/que_options.go b/pkg/generators/zync/config/que_options.go index 6815ae86..85648f4b 100644 --- a/pkg/generators/zync/config/que_options.go +++ b/pkg/generators/zync/config/que_options.go @@ -1,45 +1,22 @@ package config import ( - "github.com/3scale-ops/basereconciler/util" saasv1alpha1 "github.com/3scale-ops/saas-operator/api/v1alpha1" "github.com/3scale-ops/saas-operator/pkg/resource_builders/pod" ) -// QueOptions holds configuration for the que pods -type QueOptions struct { - RailsEnvironment pod.EnvVarValue `env:"RAILS_ENV"` - RailsLogLevel pod.EnvVarValue `env:"RAILS_LOG_LEVEL"` - RailsLogToStdOut pod.EnvVarValue `env:"RAILS_LOG_TO_STDOUT"` - DatabaseURL pod.EnvVarValue `env:"DATABASE_URL" secret:"zync"` - SecretKeyBase pod.EnvVarValue `env:"SECRET_KEY_BASE" secret:"zync"` - ZyncAuthenticationToken pod.EnvVarValue `env:"ZYNC_AUTHENTICATION_TOKEN" secret:"zync"` - BugsnagAPIKey pod.EnvVarValue `env:"BUGSNAG_API_KEY" secret:"zync"` - BugsnagReleaseStage pod.EnvVarValue `env:"BUGSNAG_RELEASE_STAGE"` -} - -// NewQueOptions returns an Options struct for the given saasv1alpha1.ZyncSpec -func NewQueOptions(spec saasv1alpha1.ZyncSpec) QueOptions { - opts := QueOptions{ - RailsEnvironment: &pod.ClearTextValue{Value: *spec.Config.Rails.Environment}, - RailsLogLevel: &pod.ClearTextValue{Value: *spec.Config.Rails.LogLevel}, - RailsLogToStdOut: &pod.ClearTextValue{Value: "true"}, - - DatabaseURL: &pod.SecretValue{Value: spec.Config.DatabaseDSN}, - SecretKeyBase: &pod.SecretValue{Value: spec.Config.SecretKeyBase}, - ZyncAuthenticationToken: &pod.SecretValue{Value: spec.Config.ZyncAuthToken}, - } - - if spec.Config.Bugsnag.Enabled() { - opts.BugsnagAPIKey = &pod.SecretValue{Value: spec.Config.Bugsnag.APIKey} - - if spec.Config.Bugsnag.ReleaseStage != nil { - opts.BugsnagReleaseStage = &pod.ClearTextValue{Value: *spec.Config.Bugsnag.ReleaseStage} - } - - } else { - opts.BugsnagAPIKey = &pod.SecretValue{Value: saasv1alpha1.SecretReference{Override: util.Pointer("")}} - } +// NewQueOptions returns Zync Que options for the given saasv1alpha1.ZyncSpec +func NewQueOptions(spec saasv1alpha1.ZyncSpec) pod.Options { + opts := pod.Options{} + + opts.Unpack(spec.Config.Rails.Environment).IntoEnvvar("RAILS_ENV") + opts.Unpack(spec.Config.Rails.LogLevel).IntoEnvvar("RAILS_LOG_LEVEL") + opts.Unpack("true").IntoEnvvar("RAILS_LOG_TO_STDOUT") + opts.Unpack(spec.Config.DatabaseDSN).IntoEnvvar("DATABASE_URL").AsSecretRef("zync") + opts.Unpack(spec.Config.SecretKeyBase).IntoEnvvar("SECRET_KEY_BASE").AsSecretRef("zync") + opts.Unpack(spec.Config.ZyncAuthToken).IntoEnvvar("ZYNC_AUTHENTICATION_TOKEN").AsSecretRef("zync") + opts.Unpack(spec.Config.Bugsnag.APIKey).IntoEnvvar("BUGSNAG_API_KEY").AsSecretRef("zync").EmptyIf(!spec.Config.Bugsnag.Enabled()) + opts.Unpack(spec.Config.Bugsnag.ReleaseStage).IntoEnvvar("BUGSNAG_RELEASE_STAGE") return opts } diff --git a/pkg/generators/zync/console_statefulset.go b/pkg/generators/zync/console_statefulset.go index 644957e2..425464b0 100644 --- a/pkg/generators/zync/console_statefulset.go +++ b/pkg/generators/zync/console_statefulset.go @@ -47,10 +47,9 @@ func (gen *ConsoleGenerator) statefulset() *appsv1.StatefulSet { pod.ContainerPortTCP("http", 8080), pod.ContainerPortTCP("metrics", 9393), ), - Env: func() []corev1.EnvVar { - envVars := pod.BuildEnvironment(gen.Options) - envVars = append(envVars, - corev1.EnvVar{ + Env: gen.Options.WithExtraEnv( + []corev1.EnvVar{ + { Name: "POD_NAME", ValueFrom: &corev1.EnvVarSource{ FieldRef: &corev1.ObjectFieldSelector{ @@ -59,7 +58,7 @@ func (gen *ConsoleGenerator) statefulset() *appsv1.StatefulSet { }, }, }, - corev1.EnvVar{ + { Name: "POD_NAMESPACE", ValueFrom: &corev1.EnvVarSource{ FieldRef: &corev1.ObjectFieldSelector{ @@ -68,9 +67,8 @@ func (gen *ConsoleGenerator) statefulset() *appsv1.StatefulSet { }, }, }, - ) - return envVars - }(), + }, + ).BuildEnvironment(), Resources: corev1.ResourceRequirements(*gen.Spec.Resources), ImagePullPolicy: *gen.Spec.Image.PullPolicy, }, diff --git a/pkg/generators/zync/generator.go b/pkg/generators/zync/generator.go index 47ef2e14..24df7b24 100644 --- a/pkg/generators/zync/generator.go +++ b/pkg/generators/zync/generator.go @@ -15,7 +15,6 @@ import ( "github.com/3scale-ops/saas-operator/pkg/resource_builders/podmonitor" operatorutil "github.com/3scale-ops/saas-operator/pkg/util" deployment_workload "github.com/3scale-ops/saas-operator/pkg/workloads/deployment" - externalsecretsv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1" grafanav1alpha1 "github.com/grafana-operator/grafana-operator/v4/api/integreatly/v1alpha1" monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" appsv1 "k8s.io/api/apps/v1" @@ -112,23 +111,23 @@ func (gen *Generator) Resources() ([]resource.TemplateInterface, error) { if err != nil { return nil, err } + + externalsecrets := pod.Union(gen.API.Options, gen.Que.Options). + GenerateExternalSecrets(gen.GetKey().Namespace, gen.GetLabels(), + *gen.Config.ExternalSecret.SecretStoreRef.Name, *gen.Config.ExternalSecret.SecretStoreRef.Kind, *gen.Config.ExternalSecret.RefreshInterval) + misc := []resource.TemplateInterface{ // GrafanaDashboard resource.NewTemplate[*grafanav1alpha1.GrafanaDashboard]( grafanadashboard.New(gen.GetKey(), gen.GetLabels(), gen.GrafanaDashboardSpec, "dashboards/zync.json.gtpl")). WithEnabled(!gen.GrafanaDashboardSpec.IsDeactivated()), - // ExternalSecret - resource.NewTemplate[*externalsecretsv1beta1.ExternalSecret]( - pod.GenerateExternalSecretFn("zync", gen.GetNamespace(), - *gen.Config.ExternalSecret.SecretStoreRef.Name, *gen.Config.ExternalSecret.SecretStoreRef.Kind, - *gen.Config.ExternalSecret.RefreshInterval, gen.GetLabels(), gen.API.Options), - ), } return operatorutil.ConcatSlices( app_resources, que_resources, gen.Console.StatefulSet(), + externalsecrets, misc, ), nil } @@ -139,7 +138,7 @@ type APIGenerator struct { generators.BaseOptionsV2 Image saasv1alpha1.ImageSpec APISpec saasv1alpha1.APISpec - Options config.APIOptions + Options pod.Options Traffic bool } @@ -187,7 +186,7 @@ type QueGenerator struct { generators.BaseOptionsV2 Image saasv1alpha1.ImageSpec QueSpec saasv1alpha1.QueSpec - Options config.QueOptions + Options pod.Options } // Validate that QueGenerator implements deployment_workload.DeploymentWorkload interface @@ -215,7 +214,7 @@ type ConsoleGenerator struct { generators.BaseOptionsV2 Image saasv1alpha1.ImageSpec Spec saasv1alpha1.ZyncRailsConsoleSpec - Options config.APIOptions + Options pod.Options Enabled bool } diff --git a/pkg/generators/zync/que_deployment.go b/pkg/generators/zync/que_deployment.go index 3f281914..61d266bc 100644 --- a/pkg/generators/zync/que_deployment.go +++ b/pkg/generators/zync/que_deployment.go @@ -41,10 +41,9 @@ func (gen *QueGenerator) deployment() *appsv1.Deployment { Ports: pod.ContainerPorts( pod.ContainerPortTCP("metrics", 9394), ), - Env: func() []corev1.EnvVar { - envVars := pod.BuildEnvironment(gen.Options) - envVars = append(envVars, - corev1.EnvVar{ + Env: gen.Options.WithExtraEnv( + []corev1.EnvVar{ + { Name: "POD_NAME", ValueFrom: &corev1.EnvVarSource{ FieldRef: &corev1.ObjectFieldSelector{ @@ -53,7 +52,7 @@ func (gen *QueGenerator) deployment() *appsv1.Deployment { }, }, }, - corev1.EnvVar{ + { Name: "POD_NAMESPACE", ValueFrom: &corev1.EnvVarSource{ FieldRef: &corev1.ObjectFieldSelector{ @@ -62,9 +61,8 @@ func (gen *QueGenerator) deployment() *appsv1.Deployment { }, }, }, - ) - return envVars - }(), + }, + ).BuildEnvironment(), Resources: corev1.ResourceRequirements(*gen.QueSpec.Resources), ImagePullPolicy: *gen.Image.PullPolicy, LivenessProbe: pod.HTTPProbe("/metrics", intstr.FromString("metrics"), corev1.URISchemeHTTP, *gen.QueSpec.LivenessProbe), diff --git a/pkg/resource_builders/externalsecret/resource.go b/pkg/resource_builders/externalsecret/resource.go new file mode 100644 index 00000000..8fd9648c --- /dev/null +++ b/pkg/resource_builders/externalsecret/resource.go @@ -0,0 +1,33 @@ +package externalsecret + +import ( + externalsecretsv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" +) + +func New(key types.NamespacedName, labels map[string]string, + secretStoreName, secretStoreKind string, refreshInterval metav1.Duration, + data []externalsecretsv1beta1.ExternalSecretData) *externalsecretsv1beta1.ExternalSecret { + + return &externalsecretsv1beta1.ExternalSecret{ + ObjectMeta: metav1.ObjectMeta{ + Name: key.Name, + Namespace: key.Namespace, + Labels: labels, + }, + Spec: externalsecretsv1beta1.ExternalSecretSpec{ + SecretStoreRef: externalsecretsv1beta1.SecretStoreRef{ + Name: secretStoreName, + Kind: secretStoreKind, + }, + Target: externalsecretsv1beta1.ExternalSecretTarget{ + Name: key.Name, + CreationPolicy: "Owner", + DeletionPolicy: "Retain", + }, + RefreshInterval: &refreshInterval, + Data: data, + }, + } +} diff --git a/pkg/resource_builders/pod/environment.go b/pkg/resource_builders/pod/environment.go index a11d6315..48925780 100644 --- a/pkg/resource_builders/pod/environment.go +++ b/pkg/resource_builders/pod/environment.go @@ -5,103 +5,210 @@ import ( "reflect" "strings" + "github.com/3scale-ops/basereconciler/mutators" + "github.com/3scale-ops/basereconciler/resource" + "github.com/3scale-ops/basereconciler/util" saasv1alpha1 "github.com/3scale-ops/saas-operator/api/v1alpha1" + "github.com/3scale-ops/saas-operator/pkg/resource_builders/externalsecret" + operatorutil "github.com/3scale-ops/saas-operator/pkg/util" + externalsecretsv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1" + clone "github.com/huandu/go-clone/generic" + "github.com/samber/lo" corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" ) -type EnvVarValue interface { - ToEnvVar(key string) corev1.EnvVar +type Option struct { + value *string + format *string + secretValue *saasv1alpha1.SecretReference + envVariable string + secretName string + set bool } -type ClearTextValue struct { - Value string +func (o *Option) IntoEnvvar(e string) *Option { o.envVariable = e; return o } +func (o *Option) AsSecretRef(s string) *Option { o.secretName = s; return o } +func (o *Option) EmptyIf(empty bool) *Option { + if empty { + o.secretValue = nil + o.value = util.Pointer("") + } + return o } -func (ctv *ClearTextValue) ToEnvVar(key string) corev1.EnvVar { - return corev1.EnvVar{ - Name: key, - Value: ctv.Value, - } +type Options []*Option + +func NewOptions() *Options { return &Options{} } + +// DeepCopy traveses the struct and returns +// a deep copy of it +func (options *Options) DeepCopy() *Options { + return clone.Clone(options) } -type SecretValue struct { - Value saasv1alpha1.SecretReference +// FilterSecretOptions returns a list of options that will generate a Secret resource +func (options *Options) FilterSecretOptions() Options { + return lo.Filter[*Option](*options, func(item *Option, index int) bool { + return item.secretValue != nil && item.secretValue.Override == nil && item.secretName != "" + }) } -func (sv *SecretValue) ToEnvVar(key string) corev1.EnvVar { - s := strings.Split(key, ":") - envvar := s[0] - secret := s[1] +func (options *Options) ListSecretResourceNames() []string { + list := lo.Reduce(options.FilterSecretOptions(), func(agg []string, item *Option, _ int) []string { + return append(agg, item.secretName) + }, []string{}) - if sv.Value.Override != nil { - return corev1.EnvVar{ - Name: envvar, - Value: *sv.Value.Override, - } - } + return lo.Uniq(list) +} - return corev1.EnvVar{ - Name: envvar, - ValueFrom: &corev1.EnvVarSource{ - SecretKeyRef: &corev1.SecretKeySelector{ - Key: envvar, - LocalObjectReference: corev1.LocalObjectReference{ - Name: secret, - }, - }, - }, +func (options *Options) GenerateRolloutTriggers(additionalSecrets ...string) []resource.TemplateMutationFunction { + secrets := options.ListSecretResourceNames() + triggers := make([]resource.TemplateMutationFunction, 0, len(secrets)) + for _, secret := range secrets { + triggers = append( + triggers, + mutators.RolloutTrigger{Name: secret, SecretName: util.Pointer(secret)}.Add(), + ) } + return triggers } -func BuildEnvironment(opts interface{}) []corev1.EnvVar { - env := []corev1.EnvVar{} +// Unpack retrieves the value specified from the API and adds a matching option to the +// list of options. It handles both values and pointers seamlessly. +// Considers a nil value as an unset option. +// It always unpacks into an string representation of the value so it can be stored as +// an environment variable. +// A parameter indicating the format (as in a call to fmt.Sprintf()) can be optionally passed. +func (options *Options) Unpack(o any, params ...string) *Option { + if len(params) > 1 { + panic(fmt.Errorf("too many params in call to Unpack")) + } - t := reflect.TypeOf(opts) + var opt *Option + var val any - for i := 0; i < t.NumField(); i++ { + if reflect.ValueOf(o).Kind() == reflect.Ptr { + if lo.IsNil(o) { + // underlying value is nil so option is unset + return &Option{set: false} + } else { + val = reflect.ValueOf(o).Elem().Interface() + } + } else { + val = o + } - field := t.Field(i) + switch v := val.(type) { - // Ensure field is of EnvVarValue type - if field.Type.String() != "pod.EnvVarValue" { - panic(fmt.Errorf("Field in '%s/%s' is not a 'pod.EnvVarValue'", t.Name(), field.Name)) - } + case saasv1alpha1.SecretReference: + opt = &Option{secretValue: &v, set: true} - value := reflect.ValueOf(opts).FieldByName(field.Name) - // Skip field if its value is not set - if value.IsZero() { - continue + default: + var format string + if len(params) > 0 { + format = params[0] + } else { + format = "%v" } + opt = &Option{value: util.Pointer(fmt.Sprintf(format, v)), set: true} + } - // Parse the field "env" tag - envVarName, ok := field.Tag.Lookup("env") - if !ok { - panic(fmt.Errorf("missing 'env' tag in %s/%s", t.Name(), field.Name)) + *options = append(*options, opt) + return opt +} + +// WithExtraEnv returns a copy of the Options list with the added extra envvars +func (options *Options) WithExtraEnv(extra []corev1.EnvVar) *Options { + + out := options.DeepCopy() + for _, envvar := range extra { + v := envvar.Value + o, exists := lo.Find(*out, func(o *Option) bool { + return o.envVariable == envvar.Name + }) + if exists { + o.value = &v + o.secretValue = nil + o.set = true + o.secretName = "" + } else { + out.Unpack(v).IntoEnvvar(envvar.Name) } + } + return out +} - secretName, hasSecretTag := field.Tag.Lookup("secret") +// BuildEnvironment generates a list of corev1.Envvar that matches the +// list of options +func (opts *Options) BuildEnvironment() []corev1.EnvVar { - valueType := value.Elem().Elem().Type().String() - // If value is of ClearTextValue type it shoud not have the 'secret' tag - if valueType == "pod.ClearTextValue" && hasSecretTag { - panic(fmt.Errorf("unexpected 'secret' tag in field %s/%s", t.Name(), field.Name)) - } + env := []corev1.EnvVar{} + for _, opt := range *opts { - // If value is of SecretValue type it shoud have the 'secret' tag - if valueType == "pod.SecretValue" && !hasSecretTag { - panic(fmt.Errorf("missing 'secret' tag in field %s/%s", t.Name(), field.Name)) + if !opt.set { + continue } - var arg reflect.Value - if valueType == "pod.ClearTextValue" { - arg = reflect.ValueOf(envVarName) - } else { - arg = reflect.ValueOf(strings.Join([]string{envVarName, secretName}, ":")) + if opt.secretValue != nil { + + if opt.secretValue.Override != nil { + opt.value = opt.secretValue.Override + } else { + env = append(env, corev1.EnvVar{ + Name: opt.envVariable, + ValueFrom: &corev1.EnvVarSource{ + SecretKeyRef: &corev1.SecretKeySelector{ + Key: opt.envVariable, + LocalObjectReference: corev1.LocalObjectReference{ + Name: opt.secretName, + }, + }}}) + } } - envvar := value.MethodByName("ToEnvVar").Call([]reflect.Value{arg}) - env = append(env, envvar[0].Interface().(corev1.EnvVar)) + if opt.value != nil { + env = append(env, corev1.EnvVar{ + Name: opt.envVariable, + Value: *opt.value, + }) + } } return env } + +// GenerateExternalSecrets generates the external secret templates required to match the list of options +func (opts *Options) GenerateExternalSecrets(namespace string, labels map[string]string, secretStoreName, secretStoreKind string, refreshInterval metav1.Duration) []resource.TemplateInterface { + list := []resource.TemplateInterface{} + + for _, group := range lo.PartitionBy[*Option, string](opts.FilterSecretOptions(), func(item *Option) string { return item.secretName }) { + data := []externalsecretsv1beta1.ExternalSecretData{} + name := group[0].secretName + for _, opt := range group { + data = append(data, externalsecretsv1beta1.ExternalSecretData{ + SecretKey: opt.envVariable, + RemoteRef: externalsecretsv1beta1.ExternalSecretDataRemoteRef{ + Key: strings.TrimPrefix(opt.secretValue.FromVault.Path, "secret/data/"), + Property: opt.secretValue.FromVault.Key, + ConversionStrategy: "Default", + DecodingStrategy: "None", + }, + }) + } + list = append(list, resource.NewTemplateFromObjectFunction( + func() *externalsecretsv1beta1.ExternalSecret { + return externalsecret.New(types.NamespacedName{Name: name, Namespace: namespace}, labels, secretStoreName, secretStoreKind, refreshInterval, data) + })) + } + return list +} + +func Union(lists ...[]*Option) *Options { + all := operatorutil.ConcatSlices[*Option](lists...) + lo.UniqBy(all, func(item *Option) string { + return item.envVariable + }) + return util.Pointer[Options](all) +} diff --git a/pkg/resource_builders/pod/environment_test.go b/pkg/resource_builders/pod/environment_test.go index 1960843c..8a287c30 100644 --- a/pkg/resource_builders/pod/environment_test.go +++ b/pkg/resource_builders/pod/environment_test.go @@ -1,170 +1,356 @@ package pod import ( + "context" "reflect" "testing" + "time" "github.com/3scale-ops/basereconciler/util" - "github.com/3scale-ops/saas-operator/api/v1alpha1" saasv1alpha1 "github.com/3scale-ops/saas-operator/api/v1alpha1" + externalsecretsv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1" + "github.com/google/go-cmp/cmp" corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/client/fake" ) -func TestClearTextValue_ToEnvVar(t *testing.T) { - type fields struct { - Value string - } +func TestOptions_BuildEnvironment(t *testing.T) { type args struct { - key string + extra []corev1.EnvVar } tests := []struct { - name string - fields fields - args args - want corev1.EnvVar + name string + opts *Options + args args + want []corev1.EnvVar }{ { - name: "Returns EnvVar from clear text value", - fields: fields{Value: "value"}, - args: args{key: "key"}, - want: corev1.EnvVar{Name: "key", Value: "value"}, + name: "Text value", + opts: func() *Options { + o := NewOptions() + o.Unpack("value").IntoEnvvar("envvar") + return o + }(), + args: args{extra: []corev1.EnvVar{}}, + want: []corev1.EnvVar{{ + Name: "envvar", + Value: "value", + }}, }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - ctv := &ClearTextValue{ - Value: tt.fields.Value, - } - if got := ctv.ToEnvVar(tt.args.key); !reflect.DeepEqual(got, tt.want) { - t.Errorf("ClearTextValue.ToEnvVar() = %v, want %v", got, tt.want) - } - }) - } -} - -func TestSecretValue_ToEnvVar(t *testing.T) { - type fields struct { - Value saasv1alpha1.SecretReference - } - type args struct { - key string - } - tests := []struct { - name string - fields fields - args args - want corev1.EnvVar - }{ { - name: "Returns EnvVar from a Secret", - fields: fields{Value: saasv1alpha1.SecretReference{FromVault: &saasv1alpha1.VaultSecretReference{}}}, - args: args{key: "key:my-secret"}, - want: corev1.EnvVar{ - Name: "key", + name: "Text value with custom format", + opts: func() *Options { + o := NewOptions() + o.Unpack(8080, ":%d").IntoEnvvar("envvar") + return o + }(), + args: args{extra: []corev1.EnvVar{}}, + want: []corev1.EnvVar{{ + Name: "envvar", + Value: ":8080", + }}, + }, + { + name: "Pointer to text value", + opts: func() *Options { + o := NewOptions() + o.Unpack(util.Pointer("value")).IntoEnvvar("envvar") + return o + }(), + args: args{extra: []corev1.EnvVar{}}, + want: []corev1.EnvVar{{ + Name: "envvar", + Value: "value", + }}, + }, + { + name: "Don't panic on nil pointer to text value", + opts: func() *Options { + o := NewOptions() + var v *string + o.Unpack(v).IntoEnvvar("envvar") + return o + }(), + args: args{extra: []corev1.EnvVar{}}, + want: []corev1.EnvVar{}, + }, + { + name: "SecretReference", + opts: func() *Options { + o := &Options{} + o.Unpack(saasv1alpha1.SecretReference{FromVault: &saasv1alpha1.VaultSecretReference{ + Path: "path", + Key: "key", + }}).IntoEnvvar("envvar").AsSecretRef("secret") + return o + }(), + args: args{extra: []corev1.EnvVar{}}, + want: []corev1.EnvVar{{ + Name: "envvar", ValueFrom: &corev1.EnvVarSource{ SecretKeyRef: &corev1.SecretKeySelector{ - Key: "key", LocalObjectReference: corev1.LocalObjectReference{ - Name: "my-secret", + Name: "secret", }, + Key: "envvar", }, }, + }}, + }, + { + name: "Pointer to SecretReference", + opts: func() *Options { + o := &Options{} + o.Unpack(&saasv1alpha1.SecretReference{FromVault: &saasv1alpha1.VaultSecretReference{ + Path: "path", + Key: "key", + }}).IntoEnvvar("envvar").AsSecretRef("secret") + return o + }(), + args: args{extra: []corev1.EnvVar{}}, + want: []corev1.EnvVar{{ + Name: "envvar", + ValueFrom: &corev1.EnvVarSource{ + SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "secret", + }, + Key: "envvar", + }, + }, + }}, + }, + { + name: "Don't panic on nil pointer to SecretReference", + opts: func() *Options { + o := &Options{} + var v *saasv1alpha1.SecretReference + o.Unpack(v).IntoEnvvar("envvar").AsSecretRef("secret") + return o + }(), + args: args{extra: []corev1.EnvVar{}}, + want: []corev1.EnvVar{}, + }, + { + name: "SecretReference with override", + opts: func() *Options { + o := &Options{} + o.Unpack(saasv1alpha1.SecretReference{Override: util.Pointer("value")}).IntoEnvvar("envvar") + return o + }(), + args: args{extra: []corev1.EnvVar{}}, + want: []corev1.EnvVar{{ + Name: "envvar", + Value: "value", + }}, + }, + { + name: "EmptyIf", + opts: func() *Options { + o := &Options{} + o.Unpack(&saasv1alpha1.SecretReference{FromVault: &saasv1alpha1.VaultSecretReference{ + Path: "path", + Key: "key", + }}).IntoEnvvar("envvar").AsSecretRef("secret").EmptyIf(true) + return o + }(), + args: args{extra: []corev1.EnvVar{}}, + want: []corev1.EnvVar{{ + Name: "envvar", + Value: "", + }}, + }, + { + name: "Adds/overwrites extra envvars", + opts: func() *Options { + o := &Options{} + o.Unpack(&saasv1alpha1.SecretReference{FromVault: &saasv1alpha1.VaultSecretReference{ + Path: "path", + Key: "key", + }}).IntoEnvvar("envvar1").AsSecretRef("secret").EmptyIf(true) + o.Unpack("value2").IntoEnvvar("envvar2") + return o + }(), + args: args{extra: []corev1.EnvVar{ + { + Name: "envvar1", + Value: "value1", + }, + { + Name: "envvar3", + Value: "value3", + }, + }}, + want: []corev1.EnvVar{ + { + Name: "envvar1", + Value: "value1", + }, + { + Name: "envvar2", + Value: "value2", + }, + { + Name: "envvar3", + Value: "value3", + }, }, }, { - name: "Returns EnvVar from an overrided Secret", - fields: fields{Value: saasv1alpha1.SecretReference{Override: util.Pointer("override")}}, - args: args{key: "key:my-secret"}, - want: corev1.EnvVar{Name: "key", Value: "override"}, + name: "bool value", + opts: func() *Options { + o := NewOptions() + o.Unpack(true).IntoEnvvar("envvar") + return o + }(), + args: args{extra: []corev1.EnvVar{}}, + want: []corev1.EnvVar{{ + Name: "envvar", + Value: "true", + }}, + }, + { + name: "Pointer to int value", + opts: func() *Options { + o := NewOptions() + o.Unpack(util.Pointer(100)).IntoEnvvar("envvar") + return o + }(), + args: args{extra: []corev1.EnvVar{}}, + want: []corev1.EnvVar{{ + Name: "envvar", + Value: "100", + }}, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - sv := &SecretValue{ - Value: tt.fields.Value, - } - if got := sv.ToEnvVar(tt.args.key); !reflect.DeepEqual(got, tt.want) { - t.Errorf("SecretValue.ToEnvVar() = %v, want %v", got, tt.want) + got := tt.opts.WithExtraEnv(tt.args.extra).BuildEnvironment() + if diff := cmp.Diff(got, tt.want); len(diff) > 0 { + t.Errorf("Options.BuildEnvironment() got diff %v", diff) } }) } } -func TestBuildEnvironment(t *testing.T) { +func TestOptions_GenerateExternalSecrets(t *testing.T) { type args struct { - opts interface{} + namespace string + labels map[string]string + secretStoreName string + secretStoreKind string + refreshInterval metav1.Duration } tests := []struct { - name string - args args - want []corev1.EnvVar - wantPanic bool + name string + opts *Options + args args + want []client.Object }{ { - name: "Returns a slice of EnvVar", + name: "Does not generate any external secret", + opts: func() *Options { + o := NewOptions() + o.Unpack("value1").IntoEnvvar("envvar1") + o.Unpack("value2").IntoEnvvar("envvar2") + return o + }(), + args: args{}, + want: []client.Object{}, + }, + { + name: "Generates external secrets for the secret options", + opts: func() *Options { + o := NewOptions() + o.Unpack(&saasv1alpha1.SecretReference{FromVault: &saasv1alpha1.VaultSecretReference{ + Path: "path1", + Key: "key1", + }}).IntoEnvvar("envvar1").AsSecretRef("secret1") + o.Unpack(&saasv1alpha1.SecretReference{FromVault: &saasv1alpha1.VaultSecretReference{ + Path: "path2", + Key: "key2", + }}).IntoEnvvar("envvar2").AsSecretRef("secret1") + o.Unpack(&saasv1alpha1.SecretReference{FromVault: &saasv1alpha1.VaultSecretReference{ + Path: "path3", + Key: "key3", + }}).IntoEnvvar("envvar3").AsSecretRef("secret2") + return o + }(), args: args{ - opts: struct { - Option1 EnvVarValue `env:"OPTION1"` - Option2 EnvVarValue `env:"OPTION2"` - Option3 EnvVarValue `env:"OPTION3" secret:"my-secret"` - Option4 EnvVarValue `env:"OPTION4"` - }{ - Option1: &ClearTextValue{Value: "value1"}, - Option2: &ClearTextValue{Value: "value2"}, - Option3: &SecretValue{Value: v1alpha1.SecretReference{}}, - }, + namespace: "ns", + labels: map[string]string{"label-key": "label-value"}, + secretStoreName: "vault", + secretStoreKind: "SecretStore", + refreshInterval: metav1.Duration{Duration: 60 * time.Second}, }, - want: []corev1.EnvVar{ - { - Name: "OPTION1", - Value: "value1", - }, - { - Name: "OPTION2", - Value: "value2", - }, - { - Name: "OPTION3", - ValueFrom: &corev1.EnvVarSource{ - SecretKeyRef: &corev1.SecretKeySelector{ - Key: "OPTION3", - LocalObjectReference: corev1.LocalObjectReference{ - Name: "my-secret", + want: []client.Object{ + &externalsecretsv1beta1.ExternalSecret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "secret1", + Namespace: "ns", + Labels: map[string]string{"label-key": "label-value"}, + }, + Spec: externalsecretsv1beta1.ExternalSecretSpec{ + SecretStoreRef: externalsecretsv1beta1.SecretStoreRef{ + Name: "vault", + Kind: "SecretStore", + }, + Target: externalsecretsv1beta1.ExternalSecretTarget{ + Name: "secret1", + CreationPolicy: "Owner", + DeletionPolicy: "Retain", + }, + RefreshInterval: util.Pointer(metav1.Duration{Duration: 60 * time.Second}), + Data: []externalsecretsv1beta1.ExternalSecretData{ + { + SecretKey: "envvar1", + RemoteRef: externalsecretsv1beta1.ExternalSecretDataRemoteRef{ + Key: "path1", + Property: "key1", + ConversionStrategy: "Default", + DecodingStrategy: "None", + }, + }, + { + SecretKey: "envvar2", + RemoteRef: externalsecretsv1beta1.ExternalSecretDataRemoteRef{ + Key: "path2", + Property: "key2", + ConversionStrategy: "Default", + DecodingStrategy: "None", + }, }, }, }, }, - }, - }, - { - name: "Returns a slice of EnvVar, with overrides", - args: args{ - opts: struct { - Option1 EnvVarValue `env:"OPTION1"` - Option2 EnvVarValue `env:"OPTION2" secret:"my-secret"` - Option3 EnvVarValue `env:"OPTION3" secret:"my-secret"` - }{ - Option1: &ClearTextValue{Value: "value1"}, - Option2: &SecretValue{Value: v1alpha1.SecretReference{Override: util.Pointer("override")}}, - Option3: &SecretValue{Value: v1alpha1.SecretReference{}}, - }, - }, - want: []corev1.EnvVar{ - { - Name: "OPTION1", - Value: "value1", - }, - { - Name: "OPTION2", - Value: "override", - }, - { - Name: "OPTION3", - ValueFrom: &corev1.EnvVarSource{ - SecretKeyRef: &corev1.SecretKeySelector{ - Key: "OPTION3", - LocalObjectReference: corev1.LocalObjectReference{ - Name: "my-secret", + &externalsecretsv1beta1.ExternalSecret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "secret2", + Namespace: "ns", + Labels: map[string]string{"label-key": "label-value"}, + }, + Spec: externalsecretsv1beta1.ExternalSecretSpec{ + SecretStoreRef: externalsecretsv1beta1.SecretStoreRef{ + Name: "vault", + Kind: "SecretStore", + }, + Target: externalsecretsv1beta1.ExternalSecretTarget{ + Name: "secret2", + CreationPolicy: "Owner", + DeletionPolicy: "Retain", + }, + RefreshInterval: util.Pointer(metav1.Duration{Duration: 60 * time.Second}), + Data: []externalsecretsv1beta1.ExternalSecretData{ + { + SecretKey: "envvar3", + RemoteRef: externalsecretsv1beta1.ExternalSecretDataRemoteRef{ + Key: "path3", + Property: "key3", + ConversionStrategy: "Default", + DecodingStrategy: "None", + }, }, }, }, @@ -172,56 +358,130 @@ func TestBuildEnvironment(t *testing.T) { }, }, { - name: "Panics due to field not being an EnvVarValue", - args: args{ - opts: struct { - Option1 string `env:"OPTION1"` - }{ - Option1: "value", - }, - }, - want: nil, - wantPanic: true, + name: "Skips secret options with override", + opts: func() *Options { + o := NewOptions() + o.Unpack(&saasv1alpha1.SecretReference{Override: util.Pointer("override")}).IntoEnvvar("envvar1").AsSecretRef("secret") + return o + }(), + args: args{}, + want: []client.Object{}, }, { - name: "Panics due to field missing 'secret' tag", - args: args{ - opts: struct { - Option1 EnvVarValue `env:"OPTION1"` - }{ - Option1: &SecretValue{Value: v1alpha1.SecretReference{}}, - }, - }, - want: nil, - wantPanic: true, + name: "Skips secret options with nil value", + opts: func() *Options { + o := NewOptions() + var v *saasv1alpha1.SecretReference + o.Unpack(v).IntoEnvvar("envvar1").AsSecretRef("secret") + return o + }(), + args: args{}, + want: []client.Object{}, }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + templates := tt.opts.GenerateExternalSecrets(tt.args.namespace, tt.args.labels, tt.args.secretStoreName, tt.args.secretStoreKind, tt.args.refreshInterval) + got := []client.Object{} + for _, tplt := range templates { + es, _ := tplt.Build(context.TODO(), fake.NewClientBuilder().Build(), nil) + got = append(got, es) + } + if diff := cmp.Diff(got, tt.want); len(diff) > 0 { + t.Errorf("Options.GenerateExternalSecrets() got diff %v", diff) + } + }) + } +} + +func TestOptions_WithExtraEnv(t *testing.T) { + type args struct { + extra []corev1.EnvVar + } + tests := []struct { + name string + options *Options + args args + want *Options + wantOld *Options + }{ { - name: "Panics due to unexpected 'secret' tag", + name: "", + options: &Options{{ + value: util.Pointer("value1"), + envVariable: "envvar1", + set: true, + }}, args: args{ - opts: struct { - Option1 EnvVarValue `env:"OPTION1" secret:"some-secret"` - }{ - Option1: &ClearTextValue{Value: "xxxx"}, + extra: []corev1.EnvVar{ + {Name: "envvar1", Value: "aaaa"}, + {Name: "envvar2", Value: "bbbb"}, + }, + }, + want: &Options{ + { + value: util.Pointer("aaaa"), + envVariable: "envvar1", + set: true, + }, + { + value: util.Pointer("bbbb"), + envVariable: "envvar2", + set: true, }, }, - want: nil, - wantPanic: true, + wantOld: &Options{{ + value: util.Pointer("value1"), + envVariable: "envvar1", + set: true, + }}, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - defer func() { - r := recover() - if r == nil && tt.wantPanic { - t.Errorf("code did not panic") - } - if r != nil && !tt.wantPanic { - t.Errorf("code caused a panic") - } - }() + got := tt.options.WithExtraEnv(tt.args.extra) + if diff := cmp.Diff(got, tt.want, cmp.AllowUnexported(Option{})); len(diff) > 0 { + t.Errorf("Options.WithExtraEnv() got diff %v", diff) + } + if diff := cmp.Diff(tt.options, tt.wantOld, cmp.AllowUnexported(Option{})); len(diff) > 0 { + t.Errorf("Options.WithExtraEnv() gotOld diff %v", diff) + } + }) + } +} - if got := BuildEnvironment(tt.args.opts); !reflect.DeepEqual(got, tt.want) { - t.Errorf("BuildEnvironment() = %v, want %v", got, tt.want) +func TestOptions_ListSecretResourceNames(t *testing.T) { + tests := []struct { + name string + options *Options + want []string + }{ + { + name: "", + options: func() *Options { + o := &Options{} + // ok + o.Unpack(&saasv1alpha1.SecretReference{FromVault: &saasv1alpha1.VaultSecretReference{}}).IntoEnvvar("envvar1").AsSecretRef("secret1") + // not ok: not a secret value + o.Unpack("value").IntoEnvvar("envvar2") + // not ok: secret value with override + o.Unpack(&saasv1alpha1.SecretReference{Override: util.Pointer("value")}).IntoEnvvar("envvar3").AsSecretRef("secret2") + var v *saasv1alpha1.SecretReference + // not ok: secret value is nil + o.Unpack(v).IntoEnvvar("envvar1").AsSecretRef("secret3") + // ok + o.Unpack(&saasv1alpha1.SecretReference{FromVault: &saasv1alpha1.VaultSecretReference{}}).IntoEnvvar("envvar2").AsSecretRef("secret1") + // ok + o.Unpack(&saasv1alpha1.SecretReference{FromVault: &saasv1alpha1.VaultSecretReference{}}).IntoEnvvar("envvar3").AsSecretRef("secret2") + return o + }(), + want: []string{"secret1", "secret2"}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := tt.options.ListSecretResourceNames(); !reflect.DeepEqual(got, tt.want) { + t.Errorf("Options.ListSecretResourceNames() = %v, want %v", got, tt.want) } }) } diff --git a/pkg/resource_builders/pod/externalsecrets.go b/pkg/resource_builders/pod/externalsecrets.go deleted file mode 100644 index d485dfd4..00000000 --- a/pkg/resource_builders/pod/externalsecrets.go +++ /dev/null @@ -1,95 +0,0 @@ -package pod - -import ( - "fmt" - "reflect" - "strings" - - externalsecretsv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "sigs.k8s.io/controller-runtime/pkg/client" -) - -// GenerateExternalSecretFn generates a ExternalSecret -func GenerateExternalSecretFn(name, namespace, secretStoreName, secretStoreKind string, refreshInterval metav1.Duration, labels map[string]string, - opts interface{}) func(client.Object) (*externalsecretsv1beta1.ExternalSecret, error) { - - return func(client.Object) (*externalsecretsv1beta1.ExternalSecret, error) { - return &externalsecretsv1beta1.ExternalSecret{ - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Namespace: namespace, - Labels: labels, - }, - Spec: externalsecretsv1beta1.ExternalSecretSpec{ - SecretStoreRef: externalsecretsv1beta1.SecretStoreRef{ - Name: secretStoreName, - Kind: secretStoreKind, - }, - Target: externalsecretsv1beta1.ExternalSecretTarget{ - Name: name, - CreationPolicy: "Owner", - DeletionPolicy: "Retain", - }, - RefreshInterval: &refreshInterval, - Data: keysSlice(name, opts), - }, - }, nil - } -} - -func keysSlice(name string, opts interface{}) []externalsecretsv1beta1.ExternalSecretData { - - s := []externalsecretsv1beta1.ExternalSecretData{} - - t := reflect.TypeOf(opts) - - for i := 0; i < t.NumField(); i++ { - - field := t.Field(i) - - // Ensure field is of EnvVarValue type - if field.Type.String() != "pod.EnvVarValue" { - panic(fmt.Errorf("field in '%s/%s' is not a 'pod.EnvVarValue'", t.Name(), field.Name)) - } - - secretName, hasSecretTag := field.Tag.Lookup("secret") - if !hasSecretTag || secretName != name { - continue - } - - keyName, hasEnvTag := field.Tag.Lookup("env") - if !hasEnvTag { - panic(fmt.Errorf("missing 'env' tag from field '%s/%s'", t.Name(), field.Name)) - } - - value := reflect.ValueOf(opts).FieldByName(field.Name) - // Skip field if its value is not set - if value.IsZero() { - continue - } - - // Value should be of SecretValue type - valueType := value.Elem().Elem().Type().String() - if valueType != "pod.SecretValue" { - panic(fmt.Errorf("wrong type '%s' for field %s/%s", valueType, t.Name(), field.Name)) - } - - secretValue := value.Elem().Elem().Interface().(SecretValue) - if secretValue.Value.Override != nil { - continue - } - - s = append(s, externalsecretsv1beta1.ExternalSecretData{ - SecretKey: keyName, - RemoteRef: externalsecretsv1beta1.ExternalSecretDataRemoteRef{ - Key: strings.TrimPrefix(secretValue.Value.FromVault.Path, "secret/data/"), - Property: secretValue.Value.FromVault.Key, - ConversionStrategy: "Default", - DecodingStrategy: "None", - }, - }) - } - - return s -} diff --git a/pkg/resource_builders/pod/externalsecrets_test.go b/pkg/resource_builders/pod/externalsecrets_test.go deleted file mode 100644 index 4c6ac34c..00000000 --- a/pkg/resource_builders/pod/externalsecrets_test.go +++ /dev/null @@ -1,281 +0,0 @@ -package pod - -import ( - "reflect" - "testing" - "time" - - "github.com/3scale-ops/basereconciler/util" - saasv1alpha1 "github.com/3scale-ops/saas-operator/api/v1alpha1" - externalsecretsv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1" - "github.com/go-test/deep" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -func TestGenerateExternalSecretFn(t *testing.T) { - type args struct { - name string - namespace string - secretStoreName string - secretStoreKind string - refreshInterval metav1.Duration - labels map[string]string - opts interface{} - } - tests := []struct { - name string - args args - want *externalsecretsv1beta1.ExternalSecret - }{ - { - name: "Generates a new ExternalSecret from an Options struct", - args: args{ - name: "my-secret", - namespace: "test", - secretStoreName: "vault-mgmt", - secretStoreKind: "ClusterSecretStore", - refreshInterval: metav1.Duration{Duration: 120 * time.Second}, - labels: map[string]string{}, - opts: struct { - Option1 EnvVarValue `env:"OPTION1"` - Option2 EnvVarValue `env:"OPTION2" secret:"my-secret"` - Option3 EnvVarValue `env:"OPTION3" secret:"my-secret"` - Option4 EnvVarValue `env:"OPTION4" secret:"other-secret"` - Option5 EnvVarValue `env:"OPTION5" secret:"not-set"` - }{ - Option1: &ClearTextValue{Value: "value1"}, - Option2: &SecretValue{Value: saasv1alpha1.SecretReference{ - FromVault: &saasv1alpha1.VaultSecretReference{Key: "key2", Path: "path2"}}}, - Option3: &SecretValue{Value: saasv1alpha1.SecretReference{ - FromVault: &saasv1alpha1.VaultSecretReference{Key: "key3", Path: "path3"}}}, - Option4: &SecretValue{Value: saasv1alpha1.SecretReference{ - FromVault: &saasv1alpha1.VaultSecretReference{Key: "key3", Path: "path3"}}}, - }, - }, - want: &externalsecretsv1beta1.ExternalSecret{ - ObjectMeta: metav1.ObjectMeta{ - Name: "my-secret", - Namespace: "test", - Labels: map[string]string{}, - }, - Spec: externalsecretsv1beta1.ExternalSecretSpec{ - SecretStoreRef: externalsecretsv1beta1.SecretStoreRef{ - Name: "vault-mgmt", - Kind: "ClusterSecretStore", - }, - Target: externalsecretsv1beta1.ExternalSecretTarget{Name: "my-secret", CreationPolicy: "Owner", DeletionPolicy: "Retain"}, - RefreshInterval: &metav1.Duration{Duration: 120 * time.Second}, - Data: []externalsecretsv1beta1.ExternalSecretData{ - { - SecretKey: "OPTION2", - RemoteRef: externalsecretsv1beta1.ExternalSecretDataRemoteRef{ - Key: "path2", - Property: "key2", - ConversionStrategy: "Default", - DecodingStrategy: "None", - }, - }, - { - SecretKey: "OPTION3", - RemoteRef: externalsecretsv1beta1.ExternalSecretDataRemoteRef{ - Key: "path3", - Property: "key3", - ConversionStrategy: "Default", - DecodingStrategy: "None", - }, - }, - }, - }, - }, - }, - { - name: "Generates other ExternalSecret from the same Options struct (see previous test)", - args: args{ - name: "other-secret", - namespace: "test", - secretStoreName: "vault-mgmt", - secretStoreKind: "ClusterSecretStore", - refreshInterval: metav1.Duration{Duration: 2 * time.Minute}, - labels: map[string]string{}, - opts: struct { - Option1 EnvVarValue `env:"OPTION1"` - Option2 EnvVarValue `env:"OPTION2" secret:"my-secret"` - Option3 EnvVarValue `env:"OPTION3" secret:"my-secret"` - Option4 EnvVarValue `env:"OPTION4" secret:"other-secret"` - }{ - Option1: &ClearTextValue{Value: "value1"}, - Option2: &SecretValue{Value: saasv1alpha1.SecretReference{ - FromVault: &saasv1alpha1.VaultSecretReference{Key: "key2", Path: "path2"}}}, - Option3: &SecretValue{Value: saasv1alpha1.SecretReference{ - FromVault: &saasv1alpha1.VaultSecretReference{Key: "key3", Path: "path3"}}}, - Option4: &SecretValue{Value: saasv1alpha1.SecretReference{ - FromVault: &saasv1alpha1.VaultSecretReference{Key: "key4", Path: "path4"}}}, - }, - }, - want: &externalsecretsv1beta1.ExternalSecret{ - ObjectMeta: metav1.ObjectMeta{ - Name: "other-secret", - Namespace: "test", - Labels: map[string]string{}, - }, - Spec: externalsecretsv1beta1.ExternalSecretSpec{ - SecretStoreRef: externalsecretsv1beta1.SecretStoreRef{ - Name: "vault-mgmt", - Kind: "ClusterSecretStore", - }, - Target: externalsecretsv1beta1.ExternalSecretTarget{Name: "other-secret", CreationPolicy: "Owner", DeletionPolicy: "Retain"}, - RefreshInterval: &metav1.Duration{Duration: 120 * time.Second}, - Data: []externalsecretsv1beta1.ExternalSecretData{ - { - SecretKey: "OPTION4", - RemoteRef: externalsecretsv1beta1.ExternalSecretDataRemoteRef{ - Key: "path4", - Property: "key4", - ConversionStrategy: "Default", - DecodingStrategy: "None", - }, - }, - }, - }, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, _ := GenerateExternalSecretFn(tt.args.name, tt.args.namespace, tt.args.secretStoreName, tt.args.secretStoreKind, tt.args.refreshInterval, tt.args.labels, tt.args.opts)(nil) - if diff := deep.Equal(got, tt.want); len(diff) > 0 { - t.Errorf("GenerateExternalSecretFn() = diff %v", diff) - } - }) - } -} - -func Test_keysSlice(t *testing.T) { - type args struct { - name string - opts interface{} - } - tests := []struct { - name string - args args - want []externalsecretsv1beta1.ExternalSecretData - wantPanic bool - }{ - { - name: "Generates a DataSources map", - args: args{ - name: "my-secret", - opts: struct { - Option1 EnvVarValue `env:"OPTION1"` - Option2 EnvVarValue `env:"OPTION2" secret:"my-secret"` - Option3 EnvVarValue `env:"OPTION3" secret:"my-secret"` - Option4 EnvVarValue `env:"OPTION4" secret:"other-secret"` - }{ - Option1: &ClearTextValue{Value: "value1"}, - Option2: &SecretValue{Value: saasv1alpha1.SecretReference{ - FromVault: &saasv1alpha1.VaultSecretReference{Key: "key2", Path: "path2"}}}, - Option3: &SecretValue{Value: saasv1alpha1.SecretReference{ - FromVault: &saasv1alpha1.VaultSecretReference{Key: "key3", Path: "path3"}}}, - Option4: &SecretValue{Value: saasv1alpha1.SecretReference{ - FromVault: &saasv1alpha1.VaultSecretReference{Key: "key4", Path: "path4"}}}, - }, - }, - want: []externalsecretsv1beta1.ExternalSecretData{ - { - SecretKey: "OPTION2", - RemoteRef: externalsecretsv1beta1.ExternalSecretDataRemoteRef{ - Key: "path2", - Property: "key2", - ConversionStrategy: "Default", - DecodingStrategy: "None", - }, - }, - { - SecretKey: "OPTION3", - RemoteRef: externalsecretsv1beta1.ExternalSecretDataRemoteRef{ - Key: "path3", - Property: "key3", - ConversionStrategy: "Default", - DecodingStrategy: "None", - }, - }, - }, - wantPanic: false, - }, - { - name: "Generates a DataSources map, with secret overrides", - args: args{ - name: "my-secret", - opts: struct { - Option1 EnvVarValue `env:"OPTION1"` - Option2 EnvVarValue `env:"OPTION2" secret:"my-secret"` - Option3 EnvVarValue `env:"OPTION3" secret:"my-secret"` - Option4 EnvVarValue `env:"OPTION4" secret:"other-secret"` - }{ - Option1: &ClearTextValue{Value: "value1"}, - Option2: &SecretValue{Value: saasv1alpha1.SecretReference{ - FromVault: &saasv1alpha1.VaultSecretReference{Key: "key2", Path: "path2"}}}, - Option3: &SecretValue{Value: saasv1alpha1.SecretReference{ - Override: util.Pointer("override")}}, - Option4: &SecretValue{Value: saasv1alpha1.SecretReference{ - FromVault: &saasv1alpha1.VaultSecretReference{Key: "key4", Path: "path4"}}}, - }, - }, - want: []externalsecretsv1beta1.ExternalSecretData{ - { - SecretKey: "OPTION2", - RemoteRef: externalsecretsv1beta1.ExternalSecretDataRemoteRef{ - Key: "path2", - Property: "key2", - ConversionStrategy: "Default", - DecodingStrategy: "None", - }, - }, - }, - wantPanic: false, - }, - { - name: "Panics if value is not a SecretValue", - args: args{ - name: "my-secret", - opts: struct { - Option1 EnvVarValue `env:"OPTION1" secret:"my-secret"` - }{ - Option1: &ClearTextValue{Value: "xxxx"}, - }, - }, - want: []externalsecretsv1beta1.ExternalSecretData{}, - wantPanic: true, - }, - { - name: "Panics if 'env' tag is missing", - args: args{ - name: "my-secret", - opts: struct { - Option1 EnvVarValue `secret:"my-secret"` - }{ - Option1: &SecretValue{Value: saasv1alpha1.SecretReference{}}, - }, - }, - want: []externalsecretsv1beta1.ExternalSecretData{}, - wantPanic: true, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - defer func() { - r := recover() - if r == nil && tt.wantPanic { - t.Errorf("code did not panic") - } - if r != nil && !tt.wantPanic { - t.Errorf("code caused a panic") - } - }() - - if got := keysSlice(tt.args.name, tt.args.opts); !reflect.DeepEqual(got, tt.want) { - t.Errorf("keysSlice() = %v, want %v", got, tt.want) - } - }) - } -} diff --git a/pkg/resource_builders/twemproxy/options.go b/pkg/resource_builders/twemproxy/options.go index 0e93d949..49073e1b 100644 --- a/pkg/resource_builders/twemproxy/options.go +++ b/pkg/resource_builders/twemproxy/options.go @@ -1,8 +1,6 @@ package twemproxy import ( - "fmt" - saasv1alpha1 "github.com/3scale-ops/saas-operator/api/v1alpha1" "github.com/3scale-ops/saas-operator/pkg/resource_builders/pod" ) @@ -11,21 +9,14 @@ const ( TwemproxyConfigFile = "/etc/twemproxy/nutcracker.yml" ) -// TwemproxyOptions holds configuration for the Twemproxy sidecar -type TwemproxyOptions struct { - ConfigFile pod.EnvVarValue `env:"TWEMPROXY_CONFIG_FILE"` - MetricsAddress pod.EnvVarValue `env:"TWEMPROXY_METRICS_ADDRESS"` - StatsInterval pod.EnvVarValue `env:"TWEMPROXY_STATS_INTERVAL"` - LogLevel pod.EnvVarValue `env:"TWEMPROXY_LOG_LEVEL"` -} +// NewOptions generates the configuration for the Twemproxy sidecar +func NewOptions(spec saasv1alpha1.TwemproxySpec) *pod.Options { + opts := pod.NewOptions() + + opts.Unpack(TwemproxyConfigFile).IntoEnvvar("TWEMPROXY_CONFIG_FILE") + opts.Unpack(spec.Options.MetricsPort, ":%d").IntoEnvvar("TWEMPROXY_METRICS_ADDRESS") + opts.Unpack(spec.Options.StatsInterval.Milliseconds()).IntoEnvvar("TWEMPROXY_STATS_INTERVAL") + opts.Unpack(spec.Options.LogLevel).IntoEnvvar("TWEMPROXY_LOG_LEVEL") -// NewTwemproxyOptions returns a NewTwemproxyOptions struct for the given saasv1alpha1.BackendSpec -func NewTwemproxyOptions(spec saasv1alpha1.TwemproxySpec) TwemproxyOptions { - opts := TwemproxyOptions{ - ConfigFile: &pod.ClearTextValue{Value: TwemproxyConfigFile}, - MetricsAddress: &pod.ClearTextValue{Value: fmt.Sprintf(":%d", *spec.Options.MetricsPort)}, - StatsInterval: &pod.ClearTextValue{Value: fmt.Sprintf("%d", spec.Options.StatsInterval.Milliseconds())}, - LogLevel: &pod.ClearTextValue{Value: fmt.Sprintf("%d", *spec.Options.LogLevel)}, - } return opts } diff --git a/pkg/resource_builders/twemproxy/util.go b/pkg/resource_builders/twemproxy/util.go index 5a648d3f..149eedb2 100644 --- a/pkg/resource_builders/twemproxy/util.go +++ b/pkg/resource_builders/twemproxy/util.go @@ -19,7 +19,7 @@ const ( func TwemproxyContainer(twemproxySpec *saasv1alpha1.TwemproxySpec) corev1.Container { return corev1.Container{ - Env: pod.BuildEnvironment(NewTwemproxyOptions(*twemproxySpec)), + Env: NewOptions(*twemproxySpec).BuildEnvironment(), Name: twemproxy, Image: pod.Image(*twemproxySpec.Image), Ports: pod.ContainerPorts( diff --git a/pkg/workloads/deployment/deployment_based_workload.go b/pkg/workloads/deployment/deployment_based_workload.go index c628bfdb..e30708c5 100644 --- a/pkg/workloads/deployment/deployment_based_workload.go +++ b/pkg/workloads/deployment/deployment_based_workload.go @@ -1,8 +1,6 @@ package delpoyment_workload import ( - "reflect" - "github.com/3scale-ops/basereconciler/resource" "github.com/3scale-ops/basereconciler/util" marin3rv1alpha1 "github.com/3scale-ops/marin3r/apis/marin3r/v1alpha1" @@ -12,6 +10,7 @@ import ( "github.com/3scale-ops/saas-operator/pkg/resource_builders/pdb" "github.com/3scale-ops/saas-operator/pkg/resource_builders/podmonitor" monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" + "github.com/samber/lo" appsv1 "k8s.io/api/apps/v1" autoscalingv2 "k8s.io/api/autoscaling/v2" corev1 "k8s.io/api/core/v1" @@ -25,7 +24,7 @@ func New(main DeploymentWorkload, canary DeploymentWorkload) ([]resource.Templat resources := workloadResources(main) - if unwrapNil(canary) != nil { + if !lo.IsNil(canary) { resources = append(resources, workloadResources(canary)...) } @@ -194,15 +193,8 @@ func nodeIdToEnvoyConfig(w WithWorkloadMeta) resource.TemplateBuilderFunction[*m } } -func unwrapNil(w DeploymentWorkload) DeploymentWorkload { - if w == nil || reflect.ValueOf(w).IsNil() { - return nil - } - return w -} - func toWithTraffic(w DeploymentWorkload) WithTraffic { - if w == nil || reflect.ValueOf(w).IsNil() { + if lo.IsNil(w) { return nil } return w.(WithTraffic) diff --git a/pkg/workloads/deployment/deployment_based_workload_test.go b/pkg/workloads/deployment/deployment_based_workload_test.go index 74e67408..8b0df350 100644 --- a/pkg/workloads/deployment/deployment_based_workload_test.go +++ b/pkg/workloads/deployment/deployment_based_workload_test.go @@ -618,49 +618,6 @@ func Test_applyNodeIdToEnvoyConfig(t *testing.T) { } } -func Test_unwrapNil(t *testing.T) { - type args struct { - w DeploymentWorkload - } - tests := []struct { - name string - args args - want DeploymentWorkload - }{ - { - name: "Detects a nil value", - args: args{ - w: nil, - }, - want: nil, - }, - { - name: "Detects interface containing nil value", - args: args{ - w: func() DeploymentWorkload { - val := (*TestWorkloadGenerator)(nil) - return val - }(), - }, - want: nil, - }, - { - name: "Lets an interface containing a non nil value pass through", - args: args{ - w: &TestWorkloadGenerator{}, - }, - want: &TestWorkloadGenerator{}, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if got := unwrapNil(tt.args.w); !reflect.DeepEqual(got, tt.want) { - t.Errorf("unwrapNil() = %+v, want %+v", got, tt.want) - } - }) - } -} - func Test_toWithTraffic(t *testing.T) { type args struct { w DeploymentWorkload From 009ce511bead5dd490af16512f40dc4b6cf43944 Mon Sep 17 00:00:00 2001 From: Roi Vazquez Date: Wed, 10 Jan 2024 16:12:09 +0100 Subject: [PATCH 2/8] Dynamic watches --- controllers/apicast_controller.go | 21 +++---------- controllers/autossl_controller.go | 19 +++-------- controllers/backend_controller.go | 26 ++++----------- controllers/corsproxy_controller.go | 24 ++++---------- controllers/echoapi_controller.go | 21 +++---------- controllers/mappingservice_controller.go | 24 ++++---------- controllers/redisshard_controller.go | 11 +++---- controllers/sentinel_controller.go | 24 +++++--------- controllers/system_controller.go | 28 ++++------------- controllers/system_controller_suite_test.go | 20 +++++++----- controllers/twemproxyconfig_controller.go | 2 +- controllers/zync_controller.go | 25 ++++----------- go.mod | 4 +-- go.sum | 35 ++------------------- 14 files changed, 71 insertions(+), 213 deletions(-) diff --git a/controllers/apicast_controller.go b/controllers/apicast_controller.go index f1a1e27a..6d945bca 100644 --- a/controllers/apicast_controller.go +++ b/controllers/apicast_controller.go @@ -21,15 +21,8 @@ import ( "github.com/3scale-ops/basereconciler/reconciler" "github.com/3scale-ops/basereconciler/util" - marin3rv1alpha1 "github.com/3scale-ops/marin3r/apis/marin3r/v1alpha1" saasv1alpha1 "github.com/3scale-ops/saas-operator/api/v1alpha1" "github.com/3scale-ops/saas-operator/pkg/generators/apicast" - grafanav1alpha1 "github.com/grafana-operator/grafana-operator/v4/api/integreatly/v1alpha1" - monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" - appsv1 "k8s.io/api/apps/v1" - autoscalingv2 "k8s.io/api/autoscaling/v2" - corev1 "k8s.io/api/core/v1" - policyv1 "k8s.io/api/policy/v1" ctrl "sigs.k8s.io/controller-runtime" ) @@ -80,14 +73,8 @@ func (r *ApicastReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ct // SetupWithManager sets up the controller with the Manager. func (r *ApicastReconciler) SetupWithManager(mgr ctrl.Manager) error { - return ctrl.NewControllerManagedBy(mgr). - For(&saasv1alpha1.Apicast{}). - Owns(&appsv1.Deployment{}). - Owns(&corev1.Service{}). - Owns(&policyv1.PodDisruptionBudget{}). - Owns(&autoscalingv2.HorizontalPodAutoscaler{}). - Owns(&monitoringv1.PodMonitor{}). - Owns(&grafanav1alpha1.GrafanaDashboard{}). - Owns(&marin3rv1alpha1.EnvoyConfig{}). - Complete(r) + return reconciler.SetupWithDynamicTypeWatches(r, + ctrl.NewControllerManagedBy(mgr). + For(&saasv1alpha1.Apicast{}), + ) } diff --git a/controllers/autossl_controller.go b/controllers/autossl_controller.go index c4ea9607..f0a5ae3c 100644 --- a/controllers/autossl_controller.go +++ b/controllers/autossl_controller.go @@ -23,12 +23,6 @@ import ( "github.com/3scale-ops/basereconciler/util" saasv1alpha1 "github.com/3scale-ops/saas-operator/api/v1alpha1" "github.com/3scale-ops/saas-operator/pkg/generators/autossl" - grafanav1alpha1 "github.com/grafana-operator/grafana-operator/v4/api/integreatly/v1alpha1" - monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" - appsv1 "k8s.io/api/apps/v1" - autoscalingv2 "k8s.io/api/autoscaling/v2" - corev1 "k8s.io/api/core/v1" - policyv1 "k8s.io/api/policy/v1" ctrl "sigs.k8s.io/controller-runtime" ) @@ -78,13 +72,8 @@ func (r *AutoSSLReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ct // SetupWithManager sets up the controller with the Manager. func (r *AutoSSLReconciler) SetupWithManager(mgr ctrl.Manager) error { - return ctrl.NewControllerManagedBy(mgr). - For(&saasv1alpha1.AutoSSL{}). - Owns(&appsv1.Deployment{}). - Owns(&corev1.Service{}). - Owns(&policyv1.PodDisruptionBudget{}). - Owns(&autoscalingv2.HorizontalPodAutoscaler{}). - Owns(&monitoringv1.PodMonitor{}). - Owns(&grafanav1alpha1.GrafanaDashboard{}). - Complete(r) + return reconciler.SetupWithDynamicTypeWatches(r, + ctrl.NewControllerManagedBy(mgr). + For(&saasv1alpha1.AutoSSL{}), + ) } diff --git a/controllers/backend_controller.go b/controllers/backend_controller.go index 4582ea82..6b808c99 100644 --- a/controllers/backend_controller.go +++ b/controllers/backend_controller.go @@ -21,16 +21,9 @@ import ( "github.com/3scale-ops/basereconciler/reconciler" "github.com/3scale-ops/basereconciler/util" - marin3rv1alpha1 "github.com/3scale-ops/marin3r/apis/marin3r/v1alpha1" saasv1alpha1 "github.com/3scale-ops/saas-operator/api/v1alpha1" "github.com/3scale-ops/saas-operator/pkg/generators/backend" - externalsecretsv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1" - grafanav1alpha1 "github.com/grafana-operator/grafana-operator/v4/api/integreatly/v1alpha1" - monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" - appsv1 "k8s.io/api/apps/v1" - autoscalingv2 "k8s.io/api/autoscaling/v2" corev1 "k8s.io/api/core/v1" - policyv1 "k8s.io/api/policy/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/source" @@ -86,17 +79,10 @@ func (r *BackendReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ct // SetupWithManager sets up the controller with the Manager. func (r *BackendReconciler) SetupWithManager(mgr ctrl.Manager) error { - return ctrl.NewControllerManagedBy(mgr). - For(&saasv1alpha1.Backend{}). - Owns(&appsv1.Deployment{}). - Owns(&corev1.Service{}). - Owns(&policyv1.PodDisruptionBudget{}). - Owns(&autoscalingv2.HorizontalPodAutoscaler{}). - Owns(&monitoringv1.PodMonitor{}). - Owns(&externalsecretsv1beta1.ExternalSecret{}). - Owns(&grafanav1alpha1.GrafanaDashboard{}). - Owns(&marin3rv1alpha1.EnvoyConfig{}). - Watches(&source.Kind{Type: &corev1.Secret{TypeMeta: metav1.TypeMeta{Kind: "Secret"}}}, - r.FilteredEventHandler(&saasv1alpha1.BackendList{}, nil, r.Log)). - Complete(r) + return reconciler.SetupWithDynamicTypeWatches(r, + ctrl.NewControllerManagedBy(mgr). + For(&saasv1alpha1.Backend{}). + Watches(&source.Kind{Type: &corev1.Secret{TypeMeta: metav1.TypeMeta{Kind: "Secret"}}}, + r.FilteredEventHandler(&saasv1alpha1.BackendList{}, nil, r.Log)), + ) } diff --git a/controllers/corsproxy_controller.go b/controllers/corsproxy_controller.go index 797d1774..d687d528 100644 --- a/controllers/corsproxy_controller.go +++ b/controllers/corsproxy_controller.go @@ -23,13 +23,7 @@ import ( "github.com/3scale-ops/basereconciler/util" saasv1alpha1 "github.com/3scale-ops/saas-operator/api/v1alpha1" "github.com/3scale-ops/saas-operator/pkg/generators/corsproxy" - externalsecretsv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1" - grafanav1alpha1 "github.com/grafana-operator/grafana-operator/v4/api/integreatly/v1alpha1" - monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" - appsv1 "k8s.io/api/apps/v1" - autoscalingv2 "k8s.io/api/autoscaling/v2" corev1 "k8s.io/api/core/v1" - policyv1 "k8s.io/api/policy/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/source" @@ -80,16 +74,10 @@ func (r *CORSProxyReconciler) Reconcile(ctx context.Context, req ctrl.Request) ( // SetupWithManager sets up the controller with the Manager. func (r *CORSProxyReconciler) SetupWithManager(mgr ctrl.Manager) error { - return ctrl.NewControllerManagedBy(mgr). - For(&saasv1alpha1.CORSProxy{}). - Owns(&appsv1.Deployment{}). - Owns(&corev1.Service{}). - Owns(&policyv1.PodDisruptionBudget{}). - Owns(&autoscalingv2.HorizontalPodAutoscaler{}). - Owns(&monitoringv1.PodMonitor{}). - Owns(&externalsecretsv1beta1.ExternalSecret{}). - Owns(&grafanav1alpha1.GrafanaDashboard{}). - Watches(&source.Kind{Type: &corev1.Secret{TypeMeta: metav1.TypeMeta{Kind: "Secret"}}}, - r.FilteredEventHandler(&saasv1alpha1.CORSProxyList{}, nil, r.Log)). - Complete(r) + return reconciler.SetupWithDynamicTypeWatches(r, + ctrl.NewControllerManagedBy(mgr). + For(&saasv1alpha1.CORSProxy{}). + Watches(&source.Kind{Type: &corev1.Secret{TypeMeta: metav1.TypeMeta{Kind: "Secret"}}}, + r.FilteredEventHandler(&saasv1alpha1.CORSProxyList{}, nil, r.Log)), + ) } diff --git a/controllers/echoapi_controller.go b/controllers/echoapi_controller.go index 1a297666..19fedebb 100644 --- a/controllers/echoapi_controller.go +++ b/controllers/echoapi_controller.go @@ -21,15 +21,8 @@ import ( "github.com/3scale-ops/basereconciler/reconciler" "github.com/3scale-ops/basereconciler/util" - marin3rv1alpha1 "github.com/3scale-ops/marin3r/apis/marin3r/v1alpha1" saasv1alpha1 "github.com/3scale-ops/saas-operator/api/v1alpha1" "github.com/3scale-ops/saas-operator/pkg/generators/echoapi" - grafanav1alpha1 "github.com/grafana-operator/grafana-operator/v4/api/integreatly/v1alpha1" - monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" - appsv1 "k8s.io/api/apps/v1" - autoscalingv2 "k8s.io/api/autoscaling/v2" - corev1 "k8s.io/api/core/v1" - policyv1 "k8s.io/api/policy/v1" ctrl "sigs.k8s.io/controller-runtime" ) @@ -76,14 +69,8 @@ func (r *EchoAPIReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ct // SetupWithManager sets up the controller with the Manager. func (r *EchoAPIReconciler) SetupWithManager(mgr ctrl.Manager) error { - return ctrl.NewControllerManagedBy(mgr). - For(&saasv1alpha1.EchoAPI{}). - Owns(&appsv1.Deployment{}). - Owns(&corev1.Service{}). - Owns(&policyv1.PodDisruptionBudget{}). - Owns(&autoscalingv2.HorizontalPodAutoscaler{}). - Owns(&monitoringv1.PodMonitor{}). - Owns(&grafanav1alpha1.GrafanaDashboard{}). - Owns(&marin3rv1alpha1.EnvoyConfig{}). - Complete(r) + return reconciler.SetupWithDynamicTypeWatches(r, + ctrl.NewControllerManagedBy(mgr). + For(&saasv1alpha1.EchoAPI{}), + ) } diff --git a/controllers/mappingservice_controller.go b/controllers/mappingservice_controller.go index 73b4cf73..c1a67fed 100644 --- a/controllers/mappingservice_controller.go +++ b/controllers/mappingservice_controller.go @@ -23,13 +23,7 @@ import ( "github.com/3scale-ops/basereconciler/util" saasv1alpha1 "github.com/3scale-ops/saas-operator/api/v1alpha1" "github.com/3scale-ops/saas-operator/pkg/generators/mappingservice" - externalsecretsv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1" - grafanav1alpha1 "github.com/grafana-operator/grafana-operator/v4/api/integreatly/v1alpha1" - monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" - appsv1 "k8s.io/api/apps/v1" - autoscalingv2 "k8s.io/api/autoscaling/v2" corev1 "k8s.io/api/core/v1" - policyv1 "k8s.io/api/policy/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/source" @@ -80,16 +74,10 @@ func (r *MappingServiceReconciler) Reconcile(ctx context.Context, req ctrl.Reque // SetupWithManager sets up the controller with the Manager. func (r *MappingServiceReconciler) SetupWithManager(mgr ctrl.Manager) error { - return ctrl.NewControllerManagedBy(mgr). - For(&saasv1alpha1.MappingService{}). - Owns(&appsv1.Deployment{}). - Owns(&corev1.Service{}). - Owns(&policyv1.PodDisruptionBudget{}). - Owns(&autoscalingv2.HorizontalPodAutoscaler{}). - Owns(&monitoringv1.PodMonitor{}). - Owns(&externalsecretsv1beta1.ExternalSecret{}). - Owns(&grafanav1alpha1.GrafanaDashboard{}). - Watches(&source.Kind{Type: &corev1.Secret{TypeMeta: metav1.TypeMeta{Kind: "Secret"}}}, - r.FilteredEventHandler(&saasv1alpha1.MappingServiceList{}, nil, r.Log)). - Complete(r) + return reconciler.SetupWithDynamicTypeWatches(r, + ctrl.NewControllerManagedBy(mgr). + For(&saasv1alpha1.MappingService{}). + Watches(&source.Kind{Type: &corev1.Secret{TypeMeta: metav1.TypeMeta{Kind: "Secret"}}}, + r.FilteredEventHandler(&saasv1alpha1.MappingServiceList{}, nil, r.Log)), + ) } diff --git a/controllers/redisshard_controller.go b/controllers/redisshard_controller.go index 19948841..7274b389 100644 --- a/controllers/redisshard_controller.go +++ b/controllers/redisshard_controller.go @@ -29,7 +29,6 @@ import ( redis "github.com/3scale-ops/saas-operator/pkg/redis/server" "github.com/3scale-ops/saas-operator/pkg/redis/sharded" "github.com/go-logr/logr" - appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/equality" "k8s.io/apimachinery/pkg/types" @@ -83,12 +82,10 @@ func (r *RedisShardReconciler) Reconcile(ctx context.Context, req ctrl.Request) // SetupWithManager sets up the controller with the Manager. func (r *RedisShardReconciler) SetupWithManager(mgr ctrl.Manager) error { - return ctrl.NewControllerManagedBy(mgr). - For(&saasv1alpha1.RedisShard{}). - Owns(&appsv1.StatefulSet{}). - Owns(&corev1.Service{}). - Owns(&corev1.ConfigMap{}). - Complete(r) + return reconciler.SetupWithDynamicTypeWatches(r, + ctrl.NewControllerManagedBy(mgr). + For(&saasv1alpha1.RedisShard{}), + ) } func (r *RedisShardReconciler) setRedisRoles(ctx context.Context, key types.NamespacedName, diff --git a/controllers/sentinel_controller.go b/controllers/sentinel_controller.go index f7c18a95..7857d8d7 100644 --- a/controllers/sentinel_controller.go +++ b/controllers/sentinel_controller.go @@ -31,11 +31,7 @@ import ( redis "github.com/3scale-ops/saas-operator/pkg/redis/server" "github.com/3scale-ops/saas-operator/pkg/redis/sharded" "github.com/go-logr/logr" - grafanav1alpha1 "github.com/grafana-operator/grafana-operator/v4/api/integreatly/v1alpha1" "golang.org/x/time/rate" - appsv1 "k8s.io/api/apps/v1" - corev1 "k8s.io/api/core/v1" - policyv1 "k8s.io/api/policy/v1" "k8s.io/apimachinery/pkg/api/equality" "k8s.io/client-go/util/workqueue" ctrl "sigs.k8s.io/controller-runtime" @@ -207,21 +203,15 @@ func (r *SentinelReconciler) reconcileStatus(ctx context.Context, instance *saas // SetupWithManager sets up the controller with the Manager. func (r *SentinelReconciler) SetupWithManager(mgr ctrl.Manager) error { - return ctrl.NewControllerManagedBy(mgr). - For(&saasv1alpha1.Sentinel{}). - Owns(&appsv1.StatefulSet{}). - Owns(&corev1.Service{}). - Owns(&policyv1.PodDisruptionBudget{}). - Owns(&grafanav1alpha1.GrafanaDashboard{}). - Owns(&corev1.ConfigMap{}). - Watches(&source.Channel{Source: r.SentinelEvents.GetChannel()}, &handler.EnqueueRequestForObject{}). - WithOptions(controller.Options{ - RateLimiter: AggressiveRateLimiter(), - }). - Complete(r) + return reconciler.SetupWithDynamicTypeWatches(r, + ctrl.NewControllerManagedBy(mgr). + For(&saasv1alpha1.Sentinel{}). + Watches(&source.Channel{Source: r.SentinelEvents.GetChannel()}, &handler.EnqueueRequestForObject{}). + WithOptions(controller.Options{RateLimiter: PermissiveRateLimiter()}), + ) } -func AggressiveRateLimiter() ratelimiter.RateLimiter { +func PermissiveRateLimiter() ratelimiter.RateLimiter { // return workqueue.DefaultControllerRateLimiter() return workqueue.NewMaxOfRateLimiter( // First retries are more spaced that default diff --git a/controllers/system_controller.go b/controllers/system_controller.go index 4f780290..ced75e08 100644 --- a/controllers/system_controller.go +++ b/controllers/system_controller.go @@ -23,14 +23,7 @@ import ( "github.com/3scale-ops/basereconciler/util" saasv1alpha1 "github.com/3scale-ops/saas-operator/api/v1alpha1" "github.com/3scale-ops/saas-operator/pkg/generators/system" - externalsecretsv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1" - grafanav1alpha1 "github.com/grafana-operator/grafana-operator/v4/api/integreatly/v1alpha1" - monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" - pipelinev1beta1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1" - appsv1 "k8s.io/api/apps/v1" - autoscalingv2 "k8s.io/api/autoscaling/v2" corev1 "k8s.io/api/core/v1" - policyv1 "k8s.io/api/policy/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/source" @@ -86,19 +79,10 @@ func (r *SystemReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctr // SetupWithManager sets up the controller with the Manager. func (r *SystemReconciler) SetupWithManager(mgr ctrl.Manager) error { - return ctrl.NewControllerManagedBy(mgr). - For(&saasv1alpha1.System{}). - Owns(&appsv1.Deployment{}). - Owns(&appsv1.StatefulSet{}). - Owns(&corev1.Service{}). - Owns(&policyv1.PodDisruptionBudget{}). - Owns(&autoscalingv2.HorizontalPodAutoscaler{}). - Owns(&monitoringv1.PodMonitor{}). - Owns(&externalsecretsv1beta1.ExternalSecret{}). - Owns(&grafanav1alpha1.GrafanaDashboard{}). - Owns(&pipelinev1beta1.Pipeline{}). - Owns(&pipelinev1beta1.Task{}). - Watches(&source.Kind{Type: &corev1.Secret{TypeMeta: metav1.TypeMeta{Kind: "Secret"}}}, - r.FilteredEventHandler(&saasv1alpha1.SystemList{}, nil, r.Log)). - Complete(r) + return reconciler.SetupWithDynamicTypeWatches(r, + ctrl.NewControllerManagedBy(mgr). + For(&saasv1alpha1.System{}). + Watches(&source.Kind{Type: &corev1.Secret{TypeMeta: metav1.TypeMeta{Kind: "Secret"}}}, + r.FilteredEventHandler(&saasv1alpha1.SystemList{}, nil, r.Log)), + ) } diff --git a/controllers/system_controller_suite_test.go b/controllers/system_controller_suite_test.go index 1211fcbe..81d4bf12 100644 --- a/controllers/system_controller_suite_test.go +++ b/controllers/system_controller_suite_test.go @@ -89,7 +89,11 @@ var _ = Describe("System controller", func() { ReleaseStage: util.Pointer("staging"), APIKey: saasv1alpha1.SecretReference{Override: util.Pointer("override")}, }, - DatabaseSecret: saasv1alpha1.SecretReference{Override: util.Pointer("override")}, + // DatabaseSecret: saasv1alpha1.SecretReference{Override: util.Pointer("override")}, + DatabaseSecret: saasv1alpha1.SecretReference{FromVault: &saasv1alpha1.VaultSecretReference{ + Path: "path", + Key: "key", + }}, MemcachedServers: "value", Redis: saasv1alpha1.RedisSpec{ QueuesDSN: "value", @@ -310,13 +314,13 @@ var _ = Describe("System controller", func() { for _, esn := range []string{ "system-database", - "system-recaptcha", - "system-events-hook", - "system-smtp", - "system-master-apicast", - "system-zync", - "system-backend", - "system-multitenant-assets-s3", + // "system-recaptcha", + // "system-events-hook", + // "system-smtp", + // "system-master-apicast", + // "system-zync", + // "system-backend", + // "system-multitenant-assets-s3", "system-app", } { es := &externalsecretsv1beta1.ExternalSecret{} diff --git a/controllers/twemproxyconfig_controller.go b/controllers/twemproxyconfig_controller.go index c42fd28e..03902387 100644 --- a/controllers/twemproxyconfig_controller.go +++ b/controllers/twemproxyconfig_controller.go @@ -262,7 +262,7 @@ func (r *TwemproxyConfigReconciler) SetupWithManager(mgr ctrl.Manager) error { Owns(&grafanav1alpha1.GrafanaDashboard{}). Watches(&source.Channel{Source: r.SentinelEvents.GetChannel()}, &handler.EnqueueRequestForObject{}). WithOptions(controller.Options{ - RateLimiter: AggressiveRateLimiter(), + RateLimiter: PermissiveRateLimiter(), // this allows for different resources to be reconciled in parallel MaxConcurrentReconciles: 2, }). diff --git a/controllers/zync_controller.go b/controllers/zync_controller.go index 03118370..a374e644 100644 --- a/controllers/zync_controller.go +++ b/controllers/zync_controller.go @@ -23,14 +23,8 @@ import ( "github.com/3scale-ops/basereconciler/util" saasv1alpha1 "github.com/3scale-ops/saas-operator/api/v1alpha1" "github.com/3scale-ops/saas-operator/pkg/generators/zync" - externalsecretsv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1" "github.com/go-logr/logr" - grafanav1alpha1 "github.com/grafana-operator/grafana-operator/v4/api/integreatly/v1alpha1" - monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" - appsv1 "k8s.io/api/apps/v1" - autoscalingv2 "k8s.io/api/autoscaling/v2" corev1 "k8s.io/api/core/v1" - policyv1 "k8s.io/api/policy/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/source" @@ -82,17 +76,10 @@ func (r *ZyncReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl. // SetupWithManager sets up the controller with the Manager. func (r *ZyncReconciler) SetupWithManager(mgr ctrl.Manager) error { - return ctrl.NewControllerManagedBy(mgr). - For(&saasv1alpha1.Zync{}). - Owns(&appsv1.Deployment{}). - Owns(&appsv1.StatefulSet{}). - Owns(&corev1.Service{}). - Owns(&policyv1.PodDisruptionBudget{}). - Owns(&autoscalingv2.HorizontalPodAutoscaler{}). - Owns(&monitoringv1.PodMonitor{}). - Owns(&externalsecretsv1beta1.ExternalSecret{}). - Owns(&grafanav1alpha1.GrafanaDashboard{}). - Watches(&source.Kind{Type: &corev1.Secret{TypeMeta: metav1.TypeMeta{Kind: "Secret"}}}, - r.FilteredEventHandler(&saasv1alpha1.ZyncList{}, nil, r.Log)). - Complete(r) + return reconciler.SetupWithDynamicTypeWatches(r, + ctrl.NewControllerManagedBy(mgr). + For(&saasv1alpha1.Zync{}). + Watches(&source.Kind{Type: &corev1.Secret{TypeMeta: metav1.TypeMeta{Kind: "Secret"}}}, + r.FilteredEventHandler(&saasv1alpha1.ZyncList{}, nil, r.Log)), + ) } diff --git a/go.mod b/go.mod index f0a07dc3..aa269c53 100644 --- a/go.mod +++ b/go.mod @@ -20,6 +20,7 @@ require ( github.com/google/go-cmp v0.5.9 github.com/goombaio/namegenerator v0.0.0-20181006234301-989e774b106e github.com/grafana-operator/grafana-operator/v4 v4.10.0 + github.com/huandu/go-clone v1.6.0 // indirect github.com/kelseyhightower/envconfig v1.4.0 github.com/onsi/ginkgo/v2 v2.9.1 github.com/onsi/gomega v1.27.3 @@ -41,10 +42,9 @@ require ( sigs.k8s.io/yaml v1.3.0 ) -require github.com/huandu/go-clone v1.6.0 // indirect - // For local dev uncomment this and point it to the correct path in your system // replace github.com/3scale-ops/basereconciler => /home/roi/github.com/3scale/basereconciler +replace github.com/3scale-ops/basereconciler v0.4.0 => github.com/3scale-ops/basereconciler v0.4.1-0.20240111150428-b7ad2be7e877 require ( contrib.go.opencensus.io/exporter/ocagent v0.7.1-0.20200907061046-05415f1de66d // indirect diff --git a/go.sum b/go.sum index 07216148..c1183c9e 100644 --- a/go.sum +++ b/go.sum @@ -35,21 +35,15 @@ contrib.go.opencensus.io/exporter/ocagent v0.7.1-0.20200907061046-05415f1de66d/g contrib.go.opencensus.io/exporter/prometheus v0.4.0 h1:0QfIkj9z/iVZgK31D9H9ohjjIDApI2GOPScCKwxedbs= contrib.go.opencensus.io/exporter/prometheus v0.4.0/go.mod h1:o7cosnyfuPVK0tB8q0QmaQNhGnptITnPQB+z1+qeFB0= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -github.com/3scale-ops/basereconciler v0.4.0 h1:p4xpxwqWnCybHu6uxb6KxW9tKvpgk5+ry7pv42UI+EA= -github.com/3scale-ops/basereconciler v0.4.0/go.mod h1:QuHsnYMbPQYKZjXjKX93efNI2VH2jVio4emJVJy7sRg= +github.com/3scale-ops/basereconciler v0.4.1-0.20240111150428-b7ad2be7e877 h1:5HZp5o3e+m61bP+0HKHgQqOobSIsnhokT4hez14T3IE= +github.com/3scale-ops/basereconciler v0.4.1-0.20240111150428-b7ad2be7e877/go.mod h1:QuHsnYMbPQYKZjXjKX93efNI2VH2jVio4emJVJy7sRg= github.com/3scale-ops/marin3r v0.12.2 h1:sU4N7RZ5AQzfejrfP0KgpagmL/XD8a5NdSIv1qvaAnU= github.com/3scale-ops/marin3r v0.12.2/go.mod h1:BOU7EFv58PgPMgKgJFDd4ingfBhH6KC2AGJoD7i9SaU= -github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= -github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= -github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= -github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= -github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ= github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= -github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= @@ -108,7 +102,6 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ= github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= -github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= github.com/blendle/zapdriver v1.3.1 h1:C3dydBOWYRiOk+B8X9IVZ5IOe+7cl+tGOexN4QqHfpE= github.com/blendle/zapdriver v1.3.1/go.mod h1:mdXfREi6u5MArG4j9fewC+FGnXaBR+T4Ox4J2u4eHCc= github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= @@ -133,8 +126,6 @@ github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWH github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4 h1:/inchEIKaYC1Akx+H+gqO04wryn5h75LSazbRlnya1k= github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/dave/dst v0.26.2/go.mod h1:UMDJuIRPfyUCC78eFuB+SV/WI8oDeyFDvM/JR6NI3IU= github.com/dave/gopackages v0.0.0-20170318123100-46e7023ec56e/go.mod h1:i00+b/gKdIDIxuLDFob7ustLAVqhsZRk2qVZrArELGQ= @@ -148,7 +139,6 @@ github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/r github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= -github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153 h1:yUdfgN0XgIJw7foRItutHYUIhlcKzcSf5vDpdhQAKTc= github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= @@ -176,7 +166,6 @@ github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2Vvl github.com/external-secrets/external-secrets v0.8.1 h1:LI7lYmR04Zi2gMVdgifTtyGKfBtYrCA380ePgds2gsY= github.com/external-secrets/external-secrets v0.8.1/go.mod h1:N5TxTxHLbCK2vVmcUAbUUorwuZiKxJqd/j8I65+44Zc= github.com/flowstack/go-jsonschema v0.1.1/go.mod h1:yL7fNggx1o8rm9RlgXv7hTBWxdBM0rVwpMwimd3F3N0= -github.com/form3tech-oss/jwt-go v3.2.3+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= @@ -270,7 +259,6 @@ github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= github.com/google/gnostic v0.5.7-v3refs/go.mod h1:73MKFl6jIHelAJNaBGFzt3SPtZULs9dYrGFt8OiIsHQ= github.com/google/gnostic v0.6.9 h1:ZK/5VhkoX835RikCHpSUJV9a+S3e1zLh59YnyWeBW+0= github.com/google/gnostic v0.6.9/go.mod h1:Nm8234We1lq6iB9OmlgNv3nH91XLLVZHCDayfA3xq+E= @@ -321,9 +309,6 @@ github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB7 github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/grafana-operator/grafana-operator/v4 v4.10.0 h1:+AVEPP/wflmx5ySdzt1mIw+q63ZYVInxQhF3XKNhJv4= github.com/grafana-operator/grafana-operator/v4 v4.10.0/go.mod h1:k69wJcXVrqAcZBoGuh5LSqz0ak8LlVOxxqp0W3f/4V8= -github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= -github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= -github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.14.6/go.mod h1:zdiPV4Yse/1gnckTHtghG4GkDEdKCRJduHpTxT3/jcw= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks= @@ -338,19 +323,18 @@ github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/huandu/go-assert v1.1.5 h1:fjemmA7sSfYHJD7CUqs9qTwwfdNAx7/j2/ZlHXzNB3c= github.com/huandu/go-assert v1.1.5/go.mod h1:yOLvuqZwmcHIC5rIzrBhT7D3Q9c3GFnd0JrPVhn/06U= github.com/huandu/go-clone v1.6.0 h1:HMo5uvg4wgfiy5FoGOqlFLQED/VGRm2D9Pi8g1FXPGc= github.com/huandu/go-clone v1.6.0/go.mod h1:ReGivhG6op3GYr+UY3lS6mxjKp7MIGTknuU5TbTVaXE= github.com/huandu/go-clone/generic v1.7.2 h1:47pQphxs1Xc9cVADjOHN+Bm5D0hNagwH9UXErbxgVKA= github.com/huandu/go-clone/generic v1.7.2/go.mod h1:xgd9ZebcMsBWWcBx5mVMCoqMX24gLWr5lQicr+nVXNs= -github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk= github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= -github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= @@ -389,7 +373,6 @@ github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJ github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= -github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/moby/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8= github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= @@ -411,10 +394,8 @@ github.com/nsf/jsondiff v0.0.0-20230430225905-43f6cf3098c1 h1:dOYG7LS/WK00RWZc8X github.com/nsf/jsondiff v0.0.0-20230430225905-43f6cf3098c1/go.mod h1:mpRZBD8SJ55OIICQ3iWH0Yz3cjzA61JdqMLoWXeB2+8= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= -github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/ohler55/ojg v1.20.3 h1:Z+fnElsA/GbI5oiT726qJaG4Ca9q5l7UO68Qd0PtkD4= github.com/ohler55/ojg v1.20.3/go.mod h1:uHcD1ErbErC27Zhb5Df2jUjbseLLcmOCo6oxSr3jZxo= -github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -434,7 +415,6 @@ github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3I github.com/openshift/api v0.0.0-20220715133027-dab5b363ebd1 h1:FzCXZdnkGLus4hHu7/d/utr3ELPiwNt2ffAqSspi6U8= github.com/openshift/api v0.0.0-20220715133027-dab5b363ebd1/go.mod h1:LEnw1IVscIxyDnltE3Wi7bQb/QzIM8BfPNKoGA1Qlxw= github.com/openshift/build-machinery-go v0.0.0-20211213093930-7e33a7eb4ce3/go.mod h1:b1BuldmJlbA/xYtdZvKi+7j5YGB44qJUJDZ9zwiNCfE= -github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5 h1:Ii+DKncOVM8Cu1Hc+ETb5K+23HdAMvESYE3ZJ5b5cMI= github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -476,17 +456,14 @@ github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzG github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= -github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/samber/lo v1.39.0 h1:4gTz1wUhNYLhFSKl6O+8peW0v2F4BCY034GRpU9WnuA= github.com/samber/lo v1.39.0/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= -github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= -github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4= github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= @@ -507,18 +484,15 @@ github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY= github.com/tektoncd/pipeline v0.49.0 h1:LxpgoPZvIDiOvPj6vtInnGG0uzuQ5CPA+h8FdJdklh4= github.com/tektoncd/pipeline v0.49.0/go.mod h1:R3Qn/oTTf1SCLrj+rCg4sqUbpx7vE+6D8Z81+zKUdqQ= -github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= -github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= @@ -578,7 +552,6 @@ golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHl golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= @@ -894,7 +867,6 @@ gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= -gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= gopkg.in/src-d/go-billy.v4 v4.3.0/go.mod h1:tm33zBoOwxjYHZIE+OV8bxTWFMJLrconzFMd38aARFk= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= @@ -913,7 +885,6 @@ gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= From 3f89c0645e67116a2d25331d56ab965193793852 Mon Sep 17 00:00:00 2001 From: Roi Vazquez Date: Tue, 16 Jan 2024 13:21:16 +0100 Subject: [PATCH 3/8] Add support for 'valueFrom' in extra envvars --- pkg/resource_builders/pod/environment.go | 27 +++++++- pkg/resource_builders/pod/environment_test.go | 62 +++++++++++++++---- 2 files changed, 75 insertions(+), 14 deletions(-) diff --git a/pkg/resource_builders/pod/environment.go b/pkg/resource_builders/pod/environment.go index 48925780..dce189d6 100644 --- a/pkg/resource_builders/pod/environment.go +++ b/pkg/resource_builders/pod/environment.go @@ -21,6 +21,7 @@ import ( type Option struct { value *string + rawValue *corev1.EnvVarSource format *string secretValue *saasv1alpha1.SecretReference envVariable string @@ -124,17 +125,27 @@ func (options *Options) WithExtraEnv(extra []corev1.EnvVar) *Options { out := options.DeepCopy() for _, envvar := range extra { - v := envvar.Value o, exists := lo.Find(*out, func(o *Option) bool { return o.envVariable == envvar.Name }) + if exists { - o.value = &v + o.value = util.Pointer(envvar.Value) + o.rawValue = envvar.ValueFrom o.secretValue = nil o.set = true o.secretName = "" } else { - out.Unpack(v).IntoEnvvar(envvar.Name) + var v *string + if envvar.Value != "" { + v = util.Pointer(envvar.Value) + } + *out = append(*out, &Option{ + value: v, + rawValue: envvar.ValueFrom, + envVariable: envvar.Name, + set: true, + }) } } return out @@ -165,6 +176,7 @@ func (opts *Options) BuildEnvironment() []corev1.EnvVar { Name: opt.secretName, }, }}}) + continue } } @@ -173,6 +185,15 @@ func (opts *Options) BuildEnvironment() []corev1.EnvVar { Name: opt.envVariable, Value: *opt.value, }) + continue + } + + if opt.rawValue != nil { + env = append(env, corev1.EnvVar{ + Name: opt.envVariable, + ValueFrom: opt.rawValue, + }) + continue } } diff --git a/pkg/resource_builders/pod/environment_test.go b/pkg/resource_builders/pod/environment_test.go index 8a287c30..badf5163 100644 --- a/pkg/resource_builders/pod/environment_test.go +++ b/pkg/resource_builders/pod/environment_test.go @@ -182,6 +182,12 @@ func TestOptions_BuildEnvironment(t *testing.T) { Name: "envvar3", Value: "value3", }, + { + Name: "envvar4", ValueFrom: &corev1.EnvVarSource{FieldRef: &corev1.ObjectFieldSelector{ + APIVersion: "v1", + FieldPath: "metadata.name", + }}, + }, }}, want: []corev1.EnvVar{ { @@ -196,6 +202,12 @@ func TestOptions_BuildEnvironment(t *testing.T) { Name: "envvar3", Value: "value3", }, + { + Name: "envvar4", ValueFrom: &corev1.EnvVarSource{FieldRef: &corev1.ObjectFieldSelector{ + APIVersion: "v1", + FieldPath: "metadata.name", + }}, + }, }, }, { @@ -407,15 +419,26 @@ func TestOptions_WithExtraEnv(t *testing.T) { }{ { name: "", - options: &Options{{ - value: util.Pointer("value1"), - envVariable: "envvar1", - set: true, - }}, + options: &Options{ + { + value: util.Pointer("value1"), + envVariable: "envvar1", + set: true, + }, + { + value: util.Pointer("value2"), + envVariable: "envvar2", + set: true, + }, + }, args: args{ extra: []corev1.EnvVar{ {Name: "envvar1", Value: "aaaa"}, - {Name: "envvar2", Value: "bbbb"}, + {Name: "envvar3", Value: "bbbb"}, + {Name: "envvar4", ValueFrom: &corev1.EnvVarSource{FieldRef: &corev1.ObjectFieldSelector{ + APIVersion: "v1", + FieldPath: "metadata.name", + }}}, }, }, want: &Options{ @@ -424,17 +447,34 @@ func TestOptions_WithExtraEnv(t *testing.T) { envVariable: "envvar1", set: true, }, + { + value: util.Pointer("value2"), + envVariable: "envvar2", + set: true, + }, { value: util.Pointer("bbbb"), + envVariable: "envvar3", + set: true, + }, + { + rawValue: &corev1.EnvVarSource{FieldRef: &corev1.ObjectFieldSelector{APIVersion: "v1", FieldPath: "metadata.name"}}, + envVariable: "envvar4", + set: true, + }, + }, + wantOld: &Options{ + { + value: util.Pointer("value1"), + envVariable: "envvar1", + set: true, + }, + { + value: util.Pointer("value2"), envVariable: "envvar2", set: true, }, }, - wantOld: &Options{{ - value: util.Pointer("value1"), - envVariable: "envvar1", - set: true, - }}, }, } for _, tt := range tests { From e54a7ce309dfcc0ebfac51ba6f1afe0586a9a25e Mon Sep 17 00:00:00 2001 From: Roi Vazquez Date: Tue, 16 Jan 2024 15:10:42 +0100 Subject: [PATCH 4/8] Fix 'Union' function --- pkg/resource_builders/pod/environment.go | 2 +- pkg/resource_builders/pod/environment_test.go | 78 +++++++++++++++++++ 2 files changed, 79 insertions(+), 1 deletion(-) diff --git a/pkg/resource_builders/pod/environment.go b/pkg/resource_builders/pod/environment.go index dce189d6..5b7a4195 100644 --- a/pkg/resource_builders/pod/environment.go +++ b/pkg/resource_builders/pod/environment.go @@ -228,7 +228,7 @@ func (opts *Options) GenerateExternalSecrets(namespace string, labels map[string func Union(lists ...[]*Option) *Options { all := operatorutil.ConcatSlices[*Option](lists...) - lo.UniqBy(all, func(item *Option) string { + all = lo.UniqBy(all, func(item *Option) string { return item.envVariable }) return util.Pointer[Options](all) diff --git a/pkg/resource_builders/pod/environment_test.go b/pkg/resource_builders/pod/environment_test.go index badf5163..d8fda453 100644 --- a/pkg/resource_builders/pod/environment_test.go +++ b/pkg/resource_builders/pod/environment_test.go @@ -526,3 +526,81 @@ func TestOptions_ListSecretResourceNames(t *testing.T) { }) } } + +func TestUnion(t *testing.T) { + type args struct { + lists [][]*Option + } + tests := []struct { + name string + args args + want Options + }{ + { + name: "", + args: args{ + lists: [][]*Option{ + { + { + value: util.Pointer("value1"), + envVariable: "ENVVAR1", + set: false, + }, + { + value: util.Pointer("value2"), + envVariable: "ENVVAR2", + set: false, + }, + }, + { + { + value: util.Pointer("value1"), + envVariable: "ENVVAR1", + set: false, + }, + { + value: util.Pointer("value3"), + envVariable: "ENVVAR3", + set: false, + }, + { + value: util.Pointer("value4"), + envVariable: "ENVVAR4", + set: false, + }, + }, + }, + }, + want: []*Option{ + { + value: util.Pointer("value1"), + envVariable: "ENVVAR1", + set: false, + }, + { + value: util.Pointer("value2"), + envVariable: "ENVVAR2", + set: false, + }, + { + value: util.Pointer("value3"), + envVariable: "ENVVAR3", + set: false, + }, + { + value: util.Pointer("value4"), + envVariable: "ENVVAR4", + set: false, + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := Union(tt.args.lists...) + if diff := cmp.Diff(*got, tt.want, cmp.AllowUnexported(Option{})); len(diff) > 0 { + t.Errorf("Union() got diff %v", diff) + } + }) + } +} From e3056494a5554de4ae45caae3f9c196b96b60d4a Mon Sep 17 00:00:00 2001 From: Roi Vazquez Date: Tue, 16 Jan 2024 15:13:10 +0100 Subject: [PATCH 5/8] Fix rollout triggers with additional secrets --- pkg/resource_builders/pod/environment.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/resource_builders/pod/environment.go b/pkg/resource_builders/pod/environment.go index 5b7a4195..b2255eee 100644 --- a/pkg/resource_builders/pod/environment.go +++ b/pkg/resource_builders/pod/environment.go @@ -67,7 +67,7 @@ func (options *Options) ListSecretResourceNames() []string { func (options *Options) GenerateRolloutTriggers(additionalSecrets ...string) []resource.TemplateMutationFunction { secrets := options.ListSecretResourceNames() triggers := make([]resource.TemplateMutationFunction, 0, len(secrets)) - for _, secret := range secrets { + for _, secret := range append(secrets, additionalSecrets...) { triggers = append( triggers, mutators.RolloutTrigger{Name: secret, SecretName: util.Pointer(secret)}.Add(), From 26d3b69fde9747bb448aa6587f02700bcb35decd Mon Sep 17 00:00:00 2001 From: Roi Vazquez Date: Tue, 16 Jan 2024 15:32:59 +0100 Subject: [PATCH 6/8] Bump basereconciler --- go.mod | 3 +-- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/go.mod b/go.mod index aa269c53..ac5d6f20 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/3scale-ops/saas-operator go 1.20 require ( - github.com/3scale-ops/basereconciler v0.4.0 + github.com/3scale-ops/basereconciler v0.5.0 github.com/3scale-ops/marin3r v0.12.2 github.com/MakeNowJust/heredoc v1.0.0 github.com/aws/aws-sdk-go-v2 v1.21.0 @@ -44,7 +44,6 @@ require ( // For local dev uncomment this and point it to the correct path in your system // replace github.com/3scale-ops/basereconciler => /home/roi/github.com/3scale/basereconciler -replace github.com/3scale-ops/basereconciler v0.4.0 => github.com/3scale-ops/basereconciler v0.4.1-0.20240111150428-b7ad2be7e877 require ( contrib.go.opencensus.io/exporter/ocagent v0.7.1-0.20200907061046-05415f1de66d // indirect diff --git a/go.sum b/go.sum index c1183c9e..be4dd41e 100644 --- a/go.sum +++ b/go.sum @@ -35,8 +35,8 @@ contrib.go.opencensus.io/exporter/ocagent v0.7.1-0.20200907061046-05415f1de66d/g contrib.go.opencensus.io/exporter/prometheus v0.4.0 h1:0QfIkj9z/iVZgK31D9H9ohjjIDApI2GOPScCKwxedbs= contrib.go.opencensus.io/exporter/prometheus v0.4.0/go.mod h1:o7cosnyfuPVK0tB8q0QmaQNhGnptITnPQB+z1+qeFB0= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -github.com/3scale-ops/basereconciler v0.4.1-0.20240111150428-b7ad2be7e877 h1:5HZp5o3e+m61bP+0HKHgQqOobSIsnhokT4hez14T3IE= -github.com/3scale-ops/basereconciler v0.4.1-0.20240111150428-b7ad2be7e877/go.mod h1:QuHsnYMbPQYKZjXjKX93efNI2VH2jVio4emJVJy7sRg= +github.com/3scale-ops/basereconciler v0.5.0 h1:bw3jrtaG7a9O7MnQJcfgDpJvxv2P8xNS9bKW7gwEgfU= +github.com/3scale-ops/basereconciler v0.5.0/go.mod h1:QuHsnYMbPQYKZjXjKX93efNI2VH2jVio4emJVJy7sRg= github.com/3scale-ops/marin3r v0.12.2 h1:sU4N7RZ5AQzfejrfP0KgpagmL/XD8a5NdSIv1qvaAnU= github.com/3scale-ops/marin3r v0.12.2/go.mod h1:BOU7EFv58PgPMgKgJFDd4ingfBhH6KC2AGJoD7i9SaU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= From 33cdffed747a4bebb76162ea6b22c2f310c3c735 Mon Sep 17 00:00:00 2001 From: Roi Vazquez Date: Tue, 16 Jan 2024 16:12:14 +0100 Subject: [PATCH 7/8] Remove unused variable --- pkg/resource_builders/pod/environment.go | 1 - 1 file changed, 1 deletion(-) diff --git a/pkg/resource_builders/pod/environment.go b/pkg/resource_builders/pod/environment.go index b2255eee..92ab1bed 100644 --- a/pkg/resource_builders/pod/environment.go +++ b/pkg/resource_builders/pod/environment.go @@ -22,7 +22,6 @@ import ( type Option struct { value *string rawValue *corev1.EnvVarSource - format *string secretValue *saasv1alpha1.SecretReference envVariable string secretName string From 5e33b065e237b1212e60143c403d6cbad0a92b72 Mon Sep 17 00:00:00 2001 From: Roi Vazquez Date: Thu, 18 Jan 2024 12:55:42 +0100 Subject: [PATCH 8/8] Remove comment --- pkg/generators/system/config/options.go | 1 - 1 file changed, 1 deletion(-) diff --git a/pkg/generators/system/config/options.go b/pkg/generators/system/config/options.go index 1d9d7ca9..df33b8e8 100644 --- a/pkg/generators/system/config/options.go +++ b/pkg/generators/system/config/options.go @@ -5,7 +5,6 @@ import ( "github.com/3scale-ops/saas-operator/pkg/resource_builders/pod" ) -// cat | grep secret: | sed -r 's/.*`env:"(\w*)"(\s*secret:"([0-9a-zA-Z\-]*)")?`/Unpack().IntoEnvvar("\1").AsSecretRef("\3"),/gm' func NewOptions(spec saasv1alpha1.SystemSpec) pod.Options { opts := pod.Options{}