mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-05-17 18:25:26 +00:00
Assert keeps going after failure, but require immediately fails the tests, making it easier to find the output related to the test failure, rather than having to comb through a bunch of subsequent assertion failures. For equality tests, we may or may not want to continue, but for error checks we almost always want to immediately fail the test. Exceptions can be changed as-needed.
1605 lines
39 KiB
Go
1605 lines
39 KiB
Go
// Copyright 2022 The Kubernetes Authors.
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
package localizer_test
|
|
|
|
import (
|
|
"fmt"
|
|
"io/fs"
|
|
"path/filepath"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
. "sigs.k8s.io/kustomize/api/internal/localizer"
|
|
"sigs.k8s.io/kustomize/kyaml/filesys"
|
|
)
|
|
|
|
const (
|
|
podConfiguration = `apiVersion: v1
|
|
kind: Pod
|
|
metadata:
|
|
name: pod
|
|
spec:
|
|
containers:
|
|
- name: nginx
|
|
image: nginx:1.14.2
|
|
ports:
|
|
- containerPort: 80`
|
|
|
|
replacementTransformerWithPath = `apiVersion: builtin
|
|
kind: ReplacementTransformer
|
|
metadata:
|
|
name: replacement
|
|
replacements:
|
|
- path: replacement.yaml
|
|
- source:
|
|
fieldPath: metadata.[name=my-pod]
|
|
group: apps
|
|
namespace: test
|
|
version: v1
|
|
targets:
|
|
- fieldPaths:
|
|
- spec.containers.0.name
|
|
select:
|
|
name: another-pod
|
|
`
|
|
|
|
replacements = `
|
|
- source:
|
|
name: src
|
|
fieldPath: path
|
|
options:
|
|
delimiter: '='
|
|
index: 1
|
|
targets:
|
|
- select:
|
|
kind: Pod
|
|
reject:
|
|
version: v1
|
|
fieldPaths:
|
|
- metadata.annotations.config\.kubernetes\.io/local-config
|
|
- sequence.*
|
|
- source:
|
|
kind: Deployment
|
|
fieldPath: sequence.-
|
|
targets:
|
|
- select:
|
|
namespace: my
|
|
fieldPaths:
|
|
- path
|
|
options:
|
|
delimiter: '='
|
|
index: 0
|
|
`
|
|
|
|
valuesFile = `minecraftServer:
|
|
difficulty: peaceful
|
|
`
|
|
)
|
|
|
|
func makeMemoryFs(t *testing.T) filesys.FileSystem {
|
|
t.Helper()
|
|
req := require.New(t)
|
|
|
|
fSys := filesys.MakeFsInMemory()
|
|
req.NoError(fSys.MkdirAll("/a/b"))
|
|
req.NoError(fSys.WriteFile("/a/pod.yaml", []byte(podConfiguration)))
|
|
|
|
dirChain := "/alpha/beta/gamma/delta"
|
|
req.NoError(fSys.MkdirAll(dirChain))
|
|
req.NoError(fSys.WriteFile(filepath.Join(dirChain, "deployment.yaml"), []byte("deployment configuration")))
|
|
req.NoError(fSys.Mkdir("/alpha/beta/say"))
|
|
return fSys
|
|
}
|
|
|
|
func addFiles(t *testing.T, fSys filesys.FileSystem, parentDir string, files map[string]string) {
|
|
t.Helper()
|
|
|
|
// in-memory file system makes all necessary dirs when writing files
|
|
for file, content := range files {
|
|
require.NoError(t, fSys.WriteFile(filepath.Join(parentDir, file), []byte(content)))
|
|
}
|
|
}
|
|
|
|
func checkRun(t *testing.T, fSys filesys.FileSystem, target, scope, dst string) {
|
|
t.Helper()
|
|
|
|
actualDst, err := Run(target, scope, dst, fSys)
|
|
require.NoError(t, err)
|
|
require.Equal(t, dst, actualDst)
|
|
}
|
|
|
|
func makeFileSystems(t *testing.T, target string, files map[string]string) (expected filesys.FileSystem, actual filesys.FileSystem) {
|
|
t.Helper()
|
|
|
|
copies := make([]filesys.FileSystem, 2)
|
|
for i := range copies {
|
|
copies[i] = makeMemoryFs(t)
|
|
addFiles(t, copies[i], target, files)
|
|
}
|
|
return copies[0], copies[1]
|
|
}
|
|
|
|
func checkFSys(t *testing.T, fSysExpected filesys.FileSystem, fSysActual filesys.FileSystem) {
|
|
t.Helper()
|
|
|
|
assert.Equal(t, fSysExpected, fSysActual)
|
|
if t.Failed() {
|
|
reportFSysDiff(t, fSysExpected, fSysActual)
|
|
}
|
|
}
|
|
|
|
func reportFSysDiff(t *testing.T, fSysExpected filesys.FileSystem, fSysActual filesys.FileSystem) {
|
|
t.Helper()
|
|
|
|
visited := make(map[string]struct{})
|
|
err := fSysActual.Walk("/", func(path string, info fs.FileInfo, err error) error {
|
|
require.NoError(t, err)
|
|
visited[path] = struct{}{}
|
|
|
|
if info.IsDir() {
|
|
assert.Truef(t, fSysExpected.IsDir(path), "unexpected directory %q", path)
|
|
} else {
|
|
actualContent, readErr := fSysActual.ReadFile(path)
|
|
require.NoError(t, readErr)
|
|
expectedContent, findErr := fSysExpected.ReadFile(path)
|
|
require.NoErrorf(t, findErr, "unexpected file %q", path)
|
|
if findErr == nil {
|
|
assert.Equal(t, string(expectedContent), string(actualContent))
|
|
}
|
|
}
|
|
return nil
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
err = fSysExpected.Walk("/", func(path string, info fs.FileInfo, err error) error {
|
|
require.NoError(t, err)
|
|
|
|
_, exists := visited[path]
|
|
assert.Truef(t, exists, "expected path %q not found", path)
|
|
return nil
|
|
})
|
|
require.NoError(t, err)
|
|
}
|
|
|
|
func checkLocalizeInTargetSuccess(t *testing.T, files map[string]string) {
|
|
t.Helper()
|
|
|
|
fSys := makeMemoryFs(t)
|
|
addFiles(t, fSys, "/a", files)
|
|
|
|
checkRun(t, fSys, "/a", "/", "/dst")
|
|
fSysExpected := makeMemoryFs(t)
|
|
addFiles(t, fSysExpected, "/a", files)
|
|
addFiles(t, fSysExpected, "/dst/a", files)
|
|
checkFSys(t, fSysExpected, fSys)
|
|
}
|
|
|
|
func TestTargetIsScope(t *testing.T) {
|
|
kustomization := map[string]string{
|
|
"kustomization.yaml": `apiVersion: kustomize.config.k8s.io/v1beta1
|
|
kind: Kustomization
|
|
namePrefix: my-
|
|
`,
|
|
}
|
|
fSysExpected, fSysActual := makeFileSystems(t, "/a", kustomization)
|
|
|
|
checkRun(t, fSysActual, "/a", "/a", "/a/b/dst")
|
|
addFiles(t, fSysExpected, "/a/b/dst", kustomization)
|
|
checkFSys(t, fSysExpected, fSysActual)
|
|
}
|
|
|
|
func TestTargetNestedInScope(t *testing.T) {
|
|
kustomization := map[string]string{
|
|
"kustomization.yaml": `apiVersion: kustomize.config.k8s.io/v1beta1
|
|
kind: Kustomization
|
|
patches:
|
|
- patch: |-
|
|
- op: replace
|
|
path: /some/existing/path
|
|
value: new value
|
|
target:
|
|
kind: Deployment
|
|
labelSelector: env=dev
|
|
`,
|
|
}
|
|
fSysExpected, fSysActual := makeFileSystems(t, "/a/b", kustomization)
|
|
|
|
checkRun(t, fSysActual, "/a/b", "/", "/a/b/dst")
|
|
addFiles(t, fSysExpected, "/a/b/dst/a/b", kustomization)
|
|
checkFSys(t, fSysExpected, fSysActual)
|
|
}
|
|
|
|
func TestLoadKustomizationName(t *testing.T) {
|
|
kustomization := map[string]string{
|
|
"Kustomization": `apiVersion: kustomize.config.k8s.io/v1beta1
|
|
kind: Kustomization
|
|
labels:
|
|
- pairs:
|
|
label-one: value-one
|
|
label-two: value-two
|
|
`,
|
|
}
|
|
checkLocalizeInTargetSuccess(t, kustomization)
|
|
}
|
|
|
|
func TestLoadGVKNN(t *testing.T) {
|
|
for name, kustomization := range map[string]string{
|
|
"missing": `namePrefix: my-
|
|
`,
|
|
"wrong": `kind: NotChecked
|
|
`,
|
|
} {
|
|
t.Run(name, func(t *testing.T) {
|
|
files := map[string]string{
|
|
"kustomization.yaml": kustomization,
|
|
}
|
|
checkLocalizeInTargetSuccess(t, files)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestLoadLegacyFields(t *testing.T) {
|
|
kustomization := map[string]string{
|
|
"kustomization.yaml": `apiVersion: kustomize.config.k8s.io/v1beta1
|
|
commonLabels:
|
|
app: bingo
|
|
imageTags:
|
|
- name: postgres
|
|
newName: my-registry/my-postgres
|
|
newTag: v1
|
|
kind: Kustomization
|
|
`,
|
|
}
|
|
checkLocalizeInTargetSuccess(t, kustomization)
|
|
}
|
|
|
|
func TestLoadUnknownKustFields(t *testing.T) {
|
|
fSysExpected, fSysTest := makeFileSystems(t, "/a", map[string]string{
|
|
"kustomization.yaml": `namePrefix: valid
|
|
suffix: invalid`,
|
|
})
|
|
|
|
_, err := Run("/a", "", "", fSysTest)
|
|
require.EqualError(t, err,
|
|
`unable to localize target "/a": invalid Kustomization: json: unknown field "suffix"`)
|
|
|
|
checkFSys(t, fSysExpected, fSysTest)
|
|
}
|
|
|
|
func TestLocalizeFileName(t *testing.T) {
|
|
for name, path := range map[string]string{
|
|
"nested_directories": "a/b/c/d/patch.yaml",
|
|
"localize_dir_name_when_no_remote": LocalizeDir,
|
|
"in_localize_dir_name_when_no_remote": fmt.Sprintf("%s/patch.yaml", LocalizeDir),
|
|
"no_file_extension": "patch",
|
|
"kustomization_name": "a/kustomization.yaml",
|
|
} {
|
|
t.Run(name, func(t *testing.T) {
|
|
kustAndPatch := map[string]string{
|
|
"kustomization.yaml": fmt.Sprintf(`apiVersion: kustomize.config.k8s.io/v1beta1
|
|
kind: Kustomization
|
|
patches:
|
|
- path: %s
|
|
`, path),
|
|
path: podConfiguration,
|
|
}
|
|
checkLocalizeInTargetSuccess(t, kustAndPatch)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestLocalizeFileCleaned(t *testing.T) {
|
|
kustAndPatch := map[string]string{
|
|
"kustomization.yaml": `apiVersion: kustomize.config.k8s.io/v1beta1
|
|
kind: Kustomization
|
|
patches:
|
|
- path: ../gamma/../../../alpha/beta/./gamma/patch.yaml
|
|
`,
|
|
"patch.yaml": podConfiguration,
|
|
}
|
|
expected, actual := makeFileSystems(t, "/alpha/beta/gamma", kustAndPatch)
|
|
|
|
checkRun(t, actual, "/alpha/beta/gamma", "/", "/localized-gamma")
|
|
addFiles(t, expected, "/localized-gamma/alpha/beta/gamma", map[string]string{
|
|
"kustomization.yaml": `apiVersion: kustomize.config.k8s.io/v1beta1
|
|
kind: Kustomization
|
|
patches:
|
|
- path: patch.yaml
|
|
`,
|
|
"patch.yaml": podConfiguration,
|
|
})
|
|
checkFSys(t, expected, actual)
|
|
}
|
|
|
|
func TestLocalizeUnreferencedIgnored(t *testing.T) {
|
|
targetAndUnreferenced := map[string]string{
|
|
"kustomization.yaml": `apiVersion: kustomize.config.k8s.io/v1beta1
|
|
configMapGenerator:
|
|
- envs:
|
|
- env
|
|
name: referenced-file
|
|
kind: Kustomization
|
|
`,
|
|
"env": "APPLE=orange",
|
|
"env.properties": "USERNAME=password",
|
|
"dir/resource.yaml": podConfiguration,
|
|
}
|
|
expected, actual := makeFileSystems(t, "/alpha/beta", targetAndUnreferenced)
|
|
|
|
checkRun(t, actual, "/alpha/beta", "/alpha", "/beta")
|
|
addFiles(t, expected, "/beta/beta", map[string]string{
|
|
"kustomization.yaml": targetAndUnreferenced["kustomization.yaml"],
|
|
"env": targetAndUnreferenced["env"],
|
|
})
|
|
checkFSys(t, expected, actual)
|
|
}
|
|
|
|
func TestLocalizePatches(t *testing.T) {
|
|
kustAndPatch := map[string]string{
|
|
"kustomization.yaml": `apiVersion: kustomize.config.k8s.io/v1beta1
|
|
kind: Kustomization
|
|
patches:
|
|
- patch: |-
|
|
apiVersion: v1
|
|
kind: Deployment
|
|
metadata:
|
|
labels:
|
|
app.kubernetes.io/version: 1.21.0
|
|
name: dummy-app
|
|
target:
|
|
labelSelector: app.kubernetes.io/name=nginx
|
|
- options:
|
|
allowNameChange: true
|
|
path: patch.yaml
|
|
`,
|
|
"patch.yaml": podConfiguration,
|
|
}
|
|
checkLocalizeInTargetSuccess(t, kustAndPatch)
|
|
}
|
|
|
|
func TestLocalizeOpenAPI(t *testing.T) {
|
|
type testCase struct {
|
|
name string
|
|
files map[string]string
|
|
}
|
|
for _, test := range []testCase{
|
|
{
|
|
name: "no_path",
|
|
files: map[string]string{
|
|
"kustomization.yaml": `apiVersion: kustomize.config.k8s.io/v1beta1
|
|
kind: Kustomization
|
|
openapi:
|
|
version: v1.20.4
|
|
`,
|
|
},
|
|
},
|
|
{
|
|
name: "path",
|
|
files: map[string]string{
|
|
"kustomization.yaml": `apiVersion: kustomize.config.k8s.io/v1beta1
|
|
kind: Kustomization
|
|
openapi:
|
|
path: openapi.json
|
|
`,
|
|
"openapi.json": `{
|
|
"definitions": {
|
|
"io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta": {
|
|
"properties": {
|
|
"name": {
|
|
"type": "string"
|
|
}
|
|
},
|
|
"type": "object"
|
|
}
|
|
}
|
|
}`,
|
|
},
|
|
},
|
|
} {
|
|
t.Run(test.name, func(t *testing.T) {
|
|
checkLocalizeInTargetSuccess(t, test.files)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestLocalizeConfigurations(t *testing.T) {
|
|
kustAndConfigs := map[string]string{
|
|
"kustomization.yaml": `apiVersion: kustomize.config.k8s.io/v1beta1
|
|
configurations:
|
|
- commonLabels.yaml
|
|
- namePrefix.yaml
|
|
kind: Kustomization
|
|
`,
|
|
"commonLabels.yaml": `commonLabels:
|
|
- path: new/path
|
|
create: true`,
|
|
"namePrefix.yaml": `namePrefix:
|
|
- version: v1
|
|
path: metadata/name
|
|
- group: custom
|
|
path: metadata/name`,
|
|
}
|
|
checkLocalizeInTargetSuccess(t, kustAndConfigs)
|
|
}
|
|
|
|
func TestLocalizeCrds(t *testing.T) {
|
|
kustAndCrds := map[string]string{
|
|
"kustomization.yaml": `apiVersion: kustomize.config.k8s.io/v1beta1
|
|
crds:
|
|
- crd1.yaml
|
|
- crd2.yaml
|
|
kind: Kustomization
|
|
`,
|
|
"crd1.yaml": `apiVersion: apiextensions.k8s.io/v1
|
|
kind: CustomResourceDefinition
|
|
metadata:
|
|
name: controller.stable.example.com`,
|
|
"crd2.yaml": `apiVersion: apiextensions.k8s.io/v1
|
|
kind: CustomResourceDefinition
|
|
metadata:
|
|
name: crontabs.stable.example.com
|
|
scope: Cluster`,
|
|
}
|
|
checkLocalizeInTargetSuccess(t, kustAndCrds)
|
|
}
|
|
|
|
func TestLocalizePatchesJson(t *testing.T) {
|
|
kustAndPatches := map[string]string{
|
|
"kustomization.yaml": `apiVersion: kustomize.config.k8s.io/v1beta1
|
|
kind: Kustomization
|
|
patchesJson6902:
|
|
- path: patch.yaml
|
|
target:
|
|
annotationSelector: zone=west
|
|
name: pod
|
|
version: v1
|
|
- patch: '[{"op": "add", "path": "/new/path", "value": "value"}]'
|
|
target:
|
|
group: apps
|
|
kind: Pod
|
|
- path: patch.json
|
|
target:
|
|
namespace: my
|
|
`,
|
|
"patch.yaml": `- op: add
|
|
path: /some/new/path
|
|
value: value
|
|
- op: replace
|
|
path: /some/existing/path
|
|
value: new value`,
|
|
"patch.json": ` [
|
|
{"op": "copy", "from": "/here", "path": "/there"},
|
|
{"op": "remove", "path": "/some/existing/path"},
|
|
]`,
|
|
}
|
|
checkLocalizeInTargetSuccess(t, kustAndPatches)
|
|
}
|
|
|
|
func TestLocalizePatchesSM(t *testing.T) {
|
|
kustAndPatches := map[string]string{
|
|
"kustomization.yaml": `apiVersion: kustomize.config.k8s.io/v1beta1
|
|
kind: Kustomization
|
|
patchesStrategicMerge:
|
|
- |-
|
|
apiVersion: v1
|
|
kind: ConfigMap
|
|
metadata:
|
|
name: map
|
|
data:
|
|
- APPLE: orange
|
|
- patch.yaml
|
|
`,
|
|
"patch.yaml": podConfiguration,
|
|
}
|
|
checkLocalizeInTargetSuccess(t, kustAndPatches)
|
|
}
|
|
|
|
func TestLocalizeReplacements(t *testing.T) {
|
|
kustAndReplacement := map[string]string{
|
|
"kustomization.yaml": `apiVersion: kustomize.config.k8s.io/v1beta1
|
|
kind: Kustomization
|
|
replacements:
|
|
- path: replacement.yaml
|
|
- source:
|
|
fieldPath: path.0
|
|
name: map
|
|
targets:
|
|
- fieldPaths:
|
|
- path
|
|
select:
|
|
name: my-map
|
|
`,
|
|
"replacement.yaml": replacements,
|
|
}
|
|
checkLocalizeInTargetSuccess(t, kustAndReplacement)
|
|
}
|
|
|
|
func TestLocalizeConfigMapGenerator(t *testing.T) {
|
|
kustAndData := map[string]string{
|
|
"kustomization.yaml": `apiVersion: kustomize.config.k8s.io/v1beta1
|
|
configMapGenerator:
|
|
- env: single.env
|
|
envs:
|
|
- standard.env
|
|
namespace: my
|
|
options:
|
|
immutable: true
|
|
- behavior: merge
|
|
files:
|
|
- key.properties
|
|
literals:
|
|
- PEAR=pineapple
|
|
kind: Kustomization
|
|
metadata:
|
|
name: test
|
|
`,
|
|
"single.env": `MAY=contain
|
|
MORE=than
|
|
ONE=pair`,
|
|
"standard.env": `SIZE=0.1
|
|
IS_GLOBAL=true`,
|
|
"key.properties": "value",
|
|
}
|
|
checkLocalizeInTargetSuccess(t, kustAndData)
|
|
}
|
|
|
|
func TestLocalizeSecretGenerator(t *testing.T) {
|
|
kustAndData := map[string]string{
|
|
"kustomization.yaml": `apiVersion: kustomize.config.k8s.io/v1beta1
|
|
kind: Kustomization
|
|
secretGenerator:
|
|
- behavior: create
|
|
files:
|
|
- key=b/value.properties
|
|
- b/value
|
|
name: secret
|
|
- envs:
|
|
- crt
|
|
- key
|
|
type: kubernetes.io/tls
|
|
- literals:
|
|
- APPLE=orange
|
|
- PLUM=pluot
|
|
name: no-files
|
|
- env: more-fruit
|
|
`,
|
|
"crt": "tls.crt=LS0tLS1CRUd...0tLQo=",
|
|
"key": "tls.key=LS0tLS1CRUd...0tLQo=",
|
|
"more-fruit": "GRAPE=lime",
|
|
"b/value.properties": "value",
|
|
"b/value": "value",
|
|
}
|
|
checkLocalizeInTargetSuccess(t, kustAndData)
|
|
}
|
|
|
|
func TestLocalizeFileNoFile(t *testing.T) {
|
|
kustAndPatch := map[string]string{
|
|
"kustomization.yaml": `apiVersion: kustomize.config.k8s.io/v1beta1
|
|
kind: Kustomization
|
|
patches:
|
|
- path: name-DNE.yaml
|
|
`,
|
|
}
|
|
expected, actual := makeFileSystems(t, "/a/b", kustAndPatch)
|
|
|
|
_, err := Run("/a/b", "", "/dst", actual)
|
|
require.EqualError(t, err, `unable to localize target "/a/b": unable to localize patches: invalid file reference: '/a/b/name-DNE.yaml' doesn't exist`)
|
|
|
|
checkFSys(t, expected, actual)
|
|
}
|
|
|
|
func TestLocalizePluginsInlineAndFile(t *testing.T) {
|
|
for _, test := range []struct {
|
|
name string
|
|
files map[string]string
|
|
}{
|
|
{
|
|
name: "generators",
|
|
files: map[string]string{
|
|
"kustomization.yaml": `generators:
|
|
- generator.yaml
|
|
- |
|
|
apiVersion: builtin
|
|
env: second.properties
|
|
kind: ConfigMapGenerator
|
|
metadata:
|
|
name: inline
|
|
`,
|
|
"generator.yaml": `apiVersion: builtin
|
|
env: first.properties
|
|
kind: ConfigMapGenerator
|
|
metadata:
|
|
name: file
|
|
`,
|
|
"first.properties": "APPLE=orange",
|
|
"second.properties": "BANANA=pear",
|
|
},
|
|
},
|
|
{
|
|
name: "transformers",
|
|
files: map[string]string{
|
|
"kustomization.yaml": `apiVersion: kustomize.config.k8s.io/v1beta1
|
|
kind: Kustomization
|
|
transformers:
|
|
- |
|
|
apiVersion: builtin
|
|
kind: PatchTransformer
|
|
metadata:
|
|
name: inline
|
|
path: patchSM-one.yaml
|
|
- patch.yaml
|
|
`,
|
|
"patch.yaml": `apiVersion: builtin
|
|
kind: PatchTransformer
|
|
metadata:
|
|
name: file
|
|
path: patchSM-two.yaml
|
|
`,
|
|
"patchSM-one.yaml": podConfiguration,
|
|
"patchSM-two.yaml": podConfiguration,
|
|
},
|
|
},
|
|
{
|
|
name: "validators",
|
|
files: map[string]string{
|
|
"kustomization.yaml": `validators:
|
|
- |
|
|
apiVersion: builtin
|
|
kind: ReplacementTransformer
|
|
metadata:
|
|
name: inline
|
|
replacements:
|
|
- path: first.yaml
|
|
- second.yaml
|
|
`,
|
|
"first.yaml": replacementTransformerWithPath,
|
|
"second.yaml": replacementTransformerWithPath,
|
|
"replacement.yaml": replacements,
|
|
},
|
|
},
|
|
} {
|
|
t.Run(test.name, func(t *testing.T) {
|
|
checkLocalizeInTargetSuccess(t, test.files)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestLocalizeMultiplePluginsInEntry(t *testing.T) {
|
|
kustAndPlugins := map[string]string{
|
|
"kustomization.yaml": `apiVersion: kustomize.config.k8s.io/v1beta1
|
|
kind: Kustomization
|
|
transformers:
|
|
- |
|
|
apiVersion: builtin
|
|
kind: PatchTransformer
|
|
metadata:
|
|
name: one
|
|
path: patchSM-one.yaml
|
|
---
|
|
apiVersion: builtin
|
|
kind: PatchTransformer
|
|
metadata:
|
|
name: two
|
|
path: patchSM-two.yaml
|
|
`,
|
|
"patchSM-one.yaml": podConfiguration,
|
|
"patchSM-two.yaml": podConfiguration,
|
|
}
|
|
checkLocalizeInTargetSuccess(t, kustAndPlugins)
|
|
}
|
|
|
|
func TestLocalizeCleanedPathInPath(t *testing.T) {
|
|
const patchf = `apiVersion: builtin
|
|
kind: PatchTransformer
|
|
metadata:
|
|
name: cleaned-path
|
|
path: %s
|
|
`
|
|
kustAndPlugins := map[string]string{
|
|
"kustomization.yaml": `apiVersion: kustomize.config.k8s.io/v1beta1
|
|
kind: Kustomization
|
|
transformers:
|
|
- patch.yaml
|
|
`,
|
|
"patch.yaml": fmt.Sprintf(patchf, "../a/patchSM.yaml"),
|
|
"patchSM.yaml": podConfiguration,
|
|
}
|
|
expected, actual := makeFileSystems(t, "/a", kustAndPlugins)
|
|
|
|
checkRun(t, actual, "/a", "/a", "/dst")
|
|
addFiles(t, expected, "/dst", map[string]string{
|
|
"kustomization.yaml": kustAndPlugins["kustomization.yaml"],
|
|
"patch.yaml": fmt.Sprintf(patchf, "patchSM.yaml"),
|
|
"patchSM.yaml": kustAndPlugins["patchSM.yaml"],
|
|
})
|
|
checkFSys(t, expected, actual)
|
|
}
|
|
|
|
func TestLocalizeGeneratorsConfigMap(t *testing.T) {
|
|
files := map[string]string{
|
|
"kustomization.yaml": `generators:
|
|
- configMapGenerator
|
|
`,
|
|
"configMapGenerator": `apiVersion: builtin
|
|
behavior: create
|
|
env: one.env
|
|
envs:
|
|
- two.env
|
|
- three.env
|
|
files:
|
|
- four.properties
|
|
- key=five.properties
|
|
kind: ConfigMapGenerator
|
|
metadata:
|
|
name: custom-generator
|
|
options:
|
|
disableNameSuffix: true
|
|
`,
|
|
"one.env": "key1=value1",
|
|
"two.env": "key2=value2",
|
|
"three.env": "key3=value3",
|
|
"four.properties": "key4=value4",
|
|
"five.properties": "key5=value5",
|
|
}
|
|
checkLocalizeInTargetSuccess(t, files)
|
|
}
|
|
|
|
func TestLocalizeGeneratorsSecret(t *testing.T) {
|
|
files := map[string]string{
|
|
"kustomization.yaml": `generators:
|
|
- secretGenerator
|
|
`,
|
|
"secretGenerator": `apiVersion: builtin
|
|
env: one.env
|
|
envs:
|
|
- two.env
|
|
- three.env
|
|
files:
|
|
- four.properties
|
|
- key=five.properties
|
|
kind: SecretGenerator
|
|
literals:
|
|
- key6=value6
|
|
metadata:
|
|
name: custom-generator
|
|
`,
|
|
"one.env": "key1=value1",
|
|
"two.env": "key2=value2",
|
|
"three.env": "key3=value3",
|
|
"four.properties": "key4=value4",
|
|
"five.properties": "key5=value5",
|
|
}
|
|
checkLocalizeInTargetSuccess(t, files)
|
|
}
|
|
|
|
func TestLocalizeTransformersPatch(t *testing.T) {
|
|
kustAndPatches := map[string]string{
|
|
"kustomization.yaml": `apiVersion: kustomize.config.k8s.io/v1beta1
|
|
kind: Kustomization
|
|
transformers:
|
|
- |
|
|
apiVersion: builtin
|
|
kind: PatchTransformer
|
|
metadata:
|
|
name: no-path
|
|
patch: '[{"op": "add", "path": "/path", "value": "value"}]'
|
|
target:
|
|
name: pod
|
|
- patch.yaml
|
|
`,
|
|
"patch.yaml": `apiVersion: builtin
|
|
kind: PatchTransformer
|
|
metadata:
|
|
name: path
|
|
path: patchSM.yaml
|
|
`,
|
|
"patchSM.yaml": podConfiguration,
|
|
}
|
|
checkLocalizeInTargetSuccess(t, kustAndPatches)
|
|
}
|
|
|
|
func TestLocalizeTransformersPatchJson(t *testing.T) {
|
|
kustAndPatches := map[string]string{
|
|
"kustomization.yaml": `apiVersion: kustomize.config.k8s.io/v1beta1
|
|
kind: Kustomization
|
|
transformers:
|
|
- patch.yaml
|
|
`,
|
|
"patch.yaml": `apiVersion: builtin
|
|
kind: PatchJson6902Transformer
|
|
metadata:
|
|
name: path
|
|
path: nested-patch.yaml
|
|
target:
|
|
name: pod
|
|
namespace: test
|
|
---
|
|
apiVersion: builtin
|
|
jsonOp: |-
|
|
op: replace
|
|
path: /path
|
|
value: new value
|
|
kind: PatchJson6902Transformer
|
|
metadata:
|
|
name: patch6902
|
|
target:
|
|
name: deployment
|
|
`,
|
|
"nested-patch.yaml": ` [
|
|
{"op": "copy", "from": "/existing/path", "path": "/another/path"},
|
|
]
|
|
`,
|
|
}
|
|
checkLocalizeInTargetSuccess(t, kustAndPatches)
|
|
}
|
|
|
|
func TestLocalizeTransformersPatchSM(t *testing.T) {
|
|
kustAndPatches := map[string]string{
|
|
"kustomization.yaml": `transformers:
|
|
- patch.yaml
|
|
`,
|
|
"patch.yaml": `apiVersion: builtin
|
|
kind: PatchStrategicMergeTransformer
|
|
metadata:
|
|
name: path
|
|
paths:
|
|
- nested-patch.yaml
|
|
- |-
|
|
apiVersion: v1
|
|
kind: Pod
|
|
metadata:
|
|
name: my-pod
|
|
`,
|
|
"nested-patch.yaml": podConfiguration,
|
|
}
|
|
checkLocalizeInTargetSuccess(t, kustAndPatches)
|
|
}
|
|
|
|
func TestLocalizeTransformersReplacement(t *testing.T) {
|
|
kustAndReplacements := map[string]string{
|
|
"kustomization.yaml": `transformers:
|
|
- replacement-transformer.yaml
|
|
`,
|
|
"replacement-transformer.yaml": replacementTransformerWithPath,
|
|
"replacement.yaml": replacements,
|
|
}
|
|
checkLocalizeInTargetSuccess(t, kustAndReplacements)
|
|
}
|
|
|
|
func TestLocalizePluginsNoPaths(t *testing.T) {
|
|
kustAndPlugins := map[string]string{
|
|
"kustomization.yaml": `apiVersion: kustomize.config.k8s.io/v1beta1
|
|
kind: Kustomization
|
|
transformers:
|
|
- |
|
|
apiVersion: different
|
|
kind: MyTransformer
|
|
metadata:
|
|
name: still-copied
|
|
path: /nothing/special
|
|
- prefix.yaml
|
|
`,
|
|
"prefix.yaml": `apiVersion: builtin
|
|
kind: PrefixTransformer
|
|
metadata:
|
|
name: other-built-ins-still-copied
|
|
prefix: copy
|
|
`,
|
|
}
|
|
checkLocalizeInTargetSuccess(t, kustAndPlugins)
|
|
}
|
|
|
|
func TestLocalizeValidators(t *testing.T) {
|
|
kustAndPlugin := map[string]string{
|
|
"kustomization.yaml": `apiVersion: kustomize.config.k8s.io/v1beta1
|
|
kind: Kustomization
|
|
validators:
|
|
- replacement-no-change.yaml
|
|
`,
|
|
"replacement-no-change.yaml": replacementTransformerWithPath,
|
|
"replacement.yaml": replacements,
|
|
}
|
|
checkLocalizeInTargetSuccess(t, kustAndPlugin)
|
|
}
|
|
|
|
func TestLocalizeBuiltinPlugins_SequenceScalarEquivalence(t *testing.T) {
|
|
kustomization := map[string]string{
|
|
"kustomization.yaml": `transformers:
|
|
- |
|
|
apiVersion: builtin
|
|
kind: PatchTransformer
|
|
metadata:
|
|
name: path-should-be-scalar-but-accept-sequence
|
|
path:
|
|
- patchSM.yaml
|
|
`,
|
|
"patchSM.yaml": podConfiguration,
|
|
}
|
|
checkLocalizeInTargetSuccess(t, kustomization)
|
|
}
|
|
|
|
func TestLocalizeBuiltinPlugins_NotResource(t *testing.T) {
|
|
type testCase struct {
|
|
name string
|
|
files map[string]string
|
|
errPrefix string
|
|
inlineErrMsg string
|
|
fileErrMsg string
|
|
}
|
|
for _, test := range []testCase{
|
|
{
|
|
name: "bad_inline_resource",
|
|
files: map[string]string{
|
|
"kustomization.yaml": `apiVersion: kustomize.config.k8s.io/v1beta1
|
|
generators:
|
|
- |
|
|
apiVersion: builtin
|
|
kind: ConfigMapGenerator
|
|
kind: Kustomization
|
|
`,
|
|
},
|
|
errPrefix: `unable to load generators entry: unable to load resource entry "apiVersion: builtin\nkind: ConfigMapGenerator\n"`,
|
|
inlineErrMsg: `missing metadata.name in object {{builtin ConfigMapGenerator} {{ } map[] map[]}}`,
|
|
fileErrMsg: `invalid file reference: '/apiVersion: builtin
|
|
kind: ConfigMapGenerator
|
|
' doesn't exist`,
|
|
},
|
|
{
|
|
name: "bad_file_resource",
|
|
files: map[string]string{
|
|
"kustomization.yaml": `apiVersion: kustomize.config.k8s.io/v1beta1
|
|
kind: Kustomization
|
|
transformers:
|
|
- plugin.yaml
|
|
`,
|
|
"plugin.yaml": `apiVersion: builtin
|
|
metadata:
|
|
name: PatchTransformer
|
|
`,
|
|
},
|
|
errPrefix: `unable to load transformers entry: unable to load resource entry "plugin.yaml"`,
|
|
inlineErrMsg: `missing Resource metadata`,
|
|
fileErrMsg: `missing kind in object {{builtin } {{PatchTransformer } map[] map[]}}`,
|
|
},
|
|
} {
|
|
t.Run(test.name, func(t *testing.T) {
|
|
expected, actual := makeFileSystems(t, "/", test.files)
|
|
|
|
_, err := Run("/", "", "/dst", actual)
|
|
|
|
var actualErr ResourceLoadError
|
|
require.ErrorAs(t, err, &actualErr)
|
|
require.EqualError(t, actualErr.InlineError, test.inlineErrMsg)
|
|
require.EqualError(t, actualErr.FileError, test.fileErrMsg)
|
|
|
|
require.EqualError(t, err, fmt.Sprintf(`unable to localize target "/": %s: when parsing as inline received error: %s
|
|
when parsing as filepath received error: %s`, test.errPrefix, test.inlineErrMsg, test.fileErrMsg))
|
|
|
|
checkFSys(t, expected, actual)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestLocalizeBuiltinPlugins_Errors(t *testing.T) {
|
|
for name, test := range map[string]struct {
|
|
files map[string]string
|
|
fieldSpecErr string
|
|
locErr string
|
|
}{
|
|
"file_dne": {
|
|
files: map[string]string{
|
|
"kustomization.yaml": `transformers:
|
|
- |
|
|
apiVersion: builtin
|
|
kind: PatchTransformer
|
|
metadata:
|
|
name: file-does-not-exist
|
|
path: patchSM.yaml
|
|
`,
|
|
},
|
|
fieldSpecErr: "considering field 'path' of object PatchTransformer.builtin.[noGrp]/file-does-not-exist.[noNs]",
|
|
locErr: "invalid file reference: '/a/patchSM.yaml' doesn't exist",
|
|
},
|
|
"not_sequence_or_scalar": {
|
|
files: map[string]string{
|
|
"kustomization.yaml": `transformers:
|
|
- |
|
|
apiVersion: builtin
|
|
kind: PatchTransformer
|
|
metadata:
|
|
name: path-node-has-wrong-kind
|
|
path:
|
|
mappingNode: patchSM.yaml
|
|
`,
|
|
"patchSM.yaml": podConfiguration,
|
|
},
|
|
fieldSpecErr: "considering field 'path' of object PatchTransformer.builtin.[noGrp]/path-node-has-wrong-kind.[noNs]",
|
|
locErr: "expected sequence or scalar node",
|
|
},
|
|
} {
|
|
t.Run(name, func(t *testing.T) {
|
|
expected, actual := makeFileSystems(t, "/a", test.files)
|
|
_, err := Run("/a", "", "/dst", actual)
|
|
const errPrefix = `unable to localize target "/a"`
|
|
require.EqualError(t, err, fmt.Sprintf(
|
|
"%s: %s: %s", errPrefix, test.fieldSpecErr, test.locErr))
|
|
checkFSys(t, expected, actual)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestLocalizeDirInTarget(t *testing.T) {
|
|
type testCase struct {
|
|
name string
|
|
files map[string]string
|
|
}
|
|
for _, tc := range []testCase{
|
|
{
|
|
name: "multi_nested_child",
|
|
files: map[string]string{
|
|
"kustomization.yaml": `apiVersion: kustomize.config.k8s.io/v1beta1
|
|
components:
|
|
- delta/epsilon
|
|
kind: Kustomization
|
|
`,
|
|
"delta/epsilon/kustomization.yaml": `apiVersion: kustomize.config.k8s.io/v1alpha1
|
|
kind: Component
|
|
namespace: kustomize-namespace
|
|
`,
|
|
},
|
|
},
|
|
{
|
|
name: "recursive",
|
|
files: map[string]string{
|
|
"kustomization.yaml": `apiVersion: kustomize.config.k8s.io/v1beta1
|
|
components:
|
|
- delta
|
|
kind: Kustomization
|
|
`,
|
|
"delta/kustomization.yaml": `apiVersion: kustomize.config.k8s.io/v1alpha1
|
|
components:
|
|
- epsilon
|
|
kind: Component
|
|
`,
|
|
"delta/epsilon/kustomization.yaml": `apiVersion: kustomize.config.k8s.io/v1alpha1
|
|
kind: Component
|
|
namespace: kustomize-namespace
|
|
`,
|
|
},
|
|
},
|
|
{
|
|
name: "file_in_dir",
|
|
files: map[string]string{
|
|
"kustomization.yaml": `apiVersion: kustomize.config.k8s.io/v1beta1
|
|
components:
|
|
- delta
|
|
kind: Kustomization
|
|
`,
|
|
"delta/kustomization.yaml": `apiVersion: kustomize.config.k8s.io/v1alpha1
|
|
kind: Component
|
|
patches:
|
|
- path: patch.yaml
|
|
`,
|
|
"delta/patch.yaml": podConfiguration,
|
|
},
|
|
},
|
|
{
|
|
name: "multiple_calls",
|
|
files: map[string]string{
|
|
"kustomization.yaml": `apiVersion: kustomize.config.k8s.io/v1beta1
|
|
components:
|
|
- delta
|
|
- delta/epsilon
|
|
kind: Kustomization
|
|
`,
|
|
"delta/kustomization.yaml": `apiVersion: kustomize.config.k8s.io/v1alpha1
|
|
kind: Component
|
|
namespace: kustomize-namespace
|
|
`,
|
|
"delta/epsilon/kustomization.yaml": `apiVersion: kustomize.config.k8s.io/v1alpha1
|
|
buildMetadata:
|
|
- managedByLabel
|
|
kind: Component
|
|
`,
|
|
},
|
|
},
|
|
{
|
|
name: "localize_directory_name_when_no_remote",
|
|
files: map[string]string{
|
|
"kustomization.yaml": fmt.Sprintf(`apiVersion: kustomize.config.k8s.io/v1beta1
|
|
components:
|
|
- %s
|
|
kind: Kustomization
|
|
`, LocalizeDir),
|
|
fmt.Sprintf("%s/kustomization.yaml", LocalizeDir): `apiVersion: kustomize.config.k8s.io/v1alpha1
|
|
kind: Component
|
|
namespace: kustomize-namespace
|
|
`,
|
|
},
|
|
},
|
|
} {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
checkLocalizeInTargetSuccess(t, tc.files)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestLocalizeDirCleanedSibling(t *testing.T) {
|
|
kustAndComponents := map[string]string{
|
|
// This test checks that winding paths that might traverse through directories
|
|
// outside of scope, which will not be present at destination, are cleaned.
|
|
"beta/gamma/kustomization.yaml": `apiVersion: kustomize.config.k8s.io/v1beta1
|
|
components:
|
|
- delta/../../../../a/b/../../alpha/beta/sibling
|
|
kind: Kustomization`,
|
|
"beta/sibling/kustomization.yaml": `apiVersion: kustomize.config.k8s.io/v1alpha1
|
|
kind: Component
|
|
namespace: kustomize-namespace
|
|
`,
|
|
}
|
|
expected, actual := makeFileSystems(t, "/alpha", kustAndComponents)
|
|
|
|
checkRun(t, actual, "/alpha/beta/gamma", "/alpha", "/alpha/beta/dst")
|
|
cleanedFiles := map[string]string{
|
|
"beta/gamma/kustomization.yaml": `apiVersion: kustomize.config.k8s.io/v1beta1
|
|
components:
|
|
- ../sibling
|
|
kind: Kustomization
|
|
`,
|
|
"beta/sibling/kustomization.yaml": kustAndComponents["beta/sibling/kustomization.yaml"],
|
|
}
|
|
addFiles(t, expected, "/alpha/beta/dst", cleanedFiles)
|
|
checkFSys(t, expected, actual)
|
|
}
|
|
|
|
func TestLocalizeBases(t *testing.T) {
|
|
kustAndBases := map[string]string{
|
|
"kustomization.yaml": `bases:
|
|
- b
|
|
- c/d
|
|
`,
|
|
"b/kustomization.yaml": `kind: Kustomization
|
|
`,
|
|
"c/d/kustomization.yaml": `kind: Kustomization
|
|
`,
|
|
}
|
|
checkLocalizeInTargetSuccess(t, kustAndBases)
|
|
}
|
|
|
|
func TestLocalizeComponents(t *testing.T) {
|
|
kustAndComponents := map[string]string{
|
|
"kustomization.yaml": `apiVersion: kustomize.config.k8s.io/v1beta1
|
|
components:
|
|
- a
|
|
- alpha
|
|
kind: Kustomization
|
|
`,
|
|
"a/kustomization.yaml": `apiVersion: kustomize.config.k8s.io/v1alpha1
|
|
kind: Component
|
|
namePrefix: my-
|
|
`,
|
|
"alpha/kustomization.yaml": `apiVersion: kustomize.config.k8s.io/v1alpha1
|
|
kind: Component
|
|
nameSuffix: -test
|
|
`,
|
|
}
|
|
checkLocalizeInTargetSuccess(t, kustAndComponents)
|
|
}
|
|
|
|
func TestLocalizeResources(t *testing.T) {
|
|
kustAndResources := map[string]string{
|
|
"kustomization.yaml": `apiVersion: kustomize.config.k8s.io/v1beta1
|
|
kind: Kustomization
|
|
resources:
|
|
- pod.yaml
|
|
- ../../alpha
|
|
`,
|
|
"pod.yaml": podConfiguration,
|
|
"../../alpha/kustomization.yaml": `apiVersion: kustomize.config.k8s.io/v1beta1
|
|
kind: Kustomization
|
|
namePrefix: my-
|
|
`,
|
|
}
|
|
expected, actual := makeFileSystems(t, "/a/b", kustAndResources)
|
|
|
|
checkRun(t, actual, "/a/b", "/", "/localized-b")
|
|
addFiles(t, expected, "/localized-b/a/b", kustAndResources)
|
|
checkFSys(t, expected, actual)
|
|
}
|
|
|
|
func TestLocalizePathError(t *testing.T) {
|
|
kustAndResources := map[string]string{
|
|
"kustomization.yaml": `apiVersion: kustomize.config.k8s.io/v1beta1
|
|
kind: Kustomization
|
|
resources:
|
|
- b
|
|
`,
|
|
}
|
|
expected, actual := makeFileSystems(t, "/a", kustAndResources)
|
|
|
|
_, err := Run("/a", "/", "", actual)
|
|
|
|
const expectedFileErr = `invalid file reference: '/a/b' must resolve to a file`
|
|
const expectedRootErr = `unable to localize root "b": unable to find one of 'kustomization.yaml', 'kustomization.yml' or 'Kustomization' in directory '/a/b'`
|
|
var actualErr PathLocalizeError
|
|
require.ErrorAs(t, err, &actualErr)
|
|
require.Equal(t, "b", actualErr.Path)
|
|
require.EqualError(t, actualErr.FileError, expectedFileErr)
|
|
require.EqualError(t, actualErr.RootError, expectedRootErr)
|
|
|
|
const expectedErrPrefix = `unable to localize target "/a": unable to localize resources entry`
|
|
require.EqualError(t, err, fmt.Sprintf(`%s: could not localize path "b" as file: %s; could not localize path "b" as directory: %s`,
|
|
expectedErrPrefix, expectedFileErr, expectedRootErr))
|
|
|
|
checkFSys(t, expected, actual)
|
|
}
|
|
|
|
func TestLocalizeHelmChartInflationGenerator(t *testing.T) {
|
|
helmKust := map[string]string{
|
|
"kustomization.yaml": `helmChartInflationGenerator:
|
|
- chartName: nothing-to-localize
|
|
chartRepoUrl: https://itzg.github.io/warcraft-server-charts
|
|
releaseName: moria
|
|
- chartName: localize-values
|
|
values: minecraftValues.yaml
|
|
valuesLocal:
|
|
minecraftServer:
|
|
eula: true
|
|
valuesMerge: replace
|
|
- chartHome: home
|
|
chartName: copy-chartHome
|
|
`,
|
|
"minecraftValues.yaml": valuesFile,
|
|
"charts/localize-values/values.yaml": valuesFile,
|
|
"home/copy-chartHome/values.yaml": valuesFile,
|
|
}
|
|
checkLocalizeInTargetSuccess(t, helmKust)
|
|
}
|
|
|
|
func TestLocalizeHelmCharts(t *testing.T) {
|
|
for _, test := range []struct {
|
|
name string
|
|
files map[string]string
|
|
}{
|
|
{
|
|
name: "charts_only",
|
|
files: map[string]string{
|
|
"kustomization.yaml": `helmCharts:
|
|
- name: nothing-to-localize
|
|
repo: https://helm.releases.hashicorp.com
|
|
version: 1.0.0
|
|
- includeCRDs: true
|
|
name: localize-valuesFile
|
|
valuesFile: file
|
|
- additionalValuesFiles:
|
|
- another
|
|
- third
|
|
`,
|
|
"file": valuesFile,
|
|
"another": valuesFile,
|
|
"third": valuesFile,
|
|
"charts/nothing-to-localize/values.yaml": valuesFile,
|
|
"charts/localize-valuesFile/values.yaml": valuesFile,
|
|
},
|
|
},
|
|
{
|
|
name: "charts_globals_no_home",
|
|
files: map[string]string{
|
|
"kustomization.yaml": `helmCharts:
|
|
- name: default
|
|
helmGlobals:
|
|
configHome: .
|
|
`,
|
|
"charts/default/values.yaml": valuesFile,
|
|
},
|
|
},
|
|
{
|
|
name: "home_only",
|
|
files: map[string]string{
|
|
"kustomization.yaml": `helmGlobals:
|
|
chartHome: home
|
|
`,
|
|
"home/name/values.yaml": valuesFile,
|
|
},
|
|
},
|
|
} {
|
|
t.Run(test.name, func(t *testing.T) {
|
|
checkLocalizeInTargetSuccess(t, test.files)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestLocalizeHelmChartsNoDefault(t *testing.T) {
|
|
files := map[string]string{
|
|
"kustomization.yaml": `helmGlobals:
|
|
chartHome: home
|
|
`,
|
|
"home/name/values.yaml": valuesFile,
|
|
"charts/name/values.yaml": valuesFile,
|
|
}
|
|
expected, actual := makeFileSystems(t, "/a", files)
|
|
|
|
checkRun(t, actual, "/a", "/a", "/dst")
|
|
addFiles(t, expected, "/dst", map[string]string{
|
|
"kustomization.yaml": files["kustomization.yaml"],
|
|
"home/name/values.yaml": valuesFile,
|
|
})
|
|
checkFSys(t, expected, actual)
|
|
}
|
|
|
|
func TestCopyChartHomeSimple(t *testing.T) {
|
|
for _, test := range []struct {
|
|
name string
|
|
files map[string]string
|
|
}{
|
|
{
|
|
name: "does_not_exist",
|
|
files: map[string]string{
|
|
"kustomization.yaml": `helmGlobals:
|
|
chartHome: untar-dir
|
|
`,
|
|
},
|
|
},
|
|
{
|
|
name: "chart_home_structure",
|
|
files: map[string]string{
|
|
"kustomization.yaml": `helmGlobals:
|
|
chartHome: home
|
|
`,
|
|
"home/minecraft-3.1.3.tgz": "blah",
|
|
"home/terraform-1.0.0.tgz": "la",
|
|
"home/minecraft/Chart.yaml": `annotations:
|
|
artifacthub.io/links: |
|
|
- name: source
|
|
url: https://minecraft.net/
|
|
`,
|
|
"home/terraform/Chart.yaml": `description: Minecraft server
|
|
`,
|
|
},
|
|
},
|
|
} {
|
|
t.Run(test.name, func(t *testing.T) {
|
|
checkLocalizeInTargetSuccess(t, test.files)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestCopyChartHomeChanges(t *testing.T) {
|
|
for name, test := range map[string]struct {
|
|
files map[string]string
|
|
copiedFiles map[string]string
|
|
}{
|
|
"clean_does_not_exist": {
|
|
files: map[string]string{
|
|
"kustomization.yaml": `helmGlobals:
|
|
chartHome: ../b/home
|
|
`,
|
|
},
|
|
copiedFiles: map[string]string{
|
|
"kustomization.yaml": `helmGlobals:
|
|
chartHome: home
|
|
`,
|
|
},
|
|
},
|
|
"clean_default": {
|
|
files: map[string]string{
|
|
"kustomization.yaml": `helmGlobals:
|
|
chartHome: ../b/charts
|
|
`,
|
|
"charts/name/values.yaml": valuesFile,
|
|
},
|
|
copiedFiles: map[string]string{
|
|
"kustomization.yaml": `helmGlobals:
|
|
chartHome: charts
|
|
`,
|
|
"charts/name/values.yaml": valuesFile,
|
|
},
|
|
},
|
|
"not_copied": {
|
|
files: map[string]string{
|
|
"kustomization.yaml": `helmCharts:
|
|
- name: name
|
|
valuesFile: home/name/values.yaml
|
|
helmGlobals:
|
|
chartHome: home
|
|
`,
|
|
"home/name/values.yaml": valuesFile,
|
|
"home/name/many-other-files": "other contents",
|
|
},
|
|
copiedFiles: map[string]string{
|
|
"kustomization.yaml": `helmCharts:
|
|
- name: name
|
|
valuesFile: home/name/values.yaml
|
|
helmGlobals:
|
|
chartHome: home
|
|
`,
|
|
"home/name/values.yaml": valuesFile,
|
|
},
|
|
},
|
|
"does_not_exist_exits_scope": {
|
|
files: map[string]string{
|
|
"kustomization.yaml": `helmGlobals:
|
|
chartHome: ../home
|
|
`,
|
|
"../../home/will-exist-at-dst/values.yaml": valuesFile,
|
|
},
|
|
copiedFiles: map[string]string{
|
|
"kustomization.yaml": `helmGlobals:
|
|
chartHome: ../home
|
|
`,
|
|
},
|
|
},
|
|
} {
|
|
t.Run(name, func(t *testing.T) {
|
|
expected, actual := makeFileSystems(t, "/a/b", test.files)
|
|
|
|
checkRun(t, actual, "/a/b", "/a/b", "/dst")
|
|
addFiles(t, expected, "/dst", test.copiedFiles)
|
|
checkFSys(t, expected, actual)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestCopyChartHomeEmpty(t *testing.T) {
|
|
kustomization := map[string]string{
|
|
"kustomization.yaml": `helmGlobals:
|
|
chartHome: home
|
|
`,
|
|
}
|
|
expected, actual := makeFileSystems(t, "/a", kustomization)
|
|
require.NoError(t, actual.Mkdir("/a/home"))
|
|
require.NoError(t, expected.Mkdir("/a/home"))
|
|
|
|
checkRun(t, actual, "/a", "/a", "/dst")
|
|
addFiles(t, expected, "/dst", kustomization)
|
|
require.NoError(t, expected.Mkdir("/dst/home"))
|
|
checkFSys(t, expected, actual)
|
|
}
|
|
|
|
func TestCopyChartHomeError(t *testing.T) {
|
|
for name, test := range map[string]struct {
|
|
err string
|
|
files map[string]string
|
|
}{
|
|
"absolute": {
|
|
err: `unable to copy helmGlobals: absolute path "/a/b/home" not handled in alpha`,
|
|
files: map[string]string{
|
|
"a/b/kustomization.yaml": `helmGlobals:
|
|
chartHome: /a/b/home
|
|
`,
|
|
"a/b/home/name/values.yaml": valuesFile,
|
|
},
|
|
},
|
|
"file": {
|
|
err: `unable to copy helmGlobals: unable to copy home "home": invalid chart home: invalid root reference: must build at directory: '/a/b/home': file is not directory`,
|
|
files: map[string]string{
|
|
"a/b/kustomization.yaml": `helmGlobals:
|
|
chartHome: home
|
|
`,
|
|
"a/b/home": valuesFile,
|
|
},
|
|
},
|
|
"scope": {
|
|
err: `unable to copy helmGlobals: unable to copy home "../../alpha/home": invalid chart home: root "/alpha/home" outside localize scope "/a"`,
|
|
files: map[string]string{
|
|
"a/b/kustomization.yaml": `helmGlobals:
|
|
chartHome: ../../alpha/home
|
|
`,
|
|
"alpha/home/values.yaml": valuesFile,
|
|
},
|
|
},
|
|
} {
|
|
t.Run(name, func(t *testing.T) {
|
|
expected, actual := makeFileSystems(t, "/", test.files)
|
|
|
|
_, err := Run("/a/b", "/a", "/dst", actual)
|
|
const prefix = `unable to localize target "/a/b"`
|
|
require.EqualError(t, err, fmt.Sprintf("%s: %s", prefix, test.err))
|
|
|
|
checkFSys(t, expected, actual)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestLocalizeGeneratorsHelm(t *testing.T) {
|
|
files := map[string]string{
|
|
"kustomization.yaml": `generators:
|
|
- default.yaml
|
|
- explicit.yaml
|
|
`,
|
|
"default.yaml": `apiVersion: builtin
|
|
kind: HelmChartInflationGenerator
|
|
metadata:
|
|
name: no-explicit-references
|
|
name: minecraft
|
|
releaseName: moria
|
|
repo: https://itzg.github.io/minecraft-server-charts
|
|
version: 3.1.3
|
|
`,
|
|
"explicit.yaml": `additionalValuesFiles:
|
|
- time.yaml
|
|
- life.yaml
|
|
- light.yaml
|
|
apiVersion: builtin
|
|
chartHome: home
|
|
kind: HelmChartInflationGenerator
|
|
metadata:
|
|
name: explicit-references
|
|
name: mapleStory
|
|
valuesFile: mapleValues.yaml
|
|
`,
|
|
"time.yaml": valuesFile,
|
|
"life.yaml": valuesFile,
|
|
"light.yaml": valuesFile,
|
|
"mapleValues.yaml": valuesFile,
|
|
"home/mapleStory/values.yaml": valuesFile,
|
|
"charts/minecraft/values.yaml": valuesFile,
|
|
}
|
|
checkLocalizeInTargetSuccess(t, files)
|
|
}
|
|
|
|
func TestLocalizeGeneratorsNoHelm(t *testing.T) {
|
|
files := map[string]string{
|
|
"kustomization.yaml": `generators:
|
|
- configMap.yaml
|
|
`,
|
|
"configMap.yaml": `apiVersion: builtin
|
|
kind: ConfigMapGenerator
|
|
literals:
|
|
- APPLE=orange
|
|
metadata:
|
|
name: not-helm-shouldn't-copy-default-helm-chart-home
|
|
`,
|
|
"charts/minecraft/values.yaml": valuesFile,
|
|
}
|
|
expected, actual := makeFileSystems(t, "/a", files)
|
|
|
|
checkRun(t, actual, "/a", "/a", "/dst")
|
|
addFiles(t, expected, "/dst", map[string]string{
|
|
"kustomization.yaml": files["kustomization.yaml"],
|
|
"configMap.yaml": files["configMap.yaml"],
|
|
})
|
|
checkFSys(t, expected, actual)
|
|
}
|
|
|
|
func TestLocalizeEmpty(t *testing.T) {
|
|
for name, kustomization := range map[string]string{
|
|
"file": `configurations:
|
|
- ""
|
|
`,
|
|
"root": `bases:
|
|
- ""
|
|
`,
|
|
"resource": `resources:
|
|
- ""
|
|
`,
|
|
"generator_file_src": `configMapGenerator:
|
|
- files:
|
|
- ""
|
|
`,
|
|
"patchesStrategicMerge": `patchesStrategicMerge:
|
|
- ""
|
|
`,
|
|
"custom_transformers": `transformers:
|
|
- ""
|
|
`,
|
|
"custom_transformer_field": `transformers:
|
|
- |
|
|
apiVersion: builtin
|
|
kind: PatchStrategicMergeTransformer
|
|
metadata:
|
|
name: empty
|
|
paths:
|
|
- ""
|
|
`,
|
|
} {
|
|
t.Run(name, func(t *testing.T) {
|
|
checkLocalizeInTargetSuccess(t, map[string]string{
|
|
"kustomization.yaml": kustomization,
|
|
})
|
|
})
|
|
}
|
|
}
|