mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-05-17 18:25:26 +00:00
* chore: add test for multiple $patch: delete patches not panicking * fix: don't panic on multiple deletion SM patches
1769 lines
35 KiB
Go
1769 lines
35 KiB
Go
// Copyright 2019 The Kubernetes Authors.
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
package krusty_test
|
|
|
|
import (
|
|
"testing"
|
|
|
|
kusttest_test "sigs.k8s.io/kustomize/api/testutils/kusttest"
|
|
)
|
|
|
|
func TestPatchesInOneFile(t *testing.T) {
|
|
th := kusttest_test.MakeHarness(t)
|
|
th.WriteK("base", `
|
|
resources:
|
|
- namespace.yaml
|
|
- deployment-controller-manager.yaml
|
|
- deployment-audit-manager.yaml
|
|
`)
|
|
th.WriteF("base/namespace.yaml", `
|
|
apiVersion: v1
|
|
kind: Namespace
|
|
metadata:
|
|
labels:
|
|
control-plane: controller-manager
|
|
admission.gatekeeper.sh/ignore: no-self-managing
|
|
name: system
|
|
`)
|
|
th.WriteF("base/deployment-controller-manager.yaml", `
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: controller-manager
|
|
namespace: system
|
|
labels:
|
|
control-plane: controller-manager
|
|
gatekeeper.sh/operation: webhook
|
|
spec:
|
|
selector:
|
|
matchLabels:
|
|
control-plane: controller-manager
|
|
gatekeeper.sh/operation: webhook
|
|
replicas: 3
|
|
template:
|
|
metadata:
|
|
annotations:
|
|
container.seccomp.security.alpha.kubernetes.io/manager: runtime/default
|
|
labels:
|
|
control-plane: controller-manager
|
|
gatekeeper.sh/operation: webhook
|
|
spec:
|
|
containers:
|
|
- command:
|
|
- /manager
|
|
args:
|
|
- "--port=8443"
|
|
- "--logtostderr"
|
|
- "--exempt-namespace=gatekeeper-system"
|
|
- "--operation=webhook"
|
|
image: openpolicyagent/gatekeeper:v3.4.0
|
|
imagePullPolicy: Always
|
|
name: manager
|
|
terminationGracePeriodSeconds: 60
|
|
nodeSelector:
|
|
kubernetes.io/os: linux
|
|
priorityClassName: system-cluster-critical
|
|
`)
|
|
th.WriteF("base/deployment-audit-manager.yaml", `
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: audit
|
|
namespace: system
|
|
labels:
|
|
control-plane: audit-controller
|
|
gatekeeper.sh/operation: audit
|
|
spec:
|
|
selector:
|
|
matchLabels:
|
|
control-plane: audit-controller
|
|
gatekeeper.sh/operation: audit
|
|
replicas: 1
|
|
template:
|
|
metadata:
|
|
labels:
|
|
control-plane: audit-controller
|
|
gatekeeper.sh/operation: audit
|
|
annotations:
|
|
container.seccomp.security.alpha.kubernetes.io/manager: runtime/default
|
|
spec:
|
|
automountServiceAccountToken: true
|
|
containers:
|
|
- args:
|
|
- --operation=audit
|
|
- --operation=status
|
|
- --logtostderr
|
|
command:
|
|
- /manager
|
|
env:
|
|
- name: POD_NAMESPACE
|
|
valueFrom:
|
|
fieldRef:
|
|
apiVersion: v1
|
|
fieldPath: metadata.namespace
|
|
- name: POD_NAME
|
|
valueFrom:
|
|
fieldRef:
|
|
fieldPath: metadata.name
|
|
image: openpolicyagent/gatekeeper:v3.4.0
|
|
imagePullPolicy: Always
|
|
livenessProbe:
|
|
httpGet:
|
|
path: /healthz
|
|
port: 9090
|
|
name: manager
|
|
serviceAccountName: gatekeeper-admin
|
|
terminationGracePeriodSeconds: 60
|
|
nodeSelector:
|
|
kubernetes.io/os: linux
|
|
priorityClassName: system-cluster-critical
|
|
`)
|
|
const imagePatchAuditManager = `
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: audit
|
|
namespace: system
|
|
spec:
|
|
template:
|
|
spec:
|
|
containers:
|
|
- image: AUDIT_IMAGE
|
|
name: manager
|
|
args:
|
|
- --port=8443
|
|
- --logtostderr
|
|
- --emit-admission-events
|
|
- --exempt-namespace=gatekeeper-system
|
|
- --operation=webhook
|
|
- --disable-opa-builtin=http.send
|
|
`
|
|
const imagePatchControllerManager = `
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: controller-manager
|
|
namespace: system
|
|
spec:
|
|
template:
|
|
spec:
|
|
containers:
|
|
- image: CONTROLLER_IMAGE
|
|
name: manager
|
|
args:
|
|
- --emit-audit-events
|
|
- --operation=audit
|
|
- --operation=status
|
|
- --logtostderr
|
|
`
|
|
th.WriteF(
|
|
"overlay/image_patch_audit_manager.yaml",
|
|
imagePatchAuditManager)
|
|
th.WriteF(
|
|
"overlay/image_patch_controller_manager.yaml",
|
|
imagePatchControllerManager)
|
|
const expected = `
|
|
apiVersion: v1
|
|
kind: Namespace
|
|
metadata:
|
|
labels:
|
|
admission.gatekeeper.sh/ignore: no-self-managing
|
|
control-plane: controller-manager
|
|
name: system
|
|
---
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
labels:
|
|
control-plane: controller-manager
|
|
gatekeeper.sh/operation: webhook
|
|
name: controller-manager
|
|
namespace: system
|
|
spec:
|
|
replicas: 3
|
|
selector:
|
|
matchLabels:
|
|
control-plane: controller-manager
|
|
gatekeeper.sh/operation: webhook
|
|
template:
|
|
metadata:
|
|
annotations:
|
|
container.seccomp.security.alpha.kubernetes.io/manager: runtime/default
|
|
labels:
|
|
control-plane: controller-manager
|
|
gatekeeper.sh/operation: webhook
|
|
spec:
|
|
containers:
|
|
- args:
|
|
- --emit-audit-events
|
|
- --operation=audit
|
|
- --operation=status
|
|
- --logtostderr
|
|
command:
|
|
- /manager
|
|
image: CONTROLLER_IMAGE
|
|
imagePullPolicy: Always
|
|
name: manager
|
|
nodeSelector:
|
|
kubernetes.io/os: linux
|
|
priorityClassName: system-cluster-critical
|
|
terminationGracePeriodSeconds: 60
|
|
---
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
labels:
|
|
control-plane: audit-controller
|
|
gatekeeper.sh/operation: audit
|
|
name: audit
|
|
namespace: system
|
|
spec:
|
|
replicas: 1
|
|
selector:
|
|
matchLabels:
|
|
control-plane: audit-controller
|
|
gatekeeper.sh/operation: audit
|
|
template:
|
|
metadata:
|
|
annotations:
|
|
container.seccomp.security.alpha.kubernetes.io/manager: runtime/default
|
|
labels:
|
|
control-plane: audit-controller
|
|
gatekeeper.sh/operation: audit
|
|
spec:
|
|
automountServiceAccountToken: true
|
|
containers:
|
|
- args:
|
|
- --port=8443
|
|
- --logtostderr
|
|
- --emit-admission-events
|
|
- --exempt-namespace=gatekeeper-system
|
|
- --operation=webhook
|
|
- --disable-opa-builtin=http.send
|
|
command:
|
|
- /manager
|
|
env:
|
|
- name: POD_NAMESPACE
|
|
valueFrom:
|
|
fieldRef:
|
|
apiVersion: v1
|
|
fieldPath: metadata.namespace
|
|
- name: POD_NAME
|
|
valueFrom:
|
|
fieldRef:
|
|
fieldPath: metadata.name
|
|
image: AUDIT_IMAGE
|
|
imagePullPolicy: Always
|
|
livenessProbe:
|
|
httpGet:
|
|
path: /healthz
|
|
port: 9090
|
|
name: manager
|
|
nodeSelector:
|
|
kubernetes.io/os: linux
|
|
priorityClassName: system-cluster-critical
|
|
serviceAccountName: gatekeeper-admin
|
|
terminationGracePeriodSeconds: 60
|
|
`
|
|
// Technique 1: "patchesStrategicMerge:" field, two patch files.
|
|
th.WriteK("overlay", `
|
|
resources:
|
|
- ../base
|
|
patchesStrategicMerge:
|
|
- image_patch_controller_manager.yaml
|
|
- image_patch_audit_manager.yaml
|
|
`)
|
|
m := th.Run("overlay", th.MakeDefaultOptions())
|
|
th.AssertActualEqualsExpected(m, expected)
|
|
|
|
// Technique 2: "patches:" field, two patch files.
|
|
th.WriteK("overlay", `
|
|
resources:
|
|
- ../base
|
|
patches:
|
|
- path: image_patch_controller_manager.yaml
|
|
- path: image_patch_audit_manager.yaml
|
|
`)
|
|
m = th.Run("overlay", th.MakeDefaultOptions())
|
|
th.AssertActualEqualsExpected(m, expected)
|
|
|
|
// Technique 3: "patchesStrategicMerge:" field, one patch file.
|
|
th.WriteK("overlay", `
|
|
resources:
|
|
- ../base
|
|
patchesStrategicMerge:
|
|
- twoPatchesInOneFile.yaml
|
|
`)
|
|
th.WriteF(
|
|
"overlay/twoPatchesInOneFile.yaml",
|
|
imagePatchAuditManager+"\n---\n"+imagePatchControllerManager)
|
|
m = th.Run("overlay", th.MakeDefaultOptions())
|
|
th.AssertActualEqualsExpected(m, expected)
|
|
|
|
// Technique 4: "patches:" field, one patch file.
|
|
th.WriteK("overlay", `
|
|
resources:
|
|
- ../base
|
|
patches:
|
|
- path: twoPatchesInOneFile.yaml
|
|
`)
|
|
m = th.Run("overlay", th.MakeDefaultOptions())
|
|
th.AssertActualEqualsExpected(m, expected)
|
|
}
|
|
|
|
func TestRemoveEmptyDirWithNullFieldInSmp(t *testing.T) {
|
|
th := kusttest_test.MakeHarness(t)
|
|
th.WriteK(".", `
|
|
resources:
|
|
- deployment.yaml
|
|
patchesStrategicMerge:
|
|
- patch.yaml
|
|
`)
|
|
th.WriteF("deployment.yaml", `
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: nginx
|
|
spec:
|
|
template:
|
|
spec:
|
|
volumes:
|
|
- name: fancyDisk
|
|
emptyDir: {}
|
|
`)
|
|
th.WriteF("patch.yaml", `
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: nginx
|
|
spec:
|
|
template:
|
|
spec:
|
|
volumes:
|
|
- name: fancyDisk
|
|
emptyDir: null
|
|
`)
|
|
m := th.Run(".", th.MakeDefaultOptions())
|
|
th.AssertActualEqualsExpected(m, `
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: nginx
|
|
spec:
|
|
template:
|
|
spec:
|
|
volumes:
|
|
- name: fancyDisk
|
|
`)
|
|
}
|
|
|
|
func TestRemoveEmptyDirAddPersistentDisk(t *testing.T) {
|
|
th := kusttest_test.MakeHarness(t)
|
|
th.WriteK(".", `
|
|
resources:
|
|
- deployment.yaml
|
|
patchesStrategicMerge:
|
|
- patch.yaml
|
|
`)
|
|
th.WriteF("deployment.yaml", `
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: nginx
|
|
spec:
|
|
template:
|
|
spec:
|
|
volumes:
|
|
- name: fancyDisk
|
|
emptyDir: {}
|
|
`)
|
|
th.WriteF("patch.yaml", `
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: nginx
|
|
spec:
|
|
template:
|
|
spec:
|
|
volumes:
|
|
- name: fancyDisk
|
|
emptyDir: null
|
|
gcePersistentDisk:
|
|
pdName: fancyDisk
|
|
`)
|
|
m := th.Run(".", th.MakeDefaultOptions())
|
|
th.AssertActualEqualsExpected(m, `
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: nginx
|
|
spec:
|
|
template:
|
|
spec:
|
|
volumes:
|
|
- gcePersistentDisk:
|
|
pdName: fancyDisk
|
|
name: fancyDisk
|
|
`)
|
|
}
|
|
|
|
func TestVolumeRemoveEmptyDirInOverlay(t *testing.T) {
|
|
th := kusttest_test.MakeHarness(t)
|
|
th.WriteK("base", `
|
|
resources:
|
|
- deployment.yaml
|
|
configMapGenerator:
|
|
- name: baseCm
|
|
literals:
|
|
- foo=bar
|
|
`)
|
|
th.WriteF("base/deployment.yaml", `
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: nginx
|
|
spec:
|
|
template:
|
|
spec:
|
|
containers:
|
|
- name: nginx
|
|
image: nginx
|
|
volumeMounts:
|
|
- name: fancyDisk
|
|
mountPath: /tmp/ps
|
|
volumes:
|
|
- name: fancyDisk
|
|
emptyDir: {}
|
|
- configMap:
|
|
name: baseCm
|
|
name: baseCm
|
|
`)
|
|
m := th.Run("base", th.MakeDefaultOptions())
|
|
th.AssertActualEqualsExpected(m, `
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: nginx
|
|
spec:
|
|
template:
|
|
spec:
|
|
containers:
|
|
- image: nginx
|
|
name: nginx
|
|
volumeMounts:
|
|
- mountPath: /tmp/ps
|
|
name: fancyDisk
|
|
volumes:
|
|
- emptyDir: {}
|
|
name: fancyDisk
|
|
- configMap:
|
|
name: baseCm-798k5k7g9f
|
|
name: baseCm
|
|
---
|
|
apiVersion: v1
|
|
data:
|
|
foo: bar
|
|
kind: ConfigMap
|
|
metadata:
|
|
name: baseCm-798k5k7g9f
|
|
`)
|
|
|
|
th.WriteK("overlay", `
|
|
patchesStrategicMerge:
|
|
- patch.yaml
|
|
resources:
|
|
- ../base
|
|
configMapGenerator:
|
|
- name: overlayCm
|
|
literals:
|
|
- hello=world
|
|
`)
|
|
th.WriteF("overlay/patch.yaml", `
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: nginx
|
|
spec:
|
|
template:
|
|
spec:
|
|
volumes:
|
|
- name: fancyDisk
|
|
emptyDir: null
|
|
gcePersistentDisk:
|
|
pdName: fancyDisk
|
|
- configMap:
|
|
name: overlayCm
|
|
name: overlayCm
|
|
`)
|
|
m = th.Run("overlay", th.MakeDefaultOptions())
|
|
th.AssertActualEqualsExpected(m, `
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: nginx
|
|
spec:
|
|
template:
|
|
spec:
|
|
containers:
|
|
- image: nginx
|
|
name: nginx
|
|
volumeMounts:
|
|
- mountPath: /tmp/ps
|
|
name: fancyDisk
|
|
volumes:
|
|
- gcePersistentDisk:
|
|
pdName: fancyDisk
|
|
name: fancyDisk
|
|
- configMap:
|
|
name: overlayCm-dc6fm46dhm
|
|
name: overlayCm
|
|
- configMap:
|
|
name: baseCm-798k5k7g9f
|
|
name: baseCm
|
|
---
|
|
apiVersion: v1
|
|
data:
|
|
foo: bar
|
|
kind: ConfigMap
|
|
metadata:
|
|
name: baseCm-798k5k7g9f
|
|
---
|
|
apiVersion: v1
|
|
data:
|
|
hello: world
|
|
kind: ConfigMap
|
|
metadata:
|
|
name: overlayCm-dc6fm46dhm
|
|
`)
|
|
}
|
|
|
|
// Goal is to remove " emptyDir: {}" with a patch.
|
|
func TestRemoveEmptyDirWithPatchesAtSameLevel(t *testing.T) {
|
|
th := kusttest_test.MakeHarness(t)
|
|
th.WriteK("base", `
|
|
resources:
|
|
- deployment.yaml
|
|
`)
|
|
th.WriteF("base/deployment.yaml", `
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: nginx
|
|
spec:
|
|
template:
|
|
spec:
|
|
containers:
|
|
- name: nginx
|
|
image: nginx
|
|
- name: sidecar
|
|
image: sidecar:latest
|
|
volumes:
|
|
- name: nginx-persistent-storage
|
|
emptyDir: {}
|
|
`)
|
|
th.WriteK("overlay", `
|
|
patchesStrategicMerge:
|
|
- deployment-patch1.yaml
|
|
- deployment-patch2.yaml
|
|
resources:
|
|
- ../base
|
|
`)
|
|
th.WriteF("overlay/deployment-patch1.yaml", `
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: nginx
|
|
spec:
|
|
template:
|
|
spec:
|
|
volumes:
|
|
- name: nginx-persistent-storage
|
|
emptyDir: null
|
|
gcePersistentDisk:
|
|
pdName: nginx-persistent-storage
|
|
`)
|
|
th.WriteF("overlay/deployment-patch2.yaml", `
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: nginx
|
|
spec:
|
|
template:
|
|
spec:
|
|
containers:
|
|
- image: nginx
|
|
name: nginx
|
|
env:
|
|
- name: ANOTHERENV
|
|
value: FOO
|
|
volumes:
|
|
- name: nginx-persistent-storage
|
|
`)
|
|
opts := th.MakeDefaultOptions()
|
|
m := th.Run("overlay", opts)
|
|
th.AssertActualEqualsExpected(
|
|
m, `
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: nginx
|
|
spec:
|
|
template:
|
|
spec:
|
|
containers:
|
|
- env:
|
|
- name: ANOTHERENV
|
|
value: FOO
|
|
image: nginx
|
|
name: nginx
|
|
- image: sidecar:latest
|
|
name: sidecar
|
|
volumes:
|
|
- gcePersistentDisk:
|
|
pdName: nginx-persistent-storage
|
|
name: nginx-persistent-storage
|
|
`)
|
|
}
|
|
|
|
func TestSimpleMultiplePatches(t *testing.T) {
|
|
th := kusttest_test.MakeHarness(t)
|
|
th.WriteK("base", `
|
|
namePrefix: b-
|
|
commonLabels:
|
|
team: foo
|
|
resources:
|
|
- deployment.yaml
|
|
- service.yaml
|
|
configMapGenerator:
|
|
- name: configmap-in-base
|
|
literals:
|
|
- foo=bar
|
|
`)
|
|
th.WriteF("base/deployment.yaml", `
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: nginx
|
|
spec:
|
|
template:
|
|
spec:
|
|
containers:
|
|
- name: nginx
|
|
image: nginx
|
|
volumeMounts:
|
|
- name: nginx-persistent-storage
|
|
mountPath: /tmp/ps
|
|
- name: sidecar
|
|
image: sidecar:latest
|
|
volumes:
|
|
- configMap:
|
|
name: configmap-in-base
|
|
name: configmap-in-base
|
|
`)
|
|
th.WriteF("base/service.yaml", `
|
|
apiVersion: v1
|
|
kind: Service
|
|
metadata:
|
|
name: nginx
|
|
spec:
|
|
ports:
|
|
- port: 80
|
|
`)
|
|
th.WriteK("overlay", `
|
|
namePrefix: a-
|
|
commonLabels:
|
|
env: staging
|
|
patchesStrategicMerge:
|
|
- deployment-patch1.yaml
|
|
- deployment-patch2.yaml
|
|
resources:
|
|
- ../base
|
|
configMapGenerator:
|
|
- name: configmap-in-overlay
|
|
literals:
|
|
- hello=world
|
|
`)
|
|
th.WriteF("overlay/deployment-patch1.yaml", `
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: nginx
|
|
spec:
|
|
template:
|
|
spec:
|
|
containers:
|
|
- name: nginx
|
|
image: nginx:latest
|
|
env:
|
|
- name: ENVKEY
|
|
value: ENVVALUE
|
|
volumes:
|
|
- name: nginx-persistent-storage
|
|
gcePersistentDisk:
|
|
pdName: nginx-persistent-storage
|
|
- configMap:
|
|
name: configmap-in-overlay
|
|
name: configmap-in-overlay
|
|
`)
|
|
th.WriteF("overlay/deployment-patch2.yaml", `
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: nginx
|
|
spec:
|
|
template:
|
|
spec:
|
|
containers:
|
|
- name: nginx
|
|
env:
|
|
- name: ANOTHERENV
|
|
value: FOO
|
|
`)
|
|
m := th.Run("overlay", th.MakeDefaultOptions())
|
|
th.AssertActualEqualsExpected(m, `
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
labels:
|
|
env: staging
|
|
team: foo
|
|
name: a-b-nginx
|
|
spec:
|
|
selector:
|
|
matchLabels:
|
|
env: staging
|
|
team: foo
|
|
template:
|
|
metadata:
|
|
labels:
|
|
env: staging
|
|
team: foo
|
|
spec:
|
|
containers:
|
|
- env:
|
|
- name: ANOTHERENV
|
|
value: FOO
|
|
- name: ENVKEY
|
|
value: ENVVALUE
|
|
image: nginx:latest
|
|
name: nginx
|
|
volumeMounts:
|
|
- mountPath: /tmp/ps
|
|
name: nginx-persistent-storage
|
|
- image: sidecar:latest
|
|
name: sidecar
|
|
volumes:
|
|
- gcePersistentDisk:
|
|
pdName: nginx-persistent-storage
|
|
name: nginx-persistent-storage
|
|
- configMap:
|
|
name: a-configmap-in-overlay-dc6fm46dhm
|
|
name: configmap-in-overlay
|
|
- configMap:
|
|
name: a-b-configmap-in-base-798k5k7g9f
|
|
name: configmap-in-base
|
|
---
|
|
apiVersion: v1
|
|
kind: Service
|
|
metadata:
|
|
labels:
|
|
env: staging
|
|
team: foo
|
|
name: a-b-nginx
|
|
spec:
|
|
ports:
|
|
- port: 80
|
|
selector:
|
|
env: staging
|
|
team: foo
|
|
---
|
|
apiVersion: v1
|
|
data:
|
|
foo: bar
|
|
kind: ConfigMap
|
|
metadata:
|
|
labels:
|
|
env: staging
|
|
team: foo
|
|
name: a-b-configmap-in-base-798k5k7g9f
|
|
---
|
|
apiVersion: v1
|
|
data:
|
|
hello: world
|
|
kind: ConfigMap
|
|
metadata:
|
|
labels:
|
|
env: staging
|
|
name: a-configmap-in-overlay-dc6fm46dhm
|
|
`)
|
|
}
|
|
|
|
func makeCommonFilesForMultiplePatchTests(th kusttest_test.Harness) {
|
|
th.WriteK("base", `
|
|
namePrefix: team-foo-
|
|
commonLabels:
|
|
app: mynginx
|
|
org: example.com
|
|
team: foo
|
|
commonAnnotations:
|
|
note: This is a test annotation
|
|
resources:
|
|
- deployment.yaml
|
|
- service.yaml
|
|
configMapGenerator:
|
|
- name: configmap-in-base
|
|
literals:
|
|
- foo=bar
|
|
`)
|
|
th.WriteF("base/deployment.yaml", `
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: nginx
|
|
labels:
|
|
app: nginx
|
|
spec:
|
|
template:
|
|
metadata:
|
|
labels:
|
|
app: nginx
|
|
spec:
|
|
containers:
|
|
- name: nginx
|
|
image: nginx
|
|
volumeMounts:
|
|
- name: nginx-persistent-storage
|
|
mountPath: /tmp/ps
|
|
- name: sidecar
|
|
image: sidecar:latest
|
|
volumes:
|
|
- configMap:
|
|
name: configmap-in-base
|
|
name: configmap-in-base
|
|
`)
|
|
th.WriteF("base/service.yaml", `
|
|
apiVersion: v1
|
|
kind: Service
|
|
metadata:
|
|
name: nginx
|
|
labels:
|
|
app: nginx
|
|
spec:
|
|
ports:
|
|
- port: 80
|
|
selector:
|
|
app: nginx
|
|
`)
|
|
th.WriteK("overlay/staging", `
|
|
namePrefix: staging-
|
|
commonLabels:
|
|
env: staging
|
|
patchesStrategicMerge:
|
|
- deployment-patch1.yaml
|
|
- deployment-patch2.yaml
|
|
resources:
|
|
- ../../base
|
|
configMapGenerator:
|
|
- name: configmap-in-overlay
|
|
literals:
|
|
- hello=world
|
|
`)
|
|
}
|
|
|
|
func TestMultiplePatchesNoConflict(t *testing.T) {
|
|
th := kusttest_test.MakeHarness(t)
|
|
makeCommonFilesForMultiplePatchTests(th)
|
|
th.WriteF("overlay/staging/deployment-patch1.yaml", `
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: nginx
|
|
spec:
|
|
template:
|
|
spec:
|
|
containers:
|
|
- name: nginx
|
|
image: nginx:latest
|
|
env:
|
|
- name: ENVKEY
|
|
value: ENVVALUE
|
|
volumes:
|
|
- name: nginx-persistent-storage
|
|
gcePersistentDisk:
|
|
pdName: nginx-persistent-storage
|
|
- configMap:
|
|
name: configmap-in-overlay
|
|
name: configmap-in-overlay
|
|
`)
|
|
th.WriteF("overlay/staging/deployment-patch2.yaml", `
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: nginx
|
|
spec:
|
|
template:
|
|
spec:
|
|
containers:
|
|
- name: nginx
|
|
env:
|
|
- name: ANOTHERENV
|
|
value: FOO
|
|
`)
|
|
m := th.Run("overlay/staging", th.MakeDefaultOptions())
|
|
th.AssertActualEqualsExpected(m, `
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
annotations:
|
|
note: This is a test annotation
|
|
labels:
|
|
app: mynginx
|
|
env: staging
|
|
org: example.com
|
|
team: foo
|
|
name: staging-team-foo-nginx
|
|
spec:
|
|
selector:
|
|
matchLabels:
|
|
app: mynginx
|
|
env: staging
|
|
org: example.com
|
|
team: foo
|
|
template:
|
|
metadata:
|
|
annotations:
|
|
note: This is a test annotation
|
|
labels:
|
|
app: mynginx
|
|
env: staging
|
|
org: example.com
|
|
team: foo
|
|
spec:
|
|
containers:
|
|
- env:
|
|
- name: ANOTHERENV
|
|
value: FOO
|
|
- name: ENVKEY
|
|
value: ENVVALUE
|
|
image: nginx:latest
|
|
name: nginx
|
|
volumeMounts:
|
|
- mountPath: /tmp/ps
|
|
name: nginx-persistent-storage
|
|
- image: sidecar:latest
|
|
name: sidecar
|
|
volumes:
|
|
- gcePersistentDisk:
|
|
pdName: nginx-persistent-storage
|
|
name: nginx-persistent-storage
|
|
- configMap:
|
|
name: staging-configmap-in-overlay-dc6fm46dhm
|
|
name: configmap-in-overlay
|
|
- configMap:
|
|
name: staging-team-foo-configmap-in-base-798k5k7g9f
|
|
name: configmap-in-base
|
|
---
|
|
apiVersion: v1
|
|
kind: Service
|
|
metadata:
|
|
annotations:
|
|
note: This is a test annotation
|
|
labels:
|
|
app: mynginx
|
|
env: staging
|
|
org: example.com
|
|
team: foo
|
|
name: staging-team-foo-nginx
|
|
spec:
|
|
ports:
|
|
- port: 80
|
|
selector:
|
|
app: mynginx
|
|
env: staging
|
|
org: example.com
|
|
team: foo
|
|
---
|
|
apiVersion: v1
|
|
data:
|
|
foo: bar
|
|
kind: ConfigMap
|
|
metadata:
|
|
annotations:
|
|
note: This is a test annotation
|
|
labels:
|
|
app: mynginx
|
|
env: staging
|
|
org: example.com
|
|
team: foo
|
|
name: staging-team-foo-configmap-in-base-798k5k7g9f
|
|
---
|
|
apiVersion: v1
|
|
data:
|
|
hello: world
|
|
kind: ConfigMap
|
|
metadata:
|
|
labels:
|
|
env: staging
|
|
name: staging-configmap-in-overlay-dc6fm46dhm
|
|
`)
|
|
}
|
|
|
|
func TestNonCommutablePatches(t *testing.T) {
|
|
th := kusttest_test.MakeHarness(t)
|
|
makeCommonFilesForMultiplePatchTests(th)
|
|
th.WriteF("overlay/staging/deployment-patch1.yaml", `
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: nginx
|
|
spec:
|
|
template:
|
|
spec:
|
|
containers:
|
|
- name: nginx
|
|
env:
|
|
- name: ENABLE_FEATURE_FOO
|
|
value: TRUE
|
|
volumes:
|
|
- name: nginx-persistent-storage
|
|
gcePersistentDisk:
|
|
pdName: nginx-persistent-storage
|
|
- configMap:
|
|
name: configmap-in-overlay
|
|
name: configmap-in-overlay
|
|
`)
|
|
th.WriteF("overlay/staging/deployment-patch2.yaml", `
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: nginx
|
|
spec:
|
|
template:
|
|
spec:
|
|
containers:
|
|
- name: nginx
|
|
env:
|
|
- name: ENABLE_FEATURE_FOO
|
|
value: FALSE
|
|
`)
|
|
// kyaml doesn't try to detect conflicts in patches
|
|
// (so ENABLE_FEATURE_FOO FALSE wins).
|
|
m := th.Run("overlay/staging", th.MakeDefaultOptions())
|
|
th.AssertActualEqualsExpected(m, `
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
annotations:
|
|
note: This is a test annotation
|
|
labels:
|
|
app: mynginx
|
|
env: staging
|
|
org: example.com
|
|
team: foo
|
|
name: staging-team-foo-nginx
|
|
spec:
|
|
selector:
|
|
matchLabels:
|
|
app: mynginx
|
|
env: staging
|
|
org: example.com
|
|
team: foo
|
|
template:
|
|
metadata:
|
|
annotations:
|
|
note: This is a test annotation
|
|
labels:
|
|
app: mynginx
|
|
env: staging
|
|
org: example.com
|
|
team: foo
|
|
spec:
|
|
containers:
|
|
- env:
|
|
- name: ENABLE_FEATURE_FOO
|
|
value: false
|
|
image: nginx
|
|
name: nginx
|
|
volumeMounts:
|
|
- mountPath: /tmp/ps
|
|
name: nginx-persistent-storage
|
|
- image: sidecar:latest
|
|
name: sidecar
|
|
volumes:
|
|
- gcePersistentDisk:
|
|
pdName: nginx-persistent-storage
|
|
name: nginx-persistent-storage
|
|
- configMap:
|
|
name: staging-configmap-in-overlay-dc6fm46dhm
|
|
name: configmap-in-overlay
|
|
- configMap:
|
|
name: staging-team-foo-configmap-in-base-798k5k7g9f
|
|
name: configmap-in-base
|
|
---
|
|
apiVersion: v1
|
|
kind: Service
|
|
metadata:
|
|
annotations:
|
|
note: This is a test annotation
|
|
labels:
|
|
app: mynginx
|
|
env: staging
|
|
org: example.com
|
|
team: foo
|
|
name: staging-team-foo-nginx
|
|
spec:
|
|
ports:
|
|
- port: 80
|
|
selector:
|
|
app: mynginx
|
|
env: staging
|
|
org: example.com
|
|
team: foo
|
|
---
|
|
apiVersion: v1
|
|
data:
|
|
foo: bar
|
|
kind: ConfigMap
|
|
metadata:
|
|
annotations:
|
|
note: This is a test annotation
|
|
labels:
|
|
app: mynginx
|
|
env: staging
|
|
org: example.com
|
|
team: foo
|
|
name: staging-team-foo-configmap-in-base-798k5k7g9f
|
|
---
|
|
apiVersion: v1
|
|
data:
|
|
hello: world
|
|
kind: ConfigMap
|
|
metadata:
|
|
labels:
|
|
env: staging
|
|
name: staging-configmap-in-overlay-dc6fm46dhm
|
|
`)
|
|
}
|
|
|
|
func TestMultiplePatchesWithOnePatchDeleteDirective(t *testing.T) {
|
|
additivePatch := `apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: nginx
|
|
spec:
|
|
template:
|
|
spec:
|
|
containers:
|
|
- name: nginx
|
|
env:
|
|
- name: SOME_NAME
|
|
value: somevalue
|
|
`
|
|
deletePatch := `apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: nginx
|
|
spec:
|
|
template:
|
|
spec:
|
|
containers:
|
|
- $patch: delete
|
|
name: sidecar
|
|
`
|
|
cases := map[string]struct {
|
|
patch1 string
|
|
patch2 string
|
|
expectError bool
|
|
}{
|
|
"Patch with delete directive first": {
|
|
patch1: deletePatch,
|
|
patch2: additivePatch,
|
|
},
|
|
"Patch with delete directive second": {
|
|
patch1: additivePatch,
|
|
patch2: deletePatch,
|
|
},
|
|
}
|
|
for name := range cases {
|
|
c := cases[name]
|
|
t.Run(name, func(t *testing.T) {
|
|
th := kusttest_test.MakeHarness(t)
|
|
makeCommonFilesForMultiplePatchTests(th)
|
|
th.WriteF("overlay/staging/deployment-patch1.yaml", c.patch1)
|
|
th.WriteF("overlay/staging/deployment-patch2.yaml", c.patch2)
|
|
m := th.Run("overlay/staging", th.MakeDefaultOptions())
|
|
th.AssertActualEqualsExpected(m, `apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
annotations:
|
|
note: This is a test annotation
|
|
labels:
|
|
app: mynginx
|
|
env: staging
|
|
org: example.com
|
|
team: foo
|
|
name: staging-team-foo-nginx
|
|
spec:
|
|
selector:
|
|
matchLabels:
|
|
app: mynginx
|
|
env: staging
|
|
org: example.com
|
|
team: foo
|
|
template:
|
|
metadata:
|
|
annotations:
|
|
note: This is a test annotation
|
|
labels:
|
|
app: mynginx
|
|
env: staging
|
|
org: example.com
|
|
team: foo
|
|
spec:
|
|
containers:
|
|
- env:
|
|
- name: SOME_NAME
|
|
value: somevalue
|
|
image: nginx
|
|
name: nginx
|
|
volumeMounts:
|
|
- mountPath: /tmp/ps
|
|
name: nginx-persistent-storage
|
|
volumes:
|
|
- configMap:
|
|
name: staging-team-foo-configmap-in-base-798k5k7g9f
|
|
name: configmap-in-base
|
|
---
|
|
apiVersion: v1
|
|
kind: Service
|
|
metadata:
|
|
annotations:
|
|
note: This is a test annotation
|
|
labels:
|
|
app: mynginx
|
|
env: staging
|
|
org: example.com
|
|
team: foo
|
|
name: staging-team-foo-nginx
|
|
spec:
|
|
ports:
|
|
- port: 80
|
|
selector:
|
|
app: mynginx
|
|
env: staging
|
|
org: example.com
|
|
team: foo
|
|
---
|
|
apiVersion: v1
|
|
data:
|
|
foo: bar
|
|
kind: ConfigMap
|
|
metadata:
|
|
annotations:
|
|
note: This is a test annotation
|
|
labels:
|
|
app: mynginx
|
|
env: staging
|
|
org: example.com
|
|
team: foo
|
|
name: staging-team-foo-configmap-in-base-798k5k7g9f
|
|
---
|
|
apiVersion: v1
|
|
data:
|
|
hello: world
|
|
kind: ConfigMap
|
|
metadata:
|
|
labels:
|
|
env: staging
|
|
name: staging-configmap-in-overlay-dc6fm46dhm
|
|
`)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestSinglePatchWithMultiplePatchDeleteDirectives(t *testing.T) {
|
|
th := kusttest_test.MakeHarness(t)
|
|
makeCommonFilesForMultiplePatchTests(th)
|
|
th.WriteF("overlay/staging/deployment-patch1.yaml", `
|
|
$patch: delete
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: nginx
|
|
---
|
|
$patch: delete
|
|
apiVersion: v1
|
|
kind: Service
|
|
metadata:
|
|
name: nginx
|
|
`)
|
|
th.WriteF("overlay/staging/deployment-patch2.yaml", `
|
|
apiVersion: v1
|
|
kind: ConfigMap
|
|
metadata:
|
|
name: configmap-in-base
|
|
data:
|
|
foo2: bar2
|
|
`)
|
|
th.WriteK("overlay/staging", `
|
|
namePrefix: staging-
|
|
commonLabels:
|
|
env: staging
|
|
patches:
|
|
- path: deployment-patch1.yaml
|
|
- path: deployment-patch2.yaml
|
|
resources:
|
|
- ../../base
|
|
configMapGenerator:
|
|
- name: configmap-in-overlay
|
|
literals:
|
|
- hello=world
|
|
`)
|
|
m := th.Run("overlay/staging", th.MakeDefaultOptions())
|
|
th.AssertActualEqualsExpected(m, `
|
|
apiVersion: v1
|
|
data:
|
|
foo: bar
|
|
foo2: bar2
|
|
kind: ConfigMap
|
|
metadata:
|
|
annotations:
|
|
note: This is a test annotation
|
|
labels:
|
|
app: mynginx
|
|
env: staging
|
|
org: example.com
|
|
team: foo
|
|
name: staging-team-foo-configmap-in-base-8cmgkm9f44
|
|
---
|
|
apiVersion: v1
|
|
data:
|
|
hello: world
|
|
kind: ConfigMap
|
|
metadata:
|
|
labels:
|
|
env: staging
|
|
name: staging-configmap-in-overlay-dc6fm46dhm
|
|
`)
|
|
}
|
|
|
|
func TestMultiplePatchesBothWithPatchDeleteDirective(t *testing.T) {
|
|
th := kusttest_test.MakeHarness(t)
|
|
makeCommonFilesForMultiplePatchTests(th)
|
|
th.WriteF("overlay/staging/deployment-patch1.yaml", `
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: nginx
|
|
spec:
|
|
template:
|
|
spec:
|
|
containers:
|
|
- $patch: delete
|
|
name: sidecar
|
|
`)
|
|
th.WriteF("overlay/staging/deployment-patch2.yaml", `
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: nginx
|
|
spec:
|
|
template:
|
|
spec:
|
|
containers:
|
|
- $patch: delete
|
|
name: nginx
|
|
`)
|
|
// kyaml doesn't fail on conflicts in patches; both containers
|
|
// (nginx and sidecar) are deleted per this patching instruction.
|
|
m := th.Run("overlay/staging", th.MakeDefaultOptions())
|
|
th.AssertActualEqualsExpected(m, `
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
annotations:
|
|
note: This is a test annotation
|
|
labels:
|
|
app: mynginx
|
|
env: staging
|
|
org: example.com
|
|
team: foo
|
|
name: staging-team-foo-nginx
|
|
spec:
|
|
selector:
|
|
matchLabels:
|
|
app: mynginx
|
|
env: staging
|
|
org: example.com
|
|
team: foo
|
|
template:
|
|
metadata:
|
|
annotations:
|
|
note: This is a test annotation
|
|
labels:
|
|
app: mynginx
|
|
env: staging
|
|
org: example.com
|
|
team: foo
|
|
spec:
|
|
containers: []
|
|
volumes:
|
|
- configMap:
|
|
name: staging-team-foo-configmap-in-base-798k5k7g9f
|
|
name: configmap-in-base
|
|
---
|
|
apiVersion: v1
|
|
kind: Service
|
|
metadata:
|
|
annotations:
|
|
note: This is a test annotation
|
|
labels:
|
|
app: mynginx
|
|
env: staging
|
|
org: example.com
|
|
team: foo
|
|
name: staging-team-foo-nginx
|
|
spec:
|
|
ports:
|
|
- port: 80
|
|
selector:
|
|
app: mynginx
|
|
env: staging
|
|
org: example.com
|
|
team: foo
|
|
---
|
|
apiVersion: v1
|
|
data:
|
|
foo: bar
|
|
kind: ConfigMap
|
|
metadata:
|
|
annotations:
|
|
note: This is a test annotation
|
|
labels:
|
|
app: mynginx
|
|
env: staging
|
|
org: example.com
|
|
team: foo
|
|
name: staging-team-foo-configmap-in-base-798k5k7g9f
|
|
---
|
|
apiVersion: v1
|
|
data:
|
|
hello: world
|
|
kind: ConfigMap
|
|
metadata:
|
|
labels:
|
|
env: staging
|
|
name: staging-configmap-in-overlay-dc6fm46dhm
|
|
`)
|
|
}
|
|
|
|
// test for #3513
|
|
func TestSmpWithDifferentKeysOnDifferentPorts(t *testing.T) {
|
|
th := kusttest_test.MakeHarness(t)
|
|
th.WriteK(".", `
|
|
resources:
|
|
- resource.yaml
|
|
patches:
|
|
- path: patch.yaml
|
|
target:
|
|
kind: StatefulSet
|
|
name: myapp
|
|
`)
|
|
th.WriteF("resource.yaml", `
|
|
apiVersion: apps/v1
|
|
kind: StatefulSet
|
|
metadata:
|
|
name: myapp
|
|
spec:
|
|
template:
|
|
spec:
|
|
containers:
|
|
- name: consul
|
|
image: "dashicorp/consul:1.9.1"
|
|
ports:
|
|
- containerPort: 8500
|
|
name: http
|
|
- containerPort: 8501
|
|
name: https
|
|
- containerPort: 8301
|
|
protocol: "TCP"
|
|
name: serflan-tcp
|
|
- containerPort: 8301
|
|
protocol: "UDP"
|
|
name: serflan-udp
|
|
- containerPort: 8302
|
|
name: serfwan
|
|
- containerPort: 8300
|
|
name: server
|
|
- containerPort: 8600
|
|
name: dns-tcp
|
|
protocol: "TCP"
|
|
- containerPort: 8600
|
|
name: dns-udp
|
|
protocol: "UDP"`)
|
|
th.WriteF("patch.yaml", `
|
|
kind: StatefulSet
|
|
metadata:
|
|
name: myapp
|
|
labels:
|
|
test: label
|
|
`)
|
|
m := th.Run(".", th.MakeDefaultOptions())
|
|
th.AssertActualEqualsExpected(m, `
|
|
apiVersion: apps/v1
|
|
kind: StatefulSet
|
|
metadata:
|
|
labels:
|
|
test: label
|
|
name: myapp
|
|
spec:
|
|
template:
|
|
spec:
|
|
containers:
|
|
- image: dashicorp/consul:1.9.1
|
|
name: consul
|
|
ports:
|
|
- containerPort: 8500
|
|
name: http
|
|
- containerPort: 8501
|
|
name: https
|
|
- containerPort: 8301
|
|
name: serflan-tcp
|
|
protocol: TCP
|
|
- containerPort: 8301
|
|
name: serflan-udp
|
|
protocol: UDP
|
|
- containerPort: 8302
|
|
name: serfwan
|
|
- containerPort: 8300
|
|
name: server
|
|
- containerPort: 8600
|
|
name: dns-tcp
|
|
protocol: TCP
|
|
- containerPort: 8600
|
|
name: dns-udp
|
|
protocol: UDP
|
|
`)
|
|
}
|
|
|
|
// test for #3616
|
|
func TestSmpDeleteOnResource(t *testing.T) {
|
|
th := kusttest_test.MakeHarness(t)
|
|
th.WriteK(".", `
|
|
resources:
|
|
- workloads.yaml
|
|
patches:
|
|
- patch: |
|
|
apiVersion: monitoring.coreos.com/v1
|
|
kind: PrometheusRule
|
|
metadata:
|
|
name: rule1
|
|
$patch: delete
|
|
`)
|
|
th.WriteF("workloads.yaml", `
|
|
apiVersion: monitoring.coreos.com/v1
|
|
kind: PrometheusRule
|
|
metadata:
|
|
labels:
|
|
role: alert-rules
|
|
name: rule1
|
|
spec:
|
|
groups:
|
|
- name: rabbitmq.rules
|
|
---
|
|
apiVersion: monitoring.coreos.com/v1
|
|
kind: PrometheusRule
|
|
metadata:
|
|
labels:
|
|
role: alert-rules
|
|
name: rule2
|
|
spec:
|
|
groups:
|
|
- name: rabbitmq.rules
|
|
`)
|
|
m := th.Run(".", th.MakeDefaultOptions())
|
|
th.AssertActualEqualsExpected(m, `
|
|
apiVersion: monitoring.coreos.com/v1
|
|
kind: PrometheusRule
|
|
metadata:
|
|
labels:
|
|
role: alert-rules
|
|
name: rule2
|
|
spec:
|
|
groups:
|
|
- name: rabbitmq.rules
|
|
`)
|
|
}
|
|
|
|
// test for #3620
|
|
func TestPatchPortHasNoProtocol(t *testing.T) {
|
|
th := kusttest_test.MakeHarness(t)
|
|
th.WriteK(".", `
|
|
resources:
|
|
- service.yaml
|
|
patchesStrategicMerge:
|
|
- patch.yaml
|
|
`)
|
|
th.WriteF("service.yaml", `
|
|
apiVersion: v1
|
|
kind: Service
|
|
metadata:
|
|
name: web
|
|
spec:
|
|
ports:
|
|
- port: 30900
|
|
targetPort: 30900
|
|
protocol: TCP
|
|
type: NodePort
|
|
`)
|
|
th.WriteF("patch.yaml", `
|
|
apiVersion: v1
|
|
kind: Service
|
|
metadata:
|
|
name: web
|
|
labels:
|
|
service: web
|
|
spec:
|
|
ports:
|
|
- port: 30900
|
|
targetPort: 30900
|
|
selector:
|
|
service: web
|
|
`)
|
|
m := th.Run(".", th.MakeDefaultOptions())
|
|
th.AssertActualEqualsExpected(m, `
|
|
apiVersion: v1
|
|
kind: Service
|
|
metadata:
|
|
labels:
|
|
service: web
|
|
name: web
|
|
spec:
|
|
ports:
|
|
- port: 30900
|
|
protocol: TCP
|
|
targetPort: 30900
|
|
selector:
|
|
service: web
|
|
type: NodePort
|
|
`)
|
|
}
|
|
|
|
// test for #3620
|
|
func TestPatchAddNewServicePort(t *testing.T) {
|
|
th := kusttest_test.MakeHarness(t)
|
|
th.WriteK(".", `
|
|
resources:
|
|
- service.yaml
|
|
patchesStrategicMerge:
|
|
- patch.yaml
|
|
`)
|
|
th.WriteF("service.yaml", `
|
|
apiVersion: v1
|
|
kind: Service
|
|
metadata:
|
|
name: web
|
|
spec:
|
|
ports:
|
|
- port: 30900
|
|
targetPort: 30900
|
|
protocol: TCP
|
|
type: NodePort
|
|
`)
|
|
th.WriteF("patch.yaml", `
|
|
apiVersion: v1
|
|
kind: Service
|
|
metadata:
|
|
name: web
|
|
labels:
|
|
service: web
|
|
spec:
|
|
ports:
|
|
- port: 30901
|
|
targetPort: 30901
|
|
selector:
|
|
service: web
|
|
`)
|
|
m := th.Run(".", th.MakeDefaultOptions())
|
|
th.AssertActualEqualsExpected(m, `
|
|
apiVersion: v1
|
|
kind: Service
|
|
metadata:
|
|
labels:
|
|
service: web
|
|
name: web
|
|
spec:
|
|
ports:
|
|
- port: 30901
|
|
targetPort: 30901
|
|
- port: 30900
|
|
protocol: TCP
|
|
targetPort: 30900
|
|
selector:
|
|
service: web
|
|
type: NodePort
|
|
`)
|
|
}
|
|
|
|
// test for #4111
|
|
func TestPatchPreservesInternalAnnotations(t *testing.T) {
|
|
th := kusttest_test.MakeHarness(t)
|
|
th.WriteK(".", `
|
|
nameSuffix: -abc
|
|
resources:
|
|
- fluentd.yaml
|
|
patchesJson6902:
|
|
- path: patch.yaml
|
|
target:
|
|
name: fluentd-sa
|
|
kind: ServiceAccount
|
|
version: v1
|
|
`)
|
|
th.WriteF("fluentd.yaml", `
|
|
apiVersion: v1
|
|
kind: DaemonSet
|
|
metadata:
|
|
name: fluentd
|
|
spec:
|
|
template:
|
|
spec:
|
|
containers:
|
|
- image: fluentd:latest
|
|
name: fluentd
|
|
serviceAccountName: fluentd-sa
|
|
---
|
|
apiVersion: v1
|
|
kind: ServiceAccount
|
|
metadata:
|
|
name: fluentd-sa
|
|
`)
|
|
th.WriteF("patch.yaml", `
|
|
- op: add
|
|
path: /metadata/annotations
|
|
value:
|
|
note: this is a test annotation
|
|
`)
|
|
m := th.Run(".", th.MakeDefaultOptions())
|
|
th.AssertActualEqualsExpected(m, `
|
|
apiVersion: v1
|
|
kind: DaemonSet
|
|
metadata:
|
|
name: fluentd-abc
|
|
spec:
|
|
template:
|
|
spec:
|
|
containers:
|
|
- image: fluentd:latest
|
|
name: fluentd
|
|
serviceAccountName: fluentd-sa-abc
|
|
---
|
|
apiVersion: v1
|
|
kind: ServiceAccount
|
|
metadata:
|
|
annotations:
|
|
note: this is a test annotation
|
|
name: fluentd-sa-abc
|
|
`)
|
|
}
|