diff options
-rw-r--r-- | cmd/podman/play/kube.go | 11 | ||||
-rw-r--r-- | test/e2e/play_kube_test.go | 235 |
2 files changed, 233 insertions, 13 deletions
diff --git a/cmd/podman/play/kube.go b/cmd/podman/play/kube.go index 17f3b430d..8d9a26151 100644 --- a/cmd/podman/play/kube.go +++ b/cmd/podman/play/kube.go @@ -98,15 +98,8 @@ func kube(cmd *cobra.Command, args []string) error { } } - switch len(report.Pods) { - case 0: - return nil - case 1: - fmt.Printf("Pod:\n") - default: - fmt.Printf("Pods:\n") - } for _, pod := range report.Pods { + fmt.Printf("Pod:\n") fmt.Println(pod.ID) switch len(pod.Containers) { @@ -120,6 +113,8 @@ func kube(cmd *cobra.Command, args []string) error { for _, ctr := range pod.Containers { fmt.Println(ctr) } + // Empty line for space for next block + fmt.Println() } return nil diff --git a/test/e2e/play_kube_test.go b/test/e2e/play_kube_test.go index e51e56f9a..750379b08 100644 --- a/test/e2e/play_kube_test.go +++ b/test/e2e/play_kube_test.go @@ -14,6 +14,17 @@ import ( . "github.com/onsi/gomega" ) +var unknownKindYAML = ` +apiVerson: v1 +kind: UnknownKind +metadata: + labels: + app: app1 + name: unknown +spec: + hostname: unknown +` + var yamlTemplate = ` apiVersion: v1 kind: Pod @@ -77,14 +88,109 @@ spec: status: {} ` +var deploymentYAMLTemplate = ` +apiVersion: v1 +kind: Deployment +metadata: + creationTimestamp: "2019-07-17T14:44:08Z" + labels: + app: {{ .Name }} + name: {{ .Name }} +{{ with .Annotations }} + annotations: + {{ range $key, $value := . }} + {{ $key }}: {{ $value }} + {{ end }} +{{ end }} + +spec: + replicas: {{ .Replicas }} + selector: + matchLabels: + app: {{ .Name }} + template: + {{ with .PodTemplate }} + metadata: + labels: + app: {{ .Name }} + {{ with .Annotations }} + annotations: + {{ range $key, $value := . }} + {{ $key }}: {{ $value }} + {{ end }} + {{ end }} + spec: + hostname: {{ .Hostname }} + containers: + {{ with .Ctrs }} + {{ range . }} + - command: + {{ range .Cmd }} + - {{.}} + {{ end }} + env: + - name: PATH + value: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin + - name: TERM + value: xterm + - name: HOSTNAME + - name: container + value: podman + image: {{ .Image }} + name: {{ .Name }} + imagePullPolicy: {{ .PullPolicy }} + resources: {} + {{ if .SecurityContext }} + securityContext: + allowPrivilegeEscalation: true + {{ if .Caps }} + capabilities: + {{ with .CapAdd }} + add: + {{ range . }} + - {{.}} + {{ end }} + {{ end }} + {{ with .CapDrop }} + drop: + {{ range . }} + - {{.}} + {{ end }} + {{ end }} + {{ end }} + privileged: false + readOnlyRootFilesystem: false + workingDir: / + {{ end }} + {{ end }} + {{ end }} + {{ end }} +` + var ( - defaultCtrName = "testCtr" - defaultCtrCmd = []string{"top"} - defaultCtrImage = ALPINE - defaultPodName = "testPod" - seccompPwdEPERM = []byte(`{"defaultAction":"SCMP_ACT_ALLOW","syscalls":[{"name":"getcwd","action":"SCMP_ACT_ERRNO"}]}`) + defaultCtrName = "testCtr" + defaultCtrCmd = []string{"top"} + defaultCtrImage = ALPINE + defaultPodName = "testPod" + defaultDeploymentName = "testDeployment" + seccompPwdEPERM = []byte(`{"defaultAction":"SCMP_ACT_ALLOW","syscalls":[{"name":"getcwd","action":"SCMP_ACT_ERRNO"}]}`) ) +func writeYAML(content string, fileName string) error { + f, err := os.Create(fileName) + if err != nil { + return err + } + defer f.Close() + + _, err = f.WriteString(content) + if err != nil { + return err + } + + return nil +} + func generateKubeYaml(pod *Pod, fileName string) error { f, err := os.Create(fileName) if err != nil { @@ -104,6 +210,25 @@ func generateKubeYaml(pod *Pod, fileName string) error { return nil } +func generateDeploymentKubeYaml(deployment *Deployment, fileName string) error { + f, err := os.Create(fileName) + if err != nil { + return err + } + defer f.Close() + + t, err := template.New("deployment").Parse(deploymentYAMLTemplate) + if err != nil { + return err + } + + if err := t.Execute(f, deployment); err != nil { + return err + } + + return nil +} + // Pod describes the options a kube yaml can be configured at pod level type Pod struct { Name string @@ -146,6 +271,59 @@ func withAnnotation(k, v string) podOption { } } +// Deployment describes the options a kube yaml can be configured at deployment level +type Deployment struct { + Name string + Replicas int32 + Annotations map[string]string + PodTemplate *Pod +} + +func getDeployment(options ...deploymentOption) *Deployment { + d := Deployment{defaultDeploymentName, 1, make(map[string]string), getPod()} + for _, option := range options { + option(&d) + } + + return &d +} + +type deploymentOption func(*Deployment) + +func withDeploymentAnnotation(k, v string) deploymentOption { + return func(deployment *Deployment) { + deployment.Annotations[k] = v + } +} + +func withPod(pod *Pod) deploymentOption { + return func(d *Deployment) { + d.PodTemplate = pod + } +} + +func withReplicas(replicas int32) deploymentOption { + return func(d *Deployment) { + d.Replicas = replicas + } +} + +// getPodNamesInDeployment returns list of Pod objects +// with just their name set, so that it can be passed around +// and into getCtrNameInPod for ease of testing +func getPodNamesInDeployment(d *Deployment) []Pod { + var pods []Pod + var i int32 + + for i = 0; i < d.Replicas; i++ { + p := Pod{} + p.Name = fmt.Sprintf("%s-pod-%d", d.Name, i) + pods = append(pods, p) + } + + return pods +} + // Ctr describes the options a kube yaml can be configured at container level type Ctr struct { Name string @@ -238,6 +416,16 @@ var _ = Describe("Podman generate kube", func() { processTestResult(f) }) + It("podman play kube fail with yaml of unsupported kind", func() { + err := writeYAML(unknownKindYAML, kubeYaml) + Expect(err).To(BeNil()) + + kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) + kube.WaitWithDefaultTimeout() + Expect(kube.ExitCode()).To(Not(Equal(0))) + + }) + It("podman play kube fail with nonexist authfile", func() { err := generateKubeYaml(getPod(), kubeYaml) Expect(err).To(BeNil()) @@ -541,4 +729,41 @@ spec: Expect(ctr[0].Config.Labels["key1"]).To(ContainSubstring("value1")) Expect(ctr[0].Config.StopSignal).To(Equal(uint(51))) }) + + // Deployment related tests + It("podman play kube deployment 1 replica test correct command", func() { + deployment := getDeployment() + err := generateDeploymentKubeYaml(deployment, kubeYaml) + Expect(err).To(BeNil()) + + kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) + kube.WaitWithDefaultTimeout() + Expect(kube.ExitCode()).To(Equal(0)) + + podNames := getPodNamesInDeployment(deployment) + inspect := podmanTest.Podman([]string{"inspect", getCtrNameInPod(&podNames[0])}) + inspect.WaitWithDefaultTimeout() + Expect(inspect.ExitCode()).To(Equal(0)) + Expect(inspect.OutputToString()).To(ContainSubstring(defaultCtrCmd[0])) + }) + + It("podman play kube deployment more than 1 replica test correct command", func() { + var i, numReplicas int32 + numReplicas = 5 + deployment := getDeployment(withReplicas(numReplicas)) + err := generateDeploymentKubeYaml(deployment, kubeYaml) + Expect(err).To(BeNil()) + + kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) + kube.WaitWithDefaultTimeout() + Expect(kube.ExitCode()).To(Equal(0)) + + podNames := getPodNamesInDeployment(deployment) + for i = 0; i < numReplicas; i++ { + inspect := podmanTest.Podman([]string{"inspect", getCtrNameInPod(&podNames[i])}) + inspect.WaitWithDefaultTimeout() + Expect(inspect.ExitCode()).To(Equal(0)) + Expect(inspect.OutputToString()).To(ContainSubstring(defaultCtrCmd[0])) + } + }) }) |