mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-05-17 18:25:26 +00:00
support for more helm template args (#4926)
* support for more helm template args * move templateArgs and unit tests to api/types * undo package name change * use our own simple helm chart instead of forking one * add argument to AsHelmArgs * code review * lint errors
This commit is contained in:
@@ -110,6 +110,7 @@ linters-settings:
|
||||
gomnd:
|
||||
ignored-functions:
|
||||
- os.WriteFile
|
||||
- make
|
||||
gomoddirectives:
|
||||
replace-local: true
|
||||
gosec:
|
||||
|
||||
@@ -16,6 +16,7 @@ import (
|
||||
"sigs.k8s.io/kustomize/api/resmap"
|
||||
"sigs.k8s.io/kustomize/api/types"
|
||||
"sigs.k8s.io/kustomize/kyaml/errors"
|
||||
"sigs.k8s.io/kustomize/kyaml/kio"
|
||||
"sigs.k8s.io/yaml"
|
||||
)
|
||||
|
||||
@@ -86,12 +87,20 @@ func (p *HelmChartInflationGeneratorPlugin) validateArgs() (err error) {
|
||||
p.ChartHome = types.HelmDefaultHome
|
||||
}
|
||||
|
||||
// The ValuesFile may be consulted by the plugin, so it must
|
||||
// The ValuesFile(s) may be consulted by the plugin, so it must
|
||||
// be under the loader root (unless root restrictions are
|
||||
// disabled).
|
||||
if p.ValuesFile == "" {
|
||||
p.ValuesFile = filepath.Join(p.ChartHome, p.Name, "values.yaml")
|
||||
}
|
||||
for i, file := range p.AdditionalValuesFiles {
|
||||
// use Load() to enforce root restrictions
|
||||
if _, err := p.h.Loader().Load(file); err != nil {
|
||||
return errors.WrapPrefixf(err, "could not load additionalValuesFile")
|
||||
}
|
||||
// the additional values filepaths must be relative to the kust root
|
||||
p.AdditionalValuesFiles[i] = filepath.Join(p.h.Loader().Root(), file)
|
||||
}
|
||||
|
||||
if err = p.errIfIllegalValuesMerge(); err != nil {
|
||||
return err
|
||||
@@ -240,49 +249,28 @@ func (p *HelmChartInflationGeneratorPlugin) Generate() (rm resmap.ResMap, err er
|
||||
return nil, err
|
||||
}
|
||||
var stdout []byte
|
||||
stdout, err = p.runHelmCommand(p.templateCommand())
|
||||
stdout, err = p.runHelmCommand(p.AsHelmArgs(p.absChartHome()))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
rm, err = p.h.ResmapFactory().NewResMapFromBytes(stdout)
|
||||
if err == nil {
|
||||
rm, resMapErr := p.h.ResmapFactory().NewResMapFromBytes(stdout)
|
||||
if resMapErr == nil {
|
||||
return rm, nil
|
||||
}
|
||||
// try to remove the contents before first "---" because
|
||||
// helm may produce messages to stdout before it
|
||||
stdoutStr := string(stdout)
|
||||
if idx := strings.Index(stdoutStr, "\n---\n"); idx != -1 {
|
||||
return p.h.ResmapFactory().NewResMapFromBytes([]byte(stdoutStr[idx:]))
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
r := &kio.ByteReader{Reader: bytes.NewBufferString(string(stdout)), OmitReaderAnnotations: true}
|
||||
nodes, err := r.Read()
|
||||
|
||||
func (p *HelmChartInflationGeneratorPlugin) templateCommand() []string {
|
||||
args := []string{"template"}
|
||||
if p.ReleaseName != "" {
|
||||
args = append(args, p.ReleaseName)
|
||||
if len(nodes) != 0 {
|
||||
rm, err = p.h.ResmapFactory().NewResMapFromRNodeSlice(nodes)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not parse rnode slice into resource map: %w\n", err)
|
||||
}
|
||||
return rm, nil
|
||||
}
|
||||
if p.Namespace != "" {
|
||||
args = append(args, "--namespace", p.Namespace)
|
||||
}
|
||||
args = append(args, filepath.Join(p.absChartHome(), p.Name))
|
||||
if p.ValuesFile != "" {
|
||||
args = append(args, "--values", p.ValuesFile)
|
||||
}
|
||||
if p.ReleaseName == "" {
|
||||
// AFAICT, this doesn't work as intended due to a bug in helm.
|
||||
// See https://github.com/helm/helm/issues/6019
|
||||
// I've tried placing the flag before and after the name argument.
|
||||
args = append(args, "--generate-name")
|
||||
}
|
||||
if p.IncludeCRDs {
|
||||
args = append(args, "--include-crds")
|
||||
}
|
||||
if p.SkipHooks {
|
||||
args = append(args, "--no-hooks")
|
||||
}
|
||||
return args
|
||||
return nil, fmt.Errorf("could not parse bytes into resource map: %w\n", resMapErr)
|
||||
}
|
||||
|
||||
func (p *HelmChartInflationGeneratorPlugin) pullCommand() []string {
|
||||
|
||||
@@ -4,9 +4,12 @@
|
||||
package krusty_test
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
kusttest_test "sigs.k8s.io/kustomize/api/testutils/kusttest"
|
||||
"sigs.k8s.io/kustomize/kyaml/copyutil"
|
||||
)
|
||||
|
||||
const expectedHelm = `
|
||||
@@ -233,3 +236,193 @@ spec:
|
||||
type: ClusterIP
|
||||
`)
|
||||
}
|
||||
|
||||
func TestHelmChartInflationGeneratorMultipleValuesFiles(t *testing.T) {
|
||||
th := kusttest_test.MakeEnhancedHarnessWithTmpRoot(t)
|
||||
defer th.Reset()
|
||||
if err := th.ErrIfNoHelm(); err != nil {
|
||||
t.Skip("skipping: " + err.Error())
|
||||
}
|
||||
|
||||
copyValuesFilesTestChartsIntoHarness(t, th)
|
||||
|
||||
th.WriteK(th.GetRoot(), `
|
||||
helmCharts:
|
||||
- name: test-chart
|
||||
releaseName: test-chart
|
||||
additionalValuesFiles:
|
||||
- charts/valuesFiles/file1.yaml
|
||||
- charts/valuesFiles/file2.yaml
|
||||
`)
|
||||
|
||||
m := th.Run(th.GetRoot(), th.MakeOptionsPluginsEnabled())
|
||||
asYaml, err := m.AsYaml()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, string(asYaml), `apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
labels:
|
||||
chart: test-1.0.0
|
||||
name: my-deploy
|
||||
namespace: file-2
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: test
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- image: test-image-file1:file1
|
||||
imagePullPolicy: Never
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
annotations:
|
||||
helm.sh/hook: test
|
||||
name: test-chart
|
||||
`)
|
||||
}
|
||||
|
||||
func TestHelmChartInflationGeneratorApiVersions(t *testing.T) {
|
||||
th := kusttest_test.MakeEnhancedHarnessWithTmpRoot(t)
|
||||
defer th.Reset()
|
||||
if err := th.ErrIfNoHelm(); err != nil {
|
||||
t.Skip("skipping: " + err.Error())
|
||||
}
|
||||
|
||||
copyValuesFilesTestChartsIntoHarness(t, th)
|
||||
|
||||
th.WriteK(th.GetRoot(), `
|
||||
helmCharts:
|
||||
- name: test-chart
|
||||
releaseName: test-chart
|
||||
apiVersions:
|
||||
- foo/v1
|
||||
`)
|
||||
|
||||
m := th.Run(th.GetRoot(), th.MakeOptionsPluginsEnabled())
|
||||
asYaml, err := m.AsYaml()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, string(asYaml), `apiVersion: foo/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
labels:
|
||||
chart: test-1.0.0
|
||||
name: my-deploy
|
||||
namespace: default
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: test
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- image: test-image:v1.0.0
|
||||
imagePullPolicy: Always
|
||||
---
|
||||
apiVersion: foo/v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
annotations:
|
||||
helm.sh/hook: test
|
||||
name: test-chart
|
||||
`)
|
||||
}
|
||||
|
||||
func TestHelmChartInflationGeneratorSkipTests(t *testing.T) {
|
||||
th := kusttest_test.MakeEnhancedHarnessWithTmpRoot(t)
|
||||
defer th.Reset()
|
||||
if err := th.ErrIfNoHelm(); err != nil {
|
||||
t.Skip("skipping: " + err.Error())
|
||||
}
|
||||
|
||||
copyValuesFilesTestChartsIntoHarness(t, th)
|
||||
|
||||
th.WriteK(th.GetRoot(), `
|
||||
helmCharts:
|
||||
- name: test-chart
|
||||
releaseName: test-chart
|
||||
skipTests: true
|
||||
`)
|
||||
|
||||
m := th.Run(th.GetRoot(), th.MakeOptionsPluginsEnabled())
|
||||
asYaml, err := m.AsYaml()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, string(asYaml), `apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
labels:
|
||||
chart: test-1.0.0
|
||||
name: my-deploy
|
||||
namespace: default
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: test
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- image: test-image:v1.0.0
|
||||
imagePullPolicy: Always
|
||||
`)
|
||||
}
|
||||
|
||||
func TestHelmChartInflationGeneratorNameTemplate(t *testing.T) {
|
||||
th := kusttest_test.MakeEnhancedHarnessWithTmpRoot(t)
|
||||
defer th.Reset()
|
||||
if err := th.ErrIfNoHelm(); err != nil {
|
||||
t.Skip("skipping: " + err.Error())
|
||||
}
|
||||
|
||||
copyValuesFilesTestChartsIntoHarness(t, th)
|
||||
|
||||
th.WriteK(th.GetRoot(), `
|
||||
helmCharts:
|
||||
- name: test-chart
|
||||
nameTemplate: name-template
|
||||
`)
|
||||
|
||||
m := th.Run(th.GetRoot(), th.MakeOptionsPluginsEnabled())
|
||||
asYaml, err := m.AsYaml()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, string(asYaml), `apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
labels:
|
||||
chart: test-1.0.0
|
||||
name: my-deploy
|
||||
namespace: default
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: test
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- image: test-image:v1.0.0
|
||||
imagePullPolicy: Always
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
annotations:
|
||||
helm.sh/hook: test
|
||||
name: name-template
|
||||
`)
|
||||
}
|
||||
|
||||
func copyValuesFilesTestChartsIntoHarness(t *testing.T, th *kusttest_test.HarnessEnhanced) {
|
||||
t.Helper()
|
||||
|
||||
thDir := filepath.Join(th.GetRoot(), "charts")
|
||||
chartDir := "testdata/helmcharts"
|
||||
|
||||
fs := th.GetFSys()
|
||||
require.NoError(t, fs.MkdirAll(filepath.Join(thDir, "templates")))
|
||||
require.NoError(t, copyutil.CopyDir(th.GetFSys(), chartDir, thDir))
|
||||
}
|
||||
|
||||
5
api/krusty/testdata/helmcharts/test-chart/Chart.yaml
vendored
Normal file
5
api/krusty/testdata/helmcharts/test-chart/Chart.yaml
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
apiVersion: v1
|
||||
appVersion: "1.0"
|
||||
description: A simple test helm chart.
|
||||
name: test
|
||||
version: 1.0.0
|
||||
1
api/krusty/testdata/helmcharts/test-chart/README.md
vendored
Normal file
1
api/krusty/testdata/helmcharts/test-chart/README.md
vendored
Normal file
@@ -0,0 +1 @@
|
||||
This is a simple test chart.
|
||||
7
api/krusty/testdata/helmcharts/test-chart/templates/_helpers.tpl
vendored
Normal file
7
api/krusty/testdata/helmcharts/test-chart/templates/_helpers.tpl
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
{{- define "apiversion" -}}
|
||||
{{- if .Capabilities.APIVersions.Has "foo/v1" -}}
|
||||
foo/v1
|
||||
{{- else -}}
|
||||
apps/v1
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
18
api/krusty/testdata/helmcharts/test-chart/templates/deployment.yaml
vendored
Normal file
18
api/krusty/testdata/helmcharts/test-chart/templates/deployment.yaml
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
---
|
||||
apiVersion: {{ template "apiversion" . }}
|
||||
kind: Deployment
|
||||
metadata:
|
||||
labels:
|
||||
chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
|
||||
name: my-deploy
|
||||
namespace: {{ .Values.data.namespace }}
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: {{ .Chart.Name }}
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- image: "{{ .Values.data.image.name }}:{{ .Values.data.image.tag }}"
|
||||
imagePullPolicy: {{ .Values.data.image.imagePullPolicy }}
|
||||
6
api/krusty/testdata/helmcharts/test-chart/templates/tests/test-pod.yaml
vendored
Normal file
6
api/krusty/testdata/helmcharts/test-chart/templates/tests/test-pod.yaml
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
apiVersion: {{ template "apiversion" . }}
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: {{ .Release.Name }}
|
||||
annotations:
|
||||
"helm.sh/hook": test
|
||||
6
api/krusty/testdata/helmcharts/test-chart/values.yaml
vendored
Normal file
6
api/krusty/testdata/helmcharts/test-chart/values.yaml
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
data:
|
||||
namespace: default
|
||||
image:
|
||||
name: test-image
|
||||
tag: v1.0.0
|
||||
imagePullPolicy: Always
|
||||
5
api/krusty/testdata/helmcharts/valuesFiles/file1.yaml
vendored
Normal file
5
api/krusty/testdata/helmcharts/valuesFiles/file1.yaml
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
data:
|
||||
image:
|
||||
name: test-image-file1
|
||||
tag: file1
|
||||
imagePullPolicy: Never
|
||||
2
api/krusty/testdata/helmcharts/valuesFiles/file2.yaml
vendored
Normal file
2
api/krusty/testdata/helmcharts/valuesFiles/file2.yaml
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
data:
|
||||
namespace: file-2
|
||||
@@ -3,6 +3,8 @@
|
||||
|
||||
package types
|
||||
|
||||
import "path/filepath"
|
||||
|
||||
const HelmDefaultHome = "charts"
|
||||
|
||||
type HelmGlobals struct {
|
||||
@@ -57,7 +59,11 @@ type HelmChart struct {
|
||||
// in the helm template
|
||||
Namespace string `json:"namespace,omitempty" yaml:"namespace,omitempty"`
|
||||
|
||||
// ValuesFile is local file path to a values file to use _instead of_
|
||||
// AdditionalValuesFiles are local file paths to values files to be used in
|
||||
// addition to either the default values file or the values specified in ValuesFile.
|
||||
AdditionalValuesFiles []string `json:"additionalValuesFiles,omitempty" yaml:"additionalValuesFiles,omitempty"`
|
||||
|
||||
// ValuesFile is a local file path to a values file to use _instead of_
|
||||
// the default values that accompanied the chart.
|
||||
// The default values are in '{ChartHome}/{Name}/values.yaml'.
|
||||
ValuesFile string `json:"valuesFile,omitempty" yaml:"valuesFile,omitempty"`
|
||||
@@ -78,6 +84,15 @@ type HelmChart struct {
|
||||
// SkipHooks sets the --no-hooks flag when calling helm template. This prevents
|
||||
// helm from erroneously rendering test templates.
|
||||
SkipHooks bool `json:"skipHooks,omitempty" yaml:"skipHooks,omitempty"`
|
||||
|
||||
// ApiVersions is the kubernetes apiversions used for Capabilities.APIVersions
|
||||
ApiVersions []string `json:"apiVersions,omitempty" yaml:"apiVersions,omitempty"`
|
||||
|
||||
// NameTemplate is for specifying the name template used to name the release.
|
||||
NameTemplate string `json:"nameTemplate,omitempty" yaml:"nameTemplate,omitempty"`
|
||||
|
||||
// SkipTests skips tests from templated output.
|
||||
SkipTests bool `json:"skipTests,omitempty" yaml:"skipTests,omitempty"`
|
||||
}
|
||||
|
||||
// HelmChartArgs contains arguments to helm.
|
||||
@@ -126,3 +141,45 @@ func makeHelmChartFromHca(old *HelmChartArgs) (c HelmChart) {
|
||||
c.ReleaseName = old.ReleaseName
|
||||
return
|
||||
}
|
||||
|
||||
func (h HelmChart) AsHelmArgs(absChartHome string) []string {
|
||||
args := []string{"template"}
|
||||
if h.ReleaseName != "" {
|
||||
args = append(args, h.ReleaseName)
|
||||
} else {
|
||||
// AFAICT, this doesn't work as intended due to a bug in helm.
|
||||
// See https://github.com/helm/helm/issues/6019
|
||||
// I've tried placing the flag before and after the name argument.
|
||||
args = append(args, "--generate-name")
|
||||
}
|
||||
if h.Name != "" {
|
||||
args = append(args, filepath.Join(absChartHome, h.Name))
|
||||
}
|
||||
if h.Namespace != "" {
|
||||
args = append(args, "--namespace", h.Namespace)
|
||||
}
|
||||
if h.NameTemplate != "" {
|
||||
args = append(args, "--name-template", h.NameTemplate)
|
||||
}
|
||||
|
||||
if h.ValuesFile != "" {
|
||||
args = append(args, "-f", h.ValuesFile)
|
||||
}
|
||||
for _, valuesFile := range h.AdditionalValuesFiles {
|
||||
args = append(args, "-f", valuesFile)
|
||||
}
|
||||
|
||||
for _, apiVer := range h.ApiVersions {
|
||||
args = append(args, "--api-versions", apiVer)
|
||||
}
|
||||
if h.IncludeCRDs {
|
||||
args = append(args, "--include-crds")
|
||||
}
|
||||
if h.SkipTests {
|
||||
args = append(args, "--skip-tests")
|
||||
}
|
||||
if h.SkipHooks {
|
||||
args = append(args, "--no-hooks")
|
||||
}
|
||||
return args
|
||||
}
|
||||
|
||||
61
api/types/helmchartargs_test.go
Normal file
61
api/types/helmchartargs_test.go
Normal file
@@ -0,0 +1,61 @@
|
||||
// Copyright 2019 The Kubernetes Authors.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package types_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"sigs.k8s.io/kustomize/api/types"
|
||||
)
|
||||
|
||||
func TestAsHelmArgs(t *testing.T) {
|
||||
t.Run("use generate-name", func(t *testing.T) {
|
||||
p := types.HelmChart{
|
||||
Name: "chart-name",
|
||||
Version: "1.0.0",
|
||||
Repo: "https://helm.releases.hashicorp.com",
|
||||
ApiVersions: []string{"foo", "bar"},
|
||||
NameTemplate: "template",
|
||||
SkipTests: true,
|
||||
IncludeCRDs: true,
|
||||
SkipHooks: true,
|
||||
ValuesFile: "values",
|
||||
AdditionalValuesFiles: []string{"values1", "values2"},
|
||||
Namespace: "my-ns",
|
||||
}
|
||||
require.Equal(t, p.AsHelmArgs("/home/charts"),
|
||||
[]string{"template", "--generate-name",
|
||||
"/home/charts/chart-name",
|
||||
"--namespace", "my-ns",
|
||||
"--name-template", "template",
|
||||
"-f", "values",
|
||||
"-f", "values1", "-f", "values2",
|
||||
"--api-versions", "foo", "--api-versions", "bar",
|
||||
"--include-crds",
|
||||
"--skip-tests",
|
||||
"--no-hooks"})
|
||||
})
|
||||
|
||||
t.Run("use release-name", func(t *testing.T) {
|
||||
p := types.HelmChart{
|
||||
Name: "chart-name",
|
||||
Version: "1.0.0",
|
||||
Repo: "https://helm.releases.hashicorp.com",
|
||||
ApiVersions: []string{"foo", "bar"},
|
||||
NameTemplate: "template",
|
||||
ValuesFile: "values",
|
||||
AdditionalValuesFiles: []string{"values1", "values2"},
|
||||
Namespace: "my-ns",
|
||||
ReleaseName: "test",
|
||||
}
|
||||
require.Equal(t, p.AsHelmArgs("/home/charts"),
|
||||
[]string{"template", "test", "/home/charts/chart-name",
|
||||
"--namespace", "my-ns",
|
||||
"--name-template", "template",
|
||||
"-f", "values",
|
||||
"-f", "values1", "-f", "values2",
|
||||
"--api-versions", "foo", "--api-versions", "bar"})
|
||||
})
|
||||
}
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"sigs.k8s.io/kustomize/cmd/config/internal/commands"
|
||||
"sigs.k8s.io/kustomize/kyaml/copyutil"
|
||||
"sigs.k8s.io/kustomize/kyaml/filesys"
|
||||
"sigs.k8s.io/kustomize/kyaml/openapi"
|
||||
)
|
||||
|
||||
@@ -614,7 +615,7 @@ spec:
|
||||
defer openapi.ResetOpenAPI()
|
||||
sourceDir := filepath.Join("test", "testdata", test.dataset)
|
||||
baseDir := t.TempDir()
|
||||
copyutil.CopyDir(sourceDir, baseDir)
|
||||
assert.NoError(t, copyutil.CopyDir(filesys.MakeFsOnDisk(), sourceDir, baseDir))
|
||||
runner := commands.GetCatRunner("")
|
||||
actual := &bytes.Buffer{}
|
||||
runner.Command.SetOut(actual)
|
||||
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"sigs.k8s.io/kustomize/cmd/config/internal/commands"
|
||||
"sigs.k8s.io/kustomize/kyaml/copyutil"
|
||||
"sigs.k8s.io/kustomize/kyaml/filesys"
|
||||
"sigs.k8s.io/kustomize/kyaml/openapi"
|
||||
)
|
||||
|
||||
@@ -117,7 +118,7 @@ Deployment: 1
|
||||
defer openapi.ResetOpenAPI()
|
||||
sourceDir := filepath.Join("test", "testdata", test.dataset)
|
||||
baseDir := t.TempDir()
|
||||
copyutil.CopyDir(sourceDir, baseDir)
|
||||
assert.NoError(t, copyutil.CopyDir(filesys.MakeFsOnDisk(), sourceDir, baseDir))
|
||||
runner := commands.GetCountRunner("")
|
||||
actual := &bytes.Buffer{}
|
||||
runner.Command.SetOut(actual)
|
||||
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"sigs.k8s.io/kustomize/cmd/config/internal/commands"
|
||||
"sigs.k8s.io/kustomize/kyaml/copyutil"
|
||||
"sigs.k8s.io/kustomize/kyaml/filesys"
|
||||
)
|
||||
|
||||
// TestGrepCommand_files verifies grep reads the files and filters them
|
||||
@@ -396,7 +397,7 @@ spec:
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
sourceDir := filepath.Join("test", "testdata", test.dataset)
|
||||
baseDir := t.TempDir()
|
||||
copyutil.CopyDir(sourceDir, baseDir)
|
||||
assert.NoError(t, copyutil.CopyDir(filesys.MakeFsOnDisk(), sourceDir, baseDir))
|
||||
runner := commands.GetGrepRunner("")
|
||||
actual := &bytes.Buffer{}
|
||||
runner.Command.SetOut(actual)
|
||||
|
||||
@@ -12,12 +12,14 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/sergi/go-diff/diffmatchpatch"
|
||||
"sigs.k8s.io/kustomize/kyaml/errors"
|
||||
"sigs.k8s.io/kustomize/kyaml/filesys"
|
||||
"sigs.k8s.io/kustomize/kyaml/sets"
|
||||
)
|
||||
|
||||
// CopyDir copies a src directory to a dst directory. CopyDir skips copying the .git directory from the src.
|
||||
func CopyDir(src string, dst string) error {
|
||||
return filepath.Walk(src, func(path string, info os.FileInfo, err error) error {
|
||||
func CopyDir(fSys filesys.FileSystem, src string, dst string) error {
|
||||
return errors.Wrap(fSys.Walk(src, func(path string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -36,21 +38,21 @@ func CopyDir(src string, dst string) error {
|
||||
|
||||
// make directories that don't exist
|
||||
if info.IsDir() {
|
||||
return os.MkdirAll(filepath.Join(dst, copyTo), info.Mode())
|
||||
return errors.Wrap(fSys.MkdirAll(filepath.Join(dst, copyTo)))
|
||||
}
|
||||
|
||||
// copy file by reading and writing it
|
||||
b, err := os.ReadFile(filepath.Join(src, copyTo))
|
||||
b, err := fSys.ReadFile(filepath.Join(src, copyTo))
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
err = os.WriteFile(filepath.Join(dst, copyTo), b, info.Mode())
|
||||
err = fSys.WriteFile(filepath.Join(dst, copyTo), b)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
}))
|
||||
}
|
||||
|
||||
// Diff returns a list of files that differ between the source and destination.
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
. "sigs.k8s.io/kustomize/kyaml/copyutil"
|
||||
"sigs.k8s.io/kustomize/kyaml/filesys"
|
||||
)
|
||||
|
||||
// TestDiff_identical verifies identical directories return an empty set
|
||||
@@ -306,7 +307,7 @@ func TestCopyDir(t *testing.T) {
|
||||
|
||||
d := t.TempDir()
|
||||
|
||||
err = CopyDir(s, d)
|
||||
err = CopyDir(filesys.MakeFsOnDisk(), s, d)
|
||||
assert.NoError(t, err)
|
||||
|
||||
diff, err := Diff(d, v)
|
||||
|
||||
@@ -8,11 +8,11 @@ import (
|
||||
"runtime"
|
||||
"testing"
|
||||
|
||||
"sigs.k8s.io/kustomize/kyaml/testutil"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"sigs.k8s.io/kustomize/kyaml/copyutil"
|
||||
"sigs.k8s.io/kustomize/kyaml/filesys"
|
||||
"sigs.k8s.io/kustomize/kyaml/kio/filters"
|
||||
"sigs.k8s.io/kustomize/kyaml/testutil"
|
||||
)
|
||||
|
||||
func TestMerge3_Merge(t *testing.T) {
|
||||
@@ -29,6 +29,7 @@ func TestMerge3_Merge(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
|
||||
if !assert.NoError(t, copyutil.CopyDir(
|
||||
filesys.MakeFsOnDisk(),
|
||||
filepath.Join(datadir, "dataset1-localupdates"),
|
||||
filepath.Join(dir, "dataset1"))) {
|
||||
t.FailNow()
|
||||
@@ -71,6 +72,7 @@ func TestMerge3_Merge_path(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
|
||||
if !assert.NoError(t, copyutil.CopyDir(
|
||||
filesys.MakeFsOnDisk(),
|
||||
filepath.Join(datadir, "dataset1-localupdates"),
|
||||
filepath.Join(dir, "dataset1"))) {
|
||||
t.FailNow()
|
||||
@@ -112,6 +114,7 @@ func TestMerge3_Merge_fail(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
|
||||
if !assert.NoError(t, copyutil.CopyDir(
|
||||
filesys.MakeFsOnDisk(),
|
||||
filepath.Join(datadir, "dataset1-localupdates"),
|
||||
filepath.Join(dir, "dataset1"))) {
|
||||
t.FailNow()
|
||||
|
||||
@@ -14,9 +14,9 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"sigs.k8s.io/kustomize/kyaml/copyutil"
|
||||
"sigs.k8s.io/kustomize/kyaml/errors"
|
||||
"sigs.k8s.io/kustomize/kyaml/filesys"
|
||||
"sigs.k8s.io/kustomize/kyaml/fn/runtime/container"
|
||||
"sigs.k8s.io/kustomize/kyaml/fn/runtime/runtimeutil"
|
||||
"sigs.k8s.io/kustomize/kyaml/kio"
|
||||
@@ -1272,7 +1272,7 @@ func setupTest(t *testing.T) string {
|
||||
if !assert.NoError(t, err) {
|
||||
t.FailNow()
|
||||
}
|
||||
if !assert.NoError(t, copyutil.CopyDir(ds, dir)) {
|
||||
if !assert.NoError(t, copyutil.CopyDir(filesys.MakeFsOnDisk(), ds, dir)) {
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ import (
|
||||
"sigs.k8s.io/kustomize/api/resmap"
|
||||
"sigs.k8s.io/kustomize/api/types"
|
||||
"sigs.k8s.io/kustomize/kyaml/errors"
|
||||
"sigs.k8s.io/kustomize/kyaml/kio"
|
||||
"sigs.k8s.io/yaml"
|
||||
)
|
||||
|
||||
@@ -92,12 +93,20 @@ func (p *plugin) validateArgs() (err error) {
|
||||
p.ChartHome = types.HelmDefaultHome
|
||||
}
|
||||
|
||||
// The ValuesFile may be consulted by the plugin, so it must
|
||||
// The ValuesFile(s) may be consulted by the plugin, so it must
|
||||
// be under the loader root (unless root restrictions are
|
||||
// disabled).
|
||||
if p.ValuesFile == "" {
|
||||
p.ValuesFile = filepath.Join(p.ChartHome, p.Name, "values.yaml")
|
||||
}
|
||||
for i, file := range p.AdditionalValuesFiles {
|
||||
// use Load() to enforce root restrictions
|
||||
if _, err := p.h.Loader().Load(file); err != nil {
|
||||
return errors.WrapPrefixf(err, "could not load additionalValuesFile")
|
||||
}
|
||||
// the additional values filepaths must be relative to the kust root
|
||||
p.AdditionalValuesFiles[i] = filepath.Join(p.h.Loader().Root(), file)
|
||||
}
|
||||
|
||||
if err = p.errIfIllegalValuesMerge(); err != nil {
|
||||
return err
|
||||
@@ -246,49 +255,28 @@ func (p *plugin) Generate() (rm resmap.ResMap, err error) {
|
||||
return nil, err
|
||||
}
|
||||
var stdout []byte
|
||||
stdout, err = p.runHelmCommand(p.templateCommand())
|
||||
stdout, err = p.runHelmCommand(p.AsHelmArgs(p.absChartHome()))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
rm, err = p.h.ResmapFactory().NewResMapFromBytes(stdout)
|
||||
if err == nil {
|
||||
rm, resMapErr := p.h.ResmapFactory().NewResMapFromBytes(stdout)
|
||||
if resMapErr == nil {
|
||||
return rm, nil
|
||||
}
|
||||
// try to remove the contents before first "---" because
|
||||
// helm may produce messages to stdout before it
|
||||
stdoutStr := string(stdout)
|
||||
if idx := strings.Index(stdoutStr, "\n---\n"); idx != -1 {
|
||||
return p.h.ResmapFactory().NewResMapFromBytes([]byte(stdoutStr[idx:]))
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
r := &kio.ByteReader{Reader: bytes.NewBufferString(string(stdout)), OmitReaderAnnotations: true}
|
||||
nodes, err := r.Read()
|
||||
|
||||
func (p *plugin) templateCommand() []string {
|
||||
args := []string{"template"}
|
||||
if p.ReleaseName != "" {
|
||||
args = append(args, p.ReleaseName)
|
||||
if len(nodes) != 0 {
|
||||
rm, err = p.h.ResmapFactory().NewResMapFromRNodeSlice(nodes)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not parse rnode slice into resource map: %w\n", err)
|
||||
}
|
||||
return rm, nil
|
||||
}
|
||||
if p.Namespace != "" {
|
||||
args = append(args, "--namespace", p.Namespace)
|
||||
}
|
||||
args = append(args, filepath.Join(p.absChartHome(), p.Name))
|
||||
if p.ValuesFile != "" {
|
||||
args = append(args, "--values", p.ValuesFile)
|
||||
}
|
||||
if p.ReleaseName == "" {
|
||||
// AFAICT, this doesn't work as intended due to a bug in helm.
|
||||
// See https://github.com/helm/helm/issues/6019
|
||||
// I've tried placing the flag before and after the name argument.
|
||||
args = append(args, "--generate-name")
|
||||
}
|
||||
if p.IncludeCRDs {
|
||||
args = append(args, "--include-crds")
|
||||
}
|
||||
if p.SkipHooks {
|
||||
args = append(args, "--no-hooks")
|
||||
}
|
||||
return args
|
||||
return nil, fmt.Errorf("could not parse bytes into resource map: %w\n", resMapErr)
|
||||
}
|
||||
|
||||
func (p *plugin) pullCommand() []string {
|
||||
|
||||
Reference in New Issue
Block a user