From 8d585ccfa89e4f4e1eabf652528d3f7306af3268 Mon Sep 17 00:00:00 2001 From: Peter Hunt Date: Fri, 15 Nov 2019 15:49:42 -0500 Subject: play kube: handle seccomp labels Add handling of seccomp annotations to play kube at both container and pod levels. also add a test Signed-off-by: Peter Hunt --- test/e2e/common_test.go | 9 ++++++ test/e2e/play_kube_test.go | 71 +++++++++++++++++++++++++++++++++++++++++++--- test/e2e/run_test.go | 4 +-- 3 files changed, 78 insertions(+), 6 deletions(-) (limited to 'test/e2e') diff --git a/test/e2e/common_test.go b/test/e2e/common_test.go index b390df8b2..16b971e65 100644 --- a/test/e2e/common_test.go +++ b/test/e2e/common_test.go @@ -559,3 +559,12 @@ func (p *PodmanTestIntegration) RunHealthCheck(cid string) error { } return errors.Errorf("unable to detect %s as running", cid) } + +func (p *PodmanTestIntegration) CreateSeccompJson(in []byte) (string, error) { + jsonFile := filepath.Join(p.TempDir, "seccomp.json") + err := WriteJsonFile(in, jsonFile) + if err != nil { + return "", err + } + return jsonFile, nil +} diff --git a/test/e2e/play_kube_test.go b/test/e2e/play_kube_test.go index 416c64b5a..29c60d7ac 100644 --- a/test/e2e/play_kube_test.go +++ b/test/e2e/play_kube_test.go @@ -3,6 +3,7 @@ package integration import ( + "fmt" "os" "path/filepath" "text/template" @@ -20,6 +21,13 @@ metadata: labels: app: {{ .Name }} name: {{ .Name }} +{{ with .Annotations }} + annotations: + {{ range $key, $value := . }} + {{ $key }}: {{ $value }} + {{ end }} +{{ end }} + spec: hostname: {{ .Hostname }} containers: @@ -72,6 +80,7 @@ var ( defaultCtrCmd = []string{"top"} defaultCtrImage = ALPINE defaultPodName = "testPod" + seccompPwdEPERM = []byte(`{"defaultAction":"SCMP_ACT_ALLOW","syscalls":[{"name":"getcwd","action":"SCMP_ACT_ERRNO"}]}`) ) func generateKubeYaml(pod *Pod, fileName string) error { @@ -95,16 +104,17 @@ func generateKubeYaml(pod *Pod, fileName string) error { // Pod describes the options a kube yaml can be configured at pod level type Pod struct { - Name string - Hostname string - Ctrs []*Ctr + Name string + Hostname string + Ctrs []*Ctr + Annotations map[string]string } // getPod takes a list of podOptions and returns a pod with sane defaults // and the configured options // if no containers are added, it will add the default container func getPod(options ...podOption) *Pod { - p := Pod{defaultPodName, "", make([]*Ctr, 0)} + p := Pod{defaultPodName, "", make([]*Ctr, 0), make(map[string]string)} for _, option := range options { option(&p) } @@ -128,6 +138,12 @@ func withCtr(c *Ctr) podOption { } } +func withAnnotation(k, v string) podOption { + return func(pod *Pod) { + pod.Annotations[k] = v + } +} + // Ctr describes the options a kube yaml can be configured at container level type Ctr struct { Name string @@ -330,4 +346,51 @@ var _ = Describe("Podman generate kube", func() { inspect.WaitWithDefaultTimeout() Expect(inspect.ExitCode()).To(Equal(0)) }) + + It("podman play kube seccomp container level", func() { + // expect play kube is expected to set a seccomp label if it's applied as an annotation + jsonFile, err := podmanTest.CreateSeccompJson(seccompPwdEPERM) + if err != nil { + fmt.Println(err) + Skip("Failed to prepare seccomp.json for test.") + } + + ctrAnnotation := "container.seccomp.security.alpha.kubernetes.io/" + defaultCtrName + ctr := getCtr(withCmd([]string{"pwd"})) + + err = generateKubeYaml(getPod(withCtr(ctr), withAnnotation(ctrAnnotation, "localhost:"+jsonFile)), kubeYaml) + Expect(err).To(BeNil()) + + kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) + kube.WaitWithDefaultTimeout() + Expect(kube.ExitCode()).To(Equal(0)) + + logs := podmanTest.Podman([]string{"logs", defaultCtrName}) + logs.WaitWithDefaultTimeout() + Expect(logs.ExitCode()).To(Equal(0)) + Expect(logs.OutputToString()).To(ContainSubstring("Operation not permitted")) + }) + + It("podman play kube seccomp pod level", func() { + // expect play kube is expected to set a seccomp label if it's applied as an annotation + jsonFile, err := podmanTest.CreateSeccompJson(seccompPwdEPERM) + if err != nil { + fmt.Println(err) + Skip("Failed to prepare seccomp.json for test.") + } + + ctr := getCtr(withCmd([]string{"pwd"})) + + err = generateKubeYaml(getPod(withCtr(ctr), withAnnotation("seccomp.security.alpha.kubernetes.io/pod", "localhost:"+jsonFile)), kubeYaml) + Expect(err).To(BeNil()) + + kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) + kube.WaitWithDefaultTimeout() + Expect(kube.ExitCode()).To(Equal(0)) + + logs := podmanTest.Podman([]string{"logs", defaultCtrName}) + logs.WaitWithDefaultTimeout() + Expect(logs.ExitCode()).To(Equal(0)) + Expect(logs.OutputToString()).To(ContainSubstring("Operation not permitted")) + }) }) diff --git a/test/e2e/run_test.go b/test/e2e/run_test.go index 7fc85c9ce..72547ea00 100644 --- a/test/e2e/run_test.go +++ b/test/e2e/run_test.go @@ -160,9 +160,9 @@ var _ = Describe("Podman run", func() { }) It("podman run seccomp test", func() { - jsonFile := filepath.Join(podmanTest.TempDir, "seccomp.json") + in := []byte(`{"defaultAction":"SCMP_ACT_ALLOW","syscalls":[{"name":"getcwd","action":"SCMP_ACT_ERRNO"}]}`) - err := WriteJsonFile(in, jsonFile) + jsonFile, err := podmanTest.CreateSeccompJson(in) if err != nil { fmt.Println(err) Skip("Failed to prepare seccomp.json for test.") -- cgit v1.2.3-54-g00ecf