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 3ba6a427b..587e8152d 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,14 @@ 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"` - 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"` - StatefulsetPropAnnotations []string `json:"statefulset_propagate_annotations,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"` + StatefulsetPropagateAnnotations []string `json:"statefulset_propagate_annotations,omitempty"` } // PostgresPodResourcesDefaults defines the spec of default resources @@ -182,31 +182,31 @@ type OperatorLogicalBackupConfiguration struct { // OperatorConfigurationData defines the operation config type OperatorConfigurationData struct { - EnableCRDValidation *bool `json:"enable_crd_validation,omitempty"` - EtcdHost string `json:"etcd_host,omitempty"` - KubernetesUseConfigMaps bool `json:"kubernetes_use_configmaps,omitempty"` - DockerImage string `json:"docker_image,omitempty"` - Workers uint32 `json:"workers,omitempty"` - MinInstances int32 `json:"min_instances,omitempty"` - MaxInstances int32 `json:"max_instances,omitempty"` - ResyncPeriod Duration `json:"resync_period,omitempty"` - RepairPeriod Duration `json:"repair_period,omitempty"` - SetMemoryRequestToLimit bool `json:"set_memory_request_to_limit,omitempty"` - ShmVolume *bool `json:"enable_shm_volume,omitempty"` - Sidecars map[string]string `json:"sidecar_docker_images,omitempty"` - PostgresUsersConfiguration PostgresUsersConfiguration `json:"users"` - Kubernetes KubernetesMetaConfiguration `json:"kubernetes"` - PostgresPodResources PostgresPodResourcesDefaults `json:"postgres_pod_resources"` - Timeouts OperatorTimeouts `json:"timeouts"` - LoadBalancer LoadBalancerConfiguration `json:"load_balancer"` - AWSGCP AWSGCPConfiguration `json:"aws_or_gcp"` - OperatorDebug OperatorDebugConfiguration `json:"debug"` - TeamsAPI TeamsAPIConfiguration `json:"teams_api"` - LoggingRESTAPI LoggingRESTAPIConfiguration `json:"logging_rest_api"` - Scalyr ScalyrConfiguration `json:"scalyr"` - LogicalBackup OperatorLogicalBackupConfiguration `json:"logical_backup"` - ConnectionPooler ConnectionPoolerConfiguration `json:"connection_pooler"` - StatefulsetPropAnnotations []string `json:"statefulset_propagate_annotations,omitempty"` + EnableCRDValidation *bool `json:"enable_crd_validation,omitempty"` + EtcdHost string `json:"etcd_host,omitempty"` + KubernetesUseConfigMaps bool `json:"kubernetes_use_configmaps,omitempty"` + DockerImage string `json:"docker_image,omitempty"` + Workers uint32 `json:"workers,omitempty"` + MinInstances int32 `json:"min_instances,omitempty"` + MaxInstances int32 `json:"max_instances,omitempty"` + ResyncPeriod Duration `json:"resync_period,omitempty"` + RepairPeriod Duration `json:"repair_period,omitempty"` + SetMemoryRequestToLimit bool `json:"set_memory_request_to_limit,omitempty"` + ShmVolume *bool `json:"enable_shm_volume,omitempty"` + Sidecars map[string]string `json:"sidecar_docker_images,omitempty"` + PostgresUsersConfiguration PostgresUsersConfiguration `json:"users"` + Kubernetes KubernetesMetaConfiguration `json:"kubernetes"` + PostgresPodResources PostgresPodResourcesDefaults `json:"postgres_pod_resources"` + Timeouts OperatorTimeouts `json:"timeouts"` + LoadBalancer LoadBalancerConfiguration `json:"load_balancer"` + AWSGCP AWSGCPConfiguration `json:"aws_or_gcp"` + OperatorDebug OperatorDebugConfiguration `json:"debug"` + TeamsAPI TeamsAPIConfiguration `json:"teams_api"` + LoggingRESTAPI LoggingRESTAPIConfiguration `json:"logging_rest_api"` + Scalyr ScalyrConfiguration `json:"scalyr"` + LogicalBackup OperatorLogicalBackupConfiguration `json:"logical_backup"` + ConnectionPooler ConnectionPoolerConfiguration `json:"connection_pooler"` + StatefulsetPropagateAnnotations []string `json:"statefulset_propagate_annotations,omitempty"` } //Duration shortens this frequently used name 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 e6b387ec4..2e18a5b1f 100644 --- a/pkg/apis/acid.zalan.do/v1/zz_generated.deepcopy.go +++ b/pkg/apis/acid.zalan.do/v1/zz_generated.deepcopy.go @@ -202,6 +202,11 @@ func (in *KubernetesMetaConfiguration) DeepCopyInto(out *KubernetesMetaConfigura } } out.PodEnvironmentConfigMap = in.PodEnvironmentConfigMap + if in.StatefulsetPropagateAnnotations != nil { + in, out := &in.StatefulsetPropagateAnnotations, &out.StatefulsetPropagateAnnotations + *out = make([]string, len(*in)) + copy(*out, *in) + } return } diff --git a/pkg/cluster/k8sres.go b/pkg/cluster/k8sres.go index 914ebb8ad..31bc744ea 100644 --- a/pkg/cluster/k8sres.go +++ b/pkg/cluster/k8sres.go @@ -6,6 +6,7 @@ import ( "fmt" "path" "sort" + "strconv" "github.com/sirupsen/logrus" @@ -1149,13 +1150,14 @@ func (c *Cluster) generateStatefulSet(spec *acidv1.PostgresSpec) (*appsv1.Statef } annotations = make(map[string]string) + annotations[rollingUpdateStatefulsetAnnotationKey] = strconv.FormatBool(false) statefulSet := &appsv1.StatefulSet{ ObjectMeta: metav1.ObjectMeta{ Name: c.statefulSetName(), Namespace: c.Namespace, Labels: c.labelsSet(true), - Annotations: annotations, + Annotations: c.PropagateAnnotationsToStatefulsets(annotations), }, Spec: appsv1.StatefulSetSpec{ Replicas: &numberOfInstances, diff --git a/pkg/cluster/sync.go b/pkg/cluster/sync.go index 5b74416ca..2ce0c7e88 100644 --- a/pkg/cluster/sync.go +++ b/pkg/cluster/sync.go @@ -331,21 +331,8 @@ func (c *Cluster) syncStatefulSet() error { } } } - ToPropagateAnnotations := c.OpConfig.StatefulsetPropAnnotations - PgCRDAnnotations := c.Postgresql.ObjectMeta.GetAnnotations() - annotations := make(map[string]string) - - if ToPropagateAnnotations != nil && PgCRDAnnotations != nil { - for _, anno := range ToPropagateAnnotations { - for k, v := range PgCRDAnnotations { - matched, err := regexp.MatchString(anno, k) - if err == nil && matched { - annotations[k] = v - } - } - } - c.updateStatefulSetAnnotations(annotations) - } + annotations := c.PropagateAnnotationsToStatefulsets(c.Statefulset.Annotations) + c.updateStatefulSetAnnotations(annotations) } // Apply special PostgreSQL parameters that can only be set via the Patroni API. @@ -370,6 +357,26 @@ func (c *Cluster) syncStatefulSet() error { return nil } +// PropagateAnnotationsToStatefulsets updates annotations to statefulsets if required +// based on the annotations in postgres CRD +func (c *Cluster) PropagateAnnotationsToStatefulsets(annotations map[string]string) map[string]string { + ToPropagateAnnotations := c.OpConfig.StatefulsetPropagateAnnotations + PgCRDAnnotations := c.Postgresql.ObjectMeta.GetAnnotations() + + if ToPropagateAnnotations != nil && PgCRDAnnotations != nil { + for _, anno := range ToPropagateAnnotations { + for k, v := range PgCRDAnnotations { + matched, err := regexp.MatchString(anno, k) + if err == nil && matched { + annotations[k] = v + } + } + } + } + return annotations + +} + // checkAndSetGlobalPostgreSQLConfiguration checks whether cluster-wide API parameters // (like max_connections) has changed and if necessary sets it via the Patroni API func (c *Cluster) checkAndSetGlobalPostgreSQLConfiguration() error { diff --git a/pkg/controller/operator_config.go b/pkg/controller/operator_config.go index e605ecd77..a94fe7ecc 100644 --- a/pkg/controller/operator_config.go +++ b/pkg/controller/operator_config.go @@ -46,7 +46,7 @@ func (c *Controller) importConfigurationFromCRD(fromCRD *acidv1.OperatorConfigur result.ShmVolume = fromCRD.ShmVolume result.Sidecars = fromCRD.Sidecars - result.StatefulsetPropAnnotations = fromCRD.StatefulsetPropAnnotations + result.StatefulsetPropagateAnnotations = fromCRD.StatefulsetPropagateAnnotations // user config result.SuperUsername = fromCRD.PostgresUsersConfiguration.SuperUsername diff --git a/pkg/util/config/config.go b/pkg/util/config/config.go index 7a5f1bfc2..3222e2f55 100644 --- a/pkg/util/config/config.go +++ b/pkg/util/config/config.go @@ -134,7 +134,7 @@ type Config struct { EnableReplicaLoadBalancer bool `name:"enable_replica_load_balancer" default:"false"` CustomServiceAnnotations map[string]string `name:"custom_service_annotations"` CustomPodAnnotations map[string]string `name:"custom_pod_annotations"` - StatefulsetPropAnnotations []string `name:"statefulset_propagate_annotations"` + StatefulsetPropagateAnnotations []string `name:"statefulset_propagate_annotations"` EnablePodAntiAffinity bool `name:"enable_pod_antiaffinity" default:"false"` PodAntiAffinityTopologyKey string `name:"pod_antiaffinity_topology_key" default:"kubernetes.io/hostname"` // deprecated and kept for backward compatibility