Localize helm fields (#4978)

* Localize helm fields

* Address readability feedback

* Handle edge cases

* Improve readability

Split copyChartHome and use existence to prevent repeated copying.
This commit is contained in:
Anna Song
2023-01-26 12:56:26 -08:00
committed by GitHub
parent af9a13111b
commit fb294921f5
6 changed files with 651 additions and 44 deletions

View File

@@ -83,7 +83,7 @@ func (p *HelmChartInflationGeneratorPlugin) validateArgs() (err error) {
// the loader root (unless root restrictions are
// disabled, in which case this can be an absolute path).
if p.ChartHome == "" {
p.ChartHome = "charts"
p.ChartHome = types.HelmDefaultHome
}
// The ValuesFile may be consulted by the plugin, so it must

View File

@@ -4,7 +4,9 @@
package localizer
import (
"io/fs"
"log"
"os"
"path/filepath"
"sigs.k8s.io/kustomize/api/ifc"
@@ -119,11 +121,11 @@ func (lc *localizer) load() (*types.Kustomization, string, error) {
// built-in understanding of. This excludes helm-related fields, such as `helmGlobals` and `helmCharts`.
func (lc *localizer) localizeNativeFields(kust *types.Kustomization) error {
if path, exists := kust.OpenAPI["path"]; exists {
newPath, err := lc.localizeFile(path)
locPath, err := lc.localizeFile(path)
if err != nil {
return errors.WrapPrefixf(err, "unable to localize openapi path")
}
kust.OpenAPI["path"] = newPath
kust.OpenAPI["path"] = locPath
}
for fieldName, field := range map[string]struct {
@@ -134,11 +136,11 @@ func (lc *localizer) localizeNativeFields(kust *types.Kustomization) error {
// Allow use of deprecated field
//nolint:staticcheck
kust.Bases,
lc.localizeDir,
lc.localizeRoot,
},
"components": {
kust.Components,
lc.localizeDir,
lc.localizeRoot,
},
"configurations": {
kust.Configurations,
@@ -172,6 +174,12 @@ func (lc *localizer) localizeNativeFields(kust *types.Kustomization) error {
return errors.WrapPrefixf(err, "unable to localize secretGenerator")
}
}
if err := lc.localizeHelmInflationGenerator(kust); err != nil {
return err
}
if err := lc.localizeHelmCharts(kust); err != nil {
return err
}
if err := lc.localizePatches(kust.Patches); err != nil {
return errors.WrapPrefixf(err, "unable to localize patches")
}
@@ -181,34 +189,29 @@ func (lc *localizer) localizeNativeFields(kust *types.Kustomization) error {
}
//nolint:staticcheck
for i, patch := range kust.PatchesStrategicMerge {
localizedPath, err := lc.localizeK8sResource(string(patch))
locPath, err := lc.localizeK8sResource(string(patch))
if err != nil {
return errors.WrapPrefixf(err, "unable to localize patchesStrategicMerge entry")
}
if localizedPath != "" {
kust.PatchesStrategicMerge[i] = types.PatchStrategicMerge(localizedPath)
if locPath != "" {
kust.PatchesStrategicMerge[i] = types.PatchStrategicMerge(locPath)
}
}
for i, replacement := range kust.Replacements {
if replacement.Path != "" {
newPath, err := lc.localizeFile(replacement.Path)
if err != nil {
return errors.WrapPrefixf(err, "unable to localize replacements entry")
}
kust.Replacements[i].Path = newPath
locPath, err := lc.localizeFile(replacement.Path)
if err != nil {
return errors.WrapPrefixf(err, "unable to localize replacements entry")
}
kust.Replacements[i].Path = locPath
}
return nil
}
// localizeGenerator localizes the file paths on generator.
func (lc *localizer) localizeGenerator(generator *types.GeneratorArgs) (err error) {
var locEnvSrc string
if generator.EnvSource != "" {
locEnvSrc, err = lc.localizeFile(generator.EnvSource)
if err != nil {
return errors.WrapPrefixf(err, "unable to localize generator env file")
}
func (lc *localizer) localizeGenerator(generator *types.GeneratorArgs) error {
locEnvSrc, err := lc.localizeFile(generator.EnvSource)
if err != nil {
return errors.WrapPrefixf(err, "unable to localize generator env file")
}
locEnvs := make([]string, len(generator.EnvSources))
for i, env := range generator.EnvSources {
@@ -238,16 +241,58 @@ func (lc *localizer) localizeGenerator(generator *types.GeneratorArgs) (err erro
return nil
}
// localizeHelmInflationGenerator localizes helmChartInflationGenerator on kust.
// localizeHelmInflationGenerator localizes values files and copies local chart homes.
func (lc *localizer) localizeHelmInflationGenerator(kust *types.Kustomization) error {
for i, chart := range kust.HelmChartInflationGenerator {
locFile, err := lc.localizeFile(chart.Values)
if err != nil {
return errors.WrapPrefixf(err, "unable to localize helmChartInflationGenerator entry %d values", i)
}
kust.HelmChartInflationGenerator[i].Values = locFile
locDir, err := lc.copyChartHomeEntry(chart.ChartHome)
if err != nil {
return errors.WrapPrefixf(err, "unable to copy helmChartInflationGenerator entry %d", i)
}
kust.HelmChartInflationGenerator[i].ChartHome = locDir
}
return nil
}
// localizeHelmCharts localizes helmCharts and helmGlobals on kust.
// localizeHelmCharts localizes values files and copies a local chart home.
func (lc *localizer) localizeHelmCharts(kust *types.Kustomization) error {
for i, chart := range kust.HelmCharts {
locFile, err := lc.localizeFile(chart.ValuesFile)
if err != nil {
return errors.WrapPrefixf(err, "unable to localize helmCharts entry %d valuesFile", i)
}
kust.HelmCharts[i].ValuesFile = locFile
}
if kust.HelmGlobals != nil {
locDir, err := lc.copyChartHomeEntry(kust.HelmGlobals.ChartHome)
if err != nil {
return errors.WrapPrefixf(err, "unable to copy helmGlobals")
}
kust.HelmGlobals.ChartHome = locDir
} else if len(kust.HelmCharts) > 0 {
_, err := lc.copyChartHomeEntry("")
if err != nil {
return errors.WrapPrefixf(err, "unable to copy default chart home")
}
}
return nil
}
// localizePatches localizes the file paths on patches if they are non-empty
func (lc *localizer) localizePatches(patches []types.Patch) error {
for i := range patches {
if patches[i].Path != "" {
newPath, err := lc.localizeFile(patches[i].Path)
if err != nil {
return err
}
patches[i].Path = newPath
locPath, err := lc.localizeFile(patches[i].Path)
if err != nil {
return err
}
patches[i].Path = locPath
}
return nil
}
@@ -272,7 +317,7 @@ func (lc *localizer) localizeResource(path string) (string, error) {
}
if fileErr != nil {
var rootErr error
locPath, rootErr = lc.localizeDir(path)
locPath, rootErr = lc.localizeRoot(path)
if rootErr != nil {
err := PathLocalizeError{
Path: path,
@@ -285,8 +330,13 @@ func (lc *localizer) localizeResource(path string) (string, error) {
return locPath, nil
}
// localizeFile localizes file path and returns the localized path
// localizeFile localizes file path if set and returns the localized path
func (lc *localizer) localizeFile(path string) (string, error) {
// Some localizable fields can be empty, for example, replacements.path.
// We rely on the build command to throw errors for the ones that cannot.
if path == "" {
return "", nil
}
content, err := lc.ldr.Load(path)
if err != nil {
return "", errors.Wrap(err)
@@ -324,8 +374,11 @@ func (lc *localizer) localizeFileWithContent(path string, content []byte) (strin
return locPath, nil
}
// localizeDir localizes root path and returns the localized path
func (lc *localizer) localizeDir(path string) (string, error) {
// localizeRoot localizes root path if set and returns the localized path
func (lc *localizer) localizeRoot(path string) (string, error) {
if path == "" {
return "", nil
}
ldr, err := lc.ldr.New(path)
if err != nil {
return "", errors.Wrap(err)
@@ -368,6 +421,106 @@ func (lc *localizer) localizeDir(path string) (string, error) {
return locPath, nil
}
// copyChartHomeEntry copies the helm chart home entry to lc dst
// at the same location relative to the root and returns said relative path.
// If entry is empty, copyChartHomeEntry returns the empty string.
// If entry does not exist, copyChartHome returns entry.
//
// copyChartHomeEntry copies the default home to the same location at dst,
// without following symlinks. An empty entry also indicates the default home.
func (lc *localizer) copyChartHomeEntry(entry string) (string, error) {
path := entry
if entry == "" {
path = types.HelmDefaultHome
}
if filepath.IsAbs(path) {
return "", errors.Errorf("absolute path %q not handled in alpha", path)
}
isDefault := lc.root.Join(path) == lc.root.Join(types.HelmDefaultHome)
locPath, err := lc.copyChartHome(path, !isDefault)
if err != nil {
return "", errors.WrapPrefixf(err, "unable to copy home %q", entry)
}
if entry == "" {
return "", nil
}
return locPath, nil
}
// copyChartHome copies path relative to lc root to dst and returns the
// copied location relative to dst. If clean is true, copyChartHome uses path's
// delinked location as the copy destination.
//
// If path does not exist, copyChartHome returns path.
func (lc *localizer) copyChartHome(path string, clean bool) (string, error) {
path, err := filepath.Rel(lc.root.String(), lc.root.Join(path))
if err != nil {
return "", errors.WrapPrefixf(err, "no path to chart home %q", path)
}
// Chart home may serve as untar destination.
// Note that we don't check if path is in scope.
if !lc.fSys.Exists(lc.root.Join(path)) {
return path, nil
}
// Perform localize directory checks.
ldr, err := lc.ldr.New(path)
if err != nil {
return "", errors.WrapPrefixf(err, "invalid chart home")
}
cleaned, err := filesys.ConfirmDir(lc.fSys, ldr.Root())
if err != nil {
log.Panicf("unable to confirm validated directory %q: %s", ldr.Root(), err)
}
toDst := path
if clean {
toDst, err = filepath.Rel(lc.root.String(), cleaned.String())
if err != nil {
log.Panicf("no path between scoped directories %q and %q: %s", lc.root, cleaned, err)
}
}
// Note this check does not guarantee that we copied the entire directory.
if dst := filepath.Join(lc.dst, toDst); !lc.fSys.Exists(dst) {
err = lc.copyDir(cleaned, filepath.Join(lc.dst, toDst))
if err != nil {
return "", errors.WrapPrefixf(err, "unable to copy chart home %q", path)
}
}
return toDst, nil
}
// copyDir copies src to dst. copyDir does not follow symlinks.
func (lc *localizer) copyDir(src filesys.ConfirmedDir, dst string) error {
err := lc.fSys.Walk(src.String(),
func(path string, info fs.FileInfo, err error) error {
if err != nil {
return err
}
pathToCreate, err := filepath.Rel(src.String(), path)
if err != nil {
log.Panicf("no path from %q to child file %q: %s", src, path, err)
}
pathInDst := filepath.Join(dst, pathToCreate)
if info.Mode()&os.ModeSymlink == os.ModeSymlink {
return nil
}
if info.IsDir() {
err = lc.fSys.MkdirAll(pathInDst)
} else {
var content []byte
content, err = lc.fSys.ReadFile(path)
if err != nil {
return errors.Wrap(err)
}
err = lc.fSys.WriteFile(pathInDst, content)
}
return errors.Wrap(err)
})
if err != nil {
return errors.WrapPrefixf(err, "unable to copy directory %q", src)
}
return nil
}
// localizeBuiltinPlugins localizes built-in plugins on kust that can contain file paths. The built-in plugins
// can be inline or in a file. This excludes the HelmChartInflationGenerator.
//

View File

@@ -72,6 +72,10 @@ replacements:
delimiter: '='
index: 0
`
valuesFile = `minecraftServer:
difficulty: peaceful
`
)
func makeMemoryFs(t *testing.T) filesys.FileSystem {
@@ -208,10 +212,11 @@ patches:
func TestLoadKustomizationName(t *testing.T) {
kustomization := map[string]string{
"Kustomization": `apiVersion: kustomize.config.k8s.io/v1beta1
commonLabels:
label-one: value-one
label-two: value-two
kind: Kustomization
labels:
- pairs:
label-one: value-one
label-two: value-two
`,
}
checkLocalizeInTargetSuccess(t, kustomization)
@@ -235,14 +240,9 @@ func TestLoadGVKNN(t *testing.T) {
func TestLoadLegacyFields(t *testing.T) {
kustomization := map[string]string{
// TODO(annasong): Adjust test once localize handles helm.
"kustomization.yaml": `apiVersion: kustomize.config.k8s.io/v1beta1
helmChartInflationGenerator:
- chartName: minecraft
chartRepoUrl: https://kubernetes-charts.storage.googleapis.com
chartVersion: v1.2.0
releaseName: test
values: values.yaml
commonLabels:
app: bingo
imageTags:
- name: postgres
newName: my-registry/my-postgres
@@ -587,7 +587,7 @@ patches:
expected, actual := makeFileSystems(t, "/a/b", kustAndPatch)
err := Run("/a/b", "", "/dst", actual)
require.Error(t, err)
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)
}
@@ -1124,3 +1124,310 @@ resources:
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
`,
"file": 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)
err := Run("/a", "", "/dst", actual)
require.NoError(t, err)
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)
err := Run("/a/b", "/a/b", "/dst", actual)
require.NoError(t, err)
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"))
err := Run("/a", "", "/dst", actual)
require.NoError(t, err)
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 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,
})
})
}
}

View File

@@ -199,6 +199,10 @@ spec:
maxReplicas: 10`
urlQuery = "?submodules=0&ref=kustomize/v4.5.7&timeout=300"
valuesFile = `minecraftServer:
difficulty: peaceful
`
)
func link(t *testing.T, testDir filesys.ConfirmedDir, links map[string]string) {
@@ -267,7 +271,7 @@ func TestWorkingDir(t *testing.T) {
CheckFs(t, wd.String(), fsExpected, fsActual)
}
func TestSymlinks(t *testing.T) {
func TestLoaderSymlinks(t *testing.T) {
// test directory
// - link to target
// - link to base
@@ -500,3 +504,144 @@ func TestExistingCacheDir(t *testing.T) {
SetupDir(t, fsExpected, testDir.String(), file)
CheckFs(t, testDir.String(), fsExpected, fsActual)
}
func TestHelmNestedHome(t *testing.T) {
files := map[string]string{
"kustomization.yaml": fmt.Sprintf(`helmGlobals:
chartHome: %s
`, filepath.Join("nested", "dirs", "home")),
filepath.Join("nested", "dirs", "home", "name", "values.yaml"): `
minecraftServer:
difficulty: peaceful
`,
}
fsExpected, fsActual, testDir := PrepareFs(t, []string{
filepath.Join("nested", "dirs", "home", "name"),
}, files)
dst := testDir.Join("dst")
err := localizer.Run(fsActual, testDir.String(), "", dst)
require.NoError(t, err)
SetupDir(t, fsExpected, dst, files)
CheckFs(t, dst, fsExpected, fsActual)
}
func TestHelmLinkedHome(t *testing.T) {
// scope
// - target
// - kustomization
// - myValues.yaml
// - link to home
// - home
// - name
// - values.yaml
fsExpected, fsActual, scope := PrepareFs(t, []string{
"target",
filepath.Join("home", "name"),
},
map[string]string{
filepath.Join("target", "Kustomization"): `helmCharts:
- name: name
valuesFile: myValues.yaml
helmGlobals:
chartHome: home-link
`,
filepath.Join("target", "myValues.yaml"): valuesFile,
filepath.Join("home", "name", "values.yaml"): valuesFile,
})
link(t, scope, map[string]string{
filepath.Join("target", "home-link"): "home",
})
dst := scope.Join("dst")
err := localizer.Run(fsActual, scope.Join("target"), scope.String(), dst)
require.NoError(t, err)
SetupDir(t, fsExpected, dst, map[string]string{
filepath.Join("target", "Kustomization"): fmt.Sprintf(`helmCharts:
- name: name
valuesFile: myValues.yaml
helmGlobals:
chartHome: %s
`, filepath.Join("..", "home")),
filepath.Join("target", "myValues.yaml"): valuesFile,
filepath.Join("home", "name", "values.yaml"): valuesFile,
})
CheckFs(t, dst, fsExpected, fsActual)
}
func TestHelmLinkedDefaultHome(t *testing.T) {
// target
// - kustomization
// - link to home (named charts)
// - home
// - name
// - values.yaml
fsExpected, fsActual, target := PrepareFs(t, []string{
filepath.Join("home", "default"),
filepath.Join("home", "same"),
}, map[string]string{
"kustomization.yaml": fmt.Sprintf(`helmCharts:
- name: default
helmChartInflationGenerator:
- chartHome: %s
chartName: same
`, filepath.Join("home", "..", "charts")),
filepath.Join("home", "default", "values.yaml"): valuesFile,
filepath.Join("home", "same", "values.yaml"): valuesFile,
})
link(t, target, map[string]string{"charts": "home"})
dst := target.Join("dst")
err := localizer.Run(fsActual, target.String(), "", dst)
require.NoError(t, err)
SetupDir(t, fsExpected, dst, map[string]string{
"kustomization.yaml": `helmChartInflationGenerator:
- chartHome: charts
chartName: same
helmCharts:
- name: default
`,
filepath.Join("charts", "default", "values.yaml"): valuesFile,
filepath.Join("charts", "same", "values.yaml"): valuesFile,
})
CheckFs(t, dst, fsExpected, fsActual)
}
func TestHelmHomeEscapesScope(t *testing.T) {
// test directory
// - dir
// - file
// - target (and scope)
// - kustomization
// - home
// - link to dir
// - link to file
fsExpected, fsActual, testDir := PrepareFs(t, []string{
"dir",
filepath.Join("target", "home"),
}, map[string]string{
"file": valuesFile,
filepath.Join("target", "kustomization.yaml"): `helmGlobals:
chartHome: home
`,
})
link(t, testDir, map[string]string{
filepath.Join("target", "home", "dir-link"): "dir",
filepath.Join("target", "home", "file-link"): "file",
})
dst := testDir.Join("dst")
err := localizer.Run(fsActual, testDir.Join("target"), "", dst)
require.NoError(t, err)
SetupDir(t, fsExpected, dst, map[string]string{
"kustomization.yaml": `helmGlobals:
chartHome: home
`,
})
require.NoError(t, fsExpected.Mkdir(filepath.Join(dst, "home")))
CheckFs(t, dst, fsExpected, fsActual)
}

View File

@@ -3,6 +3,8 @@
package types
const HelmDefaultHome = "charts"
type HelmGlobals struct {
// ChartHome is a file path, relative to the kustomization root,
// to a directory containing a subdirectory for each chart to be

View File

@@ -89,7 +89,7 @@ func (p *plugin) validateArgs() (err error) {
// the loader root (unless root restrictions are
// disabled, in which case this can be an absolute path).
if p.ChartHome == "" {
p.ChartHome = "charts"
p.ChartHome = types.HelmDefaultHome
}
// The ValuesFile may be consulted by the plugin, so it must