diff --git a/config/crd/bases/policies.kubewarden.io_policyservers.yaml b/config/crd/bases/policies.kubewarden.io_policyservers.yaml index cc02be4e..0a83fc92 100644 --- a/config/crd/bases/policies.kubewarden.io_policyservers.yaml +++ b/config/crd/bases/policies.kubewarden.io_policyservers.yaml @@ -176,8 +176,9 @@ spec: securityContexts: description: Security configuration to be used in the Policy Server workload. The field allows different configurations for the pod - and containers. This configuration will not be used in containers - added by other controllers (e.g. telemetry sidecars) + and containers. If set for the containers, this configuration will + not be used in containers added by other controllers (e.g. telemetry + sidecars) properties: container: description: securityContext definition to be used in the policy diff --git a/internal/pkg/admission/policy-server-deployment.go b/internal/pkg/admission/policy-server-deployment.go index f9e6e79d..abc0c7bd 100644 --- a/internal/pkg/admission/policy-server-deployment.go +++ b/internal/pkg/admission/policy-server-deployment.go @@ -122,6 +122,7 @@ func shouldUpdatePolicyServerDeployment(policyServer *policiesv1.PolicyServer, o return *originalDeployment.Spec.Replicas != *newDeployment.Spec.Replicas || containerImageChanged || originalDeployment.Spec.Template.Spec.ServiceAccountName != newDeployment.Spec.Template.Spec.ServiceAccountName || + originalDeployment.Spec.Template.Spec.SecurityContext != newDeployment.Spec.Template.Spec.SecurityContext || originalDeployment.Annotations[constants.PolicyServerDeploymentConfigVersionAnnotation] != newDeployment.Annotations[constants.PolicyServerDeploymentConfigVersionAnnotation] || !reflect.DeepEqual(originalDeployment.Spec.Template.Spec.Containers[0].Env, newDeployment.Spec.Template.Spec.Containers[0].Env) || !haveEqualAnnotationsWithoutRestart(originalDeployment, newDeployment), nil @@ -314,6 +315,11 @@ func (r *Reconciler) deployment(configMapVersion string, policyServer *policiesv }, ) } + + podSecurityContext := &corev1.PodSecurityContext{} + if policyServer.Spec.SecurityContexts.Pod != nil { + podSecurityContext = policyServer.Spec.SecurityContexts.Pod + } if policyServer.Spec.SecurityContexts.Container != nil { admissionContainer.SecurityContext = policyServer.Spec.SecurityContexts.Container } else { @@ -379,6 +385,7 @@ func (r *Reconciler) deployment(configMapVersion string, policyServer *policiesv Annotations: templateAnnotations, }, Spec: corev1.PodSpec{ + SecurityContext: podSecurityContext, Containers: []corev1.Container{admissionContainer}, ServiceAccountName: policyServer.Spec.ServiceAccountName, Volumes: []corev1.Volume{ @@ -417,9 +424,6 @@ func (r *Reconciler) deployment(configMapVersion string, policyServer *policiesv }, }, } - if policyServer.Spec.SecurityContexts.Pod != nil { - policyServerDeployment.Spec.Template.Spec.SecurityContext = policyServer.Spec.SecurityContexts.Pod - } r.adaptDeploymentSettingsForPolicyServer(policyServerDeployment, policyServer) diff --git a/internal/pkg/admission/policy-server-deployment_test.go b/internal/pkg/admission/policy-server-deployment_test.go index 8c86a820..230eb642 100644 --- a/internal/pkg/admission/policy-server-deployment_test.go +++ b/internal/pkg/admission/policy-server-deployment_test.go @@ -19,25 +19,29 @@ const ( ) func TestShouldUpdatePolicyServerDeployment(t *testing.T) { - deployment := createDeployment(1, "sa", "", "image", nil, []corev1.EnvVar{{Name: "env1"}}, map[string]string{}) + deployment := createDeployment(1, "sa", "", "image", nil, []corev1.EnvVar{{Name: "env1"}}, nil, map[string]string{}) tests := []struct { name string original *appsv1.Deployment new *appsv1.Deployment expect bool }{ - {"equal deployments", deployment, createDeployment(1, "sa", "", "image", nil, []corev1.EnvVar{{Name: "env1"}}, map[string]string{}), false}, - {"different replicas", deployment, createDeployment(2, "sa", "", "image", nil, []corev1.EnvVar{{Name: "env1"}}, map[string]string{}), true}, - {"different image", deployment, createDeployment(1, "sa", "", "test", nil, []corev1.EnvVar{{Name: "env1"}}, map[string]string{}), true}, - {"different serviceAccount", deployment, createDeployment(1, "serviceAccount", "", "image", nil, []corev1.EnvVar{{Name: "env1"}}, map[string]string{}), true}, - {"new imagePullSecret", deployment, createDeployment(1, "sa", "regcred", "image", nil, []corev1.EnvVar{{Name: "env1"}}, map[string]string{}), true}, - {"different imagePullSecret", createDeployment(1, "sa", "regcred", "image", nil, nil, map[string]string{}), createDeployment(1, "sa", "regcred2", "image", nil, nil, map[string]string{}), false}, - {"new insecureSources", deployment, createDeployment(1, "sa", "regcred", "image", []string{"localhost:5000"}, []corev1.EnvVar{{Name: "env1"}}, map[string]string{}), true}, - {"different insecureSources", createDeployment(1, "sa", "regcred", "image", []string{"localhost:4000"}, nil, map[string]string{}), createDeployment(1, "sa", "regcred2", "image", []string{"localhost:9999"}, nil, map[string]string{}), false}, - {"different env", deployment, createDeployment(1, "sa", "", "image", nil, []corev1.EnvVar{{Name: "env1"}, {Name: "env2"}}, map[string]string{}), true}, - {"different annotation", deployment, createDeployment(1, "sa", "", "image", nil, []corev1.EnvVar{{Name: "env1"}}, map[string]string{"key": "val"}), true}, - {"same nil env", createDeployment(1, "sa", "", "image", nil, nil, map[string]string{}), createDeployment(1, "sa", "", "image", nil, nil, map[string]string{}), false}, - {"same nil annotation", createDeployment(1, "sa", "", "image", nil, []corev1.EnvVar{{Name: "env1"}}, nil), createDeployment(1, "sa", "", "image", nil, []corev1.EnvVar{{Name: "env1"}}, nil), false}, + {"equal deployments", deployment, createDeployment(1, "sa", "", "image", nil, []corev1.EnvVar{{Name: "env1"}}, nil, map[string]string{}), false}, + {"different replicas", deployment, createDeployment(2, "sa", "", "image", nil, []corev1.EnvVar{{Name: "env1"}}, nil, map[string]string{}), true}, + {"different image", deployment, createDeployment(1, "sa", "", "test", nil, []corev1.EnvVar{{Name: "env1"}}, nil, map[string]string{}), true}, + {"different serviceAccount", deployment, createDeployment(1, "serviceAccount", "", "image", nil, []corev1.EnvVar{{Name: "env1"}}, nil, map[string]string{}), true}, + {"different podSecurityContext", deployment, createDeployment(1, "sa", "", "image", nil, []corev1.EnvVar{{Name: "env1"}}, + &corev1.PodSecurityContext{ + RunAsNonRoot: &[]bool{true}[0], + }, map[string]string{}), true}, + {"new imagePullSecret", deployment, createDeployment(1, "sa", "regcred", "image", nil, []corev1.EnvVar{{Name: "env1"}}, nil, map[string]string{}), true}, + {"different imagePullSecret", createDeployment(1, "sa", "regcred", "image", nil, nil, nil, map[string]string{}), createDeployment(1, "sa", "regcred2", "image", nil, nil, nil, map[string]string{}), false}, + {"new insecureSources", deployment, createDeployment(1, "sa", "regcred", "image", []string{"localhost:5000"}, []corev1.EnvVar{{Name: "env1"}}, nil, map[string]string{}), true}, + {"different insecureSources", createDeployment(1, "sa", "regcred", "image", []string{"localhost:4000"}, nil, nil, map[string]string{}), createDeployment(1, "sa", "regcred2", "image", []string{"localhost:9999"}, nil, nil, map[string]string{}), false}, + {"different env", deployment, createDeployment(1, "sa", "", "image", nil, []corev1.EnvVar{{Name: "env1"}, {Name: "env2"}}, nil, map[string]string{}), true}, + {"different annotation", deployment, createDeployment(1, "sa", "", "image", nil, []corev1.EnvVar{{Name: "env1"}}, nil, map[string]string{"key": "val"}), true}, + {"same nil env", createDeployment(1, "sa", "", "image", nil, nil, nil, map[string]string{}), createDeployment(1, "sa", "", "image", nil, nil, nil, map[string]string{}), false}, + {"same nil annotation", createDeployment(1, "sa", "", "image", nil, []corev1.EnvVar{{Name: "env1"}}, nil, nil), createDeployment(1, "sa", "", "image", nil, []corev1.EnvVar{{Name: "env1"}}, nil, nil), false}, } policyServer := &policiesv1.PolicyServer{ @@ -59,7 +63,9 @@ func TestShouldUpdatePolicyServerDeployment(t *testing.T) { func createDeployment(replicasInt int, serviceAccount, imagePullSecret, image string, insecureSources []string, - env []corev1.EnvVar, annotations map[string]string, + env []corev1.EnvVar, + podSecurityContext *corev1.PodSecurityContext, + annotations map[string]string, ) *appsv1.Deployment { replicas := int32(replicasInt) const ( @@ -114,6 +120,7 @@ func createDeployment(replicasInt int, serviceAccount, imagePullSecret, image st Template: corev1.PodTemplateSpec{ ObjectMeta: metav1.ObjectMeta{Annotations: annotations}, Spec: corev1.PodSpec{ + SecurityContext: podSecurityContext, Containers: []corev1.Container{container}, ServiceAccountName: serviceAccount, }, @@ -160,7 +167,7 @@ func TestGetPolicyServeImageFromDeployment(t *testing.T) { }, } policyServer.Name = policyServerName - deployment := createDeployment(1, "sa", "", "image", nil, []corev1.EnvVar{}, map[string]string{}) + deployment := createDeployment(1, "sa", "", "image", nil, []corev1.EnvVar{}, nil, map[string]string{}) image, err := getPolicyServerImageFromDeployment(&policyServer, deployment) if err != nil || image != "image" { t.Errorf("The function cannot find the right container image for the policy server container. Expected: 'image', Got: %s", image) @@ -179,8 +186,8 @@ func TestIfPolicyServerImageChanged(t *testing.T) { }, } policyServer.Name = policyServerName - oldDeployment := createDeployment(1, "sa", "", "image", nil, []corev1.EnvVar{}, map[string]string{}) - newDeployment := createDeployment(1, "sa", "", "image", nil, []corev1.EnvVar{}, map[string]string{}) + oldDeployment := createDeployment(1, "sa", "", "image", nil, []corev1.EnvVar{}, nil, map[string]string{}) + newDeployment := createDeployment(1, "sa", "", "image", nil, []corev1.EnvVar{}, nil, map[string]string{}) oldDeployment.Spec.Template.Spec.Containers[0].Name = policyServerContainerName newDeployment.Spec.Template.Spec.Containers[0].Name = policyServerContainerName diff --git a/pkg/apis/policies/v1/policyserver_types.go b/pkg/apis/policies/v1/policyserver_types.go index 0878bde5..0c6c55d6 100644 --- a/pkg/apis/policies/v1/policyserver_types.go +++ b/pkg/apis/policies/v1/policyserver_types.go @@ -78,8 +78,8 @@ type PolicyServerSpec struct { // Security configuration to be used in the Policy Server workload. // The field allows different configurations for the pod and containers. - // This configuration will not be used in containers added by other - // controllers (e.g. telemetry sidecars) + // If set for the containers, this configuration will not be used in + // containers added by other controllers (e.g. telemetry sidecars) // +optional SecurityContexts PolicyServerSecurity `json:"securityContexts,omitempty"` }