From c470982ce5b96da82a757f088a842bb05d3bcdb4 Mon Sep 17 00:00:00 2001 From: Tom Wieczorek Date: Sun, 9 Dec 2018 01:02:44 +0100 Subject: [PATCH 1/2] Make transformer configs array-aware If path segments end with the special marker `[]` in transformer configs, this indicates that the respective path segment is supposed to be an array. That information may be used to suppress the meaningless creation of non-existent paths that should be arrays, not objects. --- .../expected.yaml | 57 +++++++++++++++++++ .../in/kustomization.yaml | 6 ++ .../in/statefulset-with-template.yaml | 29 ++++++++++ .../in/statefulset.yaml | 20 +++++++ .../test.yaml | 4 ++ .../config/defaultconfig/commonlabels.go | 2 +- pkg/transformers/mutatefield.go | 19 +++++-- 7 files changed, 131 insertions(+), 6 deletions(-) create mode 100644 pkg/commands/build/testdata/testcase-transformer-no-create-arrays/expected.yaml create mode 100644 pkg/commands/build/testdata/testcase-transformer-no-create-arrays/in/kustomization.yaml create mode 100644 pkg/commands/build/testdata/testcase-transformer-no-create-arrays/in/statefulset-with-template.yaml create mode 100644 pkg/commands/build/testdata/testcase-transformer-no-create-arrays/in/statefulset.yaml create mode 100644 pkg/commands/build/testdata/testcase-transformer-no-create-arrays/test.yaml diff --git a/pkg/commands/build/testdata/testcase-transformer-no-create-arrays/expected.yaml b/pkg/commands/build/testdata/testcase-transformer-no-create-arrays/expected.yaml new file mode 100644 index 000000000..9eafc8f9d --- /dev/null +++ b/pkg/commands/build/testdata/testcase-transformer-no-create-arrays/expected.yaml @@ -0,0 +1,57 @@ +apiVersion: apps/v1 +kind: StatefulSet +metadata: + labels: + notIn: arrays + name: persisted-test +spec: + replicas: 1 + selector: + matchLabels: + app: test + notIn: arrays + serviceName: test + template: + metadata: + labels: + app: test + notIn: arrays + spec: + containers: + - image: nginx + name: nginx + volumeClaimTemplates: + - metadata: + labels: + notIn: arrays + name: www + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi + storageClassName: my-storage-class +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + labels: + notIn: arrays + name: test +spec: + replicas: 1 + selector: + matchLabels: + app: test + notIn: arrays + serviceName: test + template: + metadata: + labels: + app: test + notIn: arrays + spec: + containers: + - image: nginx + name: nginx diff --git a/pkg/commands/build/testdata/testcase-transformer-no-create-arrays/in/kustomization.yaml b/pkg/commands/build/testdata/testcase-transformer-no-create-arrays/in/kustomization.yaml new file mode 100644 index 000000000..593d2618a --- /dev/null +++ b/pkg/commands/build/testdata/testcase-transformer-no-create-arrays/in/kustomization.yaml @@ -0,0 +1,6 @@ +commonLabels: + notIn: arrays + +resources: +- statefulset.yaml +- statefulset-with-template.yaml diff --git a/pkg/commands/build/testdata/testcase-transformer-no-create-arrays/in/statefulset-with-template.yaml b/pkg/commands/build/testdata/testcase-transformer-no-create-arrays/in/statefulset-with-template.yaml new file mode 100644 index 000000000..2e4eba617 --- /dev/null +++ b/pkg/commands/build/testdata/testcase-transformer-no-create-arrays/in/statefulset-with-template.yaml @@ -0,0 +1,29 @@ +kind: StatefulSet +apiVersion: apps/v1 +metadata: + name: persisted-test + labels: + notIn: arrays +spec: + serviceName: "test" + replicas: 1 + selector: + matchLabels: + app: test + template: + metadata: + labels: + app: test + spec: + containers: + - name: nginx + image: nginx + volumeClaimTemplates: + - metadata: + name: www + spec: + accessModes: [ "ReadWriteOnce" ] + storageClassName: my-storage-class + resources: + requests: + storage: 1Gi diff --git a/pkg/commands/build/testdata/testcase-transformer-no-create-arrays/in/statefulset.yaml b/pkg/commands/build/testdata/testcase-transformer-no-create-arrays/in/statefulset.yaml new file mode 100644 index 000000000..c81a03c26 --- /dev/null +++ b/pkg/commands/build/testdata/testcase-transformer-no-create-arrays/in/statefulset.yaml @@ -0,0 +1,20 @@ +kind: StatefulSet +apiVersion: apps/v1 +metadata: + name: test + labels: + notIn: arrays +spec: + serviceName: "test" + replicas: 1 + selector: + matchLabels: + app: test + template: + metadata: + labels: + app: test + spec: + containers: + - name: nginx + image: nginx diff --git a/pkg/commands/build/testdata/testcase-transformer-no-create-arrays/test.yaml b/pkg/commands/build/testdata/testcase-transformer-no-create-arrays/test.yaml new file mode 100644 index 000000000..6fa743457 --- /dev/null +++ b/pkg/commands/build/testdata/testcase-transformer-no-create-arrays/test.yaml @@ -0,0 +1,4 @@ +description: arrays are not autocreated by transformers +args: [] +filename: testdata/testcase-transformer-no-create-arrays/in +expectedStdout: testdata/testcase-transformer-no-create-arrays/expected.yaml diff --git a/pkg/transformers/config/defaultconfig/commonlabels.go b/pkg/transformers/config/defaultconfig/commonlabels.go index 7efd6a54d..875f602fa 100644 --- a/pkg/transformers/config/defaultconfig/commonlabels.go +++ b/pkg/transformers/config/defaultconfig/commonlabels.go @@ -110,7 +110,7 @@ commonLabels: group: apps kind: StatefulSet -- path: spec/volumeClaimTemplates/metadata/labels +- path: spec/volumeClaimTemplates[]/metadata/labels create: true group: apps kind: StatefulSet diff --git a/pkg/transformers/mutatefield.go b/pkg/transformers/mutatefield.go index eddfeee20..71d688e1e 100644 --- a/pkg/transformers/mutatefield.go +++ b/pkg/transformers/mutatefield.go @@ -33,18 +33,20 @@ func mutateField( return nil } - _, found := m[pathToField[0]] + firstPathSegment, isArray := getFirstPathSegment(pathToField) + + _, found := m[firstPathSegment] if !found { - if !createIfNotPresent { + if !createIfNotPresent || isArray { return nil } - m[pathToField[0]] = map[string]interface{}{} + m[firstPathSegment] = map[string]interface{}{} } if len(pathToField) == 1 { var err error for _, fn := range fns { - m[pathToField[0]], err = fn(m[pathToField[0]]) + m[firstPathSegment], err = fn(m[firstPathSegment]) if err != nil { return err } @@ -52,7 +54,7 @@ func mutateField( return nil } - v := m[pathToField[0]] + v := m[firstPathSegment] newPathToField := pathToField[1:] switch typedV := v.(type) { case nil: @@ -79,3 +81,10 @@ func mutateField( return fmt.Errorf("%#v is not expected to be a primitive type", typedV) } } + +func getFirstPathSegment(pathToField []string) (string, bool) { + if strings.HasSuffix(pathToField[0], "[]") { + return pathToField[0][:len(pathToField[0])-2], true + } + return pathToField[0], false +} From c9a5c03eaada2ed71e22a887ab960597e34c7a57 Mon Sep 17 00:00:00 2001 From: Tom Wieczorek Date: Tue, 28 May 2019 11:27:21 +0200 Subject: [PATCH 2/2] Convert legacy file based test to in-memory --- .../expected.yaml | 57 ------ .../in/kustomization.yaml | 6 - .../in/statefulset-with-template.yaml | 29 --- .../in/statefulset.yaml | 20 -- .../test.yaml | 4 - pkg/target/transformersarrays_test.go | 182 ++++++++++++++++++ 6 files changed, 182 insertions(+), 116 deletions(-) delete mode 100644 pkg/commands/build/testdata/testcase-transformer-no-create-arrays/expected.yaml delete mode 100644 pkg/commands/build/testdata/testcase-transformer-no-create-arrays/in/kustomization.yaml delete mode 100644 pkg/commands/build/testdata/testcase-transformer-no-create-arrays/in/statefulset-with-template.yaml delete mode 100644 pkg/commands/build/testdata/testcase-transformer-no-create-arrays/in/statefulset.yaml delete mode 100644 pkg/commands/build/testdata/testcase-transformer-no-create-arrays/test.yaml create mode 100644 pkg/target/transformersarrays_test.go diff --git a/pkg/commands/build/testdata/testcase-transformer-no-create-arrays/expected.yaml b/pkg/commands/build/testdata/testcase-transformer-no-create-arrays/expected.yaml deleted file mode 100644 index 9eafc8f9d..000000000 --- a/pkg/commands/build/testdata/testcase-transformer-no-create-arrays/expected.yaml +++ /dev/null @@ -1,57 +0,0 @@ -apiVersion: apps/v1 -kind: StatefulSet -metadata: - labels: - notIn: arrays - name: persisted-test -spec: - replicas: 1 - selector: - matchLabels: - app: test - notIn: arrays - serviceName: test - template: - metadata: - labels: - app: test - notIn: arrays - spec: - containers: - - image: nginx - name: nginx - volumeClaimTemplates: - - metadata: - labels: - notIn: arrays - name: www - spec: - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 1Gi - storageClassName: my-storage-class ---- -apiVersion: apps/v1 -kind: StatefulSet -metadata: - labels: - notIn: arrays - name: test -spec: - replicas: 1 - selector: - matchLabels: - app: test - notIn: arrays - serviceName: test - template: - metadata: - labels: - app: test - notIn: arrays - spec: - containers: - - image: nginx - name: nginx diff --git a/pkg/commands/build/testdata/testcase-transformer-no-create-arrays/in/kustomization.yaml b/pkg/commands/build/testdata/testcase-transformer-no-create-arrays/in/kustomization.yaml deleted file mode 100644 index 593d2618a..000000000 --- a/pkg/commands/build/testdata/testcase-transformer-no-create-arrays/in/kustomization.yaml +++ /dev/null @@ -1,6 +0,0 @@ -commonLabels: - notIn: arrays - -resources: -- statefulset.yaml -- statefulset-with-template.yaml diff --git a/pkg/commands/build/testdata/testcase-transformer-no-create-arrays/in/statefulset-with-template.yaml b/pkg/commands/build/testdata/testcase-transformer-no-create-arrays/in/statefulset-with-template.yaml deleted file mode 100644 index 2e4eba617..000000000 --- a/pkg/commands/build/testdata/testcase-transformer-no-create-arrays/in/statefulset-with-template.yaml +++ /dev/null @@ -1,29 +0,0 @@ -kind: StatefulSet -apiVersion: apps/v1 -metadata: - name: persisted-test - labels: - notIn: arrays -spec: - serviceName: "test" - replicas: 1 - selector: - matchLabels: - app: test - template: - metadata: - labels: - app: test - spec: - containers: - - name: nginx - image: nginx - volumeClaimTemplates: - - metadata: - name: www - spec: - accessModes: [ "ReadWriteOnce" ] - storageClassName: my-storage-class - resources: - requests: - storage: 1Gi diff --git a/pkg/commands/build/testdata/testcase-transformer-no-create-arrays/in/statefulset.yaml b/pkg/commands/build/testdata/testcase-transformer-no-create-arrays/in/statefulset.yaml deleted file mode 100644 index c81a03c26..000000000 --- a/pkg/commands/build/testdata/testcase-transformer-no-create-arrays/in/statefulset.yaml +++ /dev/null @@ -1,20 +0,0 @@ -kind: StatefulSet -apiVersion: apps/v1 -metadata: - name: test - labels: - notIn: arrays -spec: - serviceName: "test" - replicas: 1 - selector: - matchLabels: - app: test - template: - metadata: - labels: - app: test - spec: - containers: - - name: nginx - image: nginx diff --git a/pkg/commands/build/testdata/testcase-transformer-no-create-arrays/test.yaml b/pkg/commands/build/testdata/testcase-transformer-no-create-arrays/test.yaml deleted file mode 100644 index 6fa743457..000000000 --- a/pkg/commands/build/testdata/testcase-transformer-no-create-arrays/test.yaml +++ /dev/null @@ -1,4 +0,0 @@ -description: arrays are not autocreated by transformers -args: [] -filename: testdata/testcase-transformer-no-create-arrays/in -expectedStdout: testdata/testcase-transformer-no-create-arrays/expected.yaml diff --git a/pkg/target/transformersarrays_test.go b/pkg/target/transformersarrays_test.go new file mode 100644 index 000000000..432f0813b --- /dev/null +++ b/pkg/target/transformersarrays_test.go @@ -0,0 +1,182 @@ +// Copyright 2019 The Kubernetes Authors. +// SPDX-License-Identifier: Apache-2.0 + +package target_test + +import ( + "testing" + + kusttest_test "sigs.k8s.io/kustomize/pkg/kusttest" +) + +func makeStatefulSetKustomization(th *kusttest_test.KustTestHarness) { + th.WriteK("/app", ` +commonLabels: + notIn: arrays +resources: +- statefulset.yaml +- statefulset-with-template.yaml +`) + th.WriteF("/app/statefulset.yaml", ` +kind: StatefulSet +apiVersion: apps/v1 +metadata: + name: test + labels: + notIn: arrays +spec: + serviceName: test + replicas: 1 + selector: + matchLabels: + app: test + template: + metadata: + labels: + app: test + spec: + containers: + - name: nginx + image: k8s.gcr.io/nginx-slim:0.8 + ports: + - containerPort: 80 + name: web +`) + th.WriteF("/app/statefulset-with-template.yaml", ` +kind: StatefulSet +apiVersion: apps/v1 +metadata: + name: persisted-test + labels: + notIn: arrays +spec: + serviceName: test + replicas: 1 + selector: + matchLabels: + app: test + template: + metadata: + labels: + app: test + spec: + containers: + - name: nginx + image: k8s.gcr.io/nginx-slim:0.8 + ports: + - containerPort: 80 + name: web + volumeMounts: + - name: www + mountPath: /usr/share/nginx/html + - name: data + mountPath: /usr/share/nginx/data + volumeClaimTemplates: + - metadata: + name: www + spec: + accessModes: [ "ReadWriteOnce" ] + storageClassName: my-storage-class + resources: + requests: + storage: 1Gi + - metadata: + name: data + spec: + accessModes: [ "ReadWriteOnce" ] + storageClassName: my-storage-class + resources: + requests: + storage: 100Gi +`) +} + +func TestTransformersNoCreateArrays(t *testing.T) { + th := kusttest_test.NewKustTestHarness(t, "/app") + makeStatefulSetKustomization(th) + m, err := th.MakeKustTarget().MakeCustomizedResMap() + if err != nil { + t.Fatalf("Err: %v", err) + } + th.AssertActualEqualsExpected(m, ` +apiVersion: apps/v1 +kind: StatefulSet +metadata: + labels: + notIn: arrays + name: persisted-test +spec: + replicas: 1 + selector: + matchLabels: + app: test + notIn: arrays + serviceName: test + template: + metadata: + labels: + app: test + notIn: arrays + spec: + containers: + - image: k8s.gcr.io/nginx-slim:0.8 + name: nginx + ports: + - containerPort: 80 + name: web + volumeMounts: + - mountPath: /usr/share/nginx/html + name: www + - mountPath: /usr/share/nginx/data + name: data + volumeClaimTemplates: + - metadata: + labels: + notIn: arrays + name: www + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi + storageClassName: my-storage-class + - metadata: + labels: + notIn: arrays + name: data + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 100Gi + storageClassName: my-storage-class +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + labels: + notIn: arrays + name: test +spec: + replicas: 1 + selector: + matchLabels: + app: test + notIn: arrays + serviceName: test + template: + metadata: + labels: + app: test + notIn: arrays + spec: + containers: + - image: k8s.gcr.io/nginx-slim:0.8 + name: nginx + ports: + - containerPort: 80 + name: web +`) +}