diff --git a/kubernetes/resource_kubernetes_deployment_test.go b/kubernetes/resource_kubernetes_deployment_test.go index d5593e56cd..7ee9259d02 100644 --- a/kubernetes/resource_kubernetes_deployment_test.go +++ b/kubernetes/resource_kubernetes_deployment_test.go @@ -294,6 +294,44 @@ func TestAccKubernetesDeployment_strategy(t *testing.T) { }) } +func TestAccKubernetesDeployment_with_empty_dir_volume(t *testing.T) { + t.Parallel() + + var conf appsv1.Deployment + + depName := fmt.Sprintf("tf-acc-test-%s", acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum)) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckKubernetesDeploymentDestroy, + Steps: []resource.TestStep{ + { + Config: testAccKubernetesDeploymentWithEmptyDirVolume1(depName), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckKubernetesDeploymentExists("kubernetes_deployment.test", &conf), + resource.TestCheckResourceAttr("kubernetes_deployment.test", "spec.0.template.0.spec.0.container.0.volume_mount.#", "1"), + resource.TestCheckResourceAttr("kubernetes_deployment.test", "spec.0.template.0.spec.0.container.0.volume_mount.0.mount_path", "/cache"), + resource.TestCheckResourceAttr("kubernetes_deployment.test", "spec.0.template.0.spec.0.container.0.volume_mount.0.name", "cache-volume"), + resource.TestCheckResourceAttr("kubernetes_deployment.test", "spec.0.template.0.spec.0.volume.0.empty_dir.0.medium", "Memory"), + resource.TestCheckResourceAttr("kubernetes_deployment.test", "spec.0.template.0.spec.0.volume.0.empty_dir.0.size_limit", "0"), + ), + }, + { + Config: testAccKubernetesDeploymentWithEmptyDirVolume2(depName), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckKubernetesDeploymentExists("kubernetes_deployment.test", &conf), + resource.TestCheckResourceAttr("kubernetes_deployment.test", "spec.0.template.0.spec.0.container.0.volume_mount.#", "1"), + resource.TestCheckResourceAttr("kubernetes_deployment.test", "spec.0.template.0.spec.0.container.0.volume_mount.0.mount_path", "/cache"), + resource.TestCheckResourceAttr("kubernetes_deployment.test", "spec.0.template.0.spec.0.container.0.volume_mount.0.name", "cache-volume"), + resource.TestCheckResourceAttr("kubernetes_deployment.test", "spec.0.template.0.spec.0.volume.0.empty_dir.0.medium", "Memory"), + resource.TestCheckResourceAttr("kubernetes_deployment.test", "spec.0.template.0.spec.0.volume.0.empty_dir.0.size_limit", "1Gi"), + ), + }, + }, + }) +} + func pause() resource.TestCheckFunc { return func(s *terraform.State) error { time.Sleep(1 * time.Minute) @@ -725,3 +763,86 @@ resource "kubernetes_deployment" "test" { } `, depName) } + +func testAccKubernetesDeploymentWithEmptyDirVolume1(depName string) string { + return fmt.Sprintf(` +resource "kubernetes_deployment" "test" { + metadata { + name = "%s" + } + + spec { + selector { + foo = "bar" + } + + template { + metadata { + labels { + foo = "bar" + } + } + + spec { + container { + image = "citizenstig/httpbin" + name = "containername" + volume_mount { + mount_path = "/cache" + name = "cache-volume" + } + } + volume { + name = "cache-volume" + empty_dir = { + medium = "Memory" + } + } + } + } + } +} +`, depName) +} + +func testAccKubernetesDeploymentWithEmptyDirVolume2(depName string) string { + return fmt.Sprintf(` +resource "kubernetes_deployment" "test" { + metadata { + name = "%s" + } + + spec { + selector { + foo = "bar" + } + + template { + metadata { + labels { + foo = "bar" + } + } + + spec { + container { + image = "citizenstig/httpbin" + name = "containername" + volume_mount { + mount_path = "/cache" + name = "cache-volume" + } + } + volume { + name = "cache-volume" + empty_dir = { + size_limit = "1Gi" + medium = "Memory" + } + } + } + } + } +} +`, depName) +} diff --git a/kubernetes/resource_kubernetes_pod_test.go b/kubernetes/resource_kubernetes_pod_test.go index 9c513c2344..2adfc4c2a1 100644 --- a/kubernetes/resource_kubernetes_pod_test.go +++ b/kubernetes/resource_kubernetes_pod_test.go @@ -400,7 +400,19 @@ func TestAccKubernetesPod_with_empty_dir_volume(t *testing.T) { CheckDestroy: testAccCheckKubernetesPodDestroy, Steps: []resource.TestStep{ { - Config: testAccKubernetesPodConfigWithEmptyDirVolumes(podName, imageName), + Config: testAccKubernetesPodConfigWithEmptyDirVolumes1(podName, imageName), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckKubernetesPodExists("kubernetes_pod.test", &conf), + resource.TestCheckResourceAttr("kubernetes_pod.test", "spec.0.container.0.image", imageName), + resource.TestCheckResourceAttr("kubernetes_pod.test", "spec.0.container.0.volume_mount.#", "1"), + resource.TestCheckResourceAttr("kubernetes_pod.test", "spec.0.container.0.volume_mount.0.mount_path", "/cache"), + resource.TestCheckResourceAttr("kubernetes_pod.test", "spec.0.container.0.volume_mount.0.name", "cache-volume"), + resource.TestCheckResourceAttr("kubernetes_pod.test", "spec.0.volume.0.empty_dir.0.medium", "Memory"), + resource.TestCheckResourceAttr("kubernetes_pod.test", "spec.0.volume.0.empty_dir.0.size_limit", "0"), + ), + }, + { + Config: testAccKubernetesPodConfigWithEmptyDirVolumes2(podName, imageName), Check: resource.ComposeAggregateTestCheckFunc( testAccCheckKubernetesPodExists("kubernetes_pod.test", &conf), resource.TestCheckResourceAttr("kubernetes_pod.test", "spec.0.container.0.image", imageName), @@ -1022,7 +1034,7 @@ resource "kubernetes_pod" "test" { `, podName, imageName) } -func testAccKubernetesPodConfigWithEmptyDirVolumes(podName, imageName string) string { +func testAccKubernetesPodConfigWithEmptyDirVolumes1(podName, imageName string) string { return fmt.Sprintf(` resource "kubernetes_pod" "test" { metadata { @@ -1045,7 +1057,6 @@ resource "kubernetes_pod" "test" { volume { name = "cache-volume" empty_dir = { - size_limit = "1Gi" medium = "Memory" } } @@ -1054,6 +1065,38 @@ resource "kubernetes_pod" "test" { `, podName, imageName) } +func testAccKubernetesPodConfigWithEmptyDirVolumes2(podName, imageName string) string { + return fmt.Sprintf(` +resource "kubernetes_pod" "test" { + metadata { + labels { + app = "pod_label" + } + + name = "%s" + } + + spec { + container { + image = "%s" + name = "containername" + volume_mount { + mount_path = "/cache" + name = "cache-volume" + } + } + volume { + name = "cache-volume" + empty_dir = { + size_limit = "1Gi" + medium = "Memory" + } + } + } +} +`, podName, imageName) +} + func testAccKubernetesPodConfigNodeSelector(podName, imageName, region string) string { return fmt.Sprintf(` resource "kubernetes_pod" "test" { diff --git a/kubernetes/schema_pod_spec.go b/kubernetes/schema_pod_spec.go index 86d130ecc5..43e1db5e0a 100755 --- a/kubernetes/schema_pod_spec.go +++ b/kubernetes/schema_pod_spec.go @@ -253,7 +253,7 @@ func podSpecFields(isUpdatable bool) map[string]*schema.Schema { Type: schema.TypeList, Optional: true, Description: "List of volumes that can be mounted by containers belonging to the pod. More info: http://kubernetes.io/docs/user-guide/volumes", - Elem: volumeSchema(), + Elem: volumeSchema(isUpdatable), }, } @@ -274,7 +274,7 @@ func podSpecFields(isUpdatable bool) map[string]*schema.Schema { return s } -func volumeSchema() *schema.Resource { +func volumeSchema(isUpdatable bool) *schema.Resource { v := commonVolumeSources() v["config_map"] = &schema.Schema{ @@ -446,10 +446,12 @@ func volumeSchema() *schema.Resource { ValidateFunc: validateAttributeValueIsIn([]string{"", "Memory"}), }, "size_limit": { - Type: schema.TypeString, - Description: `Total amount of local storage required for this EmptyDir volume. The size limit is also applicable for memory medium. The maximum usage on memory medium EmptyDir would be the minimum value between the SizeLimit specified here and the sum of memory limits of all containers in a pod. The default is nil which means that the limit is undefined. More info: http://kubernetes.io/docs/user-guide/volumes#emptydir`, - Optional: true, - Default: "", + Type: schema.TypeString, + Description: `Total amount of local storage required for this EmptyDir volume. The size limit is also applicable for memory medium. The maximum usage on memory medium EmptyDir would be the minimum value between the SizeLimit specified here and the sum of memory limits of all containers in a pod. The default is nil which means that the limit is undefined. More info: http://kubernetes.io/docs/user-guide/volumes#emptydir`, + Optional: true, + Default: "0", + ForceNew: !isUpdatable, + ValidateFunc: validateResourceQuantity, }, }, }, diff --git a/kubernetes/structures_pod.go b/kubernetes/structures_pod.go index 7dcf01e9f2..4d727246db 100755 --- a/kubernetes/structures_pod.go +++ b/kubernetes/structures_pod.go @@ -734,13 +734,19 @@ func expandEmptyDirVolumeSource(l []interface{}) (*v1.EmptyDirVolumeSource, erro return &v1.EmptyDirVolumeSource{}, nil } in := l[0].(map[string]interface{}) - v, err := resource.ParseQuantity(in["size_limit"].(string)) - if err != nil { - return &v1.EmptyDirVolumeSource{}, err + + var quantity resource.Quantity + if cfg, ok := in["size_limit"].(string); ok && len(cfg) > 0 { + var err error + quantity, err = resource.ParseQuantity(cfg) + if err != nil { + return &v1.EmptyDirVolumeSource{}, err + } } + obj := &v1.EmptyDirVolumeSource{ Medium: v1.StorageMedium(in["medium"].(string)), - SizeLimit: &v, + SizeLimit: &quantity, } return obj, nil }