mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-06-13 10:00:56 +00:00
Merge pull request #1297 from arrikto/feature-complex-overlay-composition
Add complex overlay composition test
This commit is contained in:
339
pkg/target/complexcomposition_test.go
Normal file
339
pkg/target/complexcomposition_test.go
Normal file
@@ -0,0 +1,339 @@
|
||||
// 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
|
||||
`
|
||||
}
|
||||
Reference in New Issue
Block a user