kustomize

The atago project wrote these specs on its own initiative and runs them in its own CI, to exercise atago against a real program. They are not kustomize’s official test suite, and the kustomize project is not affiliated with atago.

Summary #

2 suites · 18 scenarios

Contents #

kustomize + changes (kustomization file authoring) #

kustomize create and kustomize edit modify your project in place, which makes their footprint part of their contract: they should write the kustomization file and leave everything else alone.

That is stated here as an exhaustive claim. Each command’s effect on the directory is compared before and after, so an extra file, a backup left behind, or a stray write into the user’s home directory would all fail — the home directory included, because it is redirected inside the workspace where the delta can see it.

Source: test/e2e/thirdparty/kustomize/changes.atago.yaml

Scenario: create writes exactly the kustomization file #

only when kustomize version succeeds

Given #

  • The command runs with an isolated home under ${workdir}/.atago-home (HOME/XDG or APPDATA redirected).

When #

kustomize create

Then #

  • exit code is 0
  • the step changed exactly created kustomization.yaml, modified nothing, deleted nothing
  • file kustomization.yaml contains kind: Kustomization

Scenario: edit set namespace modifies only the kustomization file #

only when kustomize version succeeds

Given #

  • The command runs with an isolated home under ${workdir}/.atago-home (HOME/XDG or APPDATA redirected).

When #

kustomize create
kustomize edit set namespace staging

Then #

  • after kustomize create:
    • exit code is 0
  • after kustomize edit set namespace staging:
    • exit code is 0
    • the step changed exactly created nothing, modified kustomization.yaml, deleted nothing
    • file kustomization.yaml contains namespace: staging

Scenario: edit set image records the image override in the file #

only when kustomize version succeeds

Given #

  • The command runs with an isolated home under ${workdir}/.atago-home (HOME/XDG or APPDATA redirected).

When #

kustomize create
kustomize edit set image nginx=nginx:3.0

Then #

  • after kustomize create:
    • exit code is 0
  • after kustomize edit set image nginx=nginx:3.0:
    • exit code is 0
    • the step changed exactly created nothing, modified kustomization.yaml, deleted nothing
    • file kustomization.yaml contains name: nginx, newTag: "3.0"

Scenario: edit fix migrates the deprecated commonLabels field to labels #

only when kustomize version succeeds

Given #

  • Fixture file kustomization.yaml is created.
  • The command runs with an isolated home under ${workdir}/.atago-home (HOME/XDG or APPDATA redirected).

Inputs #

Fixture kustomization.yaml:

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
commonLabels:
  app: x

When #

kustomize edit fix

Then #

  • exit code is 0
  • the step changed exactly created nothing, modified kustomization.yaml, deleted nothing
  • file kustomization.yaml contains labels:
  • file kustomization.yaml does not contain commonLabels:

Scenario: edit without a kustomization file fails #

only when kustomize version succeeds

When #

kustomize edit set namespace staging

Then #

  • exit code is 1
  • stderr contains Missing kustomization file

kustomize (declarative Kubernetes config) #

kustomize turns a base set of Kubernetes manifests plus a list of edits into the final YAML you apply. No cluster is involved and no network is touched, which means the same inputs must always render the same bytes — the property everything else depends on.

What is guaranteed: transformations compose in the defined order, so name prefixes, labels, and patches land predictably rather than by accident of evaluation order; generators derive the content hash that makes a config map change roll its consumers; the load restrictor refuses to read files outside the kustomization root, which is a security boundary and not a convenience; and a broken kustomization fails on stderr with exit 1 instead of emitting partial YAML someone might apply.

Source: test/e2e/thirdparty/kustomize/kustomize.atago.yaml

Scenario: version prints a semantic version #

only when kustomize version succeeds

When #

kustomize version

Then #

  • exit code is 0
  • stdout matches /^v[0-9]+\.[0-9]+\.[0-9]+/

Scenario: build applies name prefix, namespace, labels and image tag #

only when kustomize version succeeds

Given #

  • Fixture file base/deploy.yaml is created.
  • Fixture file base/kustomization.yaml is created.

Inputs #

Fixture base/deploy.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
spec:
  replicas: 1
  template:
    spec:
      containers:
      - name: web
        image: nginx:1.0

Fixture base/kustomization.yaml:

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namePrefix: prod-
namespace: production
labels:
- pairs:
    app: myapp
  includeSelectors: true
images:
- name: nginx
  newTag: "2.0"
resources:
- deploy.yaml

When #

kustomize build base

Then #

  • exit code is 0
  • stdout contains name: prod-web, namespace: production, app: myapp, image: nginx:2.0
  • stdout matches /(?s)selector:\s+matchLabels:\s+app: myapp/

Scenario: configMapGenerator appends a deterministic content hash #

only when kustomize version succeeds

Given #

  • Fixture file kustomization.yaml is created.

Inputs #

Fixture kustomization.yaml:

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
configMapGenerator:
- name: settings
  literals:
  - LOG_LEVEL=info

When #

kustomize build .

Then #

  • exit code is 0
  • stdout contains kind: ConfigMap, LOG_LEVEL: info
  • stdout matches /name: settings-[a-z0-9]+/

Scenario: disableNameSuffixHash drops the generated hash suffix #

only when kustomize version succeeds

Given #

  • Fixture file kustomization.yaml is created.

Inputs #

Fixture kustomization.yaml:

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
generatorOptions:
  disableNameSuffixHash: true
configMapGenerator:
- name: settings
  literals:
  - LOG_LEVEL=info

When #

kustomize build .

Then #

  • exit code is 0
  • stdout contains name: settings
  • stdout does not match /name: settings-[a-z0-9]+/

Scenario: secretGenerator base64-encodes values and never leaks the plaintext #

only when kustomize version succeeds

Given #

  • Fixture file kustomization.yaml is created.

Inputs #

Fixture kustomization.yaml:

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
secretGenerator:
- name: creds
  literals:
  - greeting=konnichiwa

When #

kustomize build .

Then #

  • exit code is 0
  • stdout contains kind: Secret, type: Opaque
  • stdout contains greeting: a29ubmljaGl3YQ==
  • stdout does not contain konnichiwa

Scenario: an overlay JSON6902-patches a base without editing it #

only when kustomize version succeeds

Given #

  • Fixture file base/deploy.yaml is created.
  • Fixture file base/kustomization.yaml is created.
  • Fixture file overlay/kustomization.yaml is created.

Inputs #

Fixture base/deploy.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
spec:
  replicas: 1
  template:
    spec:
      containers:
      - name: web
        image: nginx:1.0

Fixture base/kustomization.yaml:

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deploy.yaml

Fixture overlay/kustomization.yaml:

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../base
patches:
- target:
    kind: Deployment
    name: web
  patch: |-
    - op: replace
      path: /spec/replicas
      value: 5

When #

kustomize build overlay
kustomize build base

Then #

  • after kustomize build overlay:
    • exit code is 0
    • stdout contains replicas: 5
  • after kustomize build base:
    • exit code is 0
    • stdout contains replicas: 1

Scenario: a strategic-merge patch overrides only the fields it names #

only when kustomize version succeeds

Given #

  • Fixture file deploy.yaml is created.
  • Fixture file replicas-patch.yaml is created.
  • Fixture file kustomization.yaml is created.

Inputs #

Fixture deploy.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
spec:
  replicas: 1
  template:
    spec:
      containers:
      - name: web
        image: nginx:1.0

Fixture replicas-patch.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
spec:
  replicas: 4

Fixture kustomization.yaml:

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deploy.yaml
patches:
- path: replicas-patch.yaml

When #

kustomize build .

Then #

  • exit code is 0
  • stdout contains replicas: 4, image: nginx:1.0

Scenario: an empty resources list renders nothing #

only when kustomize version succeeds

Given #

  • Fixture file kustomization.yaml is created.

Inputs #

Fixture kustomization.yaml:

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources: []

When #

kustomize build .

Then #

  • exit code is 0
  • stdout is empty

Scenario: resource order does not change the rendered output #

only when kustomize version succeeds

Given #

  • Fixture file a/cm-a.yaml is created.
  • Fixture file a/cm-b.yaml is created.
  • Fixture file a/kustomization.yaml is created.
  • Fixture file b/cm-a.yaml is created.
  • Fixture file b/cm-b.yaml is created.
  • Fixture file b/kustomization.yaml is created.

Inputs #

Fixture a/cm-a.yaml:

apiVersion: v1
kind: ConfigMap
metadata:
  name: a
data:
  k: v

Fixture a/cm-b.yaml:

apiVersion: v1
kind: ConfigMap
metadata:
  name: b
data:
  k: v

Fixture a/kustomization.yaml:

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- cm-a.yaml
- cm-b.yaml

Fixture b/cm-a.yaml:

apiVersion: v1
kind: ConfigMap
metadata:
  name: a
data:
  k: v

Fixture b/cm-b.yaml:

apiVersion: v1
kind: ConfigMap
metadata:
  name: b
data:
  k: v

Fixture b/kustomization.yaml:

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- cm-b.yaml
- cm-a.yaml

When #

kustomize build a -o out-a.yaml
kustomize build b -o out-b.yaml
cmp out-a.yaml out-b.yaml

Then #

  • after kustomize build a -o out-a.yaml:
    • exit code is 0
  • after kustomize build b -o out-b.yaml:
    • exit code is 0
  • after cmp out-a.yaml out-b.yaml:
    • exit code is 0

Scenario: rendering is deterministic across repeated builds #

only when kustomize version succeeds

Given #

  • Fixture file kustomization.yaml is created.

Inputs #

Fixture kustomization.yaml:

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namePrefix: a-
configMapGenerator:
- name: c
  literals:
  - K=V

When #

kustomize build . -o first.yaml
kustomize build . -o second.yaml
cmp first.yaml second.yaml

Then #

  • after kustomize build . -o first.yaml:
    • exit code is 0
  • after kustomize build . -o second.yaml:
    • exit code is 0
  • after cmp first.yaml second.yaml:
    • exit code is 0

Scenario: building a directory without a kustomization fails cleanly #

only when kustomize version succeeds

Given #

  • Fixture file empty/.keep is created.

When #

kustomize build empty

Then #

  • exit code is 1
  • stdout is empty
  • stderr contains unable to find one of 'kustomization.yaml'

Scenario: a missing referenced resource is reported on stderr #

only when kustomize version succeeds

Given #

  • Fixture file kustomization.yaml is created.

Inputs #

Fixture kustomization.yaml:

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- missing.yaml

When #

kustomize build .

Then #

  • exit code is 1
  • stderr contains accumulating resources

Scenario: the load restrictor refuses to read a file outside the root #

only when kustomize version succeeds

Given #

  • Fixture file outside.yaml is created.
  • Fixture file root/kustomization.yaml is created.

Inputs #

Fixture outside.yaml:

apiVersion: v1
kind: ConfigMap
metadata:
  name: outside
data:
  k: v

Fixture root/kustomization.yaml:

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../outside.yaml

When #

kustomize build root

Then #

  • exit code is 1
  • stderr contains security