mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-05-18 09:22:03 +00:00
Signed-off-by: Ioannis Androulidakis <ioannis@arrikto.com> Signed-off-by: Alex Pyrgiotis <apyrgio@arrikto.com>
340 lines
7.3 KiB
Go
340 lines
7.3 KiB
Go
// Copyright 2019 The Kubernetes Authors.
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
package target_test
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
|
|
"sigs.k8s.io/kustomize/v3/pkg/kusttest"
|
|
)
|
|
|
|
// Base
|
|
// ----
|
|
const baseKustomization = `
|
|
resources:
|
|
- statefulset.yaml
|
|
`
|
|
|
|
const baseStatefulSet = `
|
|
apiVersion: apps/v1
|
|
kind: StatefulSet
|
|
metadata:
|
|
name: my-sts
|
|
spec:
|
|
serviceName: my-svc
|
|
selector:
|
|
matchLabels:
|
|
app: my-app
|
|
template:
|
|
metadata:
|
|
labels:
|
|
app: my-app
|
|
spec:
|
|
containers:
|
|
- name: app
|
|
image: my-image
|
|
volumeClaimTemplates:
|
|
- spec:
|
|
storageClassName: default
|
|
`
|
|
|
|
// Storage overlay
|
|
// ---------------
|
|
const storageKustomization = `
|
|
resources:
|
|
- ../base
|
|
patchesJson6902:
|
|
- target:
|
|
group: apps
|
|
version: v1
|
|
kind: StatefulSet
|
|
name: my-sts
|
|
path: sts-patch.json
|
|
`
|
|
|
|
const patchJsonPVCTemplate = `
|
|
[{"op": "replace", "path": "/spec/volumeClaimTemplates/0/spec/storageClassName", "value": "my-sc"}]
|
|
`
|
|
|
|
// Config overlay
|
|
// --------------
|
|
const configKustomization = `
|
|
resources:
|
|
- ../base
|
|
configMapGenerator:
|
|
- name: my-config
|
|
literals:
|
|
- MY_ENV=foo
|
|
generatorOptions:
|
|
disableNameSuffixHash: true
|
|
patchesStrategicMerge:
|
|
- sts-patch.yaml
|
|
`
|
|
|
|
const patchEnvFromConfig = `
|
|
apiVersion: apps/v1
|
|
kind: StatefulSet
|
|
metadata:
|
|
name: my-sts
|
|
spec:
|
|
template:
|
|
spec:
|
|
containers:
|
|
- name: app
|
|
envFrom:
|
|
- configMapRef:
|
|
name: my-config
|
|
`
|
|
|
|
// Tolerations overlay
|
|
// -------------------
|
|
const tolerationsKustomization = `
|
|
resources:
|
|
- ../base
|
|
patchesStrategicMerge:
|
|
- sts-patch.yaml
|
|
`
|
|
|
|
const patchTolerations = `
|
|
apiVersion: apps/v1
|
|
kind: StatefulSet
|
|
metadata:
|
|
name: my-sts
|
|
spec:
|
|
template:
|
|
spec:
|
|
tolerations:
|
|
- effect: NoExecute
|
|
key: node.kubernetes.io/not-ready
|
|
tolerationSeconds: 30
|
|
`
|
|
|
|
// HTTPS overlay
|
|
// -------------
|
|
const httpsKustomization = `
|
|
resources:
|
|
- ../base
|
|
- https-svc.yaml
|
|
patchesStrategicMerge:
|
|
- sts-patch.yaml
|
|
`
|
|
|
|
const patchService = `
|
|
apiVersion: apps/v1
|
|
kind: StatefulSet
|
|
metadata:
|
|
name: my-sts
|
|
spec:
|
|
serviceName: my-https-svc
|
|
`
|
|
|
|
const httpsService = `
|
|
apiVersion: v1
|
|
kind: Service
|
|
metadata:
|
|
name: my-https-svc
|
|
spec:
|
|
ports:
|
|
- port: 443
|
|
protocol: TCP
|
|
name: https
|
|
selector:
|
|
app: my-app
|
|
`
|
|
|
|
func writeStatefulSetBase(th *kusttest_test.KustTestHarness) {
|
|
th.WriteK("/app/base", baseKustomization)
|
|
th.WriteF("/app/base/statefulset.yaml", baseStatefulSet)
|
|
}
|
|
|
|
func writeHTTPSOverlay(th *kusttest_test.KustTestHarness) {
|
|
th.WriteK("/app/https", httpsKustomization)
|
|
th.WriteF("/app/https/https-svc.yaml", httpsService)
|
|
th.WriteF("/app/https/sts-patch.yaml", patchService)
|
|
}
|
|
|
|
func writeConfigOverlay(th *kusttest_test.KustTestHarness) {
|
|
th.WriteK("/app/config", configKustomization)
|
|
th.WriteF("/app/config/sts-patch.yaml", patchEnvFromConfig)
|
|
}
|
|
|
|
func writeTolerationsOverlay(th *kusttest_test.KustTestHarness) {
|
|
th.WriteK("/app/tolerations", tolerationsKustomization)
|
|
th.WriteF("/app/tolerations/sts-patch.yaml", patchTolerations)
|
|
}
|
|
|
|
func writeStorageOverlay(th *kusttest_test.KustTestHarness) {
|
|
th.WriteK("/app/storage", storageKustomization)
|
|
th.WriteF("/app/storage/sts-patch.json", patchJsonPVCTemplate)
|
|
}
|
|
|
|
// Here's a complex kustomization scenario that combines multiple overlays
|
|
// on a common base:
|
|
//
|
|
// dev prod
|
|
// | |
|
|
// | |
|
|
// + ------- + + ------------ + ------------- +
|
|
// | | | | |
|
|
// | | | | |
|
|
// v | v v v
|
|
// storage + -----> config tolerations https
|
|
// | | | |
|
|
// | | | |
|
|
// | + --- + + --- + |
|
|
// | | | |
|
|
// | v v |
|
|
// + -----------------------> base <------------------ +
|
|
//
|
|
// The base resource is a statefulset. Each intermediate overlay manages or
|
|
// generates new resources and patches different aspects of the same base
|
|
// resource, without using any of the `namePrefix`, `nameSuffix` or `namespace`
|
|
// kustomization keywords.
|
|
//
|
|
// Intermediate overlays:
|
|
// - storage: Changes the storage class of the stateful set with a JSON patch.
|
|
// - config: Generates a config map and adds a field as an environment
|
|
// variable.
|
|
// - tolerations: Adds a new tolerations field in the spec.
|
|
// - https: Adds a new service resource and changes the service name in the
|
|
// stateful set.
|
|
//
|
|
// Top overlays:
|
|
// - dev: Combines the storage and config intermediate overlays.
|
|
// - prod: Combines the config, tolerations and https intermediate overlays.
|
|
|
|
func TestComplexComposition_Dev_Failure(t *testing.T) {
|
|
th := kusttest_test.NewKustTestHarness(t, "/app/dev")
|
|
writeStatefulSetBase(th)
|
|
writeStorageOverlay(th)
|
|
writeConfigOverlay(th)
|
|
writeTolerationsOverlay(th)
|
|
writeHTTPSOverlay(th)
|
|
|
|
th.WriteK("/app/dev", `
|
|
resources:
|
|
- ../storage
|
|
- ../config
|
|
`)
|
|
|
|
_, err := th.MakeKustTarget().MakeCustomizedResMap()
|
|
if err == nil {
|
|
t.Fatalf("Expected resource accumulation error")
|
|
}
|
|
if !strings.Contains(
|
|
err.Error(), "already registered id: apps_v1_StatefulSet|~X|my-sts") {
|
|
t.Fatalf("Unexpected err: %v", err)
|
|
}
|
|
|
|
// Expected Output
|
|
const devMergeResult = `
|
|
apiVersion: v1
|
|
data:
|
|
MY_ENV: foo
|
|
kind: ConfigMap
|
|
metadata:
|
|
name: my-config
|
|
---
|
|
apiVersion: apps/v1
|
|
kind: StatefulSet
|
|
metadata:
|
|
name: my-sts
|
|
spec:
|
|
serviceName: my-svc
|
|
selector:
|
|
matchLabels:
|
|
app: my-app
|
|
template:
|
|
metadata:
|
|
labels:
|
|
app: my-app
|
|
spec:
|
|
containers:
|
|
- name: app
|
|
image: my-image
|
|
envFrom:
|
|
- configMapRef:
|
|
name: my-config
|
|
volumeClaimTemplates:
|
|
- spec:
|
|
storageClassName: my-sc
|
|
`
|
|
}
|
|
|
|
func TestComplexComposition_Prod_Failure(t *testing.T) {
|
|
th := kusttest_test.NewKustTestHarness(t, "/app/prod")
|
|
writeStatefulSetBase(th)
|
|
writeStorageOverlay(th)
|
|
writeConfigOverlay(th)
|
|
writeTolerationsOverlay(th)
|
|
writeHTTPSOverlay(th)
|
|
|
|
th.WriteK("/app/prod", `
|
|
resources:
|
|
- ../config
|
|
- ../tolerations
|
|
- ../https
|
|
`)
|
|
|
|
_, err := th.MakeKustTarget().MakeCustomizedResMap()
|
|
if err == nil {
|
|
t.Fatalf("Expected resource accumulation error")
|
|
}
|
|
if !strings.Contains(
|
|
err.Error(), "already registered id: apps_v1_StatefulSet|~X|my-sts") {
|
|
t.Fatalf("Unexpected err: %v", err)
|
|
}
|
|
|
|
// Expected Output
|
|
const prodMergeResult = `
|
|
apiVersion: v1
|
|
data:
|
|
MY_ENV: foo
|
|
kind: ConfigMap
|
|
metadata:
|
|
name: my-config
|
|
---
|
|
apiVersion: v1
|
|
kind: Service
|
|
metadata:
|
|
name: my-https-svc
|
|
spec:
|
|
ports:
|
|
- name: https
|
|
port: 443
|
|
protocol: TCP
|
|
selector:
|
|
app: my-app
|
|
---
|
|
apiVersion: apps/v1
|
|
kind: StatefulSet
|
|
metadata:
|
|
name: my-sts
|
|
spec:
|
|
serviceName: my-https-svc
|
|
selector:
|
|
matchLabels:
|
|
app: my-app
|
|
template:
|
|
metadata:
|
|
labels:
|
|
app: my-app
|
|
spec:
|
|
containers:
|
|
- image: my-image
|
|
envFrom:
|
|
- configMapRef:
|
|
name: my-config
|
|
name: app
|
|
tolerations:
|
|
- effect: NoExecute
|
|
key: node.kubernetes.io/not-ready
|
|
tolerationSeconds: 30
|
|
volumeClaimTemplates:
|
|
- spec:
|
|
storageClassName: default
|
|
`
|
|
}
|