Skip to content

Handle storage class immutable fields with force new plan fix #194 #199

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 23, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion kustomize/resource_kustomization.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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
}
}

}
}

Expand Down
45 changes: 45 additions & 0 deletions kustomize/resource_kustomization_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

resources:
- storage-class-parameters.yaml
- storage-class-provisioner.yaml
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: local-storage-provisioner
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer
Original file line number Diff line number Diff line change
@@ -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