From a94c58239f93e724432441a5be1bb2c0203bc1d7 Mon Sep 17 00:00:00 2001 From: Jonathan Hurley Date: Fri, 26 Jul 2019 21:00:08 -0500 Subject: [PATCH] adding feature for apparmor annotation --- score/apparmor/apparmor.go | 31 ++++++++++++++++++ score/apparmor_test.go | 13 ++++++++ score/score.go | 2 ++ score/testdata/deployment-sets-apparmor.yaml | 32 +++++++++++++++++++ .../deployment-sets-default-apparmor.yaml | 32 +++++++++++++++++++ .../testdata/deployment-sets-no-apparmor.yaml | 30 +++++++++++++++++ 6 files changed, 140 insertions(+) create mode 100644 score/apparmor/apparmor.go create mode 100644 score/apparmor_test.go create mode 100644 score/testdata/deployment-sets-apparmor.yaml create mode 100644 score/testdata/deployment-sets-default-apparmor.yaml create mode 100644 score/testdata/deployment-sets-no-apparmor.yaml diff --git a/score/apparmor/apparmor.go b/score/apparmor/apparmor.go new file mode 100644 index 00000000..603d1771 --- /dev/null +++ b/score/apparmor/apparmor.go @@ -0,0 +1,31 @@ +package apparmor + +import ( + "strings" + + "github.com/zegl/kube-score/score/checks" + "github.com/zegl/kube-score/scorecard" + appsv1 "k8s.io/api/apps/v1" +) + +func Register( allChecks *checks.Checks ) { + allChecks.RegisterDeploymentCheck( "Deployment sets apparmor annotation", `Makes sure that all Deployments set apparmor annotation`, deploymentHas() ) +} + +func deploymentHas() func( appsv1.Deployment ) ( scorecard.TestScore, error ) { + return func( deployment appsv1.Deployment ) ( score scorecard.TestScore, err error ) { + if armor, found := deployment.Spec.Template.GetObjectMeta().GetAnnotations()[ "container.apparmor.security.beta.kubernetes.io" ]; found { + if strings.Index( armor, "localhost/docker-default" ) != -1 { + score.Grade = scorecard.GradeAlmostOK + score.AddComment( "", "apparmor annotation is set:", "It is recommended to not use docker-default and instead customize a profile" ) + return + } + score.Grade = scorecard.GradeAllOK + score.AddComment( "", "apparmor annotation is set:", armor ) + return + } + score.Grade = scorecard.GradeCritical + score.AddComment( "", "apparmor annotation is not set", "It is recommended to set apparmor annotation and customize a profile" ) + return + } +} diff --git a/score/apparmor_test.go b/score/apparmor_test.go new file mode 100644 index 00000000..b0af7cdb --- /dev/null +++ b/score/apparmor_test.go @@ -0,0 +1,13 @@ +package score + +import "testing" + +func TestApparmorAnnotation(t *testing.T) { + testExpectedScore(t, "deployment-sets-apparmor.yaml", "Deployment sets apparmor annotation", 10) +} +func TestNoApparmorAnnotation(t *testing.T) { + testExpectedScore(t, "deployment-sets-no-apparmor.yaml", "Deployment sets apparmor annotation", 1) +} +func TestDefaultApparmorAnnotation(t *testing.T) { + testExpectedScore(t, "deployment-sets-default-apparmor.yaml", "Deployment sets apparmor annotation", 7) +} diff --git a/score/score.go b/score/score.go index 9aaf27f5..a60187a8 100644 --- a/score/score.go +++ b/score/score.go @@ -4,6 +4,7 @@ import ( "github.com/zegl/kube-score/config" ks "github.com/zegl/kube-score/domain" "github.com/zegl/kube-score/score/apps" + "github.com/zegl/kube-score/score/apparmor" "github.com/zegl/kube-score/score/checks" "github.com/zegl/kube-score/score/container" "github.com/zegl/kube-score/score/cronjob" @@ -33,6 +34,7 @@ func RegisterAllChecks(allObjects ks.AllTypes, cnf config.Configuration) *checks service.Register(allChecks, allObjects, allObjects) stable.Register(allChecks) apps.Register(allChecks) + apparmor.Register(allChecks) meta.Register(allChecks) return allChecks diff --git a/score/testdata/deployment-sets-apparmor.yaml b/score/testdata/deployment-sets-apparmor.yaml new file mode 100644 index 00000000..83e68c3e --- /dev/null +++ b/score/testdata/deployment-sets-apparmor.yaml @@ -0,0 +1,32 @@ +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: my-service +spec: + replicas: 1 + selector: + matchLabels: + app: my-service + template: + metadata: + annotations: + container.apparmor.security.beta.kubernetes.io: localhost/docker-custom + labels: + app: my-service + spec: + containers: + - name: my-service + image: "alpine:latest" + imagePullPolicy: Always + ports: + - containerPort: 8080 + protocol: TCP + name: "http-node" + resources: + limits: + cpu: 50m + memory: 128Mi + requests: + cpu: 50m + memory: 128Mi diff --git a/score/testdata/deployment-sets-default-apparmor.yaml b/score/testdata/deployment-sets-default-apparmor.yaml new file mode 100644 index 00000000..9a7f2aca --- /dev/null +++ b/score/testdata/deployment-sets-default-apparmor.yaml @@ -0,0 +1,32 @@ +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: my-service +spec: + replicas: 1 + selector: + matchLabels: + app: my-service + template: + metadata: + annotations: + container.apparmor.security.beta.kubernetes.io: localhost/docker-default + labels: + app: my-service + spec: + containers: + - name: my-service + image: "alpine:latest" + imagePullPolicy: Always + ports: + - containerPort: 8080 + protocol: TCP + name: "http-node" + resources: + limits: + cpu: 50m + memory: 128Mi + requests: + cpu: 50m + memory: 128Mi diff --git a/score/testdata/deployment-sets-no-apparmor.yaml b/score/testdata/deployment-sets-no-apparmor.yaml new file mode 100644 index 00000000..02ccdda0 --- /dev/null +++ b/score/testdata/deployment-sets-no-apparmor.yaml @@ -0,0 +1,30 @@ +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: my-service +spec: + replicas: 1 + selector: + matchLabels: + app: my-service + template: + metadata: + labels: + app: my-service + spec: + containers: + - name: my-service + image: "alpine:latest" + imagePullPolicy: Always + ports: + - containerPort: 8080 + protocol: TCP + name: "http-node" + resources: + limits: + cpu: 50m + memory: 128Mi + requests: + cpu: 50m + memory: 128Mi