Skip to content

Commit

Permalink
Fix restart_policy validation in Deployment (hashicorp#2595)
Browse files Browse the repository at this point in the history
Fix validation of restart_policy in Deployment's pod template
  • Loading branch information
alexsomesan authored Oct 17, 2024
1 parent b4cf5b6 commit 01f6171
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 3 deletions.
3 changes: 3 additions & 0 deletions .changelog/2595.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:improvement
resource/kubernetes_deployment_v1: Fix validation of `restart_policy` values
```
2 changes: 1 addition & 1 deletion .github/workflows/documentation-check.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,6 @@ jobs:
- name: Undocumented changes
run: |
echo "Documentation is not up to date. Please refer to the `Making Changes` in the Contribution Guide on how to properly update documentation."
echo 'Documentation is not up to date. Please refer to the `Making Changes` in the Contribution Guide on how to properly update documentation.'
exit 1
if: failure()
2 changes: 1 addition & 1 deletion docs/resources/deployment_v1.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ Optional:
- `os` (Block List, Max: 1) Specifies the OS of the containers in the pod. (see [below for nested schema](#nestedblock--spec--template--spec--os))
- `priority_class_name` (String) If specified, indicates the pod's priority. "system-node-critical" and "system-cluster-critical" are two special keywords which indicate the highest priorities with the former being the highest priority. Any other name must be defined by creating a PriorityClass object with that name. If not specified, the pod priority will be default or zero if there is no default.
- `readiness_gate` (Block List) If specified, all readiness gates will be evaluated for pod readiness. A pod is ready when all its containers are ready AND all conditions specified in the readiness gates have status equal to "True" More info: https://git.k8s.io/enhancements/keps/sig-network/0007-pod-ready%2B%2B.md (see [below for nested schema](#nestedblock--spec--template--spec--readiness_gate))
- `restart_policy` (String) Restart policy for all containers within the pod. One of Always, OnFailure, Never. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy.
- `restart_policy` (String) Restart policy for all containers within the pod. Defaults to Always as the only option. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy.
- `runtime_class_name` (String) RuntimeClassName is a feature for selecting the container runtime configuration. The container runtime configuration is used to run a Pod's containers. More info: https://kubernetes.io/docs/concepts/containers/runtime-class
- `scheduler_name` (String) If specified, the pod will be dispatched by specified scheduler. If not specified, the pod will be dispatched by default scheduler.
- `security_context` (Block List, Max: 1) SecurityContext holds pod-level security attributes and common container settings. Optional: Defaults to empty (see [below for nested schema](#nestedblock--spec--template--spec--security_context))
Expand Down
13 changes: 12 additions & 1 deletion kubernetes/resource_kubernetes_deployment_v1.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"

appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
Expand Down Expand Up @@ -199,7 +200,7 @@ func resourceKubernetesDeploymentSchemaV1() map[string]*schema.Schema {
Required: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: podSpecFields(true, false),
Schema: deploymentPodTemplateSpecFields(),
},
},
},
Expand All @@ -217,6 +218,16 @@ func resourceKubernetesDeploymentSchemaV1() map[string]*schema.Schema {
}
}

func deploymentPodTemplateSpecFields() map[string]*schema.Schema {
psf := podSpecFields(true, false)
rp := psf["restart_policy"]
rp.ValidateFunc = validation.StringInSlice([]string{
string(corev1.RestartPolicyAlways),
}, false)
rp.Description = "Restart policy for all containers within the pod. Defaults to Always as the only option. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy."
return psf
}

func resourceKubernetesDeploymentV1Create(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
conn, err := meta.(KubeClientsets).MainClientset()
if err != nil {
Expand Down
63 changes: 63 additions & 0 deletions kubernetes/resource_kubernetes_deployment_v1_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1225,6 +1225,36 @@ func TestAccKubernetesDeploymentV1_config_with_automount_service_account_token(t
})
}

func TestAccKubernetesDeploymentV1_with_restart_policy(t *testing.T) {
var conf appsv1.Deployment
name := fmt.Sprintf("tf-acc-test-%s", acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum))
resourceName := "kubernetes_deployment_v1.test"
imageName := busyboxImage

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
IDRefreshName: resourceName,
IDRefreshIgnore: []string{"metadata.0.resource_version"},
ProviderFactories: testAccProviderFactories,
CheckDestroy: testAccCheckKubernetesDeploymentV1Destroy,
Steps: []resource.TestStep{
{
Config: testAccKubernetesDeploymentV1Config_with_restart_policy(name, imageName, "Never"),
ExpectError: regexp.MustCompile("expected spec\\.0\\.template\\.0\\.spec\\.0\\.restart_policy to be one of \\[\"Always\"\\], got Never"),
},
{
Config: testAccKubernetesDeploymentV1Config_with_restart_policy(name, imageName, "Always"),
Check: resource.ComposeAggregateTestCheckFunc(
testAccCheckKubernetesDeploymentV1Exists(resourceName, &conf),
resource.TestCheckResourceAttrSet(resourceName, "metadata.0.generation"),
resource.TestCheckResourceAttrSet(resourceName, "metadata.0.resource_version"),
resource.TestCheckResourceAttrSet(resourceName, "metadata.0.uid"),
),
},
},
})
}

func testAccCheckKubernetesDeploymentForceNew(old, new *appsv1.Deployment, wantNew bool) resource.TestCheckFunc {
return func(s *terraform.State) error {
if wantNew {
Expand Down Expand Up @@ -1409,6 +1439,39 @@ func testAccKubernetesDeploymentV1Config_basic(name, imageName string) string {
`, name, imageName)
}

func testAccKubernetesDeploymentV1Config_with_restart_policy(name, imageName, restartPolicy string) string {
return fmt.Sprintf(`resource "kubernetes_deployment_v1" "test" {
metadata {
name = "%s"
}
spec {
replicas = 2
selector {
match_labels = {
TestLabelOne = "one"
}
}
template {
metadata {
labels = {
TestLabelOne = "one"
}
}
spec {
container {
image = "%s"
name = "tf-acc-test"
command = ["sleep", "300"]
}
restart_policy = "%s"
termination_grace_period_seconds = 1
}
}
}
}
`, name, imageName, restartPolicy)
}

func testAccKubernetesDeploymentV1Config_initContainer(namespace, name, imageName, imageName1, memory, envName, initName, initCommand, pullPolicy string) string {
return fmt.Sprintf(`resource "kubernetes_namespace_v1" "test" {
metadata {
Expand Down

0 comments on commit 01f6171

Please sign in to comment.