diff --git a/kustomize/resource_kustomization.go b/kustomize/resource_kustomization.go index 875f048..7318495 100644 --- a/kustomize/resource_kustomization.go +++ b/kustomize/resource_kustomization.go @@ -14,7 +14,7 @@ import ( k8smeta "k8s.io/apimachinery/pkg/api/meta" k8smetav1 "k8s.io/apimachinery/pkg/apis/meta/v1" k8sschema "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/apimachinery/pkg/util/validation/field" + "k8s.io/apimachinery/pkg/util/validation/field" ) func kustomizationResource() *schema.Resource { @@ -272,6 +272,14 @@ func kustomizationResourceDiff(ctx context.Context, d *schema.ResourceDiff, m in return nil } + // if cause is updates to storage class provisioner or parameters are forbidden force a delete and re-create plan + if k8serrors.HasStatusCause(err, k8smetav1.CauseType(field.ErrorTypeForbidden)) { + if strings.HasSuffix(msg, ": updates to provisioner are forbidden.") || strings.HasPrefix(msg, "Forbidden: updates to parameters are forbidden") { + d.ForceNew("manifest") + return nil + } + } + } } diff --git a/kustomize/resource_kustomization_test.go b/kustomize/resource_kustomization_test.go index dfef327..00e91db 100644 --- a/kustomize/resource_kustomization_test.go +++ b/kustomize/resource_kustomization_test.go @@ -445,6 +445,51 @@ resource "kustomization_resource" "rb" { ` } +// +// +// Update_Recreate_StorageClass Test +func TestAccResourceKustomization_updateRecreateStorageClass(t *testing.T) { + + resource.Test(t, resource.TestCase{ + Providers: testAccProviders, + Steps: []resource.TestStep{ + // + // + // Applying initial storage class + { + Config: testAccResourceKustomizationConfig_updateRecreateStorageClassProvisioner("test_kustomizations/update_recreate_storage_class/initial"), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttrSet("kustomization_resource.scparam", "id"), + resource.TestCheckResourceAttrSet("kustomization_resource.scprov", "id"), + ), + }, + // + // + // Applying changed storage class + { + Config: testAccResourceKustomizationConfig_updateRecreateStorageClassProvisioner("test_kustomizations/update_recreate_storage_class/modified"), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttrSet("kustomization_resource.scparam", "id"), + resource.TestCheckResourceAttrSet("kustomization_resource.scprov", "id"), + ), + }, + }, + }) +} + +func testAccResourceKustomizationConfig_updateRecreateStorageClassProvisioner(path string) string { + return testAccDataSourceKustomizationConfig_basic(path) + ` +resource "kustomization_resource" "scparam" { + manifest = data.kustomization_build.test.manifests["storage.k8s.io/StorageClass/_/local-storage-parameters"] +} + +resource "kustomization_resource" "scprov" { + manifest = data.kustomization_build.test.manifests["storage.k8s.io/StorageClass/_/local-storage-provisioner"] +} + +` +} + // // // Upgrade_API_Version Test diff --git a/kustomize/test_kustomizations/update_recreate_storage_class/initial/kustomization.yaml b/kustomize/test_kustomizations/update_recreate_storage_class/initial/kustomization.yaml new file mode 100644 index 0000000..4df3649 --- /dev/null +++ b/kustomize/test_kustomizations/update_recreate_storage_class/initial/kustomization.yaml @@ -0,0 +1,6 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +resources: +- storage-class-parameters.yaml +- storage-class-provisioner.yaml \ No newline at end of file diff --git a/kustomize/test_kustomizations/update_recreate_storage_class/initial/storage-class-parameters.yaml b/kustomize/test_kustomizations/update_recreate_storage_class/initial/storage-class-parameters.yaml new file mode 100644 index 0000000..0f073b0 --- /dev/null +++ b/kustomize/test_kustomizations/update_recreate_storage_class/initial/storage-class-parameters.yaml @@ -0,0 +1,8 @@ +apiVersion: storage.k8s.io/v1 +kind: StorageClass +metadata: + name: local-storage-parameters +provisioner: kubernetes.io/no-provisioner +volumeBindingMode: WaitForFirstConsumer +parameters: + test: test diff --git a/kustomize/test_kustomizations/update_recreate_storage_class/initial/storage-class-provisioner.yaml b/kustomize/test_kustomizations/update_recreate_storage_class/initial/storage-class-provisioner.yaml new file mode 100644 index 0000000..486ea9a --- /dev/null +++ b/kustomize/test_kustomizations/update_recreate_storage_class/initial/storage-class-provisioner.yaml @@ -0,0 +1,6 @@ +apiVersion: storage.k8s.io/v1 +kind: StorageClass +metadata: + name: local-storage-provisioner +provisioner: kubernetes.io/no-provisioner +volumeBindingMode: WaitForFirstConsumer diff --git a/kustomize/test_kustomizations/update_recreate_storage_class/modified/kustomization.yaml b/kustomize/test_kustomizations/update_recreate_storage_class/modified/kustomization.yaml new file mode 100644 index 0000000..a9d7333 --- /dev/null +++ b/kustomize/test_kustomizations/update_recreate_storage_class/modified/kustomization.yaml @@ -0,0 +1,25 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +resources: +- ../initial + +patches: +- patch: | + - op: replace + path: /parameters/test + value: test2 + target: + group: "storage.k8s.io" + version: v1 + kind: StorageClass + name: local-storage-parameters +- patch: | + - op: replace + path: /provisioner + value: example.com/external-nfs + target: + group: "storage.k8s.io" + version: v1 + kind: StorageClass + name: local-storage-provisioner