mirror of
https://github.com/zalando/postgres-operator.git
synced 2026-10-04 13:51:32 +02:00
configurable container capabilities (#1336)
* configurable container capabilities * revert change on TestTLS * fix e2e test * minor fix
This commit is contained in:
@@ -968,6 +968,14 @@ var OperatorConfigCRDResourceValidation = apiextv1.CustomResourceValidation{
|
||||
"kubernetes": {
|
||||
Type: "object",
|
||||
Properties: map[string]apiextv1.JSONSchemaProps{
|
||||
"additional_pod_capabilities": {
|
||||
Type: "array",
|
||||
Items: &apiextv1.JSONSchemaPropsOrArray{
|
||||
Schema: &apiextv1.JSONSchemaProps{
|
||||
Type: "string",
|
||||
},
|
||||
},
|
||||
},
|
||||
"cluster_domain": {
|
||||
Type: "string",
|
||||
},
|
||||
|
||||
@@ -52,6 +52,7 @@ type KubernetesMetaConfiguration struct {
|
||||
SpiloRunAsUser *int64 `json:"spilo_runasuser,omitempty"`
|
||||
SpiloRunAsGroup *int64 `json:"spilo_runasgroup,omitempty"`
|
||||
SpiloFSGroup *int64 `json:"spilo_fsgroup,omitempty"`
|
||||
AdditionalPodCapabilities []string `json:"additional_pod_capabilities,omitempty"`
|
||||
WatchedNamespace string `json:"watched_namespace,omitempty"`
|
||||
PDBNameFormat config.StringTemplate `json:"pdb_name_format,omitempty"`
|
||||
EnablePodDisruptionBudget *bool `json:"enable_pod_disruption_budget,omitempty"`
|
||||
|
||||
@@ -162,6 +162,11 @@ func (in *KubernetesMetaConfiguration) DeepCopyInto(out *KubernetesMetaConfigura
|
||||
*out = new(int64)
|
||||
**out = **in
|
||||
}
|
||||
if in.AdditionalPodCapabilities != nil {
|
||||
in, out := &in.AdditionalPodCapabilities, &out.AdditionalPodCapabilities
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.EnablePodDisruptionBudget != nil {
|
||||
in, out := &in.EnablePodDisruptionBudget, &out.EnablePodDisruptionBudget
|
||||
*out = new(bool)
|
||||
|
||||
@@ -320,6 +320,19 @@ func getLocalAndBoostrapPostgreSQLParameters(parameters map[string]string) (loca
|
||||
return
|
||||
}
|
||||
|
||||
func generateCapabilities(capabilities []string) v1.Capabilities {
|
||||
if len(capabilities) > 1 {
|
||||
additionalCapabilities := []v1.Capability{}
|
||||
for _, capability := range capabilities {
|
||||
additionalCapabilities = append(additionalCapabilities, v1.Capability(strings.ToUpper(capability)))
|
||||
}
|
||||
return v1.Capabilities{
|
||||
Add: additionalCapabilities,
|
||||
}
|
||||
}
|
||||
return v1.Capabilities{}
|
||||
}
|
||||
|
||||
func nodeAffinity(nodeReadinessLabel map[string]string, nodeAffinity *v1.NodeAffinity) *v1.Affinity {
|
||||
if len(nodeReadinessLabel) == 0 && nodeAffinity == nil {
|
||||
return nil
|
||||
@@ -430,6 +443,7 @@ func generateContainer(
|
||||
envVars []v1.EnvVar,
|
||||
volumeMounts []v1.VolumeMount,
|
||||
privilegedMode bool,
|
||||
additionalPodCapabilities v1.Capabilities,
|
||||
) *v1.Container {
|
||||
return &v1.Container{
|
||||
Name: name,
|
||||
@@ -456,6 +470,7 @@ func generateContainer(
|
||||
AllowPrivilegeEscalation: &privilegedMode,
|
||||
Privileged: &privilegedMode,
|
||||
ReadOnlyRootFilesystem: util.False(),
|
||||
Capabilities: &additionalPodCapabilities,
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -1148,6 +1163,7 @@ func (c *Cluster) generateStatefulSet(spec *acidv1.PostgresSpec) (*appsv1.Statef
|
||||
deduplicateEnvVars(spiloEnvVars, c.containerName(), c.logger),
|
||||
volumeMounts,
|
||||
c.OpConfig.Resources.SpiloPrivileged,
|
||||
generateCapabilities(c.OpConfig.AdditionalPodCapabilities),
|
||||
)
|
||||
|
||||
// generate container specs for sidecars specified in the cluster manifest
|
||||
@@ -1901,6 +1917,7 @@ func (c *Cluster) generateLogicalBackupJob() (*batchv1beta1.CronJob, error) {
|
||||
envVars,
|
||||
[]v1.VolumeMount{},
|
||||
c.OpConfig.SpiloPrivileged, // use same value as for normal DB pods
|
||||
v1.Capabilities{},
|
||||
)
|
||||
|
||||
labels := map[string]string{
|
||||
|
||||
@@ -1489,3 +1489,42 @@ func TestGenerateService(t *testing.T) {
|
||||
assert.Equal(t, v1.ServiceExternalTrafficPolicyTypeLocal, service.Spec.ExternalTrafficPolicy)
|
||||
|
||||
}
|
||||
|
||||
func TestGenerateCapabilities(t *testing.T) {
|
||||
|
||||
testName := "TestGenerateCapabilities"
|
||||
tests := []struct {
|
||||
subTest string
|
||||
configured []string
|
||||
capabilities v1.Capabilities
|
||||
err error
|
||||
}{
|
||||
{
|
||||
subTest: "no capabilities",
|
||||
configured: nil,
|
||||
capabilities: v1.Capabilities{},
|
||||
err: fmt.Errorf("could not parse capabilities configuration of nil"),
|
||||
},
|
||||
{
|
||||
subTest: "empty capabilities",
|
||||
configured: []string{},
|
||||
capabilities: v1.Capabilities{},
|
||||
err: fmt.Errorf("could not parse empty capabilities configuration"),
|
||||
},
|
||||
{
|
||||
subTest: "configured capabilities",
|
||||
configured: []string{"SYS_NICE", "CHOWN"},
|
||||
capabilities: v1.Capabilities{
|
||||
Add: []v1.Capability{"SYS_NICE", "CHOWN"},
|
||||
},
|
||||
err: fmt.Errorf("could not parse empty capabilities configuration"),
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
caps := generateCapabilities(tt.configured)
|
||||
if !reflect.DeepEqual(caps, tt.capabilities) {
|
||||
t.Errorf("%s %s: expected `%v` but got `%v`",
|
||||
testName, tt.subTest, tt.capabilities, caps)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,6 +66,7 @@ func (c *Controller) importConfigurationFromCRD(fromCRD *acidv1.OperatorConfigur
|
||||
result.SpiloRunAsUser = fromCRD.Kubernetes.SpiloRunAsUser
|
||||
result.SpiloRunAsGroup = fromCRD.Kubernetes.SpiloRunAsGroup
|
||||
result.SpiloFSGroup = fromCRD.Kubernetes.SpiloFSGroup
|
||||
result.AdditionalPodCapabilities = fromCRD.Kubernetes.AdditionalPodCapabilities
|
||||
result.ClusterDomain = util.Coalesce(fromCRD.Kubernetes.ClusterDomain, "cluster.local")
|
||||
result.WatchedNamespace = fromCRD.Kubernetes.WatchedNamespace
|
||||
result.PDBNameFormat = fromCRD.Kubernetes.PDBNameFormat
|
||||
|
||||
+33
-32
@@ -23,38 +23,39 @@ 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"`
|
||||
SpiloRunAsUser *int64 `json:"spilo_runasuser,omitempty"`
|
||||
SpiloRunAsGroup *int64 `json:"spilo_runasgroup,omitempty"`
|
||||
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:""`
|
||||
InheritedAnnotations []string `name:"inherited_annotations" default:""`
|
||||
DownscalerAnnotations []string `name:"downscaler_annotations"`
|
||||
ClusterNameLabel string `name:"cluster_name_label" default:"cluster-name"`
|
||||
DeleteAnnotationDateKey string `name:"delete_annotation_date_key"`
|
||||
DeleteAnnotationNameKey string `name:"delete_annotation_name_key"`
|
||||
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"`
|
||||
PodEnvironmentSecret string `name:"pod_environment_secret"`
|
||||
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"`
|
||||
SpiloRunAsUser *int64 `json:"spilo_runasuser,omitempty"`
|
||||
SpiloRunAsGroup *int64 `json:"spilo_runasgroup,omitempty"`
|
||||
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"`
|
||||
AdditionalPodCapabilities []string `name:"additional_pod_capabilities" default:""`
|
||||
ClusterLabels map[string]string `name:"cluster_labels" default:"application:spilo"`
|
||||
InheritedLabels []string `name:"inherited_labels" default:""`
|
||||
InheritedAnnotations []string `name:"inherited_annotations" default:""`
|
||||
DownscalerAnnotations []string `name:"downscaler_annotations"`
|
||||
ClusterNameLabel string `name:"cluster_name_label" default:"cluster-name"`
|
||||
DeleteAnnotationDateKey string `name:"delete_annotation_date_key"`
|
||||
DeleteAnnotationNameKey string `name:"delete_annotation_name_key"`
|
||||
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"`
|
||||
PodEnvironmentSecret string `name:"pod_environment_secret"`
|
||||
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"`
|
||||
}
|
||||
|
||||
type InfrastructureRole struct {
|
||||
|
||||
Reference in New Issue
Block a user