From b60047cb3892ffbf1a3d922d925eb529f3ab84cf Mon Sep 17 00:00:00 2001 From: Valery Mogilevsky Date: Thu, 19 Dec 2024 15:22:04 +0200 Subject: [PATCH] THREESCALE-11021 add redis ACL credentials to system and backend --- apis/apps/v1alpha1/apimanager_types.go | 26 +++++ apis/apps/v1alpha1/zz_generated.deepcopy.go | 5 + pkg/3scale/amp/component/backend.go | 27 ++++- pkg/3scale/amp/component/backend_options.go | 2 + pkg/3scale/amp/component/redis.go | 18 +++ pkg/3scale/amp/component/redis_options.go | 19 ++++ pkg/3scale/amp/component/system.go | 33 +++++- pkg/3scale/amp/component/system_options.go | 2 + .../amp/operator/backend_options_provider.go | 6 + .../amp/operator/redis_options_provider.go | 104 ++++++++++++++++++ .../amp/operator/system_options_provider.go | 5 + 11 files changed, 244 insertions(+), 3 deletions(-) diff --git a/apis/apps/v1alpha1/apimanager_types.go b/apis/apps/v1alpha1/apimanager_types.go index 9b74b0f6f..8fb592c90 100644 --- a/apis/apps/v1alpha1/apimanager_types.go +++ b/apis/apps/v1alpha1/apimanager_types.go @@ -84,6 +84,8 @@ type APIManagerSpec struct { PodDisruptionBudget *PodDisruptionBudgetSpec `json:"podDisruptionBudget,omitempty"` // +optional Monitoring *MonitoringSpec `json:"monitoring,omitempty"` + // +optional + SentinelIsUsed *bool `json:"sentinelIsUsed,omitempty"` } // APIManagerStatus defines the observed state of APIManager @@ -1535,3 +1537,27 @@ type APIManagerList struct { func init() { SchemeBuilder.Register(&APIManager{}, &APIManagerList{}) } + +func (apimanager *APIManager) IsSystemSentinelUsed() bool { + tlsEnabled := false + if apimanager.Spec.SentinelIsUsed != nil && + *apimanager.Spec.SentinelIsUsed && + apimanager.Spec.ExternalComponents != nil && + apimanager.Spec.ExternalComponents.System != nil && + apimanager.Spec.ExternalComponents.Backend != nil && + *apimanager.Spec.ExternalComponents.System.Redis { + tlsEnabled = true + } + return tlsEnabled +} +func (apimanager *APIManager) IsBackendSentinelUsed() bool { + tlsEnabled := false + if apimanager.Spec.SentinelIsUsed != nil && + *apimanager.Spec.SentinelIsUsed && + apimanager.Spec.ExternalComponents != nil && + apimanager.Spec.ExternalComponents.Backend != nil && + *apimanager.Spec.ExternalComponents.Backend.Redis { + tlsEnabled = true + } + return tlsEnabled +} diff --git a/apis/apps/v1alpha1/zz_generated.deepcopy.go b/apis/apps/v1alpha1/zz_generated.deepcopy.go index d34eacd46..531ae2724 100644 --- a/apis/apps/v1alpha1/zz_generated.deepcopy.go +++ b/apis/apps/v1alpha1/zz_generated.deepcopy.go @@ -436,6 +436,11 @@ func (in *APIManagerSpec) DeepCopyInto(out *APIManagerSpec) { *out = new(MonitoringSpec) (*in).DeepCopyInto(*out) } + if in.SentinelIsUsed != nil { + in, out := &in.SentinelIsUsed, &out.SentinelIsUsed + *out = new(bool) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new APIManagerSpec. diff --git a/pkg/3scale/amp/component/backend.go b/pkg/3scale/amp/component/backend.go index 692d2f6bb..da2cc96da 100644 --- a/pkg/3scale/amp/component/backend.go +++ b/pkg/3scale/amp/component/backend.go @@ -29,6 +29,16 @@ const ( BackendSecretBackendRedisStorageSentinelRoleFieldName = "REDIS_STORAGE_SENTINEL_ROLE" BackendSecretBackendRedisQueuesSentinelHostsFieldName = "REDIS_QUEUES_SENTINEL_HOSTS" BackendSecretBackendRedisQueuesSentinelRoleFieldName = "REDIS_QUEUES_SENTINEL_ROLE" + + // ACL + BackendSecretBackendRedisConfigRedisUsernameFieldName = "CONFIG_REDIS_USERNAME" + BackendSecretBackendRedisConfigRedisPasswordFieldName = "CONFIG_REDIS_PASSWORD" + BackendSecretBackendRedisConfigRedisSentinelUsernameFieldName = "CONFIG_REDIS_SENTINEL_USERNAME" + BackendSecretBackendRedisConfigRedisSentinelPasswordFieldName = "CONFIG_REDIS_SENTINEL_PASSWORD" + BackendSecretBackendRedisConfigQueuesUsernameFieldName = "CONFIG_QUEUES_USERNAME" + BackendSecretBackendRedisConfigQueuesPasswordFieldName = "CONFIG_QUEUES_PASSWORD" + BackendSecretBackendRedisConfigQueuesSentinelUsernameFieldName = "CONFIG_QUEUES_SENTINEL_USERNAME" + BackendSecretBackendRedisConfigQueuesSentinelPasswordFieldName = "CONFIG_QUEUES_SENTINEL_PASSWORD" ) const ( @@ -372,7 +382,8 @@ func (backend *Backend) EnvironmentConfigMap() *v1.ConfigMap { } func (backend *Backend) buildBackendCommonEnv() []v1.EnvVar { - return []v1.EnvVar{ + result := []v1.EnvVar{} + result = append(result, helper.EnvVarFromSecret("CONFIG_REDIS_PROXY", BackendSecretBackendRedisSecretName, BackendSecretBackendRedisStorageURLFieldName), helper.EnvVarFromSecret("CONFIG_REDIS_SENTINEL_HOSTS", BackendSecretBackendRedisSecretName, BackendSecretBackendRedisStorageSentinelHostsFieldName), helper.EnvVarFromSecret("CONFIG_REDIS_SENTINEL_ROLE", BackendSecretBackendRedisSecretName, BackendSecretBackendRedisStorageSentinelRoleFieldName), @@ -380,7 +391,21 @@ func (backend *Backend) buildBackendCommonEnv() []v1.EnvVar { helper.EnvVarFromSecret("CONFIG_QUEUES_SENTINEL_HOSTS", BackendSecretBackendRedisSecretName, BackendSecretBackendRedisQueuesSentinelHostsFieldName), helper.EnvVarFromSecret("CONFIG_QUEUES_SENTINEL_ROLE", BackendSecretBackendRedisSecretName, BackendSecretBackendRedisQueuesSentinelRoleFieldName), helper.EnvVarFromConfigMap("RACK_ENV", "backend-environment", "RACK_ENV"), + // ACL + helper.EnvVarFromSecret("CONFIG_REDIS_USERNAME", BackendSecretBackendRedisSecretName, BackendSecretBackendRedisConfigRedisUsernameFieldName), + helper.EnvVarFromSecret("CONFIG_REDIS_PASSWORD", BackendSecretBackendRedisSecretName, BackendSecretBackendRedisConfigRedisPasswordFieldName), + helper.EnvVarFromSecret("CONFIG_QUEUES_USERNAME", BackendSecretBackendRedisSecretName, BackendSecretBackendRedisConfigQueuesUsernameFieldName), + helper.EnvVarFromSecret("CONFIG_QUEUES_PASSWORD", BackendSecretBackendRedisSecretName, BackendSecretBackendRedisConfigQueuesPasswordFieldName), + ) + if backend.Options.RedisSentinelIsUsed { //ACL + result = append(result, + helper.EnvVarFromSecret("CONFIG_REDIS_SENTINEL_USERNAME", BackendSecretBackendRedisSecretName, BackendSecretBackendRedisConfigRedisSentinelUsernameFieldName), + helper.EnvVarFromSecret("CONFIG_REDIS_SENTINEL_PASSWORD", BackendSecretBackendRedisSecretName, BackendSecretBackendRedisConfigRedisSentinelPasswordFieldName), + helper.EnvVarFromSecret("CONFIG_QUEUES_SENTINEL_USERNAME", BackendSecretBackendRedisSecretName, BackendSecretBackendRedisConfigQueuesSentinelUsernameFieldName), + helper.EnvVarFromSecret("CONFIG_QUEUES_SENTINEL_PASSWORD", BackendSecretBackendRedisSecretName, BackendSecretBackendRedisConfigQueuesSentinelPasswordFieldName), + ) } + return result } func (backend *Backend) buildBackendWorkerEnv() []v1.EnvVar { diff --git a/pkg/3scale/amp/component/backend_options.go b/pkg/3scale/amp/component/backend_options.go index c39929c48..1b230a34b 100644 --- a/pkg/3scale/amp/component/backend_options.go +++ b/pkg/3scale/amp/component/backend_options.go @@ -54,6 +54,8 @@ type BackendOptions struct { // that need namespace filtering because they are "global" once imported // to the prometheus or grafana services. Namespace string `validate:"required"` + + RedisSentinelIsUsed bool } func NewBackendOptions() *BackendOptions { diff --git a/pkg/3scale/amp/component/redis.go b/pkg/3scale/amp/component/redis.go index 35613ac6f..1f266f704 100644 --- a/pkg/3scale/amp/component/redis.go +++ b/pkg/3scale/amp/component/redis.go @@ -297,6 +297,15 @@ func (redis *Redis) BackendRedisSecret() *v1.Secret { BackendSecretBackendRedisStorageSentinelRoleFieldName: redis.Options.BackendRedisStorageSentinelRole, BackendSecretBackendRedisQueuesSentinelHostsFieldName: redis.Options.BackendRedisQueuesSentinelHosts, BackendSecretBackendRedisQueuesSentinelRoleFieldName: redis.Options.BackendRedisQueuesSentinelRole, + // ACL + BackendSecretBackendRedisConfigRedisUsernameFieldName: redis.Options.BackendRedisConfigRedisUsername, + BackendSecretBackendRedisConfigRedisPasswordFieldName: redis.Options.BackendRedisConfigRedisPassword, + BackendSecretBackendRedisConfigRedisSentinelUsernameFieldName: redis.Options.BackendRedisConfigRedisSentinelUsername, + BackendSecretBackendRedisConfigRedisSentinelPasswordFieldName: redis.Options.BackendRedisConfigRedisSentinelPassword, + BackendSecretBackendRedisConfigQueuesUsernameFieldName: redis.Options.BackendRedisConfigQueuesUsername, + BackendSecretBackendRedisConfigQueuesPasswordFieldName: redis.Options.BackendRedisConfigQueuesPassword, + BackendSecretBackendRedisConfigQueuesSentinelUsernameFieldName: redis.Options.BackendRedisConfigQueuesSentinelUsername, + BackendSecretBackendRedisConfigQueuesSentinelPasswordFieldName: redis.Options.BackendRedisConfigQueuesSentinelPassword, }, Type: v1.SecretTypeOpaque, } @@ -476,6 +485,15 @@ func (redis *Redis) SystemRedisSecret() *v1.Secret { SystemSecretSystemRedisURLFieldName: redis.Options.SystemRedisURL, SystemSecretSystemRedisSentinelHosts: redis.Options.SystemRedisSentinelsHosts, SystemSecretSystemRedisSentinelRole: redis.Options.SystemRedisSentinelsRole, + // ACL + SystemSecretSystemRedisUsernameFieldName: redis.Options.SystemRedisUsername, + SystemSecretSystemRedisPasswordFieldName: redis.Options.SystemRedisPassword, + SystemSecretSystemRedisSentinelUsernameFieldName: redis.Options.SystemRedisSentinelUsername, + SystemSecretSystemRedisSentinelPasswordFieldName: redis.Options.SystemRedisSentinelPassword, + SystemSecretBackendRedisUsernameFieldName: redis.Options.SystemBackendRedisUsername, + SystemSecretBackendRedisPasswordFieldName: redis.Options.SystemBackendRedisPassword, + SystemSecretBackendRedisSentinelUsernameFieldName: redis.Options.SystemBackendRedisSentinelUsername, + SystemSecretBackendRedisSentinelPasswordFieldName: redis.Options.SystemBackendRedisSentinelPassword, }, Type: v1.SecretTypeOpaque, } diff --git a/pkg/3scale/amp/component/redis_options.go b/pkg/3scale/amp/component/redis_options.go index 28e85e26a..c97fbb725 100644 --- a/pkg/3scale/amp/component/redis_options.go +++ b/pkg/3scale/amp/component/redis_options.go @@ -47,6 +47,25 @@ type RedisOptions struct { SystemRedisSentinelsHosts string SystemRedisSentinelsRole string SystemRedisNamespace string + + // ACL + SystemRedisUsername string + SystemRedisPassword string + SystemRedisSentinelUsername string + SystemRedisSentinelPassword string + SystemBackendRedisUsername string + SystemBackendRedisPassword string + SystemBackendRedisSentinelUsername string + SystemBackendRedisSentinelPassword string + + BackendRedisConfigRedisUsername string + BackendRedisConfigRedisPassword string + BackendRedisConfigRedisSentinelUsername string + BackendRedisConfigRedisSentinelPassword string + BackendRedisConfigQueuesUsername string + BackendRedisConfigQueuesPassword string + BackendRedisConfigQueuesSentinelUsername string + BackendRedisConfigQueuesSentinelPassword string } func NewRedisOptions() *RedisOptions { diff --git a/pkg/3scale/amp/component/system.go b/pkg/3scale/amp/component/system.go index a71dde8bf..25632a774 100644 --- a/pkg/3scale/amp/component/system.go +++ b/pkg/3scale/amp/component/system.go @@ -47,6 +47,16 @@ const ( SystemSecretSystemRedisURLFieldName = "URL" SystemSecretSystemRedisSentinelHosts = "SENTINEL_HOSTS" SystemSecretSystemRedisSentinelRole = "SENTINEL_ROLE" + + // ACL env vars + SystemSecretSystemRedisUsernameFieldName = "REDIS_USERNAME" + SystemSecretSystemRedisPasswordFieldName = "REDIS_PASSWORD" + SystemSecretSystemRedisSentinelUsernameFieldName = "REDIS_SENTINEL_USERNAME" + SystemSecretSystemRedisSentinelPasswordFieldName = "REDIS_SENTINEL_PASSWORD" + SystemSecretBackendRedisUsernameFieldName = "BACKEND_REDIS_USERNAME" + SystemSecretBackendRedisPasswordFieldName = "BACKEND_REDIS_PASSWORD" + SystemSecretBackendRedisSentinelUsernameFieldName = "BACKEND_REDIS_SENTINEL_USERNAME" + SystemSecretBackendRedisSentinelPasswordFieldName = "BACKEND_REDIS_SENTINEL_PASSWORD" ) const ( @@ -165,12 +175,20 @@ func (system *System) getSystemSMTPEnvsFromSMTPSecret() []v1.EnvVar { func (system *System) SystemRedisEnvVars() []v1.EnvVar { result := []v1.EnvVar{} - result = append(result, helper.EnvVarFromSecret("REDIS_URL", SystemSecretSystemRedisSecretName, SystemSecretSystemRedisURLFieldName), helper.EnvVarFromSecret("REDIS_SENTINEL_HOSTS", SystemSecretSystemRedisSecretName, SystemSecretSystemRedisSentinelHosts), helper.EnvVarFromSecret("REDIS_SENTINEL_ROLE", SystemSecretSystemRedisSecretName, SystemSecretSystemRedisSentinelRole), + //ACL + helper.EnvVarFromSecretOptional("REDIS_USERNAME", SystemSecretSystemRedisSecretName, SystemSecretSystemRedisUsernameFieldName), + helper.EnvVarFromSecretOptional("REDIS_PASSWORD", SystemSecretSystemRedisSecretName, SystemSecretSystemRedisPasswordFieldName), ) + if system.Options.RedisSentinelIsUsed { //ACL + result = append(result, + helper.EnvVarFromSecretOptional("REDIS_SENTINEL_USERNAME", SystemSecretSystemRedisSecretName, SystemSecretSystemRedisSentinelUsernameFieldName), + helper.EnvVarFromSecretOptional("REDIS_SENTINEL_PASSWORD", SystemSecretSystemRedisSecretName, SystemSecretSystemRedisSentinelPasswordFieldName), + ) + } return result } @@ -321,11 +339,22 @@ func (system *System) buildSystemAppPostHookEnv() []v1.EnvVar { } func (system *System) BackendRedisEnvVars() []v1.EnvVar { - return []v1.EnvVar{ + result := []v1.EnvVar{} + result = append(result, helper.EnvVarFromSecret("BACKEND_REDIS_URL", BackendSecretBackendRedisSecretName, BackendSecretBackendRedisStorageURLFieldName), helper.EnvVarFromSecret("BACKEND_REDIS_SENTINEL_HOSTS", BackendSecretBackendRedisSecretName, BackendSecretBackendRedisStorageSentinelHostsFieldName), helper.EnvVarFromSecret("BACKEND_REDIS_SENTINEL_ROLE", BackendSecretBackendRedisSecretName, BackendSecretBackendRedisStorageSentinelRoleFieldName), + //ACL + helper.EnvVarFromSecret("BACKEND_REDIS_USERNAME", SystemSecretSystemRedisSecretName, SystemSecretBackendRedisUsernameFieldName), + helper.EnvVarFromSecret("BACKEND_REDIS_PASSWORD", SystemSecretSystemRedisSecretName, SystemSecretBackendRedisPasswordFieldName), + ) + if system.Options.RedisSentinelIsUsed { //ACL + result = append(result, + helper.EnvVarFromSecret("BACKEND_REDIS_SENTINEL_USERNAME", SystemSecretSystemRedisSecretName, SystemSecretBackendRedisSentinelUsernameFieldName), + helper.EnvVarFromSecret("BACKEND_REDIS_SENTINEL_PASSWORD", SystemSecretSystemRedisSecretName, SystemSecretBackendRedisSentinelPasswordFieldName), + ) } + return result } func (system *System) EnvironmentConfigMap() *v1.ConfigMap { diff --git a/pkg/3scale/amp/component/system_options.go b/pkg/3scale/amp/component/system_options.go index e949cc15c..35acd1426 100644 --- a/pkg/3scale/amp/component/system_options.go +++ b/pkg/3scale/amp/component/system_options.go @@ -104,6 +104,8 @@ type SystemOptions struct { // that need namespace filtering because they are "global" once imported // to the prometheus or grafana services. Namespace string `validate:"required"` + + RedisSentinelIsUsed bool } func NewSystemOptions() *SystemOptions { diff --git a/pkg/3scale/amp/operator/backend_options_provider.go b/pkg/3scale/amp/operator/backend_options_provider.go index c6b395a4a..6621a98f7 100644 --- a/pkg/3scale/amp/operator/backend_options_provider.go +++ b/pkg/3scale/amp/operator/backend_options_provider.go @@ -47,6 +47,7 @@ func (o *OperatorBackendOptionsProvider) GetBackendOptions() (*component.Backend o.setPriorityClassNames() o.setTopologySpreadConstraints() o.setPodTemplateAnnotations() + o.setSentinelIsUsed() o.backendOptions.CommonLabels = o.commonLabels() o.backendOptions.CommonListenerLabels = o.commonListenerLabels() @@ -276,3 +277,8 @@ func (o *OperatorBackendOptionsProvider) setTopologySpreadConstraints() { o.backendOptions.TopologySpreadConstraintsCron = o.apimanager.Spec.Backend.CronSpec.TopologySpreadConstraints } } + +// ACL +func (o *OperatorBackendOptionsProvider) setSentinelIsUsed() { + o.backendOptions.RedisSentinelIsUsed = o.apimanager.IsBackendSentinelUsed() +} diff --git a/pkg/3scale/amp/operator/redis_options_provider.go b/pkg/3scale/amp/operator/redis_options_provider.go index c41c1ff86..da045d346 100644 --- a/pkg/3scale/amp/operator/redis_options_provider.go +++ b/pkg/3scale/amp/operator/redis_options_provider.go @@ -148,6 +148,110 @@ func (r *RedisOptionsProvider) setSecretBasedOptions() error { component.SystemSecretSystemRedisSentinelRole, component.DefaultSystemRedisSentinelRole(), }, + + // ACL + { + &r.options.SystemRedisUsername, + component.SystemSecretSystemRedisSecretName, + component.SystemSecretSystemRedisUsernameFieldName, + "", + }, + { + &r.options.SystemRedisPassword, + component.SystemSecretSystemRedisSecretName, + component.SystemSecretSystemRedisPasswordFieldName, + "", + }, + { + &r.options.SystemRedisSentinelUsername, + component.SystemSecretSystemRedisSecretName, + component.SystemSecretSystemRedisSentinelUsernameFieldName, + "", + }, + { + &r.options.SystemRedisSentinelPassword, + component.SystemSecretSystemRedisSecretName, + component.SystemSecretSystemRedisSentinelPasswordFieldName, + "", + }, + // ACL + { + &r.options.SystemBackendRedisUsername, + component.SystemSecretSystemRedisSecretName, + component.SystemSecretBackendRedisUsernameFieldName, + "", + }, + { + &r.options.SystemBackendRedisPassword, + component.SystemSecretSystemRedisSecretName, + component.SystemSecretBackendRedisPasswordFieldName, + "", + }, + { + &r.options.SystemBackendRedisSentinelUsername, + component.SystemSecretSystemRedisSecretName, + component.SystemSecretBackendRedisSentinelUsernameFieldName, + "", + }, + { + &r.options.SystemBackendRedisSentinelPassword, + component.SystemSecretSystemRedisSecretName, + component.SystemSecretBackendRedisSentinelPasswordFieldName, + "", + }, + // ------- + // ACL + { + &r.options.BackendRedisConfigRedisUsername, + component.BackendSecretBackendRedisSecretName, + component.BackendSecretBackendRedisConfigRedisUsernameFieldName, + "", + }, + { + &r.options.BackendRedisConfigRedisPassword, + component.BackendSecretBackendRedisSecretName, + component.BackendSecretBackendRedisConfigRedisPasswordFieldName, + "", + }, + { + &r.options.BackendRedisConfigRedisSentinelUsername, + component.BackendSecretBackendRedisSecretName, + component.BackendSecretBackendRedisConfigRedisSentinelUsernameFieldName, + "", + }, + { + &r.options.BackendRedisConfigRedisSentinelPassword, + component.BackendSecretBackendRedisSecretName, + component.BackendSecretBackendRedisConfigRedisSentinelPasswordFieldName, + "", + }, + // ACL + { + &r.options.BackendRedisConfigQueuesUsername, + component.BackendSecretBackendRedisSecretName, + component.BackendSecretBackendRedisConfigQueuesUsernameFieldName, + "", + }, + { + &r.options.BackendRedisConfigQueuesPassword, + component.BackendSecretBackendRedisSecretName, + component.BackendSecretBackendRedisConfigQueuesPasswordFieldName, + "", + }, + { + &r.options.BackendRedisConfigQueuesSentinelUsername, + component.BackendSecretBackendRedisSecretName, + component.BackendSecretBackendRedisConfigQueuesSentinelUsernameFieldName, + "", + }, + { + &r.options.BackendRedisConfigQueuesSentinelPassword, + component.BackendSecretBackendRedisSecretName, + component.BackendSecretBackendRedisConfigQueuesSentinelPasswordFieldName, + "", + }, + // ------- + } for _, option := range cases { diff --git a/pkg/3scale/amp/operator/system_options_provider.go b/pkg/3scale/amp/operator/system_options_provider.go index a52e0f7a1..b67e57814 100644 --- a/pkg/3scale/amp/operator/system_options_provider.go +++ b/pkg/3scale/amp/operator/system_options_provider.go @@ -65,6 +65,7 @@ func (s *SystemOptionsProvider) GetSystemOptions() (*component.SystemOptions, er s.setPriorityClassNames() s.setTopologySpreadConstraints() s.setPodTemplateAnnotations() + s.setSentinelIsUsed() s.options.SideKiqMetrics = true s.options.AppMetrics = true @@ -626,3 +627,7 @@ func (s *SystemOptionsProvider) setPodTemplateAnnotations() { s.options.AppPodTemplateAnnotations = s.apimanager.Spec.System.AppSpec.Annotations s.options.SideKiqPodTemplateAnnotations = s.apimanager.Spec.System.SidekiqSpec.Annotations } + +func (s *SystemOptionsProvider) setSentinelIsUsed() { + s.options.RedisSentinelIsUsed = s.apimanager.IsSystemSentinelUsed() +}