Skip to content
This repository has been archived by the owner on Feb 27, 2023. It is now read-only.

Commit

Permalink
Custom security contexts implementation
Browse files Browse the repository at this point in the history
Allow setting custom security contexts for both contour deployments and
envoy daemonsets. The default value is unpriviledged and is equivalent
to the following:

contourSecurityContext:
  runAsUser: 65534
  runAsGroup: 65534
  runAsNonRoot: true

Fixes #112
Updates #378
  • Loading branch information
David Morgan committed Jul 6, 2021
1 parent 03d0e3c commit 650cce5
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 2 deletions.
8 changes: 8 additions & 0 deletions api/v1alpha1/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,3 +95,11 @@ func (c *Contour) EnvoyTolerationsExist() bool {

return false
}

func (c *Contour) ContourSecurityContextExists() bool {
return c.Spec.ContourSecurityContext != nil
}

func (c *Contour) EnvoySecurityContextExists() bool {
return c.Spec.EnvoySecurityContext != nil
}
7 changes: 6 additions & 1 deletion internal/objects/daemonset/daemonset.go
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,6 @@ func DesiredDaemonSet(contour *operatorv1alpha1.Contour, contourImage, envoyImag
DeprecatedServiceAccount: EnvoyContainerName,
AutomountServiceAccountToken: pointer.BoolPtr(false),
TerminationGracePeriodSeconds: pointer.Int64Ptr(int64(300)),
SecurityContext: &corev1.PodSecurityContext{},
DNSPolicy: corev1.DNSClusterFirst,
RestartPolicy: corev1.RestartPolicyAlways,
SchedulerName: "default-scheduler",
Expand All @@ -358,6 +357,12 @@ func DesiredDaemonSet(contour *operatorv1alpha1.Contour, contourImage, envoyImag
ds.Spec.Template.Spec.Tolerations = contour.Spec.NodePlacement.Envoy.Tolerations
}

if contour.EnvoySecurityContextExists() {
ds.Spec.Template.Spec.SecurityContext = contour.Spec.EnvoySecurityContext
} else {
ds.Spec.Template.Spec.SecurityContext = objutil.NewUnprivilegedPodSecurity()
}

return ds
}

Expand Down
34 changes: 34 additions & 0 deletions internal/objects/daemonset/daemonset_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,14 @@ import (
"testing"

operatorv1alpha1 "github.com/projectcontour/contour-operator/api/v1alpha1"
objutil "github.com/projectcontour/contour-operator/internal/objects"
objcontour "github.com/projectcontour/contour-operator/internal/objects/contour"
"github.com/projectcontour/contour-operator/internal/operator/config"

appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
apiequality "k8s.io/apimachinery/pkg/api/equality"
"k8s.io/utils/pointer"
)

func checkDaemonSetHasEnvVar(t *testing.T, ds *appsv1.DaemonSet, container, name string) {
Expand Down Expand Up @@ -136,6 +138,16 @@ func checkDaemonSetHasTolerations(t *testing.T, ds *appsv1.DaemonSet, expected [
t.Errorf("deployment has unexpected tolerations %v", expected)
}

func checkDaemonSetHasSecurityContext(t *testing.T, ds *appsv1.DaemonSet, expected *corev1.PodSecurityContext) {
t.Helper()

if apiequality.Semantic.DeepEqual(ds.Spec.Template.Spec.SecurityContext, expected) {
return
}

t.Errorf("deployment has unexpected security context %v", expected)
}

func TestDesiredDaemonSet(t *testing.T) {
name := "ds-test"
cfg := objcontour.Config{
Expand Down Expand Up @@ -164,6 +176,7 @@ func TestDesiredDaemonSet(t *testing.T) {
}
checkDaemonSetHasNodeSelector(t, ds, nil)
checkDaemonSetHasTolerations(t, ds, nil)
checkDaemonSetHasSecurityContext(t, ds, objutil.NewUnprivilegedPodSecurity())
}

func TestNodePlacementDaemonSet(t *testing.T) {
Expand Down Expand Up @@ -198,3 +211,24 @@ func TestNodePlacementDaemonSet(t *testing.T) {
checkDaemonSetHasNodeSelector(t, ds, selectors)
checkDaemonSetHasTolerations(t, ds, tolerations)
}

func TestSecurityContextDaemonSet(t *testing.T) {
name := "security-context-test"
sc := &corev1.PodSecurityContext{
RunAsUser: pointer.Int64(int64(0)),
}
cfg := objcontour.Config{
Name: name,
Namespace: fmt.Sprintf("%s-ns", name),
SpecNs: "projectcontour",
RemoveNs: false,
NetworkType: operatorv1alpha1.LoadBalancerServicePublishingType,
}
cntr := objcontour.New(cfg)
cntr.Spec.EnvoySecurityContext = sc

testContourImage := config.DefaultContourImage
testEnvoyImage := config.DefaultEnvoyImage
ds := DesiredDaemonSet(cntr, testContourImage, testEnvoyImage)
checkDaemonSetHasSecurityContext(t, ds, sc)
}
7 changes: 6 additions & 1 deletion internal/objects/deployment/deployment.go
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,6 @@ func DesiredDeployment(contour *operatorv1alpha1.Contour, image string) *appsv1.
ServiceAccountName: objutil.ContourRbacName,
RestartPolicy: corev1.RestartPolicyAlways,
SchedulerName: "default-scheduler",
SecurityContext: objutil.NewUnprivilegedPodSecurity(),
TerminationGracePeriodSeconds: pointer.Int64Ptr(int64(30)),
},
},
Expand All @@ -319,6 +318,12 @@ func DesiredDeployment(contour *operatorv1alpha1.Contour, image string) *appsv1.
deploy.Spec.Template.Spec.Tolerations = contour.Spec.NodePlacement.Contour.Tolerations
}

if contour.ContourSecurityContextExists() {
deploy.Spec.Template.Spec.SecurityContext = contour.Spec.ContourSecurityContext
} else {
deploy.Spec.Template.Spec.SecurityContext = objutil.NewUnprivilegedPodSecurity()
}

return deploy
}

Expand Down
33 changes: 33 additions & 0 deletions internal/objects/deployment/deployment_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,15 @@ import (
"testing"

operatorv1alpha1 "github.com/projectcontour/contour-operator/api/v1alpha1"
objutil "github.com/projectcontour/contour-operator/internal/objects"
objcontour "github.com/projectcontour/contour-operator/internal/objects/contour"
objcfg "github.com/projectcontour/contour-operator/internal/objects/sharedconfig"
"github.com/projectcontour/contour-operator/internal/operator/config"

appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
apiequality "k8s.io/apimachinery/pkg/api/equality"
"k8s.io/utils/pointer"
)

func checkDeploymentHasEnvVar(t *testing.T, deploy *appsv1.Deployment, name string) {
Expand Down Expand Up @@ -107,6 +109,16 @@ func checkDeploymentHasTolerations(t *testing.T, deploy *appsv1.Deployment, expe
t.Errorf("deployment has unexpected tolerations %v", expected)
}

func checkDeploymentHasSecurityContext(t *testing.T, deploy *appsv1.Deployment, expected *corev1.PodSecurityContext) {
t.Helper()

if apiequality.Semantic.DeepEqual(deploy.Spec.Template.Spec.SecurityContext, expected) {
return
}

t.Errorf("deployment has unexpected security context %v", expected)
}

func TestDesiredDeployment(t *testing.T) {
name := "deploy-test"
cfg := objcontour.Config{
Expand Down Expand Up @@ -155,6 +167,7 @@ func TestDesiredDeployment(t *testing.T) {
checkContainerHasArg(t, container, arg)
checkDeploymentHasNodeSelector(t, deploy, nil)
checkDeploymentHasTolerations(t, deploy, nil)
checkDeploymentHasSecurityContext(t, deploy, objutil.NewUnprivilegedPodSecurity())
}

func TestNodePlacementDeployment(t *testing.T) {
Expand Down Expand Up @@ -189,3 +202,23 @@ func TestNodePlacementDeployment(t *testing.T) {
checkDeploymentHasNodeSelector(t, deploy, selectors)
checkDeploymentHasTolerations(t, deploy, tolerations)
}

func TestSecurityContextDeployment(t *testing.T) {
name := "security-context-test"
sc := &corev1.PodSecurityContext{
RunAsUser: pointer.Int64(int64(0)),
}
cfg := objcontour.Config{
Name: name,
Namespace: fmt.Sprintf("%s-ns", name),
SpecNs: "projectcontour",
RemoveNs: false,
NetworkType: operatorv1alpha1.LoadBalancerServicePublishingType,
}
cntr := objcontour.New(cfg)
cntr.Spec.ContourSecurityContext = sc

testContourImage := config.DefaultContourImage
ds := DesiredDeployment(cntr, testContourImage)
checkDeploymentHasSecurityContext(t, ds, sc)
}

0 comments on commit 650cce5

Please sign in to comment.