From ba9cf686502077babbda1803e2b54b83c6a153b9 Mon Sep 17 00:00:00 2001 From: Felix Kunde Date: Wed, 25 Mar 2020 15:59:31 +0100 Subject: [PATCH] Change type of pod environment config map to NamespacedName (#870) * allow PodEnvironmentConfigMap in other namespaces * update codegen * update docs and comments --- charts/postgres-operator/values-crd.yaml | 8 +-- charts/postgres-operator/values.yaml | 8 +-- docs/administrator.md | 15 +++--- docs/reference/operator_parameters.md | 17 ++++--- manifests/configmap.yaml | 2 +- ...gresql-operator-default-configuration.yaml | 2 +- .../v1/operator_configuration_type.go | 15 +++--- .../acid.zalan.do/v1/zz_generated.deepcopy.go | 1 + pkg/cluster/k8sres.go | 19 ++++--- pkg/util/config/config.go | 50 +++++++++---------- 10 files changed, 73 insertions(+), 64 deletions(-) diff --git a/charts/postgres-operator/values-crd.yaml b/charts/postgres-operator/values-crd.yaml index cf9fbab15..79940b236 100644 --- a/charts/postgres-operator/values-crd.yaml +++ b/charts/postgres-operator/values-crd.yaml @@ -71,7 +71,7 @@ configKubernetes: enable_pod_disruption_budget: true # enables sidecar containers to run alongside Spilo in the same pod enable_sidecars: true - # name of the secret containing infrastructure roles names and passwords + # namespaced name of the secret containing infrastructure roles names and passwords # infrastructure_roles_secret_name: postgresql-infrastructure-roles # list of labels that can be inherited from the cluster manifest @@ -86,15 +86,15 @@ configKubernetes: # node_readiness_label: # status: ready - # name of the secret containing the OAuth2 token to pass to the teams API + # namespaced name of the secret containing the OAuth2 token to pass to the teams API # oauth_token_secret_name: postgresql-operator # defines the template for PDB (Pod Disruption Budget) names pdb_name_format: "postgres-{cluster}-pdb" # override topology key for pod anti affinity pod_antiaffinity_topology_key: "kubernetes.io/hostname" - # name of the ConfigMap with environment variables to populate on every pod - # pod_environment_configmap: "" + # namespaced name of the ConfigMap with environment variables to populate on every pod + # pod_environment_configmap: "default/my-custom-config" # specify the pod management policy of stateful sets of Postgres clusters pod_management_policy: "ordered_ready" diff --git a/charts/postgres-operator/values.yaml b/charts/postgres-operator/values.yaml index 503bf4562..29f85339d 100644 --- a/charts/postgres-operator/values.yaml +++ b/charts/postgres-operator/values.yaml @@ -67,7 +67,7 @@ configKubernetes: enable_pod_disruption_budget: "true" # enables sidecar containers to run alongside Spilo in the same pod enable_sidecars: "true" - # name of the secret containing infrastructure roles names and passwords + # namespaced name of the secret containing infrastructure roles names and passwords # infrastructure_roles_secret_name: postgresql-infrastructure-roles # list of labels that can be inherited from the cluster manifest @@ -79,15 +79,15 @@ configKubernetes: # set of labels that a running and active node should possess to be considered ready # node_readiness_label: "" - # name of the secret containing the OAuth2 token to pass to the teams API + # namespaced name of the secret containing the OAuth2 token to pass to the teams API # oauth_token_secret_name: postgresql-operator # defines the template for PDB (Pod Disruption Budget) names pdb_name_format: "postgres-{cluster}-pdb" # override topology key for pod anti affinity pod_antiaffinity_topology_key: "kubernetes.io/hostname" - # name of the ConfigMap with environment variables to populate on every pod - # pod_environment_configmap: "" + # namespaced name of the ConfigMap with environment variables to populate on every pod + # pod_environment_configmap: "default/my-custom-config" # specify the pod management policy of stateful sets of Postgres clusters pod_management_policy: "ordered_ready" diff --git a/docs/administrator.md b/docs/administrator.md index a3a0f70cc..93adf2eb1 100644 --- a/docs/administrator.md +++ b/docs/administrator.md @@ -321,11 +321,12 @@ spec: ## Custom Pod Environment Variables It is possible to configure a ConfigMap which is used by the Postgres pods as -an additional provider for environment variables. - -One use case is to customize the Spilo image and configure it with environment -variables. The ConfigMap with the additional settings is configured in the -operator's main ConfigMap: +an additional provider for environment variables. One use case is to customize +the Spilo image and configure it with environment variables. The ConfigMap with +the additional settings is referenced in the operator's main configuration. +A namespace can be specified along with the name. If left out, the configured +default namespace of your K8s client will be used and if the ConfigMap is not +found there, the Postgres cluster's namespace is taken when different: **postgres-operator ConfigMap** @@ -336,7 +337,7 @@ metadata: name: postgres-operator data: # referencing config map with custom settings - pod_environment_configmap: postgres-pod-config + pod_environment_configmap: default/postgres-pod-config ``` **OperatorConfiguration** @@ -349,7 +350,7 @@ metadata: configuration: kubernetes: # referencing config map with custom settings - pod_environment_configmap: postgres-pod-config + pod_environment_configmap: default/postgres-pod-config ``` **referenced ConfigMap `postgres-pod-config`** diff --git a/docs/reference/operator_parameters.md b/docs/reference/operator_parameters.md index 848fa1cf2..1ab92a287 100644 --- a/docs/reference/operator_parameters.md +++ b/docs/reference/operator_parameters.md @@ -221,11 +221,12 @@ configuration they are grouped under the `kubernetes` key. to the Postgres clusters after creation. * **oauth_token_secret_name** - a name of the secret containing the `OAuth2` token to pass to the teams API. - The default is `postgresql-operator`. + namespaced name of the secret containing the `OAuth2` token to pass to the + teams API. The default is `postgresql-operator`. * **infrastructure_roles_secret_name** - name of the secret containing infrastructure roles names and passwords. + namespaced name of the secret containing infrastructure roles names and + passwords. * **pod_role_label** name of the label assigned to the Postgres pods (and services/endpoints) by @@ -262,11 +263,11 @@ configuration they are grouped under the `kubernetes` key. for details on taints and tolerations. The default is empty. * **pod_environment_configmap** - a name of the ConfigMap with environment variables to populate on every pod. - Right now this ConfigMap is searched in the namespace of the Postgres cluster. - All variables from that ConfigMap are injected to the pod's environment, on - conflicts they are overridden by the environment variables generated by the - operator. The default is empty. + namespaced name of the ConfigMap with environment variables to populate on + every pod. Right now this ConfigMap is searched in the namespace of the + Postgres cluster. All variables from that ConfigMap are injected to the pod's + environment, on conflicts they are overridden by the environment variables + generated by the operator. The default is empty. * **pod_priority_class_name** a name of the [priority class](https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/#priorityclass) diff --git a/manifests/configmap.yaml b/manifests/configmap.yaml index fdc2d5d56..67c3368f3 100644 --- a/manifests/configmap.yaml +++ b/manifests/configmap.yaml @@ -69,7 +69,7 @@ data: pdb_name_format: "postgres-{cluster}-pdb" # pod_antiaffinity_topology_key: "kubernetes.io/hostname" pod_deletion_wait_timeout: 10m - # pod_environment_configmap: "" + # pod_environment_configmap: "default/my-custom-config" pod_label_wait_timeout: 10m pod_management_policy: "ordered_ready" pod_role_label: spilo-role diff --git a/manifests/postgresql-operator-default-configuration.yaml b/manifests/postgresql-operator-default-configuration.yaml index d4c9b518f..9d609713c 100644 --- a/manifests/postgresql-operator-default-configuration.yaml +++ b/manifests/postgresql-operator-default-configuration.yaml @@ -40,7 +40,7 @@ configuration: oauth_token_secret_name: postgresql-operator pdb_name_format: "postgres-{cluster}-pdb" pod_antiaffinity_topology_key: "kubernetes.io/hostname" - # pod_environment_configmap: "" + # pod_environment_configmap: "default/my-custom-config" pod_management_policy: "ordered_ready" # pod_priority_class_name: "" pod_role_label: spilo-role diff --git a/pkg/apis/acid.zalan.do/v1/operator_configuration_type.go b/pkg/apis/acid.zalan.do/v1/operator_configuration_type.go index 7c1d2b7e8..3dbe96b7f 100644 --- a/pkg/apis/acid.zalan.do/v1/operator_configuration_type.go +++ b/pkg/apis/acid.zalan.do/v1/operator_configuration_type.go @@ -65,14 +65,13 @@ type KubernetesMetaConfiguration struct { NodeReadinessLabel map[string]string `json:"node_readiness_label,omitempty"` CustomPodAnnotations map[string]string `json:"custom_pod_annotations,omitempty"` // TODO: use a proper toleration structure? - PodToleration map[string]string `json:"toleration,omitempty"` - // TODO: use namespacedname - PodEnvironmentConfigMap string `json:"pod_environment_configmap,omitempty"` - PodPriorityClassName string `json:"pod_priority_class_name,omitempty"` - MasterPodMoveTimeout Duration `json:"master_pod_move_timeout,omitempty"` - EnablePodAntiAffinity bool `json:"enable_pod_antiaffinity,omitempty"` - PodAntiAffinityTopologyKey string `json:"pod_antiaffinity_topology_key,omitempty"` - PodManagementPolicy string `json:"pod_management_policy,omitempty"` + PodToleration map[string]string `json:"toleration,omitempty"` + PodEnvironmentConfigMap spec.NamespacedName `json:"pod_environment_configmap,omitempty"` + PodPriorityClassName string `json:"pod_priority_class_name,omitempty"` + MasterPodMoveTimeout Duration `json:"master_pod_move_timeout,omitempty"` + EnablePodAntiAffinity bool `json:"enable_pod_antiaffinity,omitempty"` + PodAntiAffinityTopologyKey string `json:"pod_antiaffinity_topology_key,omitempty"` + PodManagementPolicy string `json:"pod_management_policy,omitempty"` } // PostgresPodResourcesDefaults defines the spec of default resources diff --git a/pkg/apis/acid.zalan.do/v1/zz_generated.deepcopy.go b/pkg/apis/acid.zalan.do/v1/zz_generated.deepcopy.go index fcab394ca..65a19600a 100644 --- a/pkg/apis/acid.zalan.do/v1/zz_generated.deepcopy.go +++ b/pkg/apis/acid.zalan.do/v1/zz_generated.deepcopy.go @@ -179,6 +179,7 @@ func (in *KubernetesMetaConfiguration) DeepCopyInto(out *KubernetesMetaConfigura (*out)[key] = val } } + out.PodEnvironmentConfigMap = in.PodEnvironmentConfigMap return } diff --git a/pkg/cluster/k8sres.go b/pkg/cluster/k8sres.go index 34b409d4e..2c40bb0ba 100644 --- a/pkg/cluster/k8sres.go +++ b/pkg/cluster/k8sres.go @@ -18,6 +18,7 @@ import ( acidv1 "github.com/zalando/postgres-operator/pkg/apis/acid.zalan.do/v1" "github.com/zalando/postgres-operator/pkg/spec" + pkgspec "github.com/zalando/postgres-operator/pkg/spec" "github.com/zalando/postgres-operator/pkg/util" "github.com/zalando/postgres-operator/pkg/util/config" "github.com/zalando/postgres-operator/pkg/util/constants" @@ -485,9 +486,9 @@ func generateSidecarContainers(sidecars []acidv1.Sidecar, // Check whether or not we're requested to mount an shm volume, // taking into account that PostgreSQL manifest has precedence. -func mountShmVolumeNeeded(opConfig config.Config, pgSpec *acidv1.PostgresSpec) *bool { - if pgSpec.ShmVolume != nil && *pgSpec.ShmVolume { - return pgSpec.ShmVolume +func mountShmVolumeNeeded(opConfig config.Config, spec *acidv1.PostgresSpec) *bool { + if spec.ShmVolume != nil && *spec.ShmVolume { + return spec.ShmVolume } return opConfig.ShmVolume @@ -911,11 +912,17 @@ func (c *Cluster) generateStatefulSet(spec *acidv1.PostgresSpec) (*appsv1.Statef customPodEnvVarsList := make([]v1.EnvVar, 0) - if c.OpConfig.PodEnvironmentConfigMap != "" { + if c.OpConfig.PodEnvironmentConfigMap != (pkgspec.NamespacedName{}) { var cm *v1.ConfigMap - cm, err = c.KubeClient.ConfigMaps(c.Namespace).Get(c.OpConfig.PodEnvironmentConfigMap, metav1.GetOptions{}) + cm, err = c.KubeClient.ConfigMaps(c.OpConfig.PodEnvironmentConfigMap.Namespace).Get(c.OpConfig.PodEnvironmentConfigMap.Name, metav1.GetOptions{}) if err != nil { - return nil, fmt.Errorf("could not read PodEnvironmentConfigMap: %v", err) + // if not found, try again using the cluster's namespace if it's different (old behavior) + if k8sutil.ResourceNotFound(err) && c.Namespace != c.OpConfig.PodEnvironmentConfigMap.Namespace { + cm, err = c.KubeClient.ConfigMaps(c.Namespace).Get(c.OpConfig.PodEnvironmentConfigMap.Name, metav1.GetOptions{}) + } + if err != nil { + return nil, fmt.Errorf("could not read PodEnvironmentConfigMap: %v", err) + } } for k, v := range cm.Data { customPodEnvVarsList = append(customPodEnvVarsList, v1.EnvVar{Name: k, Value: v}) diff --git a/pkg/util/config/config.go b/pkg/util/config/config.go index e0e095617..403615f06 100644 --- a/pkg/util/config/config.go +++ b/pkg/util/config/config.go @@ -22,31 +22,31 @@ type CRD struct { // Resources describes kubernetes resource specific configuration parameters type Resources struct { - ResourceCheckInterval time.Duration `name:"resource_check_interval" default:"3s"` - ResourceCheckTimeout time.Duration `name:"resource_check_timeout" default:"10m"` - PodLabelWaitTimeout time.Duration `name:"pod_label_wait_timeout" default:"10m"` - PodDeletionWaitTimeout time.Duration `name:"pod_deletion_wait_timeout" default:"10m"` - PodTerminateGracePeriod time.Duration `name:"pod_terminate_grace_period" default:"5m"` - SpiloFSGroup *int64 `name:"spilo_fsgroup"` - PodPriorityClassName string `name:"pod_priority_class_name"` - ClusterDomain string `name:"cluster_domain" default:"cluster.local"` - SpiloPrivileged bool `name:"spilo_privileged" default:"false"` - ClusterLabels map[string]string `name:"cluster_labels" default:"application:spilo"` - InheritedLabels []string `name:"inherited_labels" default:""` - ClusterNameLabel string `name:"cluster_name_label" default:"cluster-name"` - PodRoleLabel string `name:"pod_role_label" default:"spilo-role"` - PodToleration map[string]string `name:"toleration" default:""` - DefaultCPURequest string `name:"default_cpu_request" default:"100m"` - DefaultMemoryRequest string `name:"default_memory_request" default:"100Mi"` - DefaultCPULimit string `name:"default_cpu_limit" default:"1"` - DefaultMemoryLimit string `name:"default_memory_limit" default:"500Mi"` - MinCPULimit string `name:"min_cpu_limit" default:"250m"` - MinMemoryLimit string `name:"min_memory_limit" default:"250Mi"` - PodEnvironmentConfigMap string `name:"pod_environment_configmap" default:""` - NodeReadinessLabel map[string]string `name:"node_readiness_label" default:""` - MaxInstances int32 `name:"max_instances" default:"-1"` - MinInstances int32 `name:"min_instances" default:"-1"` - ShmVolume *bool `name:"enable_shm_volume" default:"true"` + ResourceCheckInterval time.Duration `name:"resource_check_interval" default:"3s"` + ResourceCheckTimeout time.Duration `name:"resource_check_timeout" default:"10m"` + PodLabelWaitTimeout time.Duration `name:"pod_label_wait_timeout" default:"10m"` + PodDeletionWaitTimeout time.Duration `name:"pod_deletion_wait_timeout" default:"10m"` + PodTerminateGracePeriod time.Duration `name:"pod_terminate_grace_period" default:"5m"` + SpiloFSGroup *int64 `name:"spilo_fsgroup"` + PodPriorityClassName string `name:"pod_priority_class_name"` + ClusterDomain string `name:"cluster_domain" default:"cluster.local"` + SpiloPrivileged bool `name:"spilo_privileged" default:"false"` + ClusterLabels map[string]string `name:"cluster_labels" default:"application:spilo"` + InheritedLabels []string `name:"inherited_labels" default:""` + ClusterNameLabel string `name:"cluster_name_label" default:"cluster-name"` + PodRoleLabel string `name:"pod_role_label" default:"spilo-role"` + PodToleration map[string]string `name:"toleration" default:""` + DefaultCPURequest string `name:"default_cpu_request" default:"100m"` + DefaultMemoryRequest string `name:"default_memory_request" default:"100Mi"` + DefaultCPULimit string `name:"default_cpu_limit" default:"1"` + DefaultMemoryLimit string `name:"default_memory_limit" default:"500Mi"` + MinCPULimit string `name:"min_cpu_limit" default:"250m"` + MinMemoryLimit string `name:"min_memory_limit" default:"250Mi"` + PodEnvironmentConfigMap spec.NamespacedName `name:"pod_environment_configmap"` + NodeReadinessLabel map[string]string `name:"node_readiness_label" default:""` + MaxInstances int32 `name:"max_instances" default:"-1"` + MinInstances int32 `name:"min_instances" default:"-1"` + ShmVolume *bool `name:"enable_shm_volume" default:"true"` } // Auth describes authentication specific configuration parameters