diff --git a/.github/config/acceptance_tests_kind_config.yaml b/.github/config/acceptance_tests_kind_config.yaml new file mode 100644 index 0000000000..c72932005e --- /dev/null +++ b/.github/config/acceptance_tests_kind_config.yaml @@ -0,0 +1,7 @@ +apiVersion: kind.x-k8s.io/v1alpha4 +kind: Cluster +nodes: +- role: control-plane + extraMounts: + - hostPath: "./.github/config/seccomp-profiles" + containerPath: "/var/lib/kubelet/seccomp/profiles" \ No newline at end of file diff --git a/.github/config/seccomp-profiles/audit.json b/.github/config/seccomp-profiles/audit.json new file mode 100644 index 0000000000..1f2d5df6a4 --- /dev/null +++ b/.github/config/seccomp-profiles/audit.json @@ -0,0 +1,3 @@ +{ + "defaultAction": "SCMP_ACT_LOG" +} \ No newline at end of file diff --git a/.github/workflows/acceptance_tests_kind.yaml b/.github/workflows/acceptance_tests_kind.yaml index fb904b8904..ede3eb9445 100644 --- a/.github/workflows/acceptance_tests_kind.yaml +++ b/.github/workflows/acceptance_tests_kind.yaml @@ -34,6 +34,7 @@ jobs: with: wait: 2m version: v${{ github.event.inputs.kindVersion }} + config: .github/config/acceptance_tests_kind_config.yaml - name: Run Acceptance Test Suite env: KUBE_CONFIG_PATH: ${{ env.KUBECONFIG }} diff --git a/kubernetes/provider_test.go b/kubernetes/provider_test.go index 7cb009ef26..45a18e0ebf 100644 --- a/kubernetes/provider_test.go +++ b/kubernetes/provider_test.go @@ -7,6 +7,7 @@ import ( "context" "errors" "fmt" + "net/url" "os" "path/filepath" "strings" @@ -317,6 +318,16 @@ func skipIfNotRunningInMinikube(t *testing.T) { } } +func skipIfNotRunningInKind(t *testing.T) { + isRunningInKind, err := isRunningInKind() + if err != nil { + t.Fatal(err) + } + if !isRunningInKind { + t.Skip("The Kubernetes endpoint must come from Kind for this test to run - skipping") + } +} + func skipIfRunningInMinikube(t *testing.T) { isInMinikube, err := isRunningInMinikube() if err != nil { @@ -344,6 +355,21 @@ func isRunningInMinikube() (bool, error) { return false, nil } +func isRunningInKind() (bool, error) { + node, err := getFirstNode() + if err != nil { + return false, err + } + u, err := url.Parse(node.Spec.ProviderID) + if err != nil { + return false, err + } + if u.Scheme == "kind" { + return true, nil + } + return false, nil +} + func isRunningInGke() (bool, error) { node, err := getFirstNode() if err != nil { diff --git a/kubernetes/resource_kubernetes_cron_job_v1_test.go b/kubernetes/resource_kubernetes_cron_job_v1_test.go index dfe1c2436a..92f8596d09 100644 --- a/kubernetes/resource_kubernetes_cron_job_v1_test.go +++ b/kubernetes/resource_kubernetes_cron_job_v1_test.go @@ -75,7 +75,7 @@ func TestAccKubernetesCronJobV1_basic(t *testing.T) { resource.TestCheckResourceAttr("kubernetes_cron_job_v1.test", "spec.0.successful_jobs_history_limit", "3"), resource.TestCheckResourceAttr("kubernetes_cron_job_v1.test", "spec.0.suspend", "false"), resource.TestCheckResourceAttr("kubernetes_cron_job_v1.test", "spec.0.job_template.0.spec.0.parallelism", "2"), - resource.TestCheckResourceAttr("kubernetes_cron_job_v1.test", "spec.0.job_template.0.spec.0.backoff_limit", "0"), + resource.TestCheckResourceAttr("kubernetes_cron_job_v1.test", "spec.0.job_template.0.spec.0.backoff_limit", "6"), resource.TestCheckResourceAttr("kubernetes_cron_job_v1.test", "spec.0.job_template.0.spec.0.template.0.spec.0.container.0.name", "hello"), resource.TestCheckResourceAttr("kubernetes_cron_job_v1.test", "spec.0.job_template.0.spec.0.template.0.metadata.#", "1"), resource.TestCheckResourceAttr("kubernetes_cron_job_v1.test", "spec.0.job_template.0.spec.0.template.0.metadata.0.labels.%", "1"), diff --git a/kubernetes/resource_kubernetes_daemonset_test.go b/kubernetes/resource_kubernetes_daemonset_test.go index a7669bf2e0..4a1fd72c79 100644 --- a/kubernetes/resource_kubernetes_daemonset_test.go +++ b/kubernetes/resource_kubernetes_daemonset_test.go @@ -293,14 +293,31 @@ func TestAccKubernetesDaemonSet_with_container_security_context_seccomp_profile( resource.TestCheckResourceAttr(resourceName, "spec.0.template.0.spec.0.container.0.security_context.0.seccomp_profile.0.type", "RuntimeDefault"), ), }, + }, + }) +} + +func TestAccKubernetesDaemonSet_with_container_security_context_seccomp_localhost_profile(t *testing.T) { + var conf appsv1.DaemonSet + name := fmt.Sprintf("tf-acc-test-%s", acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum)) + imageName := nginxImageVersion + resourceName := "kubernetes_daemonset.test" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t); skipIfNotRunningInKind(t); skipIfClusterVersionLessThan(t, "1.19.0") }, + IDRefreshName: "kubernetes_daemonset.test", + IDRefreshIgnore: []string{"metadata.0.resource_version"}, + ProviderFactories: testAccProviderFactories, + CheckDestroy: testAccCheckKubernetesDaemonSetDestroy, + Steps: []resource.TestStep{ { Config: testAccKubernetesDaemonSetConfigWithContainerSecurityContextSeccompProfileLocalhost(name, imageName), Check: resource.ComposeAggregateTestCheckFunc( testAccCheckKubernetesDaemonSetExists(resourceName, &conf), resource.TestCheckResourceAttr(resourceName, "spec.0.template.0.spec.0.security_context.0.seccomp_profile.0.type", "Localhost"), - resource.TestCheckResourceAttr(resourceName, "spec.0.template.0.spec.0.security_context.0.seccomp_profile.0.localhost_profile", ""), + resource.TestCheckResourceAttr(resourceName, "spec.0.template.0.spec.0.security_context.0.seccomp_profile.0.localhost_profile", "profiles/audit.json"), resource.TestCheckResourceAttr(resourceName, "spec.0.template.0.spec.0.container.0.security_context.0.seccomp_profile.0.type", "Localhost"), - resource.TestCheckResourceAttr(resourceName, "spec.0.template.0.spec.0.container.0.security_context.0.seccomp_profile.0.localhost_profile", ""), + resource.TestCheckResourceAttr(resourceName, "spec.0.template.0.spec.0.container.0.security_context.0.seccomp_profile.0.localhost_profile", "profiles/audit.json"), ), }, }, @@ -870,7 +887,7 @@ func testAccKubernetesDaemonSetConfigWithContainerSecurityContextSeccompProfileL security_context { seccomp_profile { type = "Localhost" - localhost_profile = "" + localhost_profile = "profiles/audit.json" } } container { @@ -880,7 +897,7 @@ func testAccKubernetesDaemonSetConfigWithContainerSecurityContextSeccompProfileL security_context { seccomp_profile { type = "Localhost" - localhost_profile = "" + localhost_profile = "profiles/audit.json" } } } diff --git a/kubernetes/resource_kubernetes_deployment_test.go b/kubernetes/resource_kubernetes_deployment_test.go index d9d3562854..4af52fe4a8 100644 --- a/kubernetes/resource_kubernetes_deployment_test.go +++ b/kubernetes/resource_kubernetes_deployment_test.go @@ -554,7 +554,7 @@ func TestAccKubernetesDeployment_with_container_security_context_seccomp_profile resourceName := "kubernetes_deployment.test" resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, + PreCheck: func() { testAccPreCheck(t); skipIfClusterVersionLessThan(t, "1.19.0") }, ProviderFactories: testAccProviderFactories, CheckDestroy: testAccCheckKubernetesDeploymentDestroy, Steps: []resource.TestStep{ @@ -574,14 +574,30 @@ func TestAccKubernetesDeployment_with_container_security_context_seccomp_profile resource.TestCheckResourceAttr(resourceName, "spec.0.template.0.spec.0.container.0.security_context.0.seccomp_profile.0.type", "RuntimeDefault"), ), }, + }, + }) +} + +func TestAccKubernetesDeployment_with_container_security_context_seccomp_localhost_profile(t *testing.T) { + var conf appsv1.Deployment + + deploymentName := fmt.Sprintf("tf-acc-test-%s", acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum)) + imageName := nginxImageVersion + resourceName := "kubernetes_deployment.test" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t); skipIfNotRunningInKind(t); skipIfClusterVersionLessThan(t, "1.19.0") }, + ProviderFactories: testAccProviderFactories, + CheckDestroy: testAccCheckKubernetesDeploymentDestroy, + Steps: []resource.TestStep{ { Config: testAccKubernetesDeploymentConfigWithContainerSecurityContextSeccompProfileLocalhost(deploymentName, imageName), Check: resource.ComposeAggregateTestCheckFunc( testAccCheckKubernetesDeploymentExists(resourceName, &conf), resource.TestCheckResourceAttr(resourceName, "spec.0.template.0.spec.0.security_context.0.seccomp_profile.0.type", "Localhost"), - resource.TestCheckResourceAttr(resourceName, "spec.0.template.0.spec.0.security_context.0.seccomp_profile.0.localhost_profile", ""), + resource.TestCheckResourceAttr(resourceName, "spec.0.template.0.spec.0.security_context.0.seccomp_profile.0.localhost_profile", "profiles/audit.json"), resource.TestCheckResourceAttr(resourceName, "spec.0.template.0.spec.0.container.0.security_context.0.seccomp_profile.0.type", "Localhost"), - resource.TestCheckResourceAttr(resourceName, "spec.0.template.0.spec.0.container.0.security_context.0.seccomp_profile.0.localhost_profile", ""), + resource.TestCheckResourceAttr(resourceName, "spec.0.template.0.spec.0.container.0.security_context.0.seccomp_profile.0.localhost_profile", "profiles/audit.json"), ), }, }, @@ -2149,7 +2165,7 @@ func testAccKubernetesDeploymentConfigWithContainerSecurityContextSeccompProfile security_context { seccomp_profile { type = "Localhost" - localhost_profile = "" + localhost_profile = "profiles/audit.json" } } container { @@ -2159,7 +2175,7 @@ func testAccKubernetesDeploymentConfigWithContainerSecurityContextSeccompProfile security_context { seccomp_profile { type = "Localhost" - localhost_profile = "" + localhost_profile = "profiles/audit.json" } } } diff --git a/kubernetes/resource_kubernetes_job_test.go b/kubernetes/resource_kubernetes_job_test.go index 7b9476ffe7..25cbbb79cd 100644 --- a/kubernetes/resource_kubernetes_job_test.go +++ b/kubernetes/resource_kubernetes_job_test.go @@ -102,7 +102,7 @@ func TestAccKubernetesJob_basic(t *testing.T) { resource.TestCheckResourceAttr("kubernetes_job.test", "metadata.0.labels.foo", "bar"), resource.TestCheckResourceAttr("kubernetes_job.test", "spec.#", "1"), resource.TestCheckResourceAttr("kubernetes_job.test", "spec.0.active_deadline_seconds", "0"), - resource.TestCheckResourceAttr("kubernetes_job.test", "spec.0.backoff_limit", "0"), + resource.TestCheckResourceAttr("kubernetes_job.test", "spec.0.backoff_limit", "6"), resource.TestCheckResourceAttr("kubernetes_job.test", "spec.0.completions", "1"), resource.TestCheckResourceAttr("kubernetes_job.test", "spec.0.parallelism", "1"), resource.TestCheckResourceAttr("kubernetes_job.test", "spec.0.manual_selector", "true"), diff --git a/kubernetes/resource_kubernetes_pod_test.go b/kubernetes/resource_kubernetes_pod_test.go index 40df8e4e3c..8a2c2864dc 100644 --- a/kubernetes/resource_kubernetes_pod_test.go +++ b/kubernetes/resource_kubernetes_pod_test.go @@ -454,14 +454,36 @@ func TestAccKubernetesPod_with_pod_security_context_seccomp_profile(t *testing.T resource.TestCheckResourceAttr(resourceName, "spec.0.container.0.security_context.0.seccomp_profile.0.type", "RuntimeDefault"), ), }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"metadata.0.resource_version"}, + }, + }, + }) +} + +func TestAccKubernetesPod_with_pod_security_context_seccomp_localhost_profile(t *testing.T) { + var conf api.Pod + + podName := acctest.RandomWithPrefix("tf-acc-test") + imageName := nginxImageVersion + resourceName := "kubernetes_pod.test" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t); skipIfNotRunningInKind(t); skipIfClusterVersionLessThan(t, "1.19.0") }, + ProviderFactories: testAccProviderFactories, + CheckDestroy: testAccCheckKubernetesPodDestroy, + Steps: []resource.TestStep{ { Config: testAccKubernetesPodConfigWithSecurityContextSeccompProfileLocalhost(podName, imageName), Check: resource.ComposeAggregateTestCheckFunc( testAccCheckKubernetesPodExists(resourceName, &conf), resource.TestCheckResourceAttr(resourceName, "spec.0.security_context.0.seccomp_profile.0.type", "Localhost"), - resource.TestCheckResourceAttr(resourceName, "spec.0.security_context.0.seccomp_profile.0.localhost_profile", ""), + resource.TestCheckResourceAttr(resourceName, "spec.0.security_context.0.seccomp_profile.0.localhost_profile", "profiles/audit.json"), resource.TestCheckResourceAttr(resourceName, "spec.0.container.0.security_context.0.seccomp_profile.0.type", "Localhost"), - resource.TestCheckResourceAttr(resourceName, "spec.0.container.0.security_context.0.seccomp_profile.0.localhost_profile", ""), + resource.TestCheckResourceAttr(resourceName, "spec.0.container.0.security_context.0.seccomp_profile.0.localhost_profile", "profiles/audit.json"), ), }, { @@ -1875,7 +1897,7 @@ resource "kubernetes_pod" "test" { security_context { seccomp_profile { type = "Localhost" - localhost_profile = "" + localhost_profile = "profiles/audit.json" } } @@ -1885,7 +1907,7 @@ resource "kubernetes_pod" "test" { security_context { seccomp_profile { type = "Localhost" - localhost_profile = "" + localhost_profile = "profiles/audit.json" } } }