Skip to content

Commit

Permalink
Helm API Versions (#506)
Browse files Browse the repository at this point in the history
helm api versions
  • Loading branch information
dbw7 committed Jul 30, 2024
1 parent 665a623 commit be1f355
Show file tree
Hide file tree
Showing 10 changed files with 34 additions and 19 deletions.
1 change: 1 addition & 0 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
## Bug Fixes

* [#498](https://github.com/suse-edge/edge-image-builder/issues/498) - Fix kernelArgs issue with Leap Micro 6.0
* [#481](https://github.com/suse-edge/edge-image-builder/issues/481) - Certain Helm charts fail when templated without specified API Versions

---

Expand Down
10 changes: 7 additions & 3 deletions pkg/helm/helm.go
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ func pullCommand(chart string, repo *image.HelmRepository, version, destDir, cer
return cmd
}

func (h *Helm) Template(chart, repository, version, valuesFilePath, kubeVersion, targetNamespace string) ([]map[string]any, error) {
func (h *Helm) Template(chart, repository, version, valuesFilePath, kubeVersion, targetNamespace string, apiVersions []string) ([]map[string]any, error) {
logFile := filepath.Join(h.outputDir, templateLogFileName)

file, err := os.OpenFile(logFile, outputFileFlags, fileio.NonExecutablePerms)
Expand All @@ -224,7 +224,7 @@ func (h *Helm) Template(chart, repository, version, valuesFilePath, kubeVersion,
}()

chartContentsBuffer := new(strings.Builder)
cmd := templateCommand(chart, repository, version, valuesFilePath, kubeVersion, targetNamespace, io.MultiWriter(file, chartContentsBuffer), file)
cmd := templateCommand(chart, repository, version, valuesFilePath, kubeVersion, targetNamespace, apiVersions, io.MultiWriter(file, chartContentsBuffer), file)

if _, err = fmt.Fprintf(file, "command: %s\n", cmd); err != nil {
return nil, fmt.Errorf("writing command prefix to log file: %w", err)
Expand All @@ -243,7 +243,7 @@ func (h *Helm) Template(chart, repository, version, valuesFilePath, kubeVersion,
return resources, nil
}

func templateCommand(chart, repository, version, valuesFilePath, kubeVersion, targetNamespace string, stdout, stderr io.Writer) *exec.Cmd {
func templateCommand(chart, repository, version, valuesFilePath, kubeVersion, targetNamespace string, apiVersions []string, stdout, stderr io.Writer) *exec.Cmd {
var args []string
args = append(args, "template", "--skip-crds", chart, repository)

Expand All @@ -259,6 +259,10 @@ func templateCommand(chart, repository, version, valuesFilePath, kubeVersion, ta
args = append(args, "-f", valuesFilePath)
}

if len(apiVersions) != 0 {
args = append(args, "--api-versions", strings.Join(apiVersions, ","))
}

args = append(args, "--kube-version", kubeVersion)

cmd := exec.Command("helm", args...)
Expand Down
6 changes: 5 additions & 1 deletion pkg/helm/helm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -502,6 +502,7 @@ func TestTemplateCommand(t *testing.T) {
repo string
chart string
version string
apiVersions []string
kubeVersion string
targetNamespace string
valuesPath string
Expand All @@ -512,6 +513,7 @@ func TestTemplateCommand(t *testing.T) {
repo: "suse-edge/kubevirt",
chart: "kubevirt",
version: "0.2.1",
apiVersions: []string{"batch/v1", "apps/v1/Deployment"},
kubeVersion: "v1.29.0+rke2r1",
targetNamespace: "kubevirt-ns",
valuesPath: "/kubevirt/values.yaml",
Expand All @@ -527,6 +529,8 @@ func TestTemplateCommand(t *testing.T) {
"0.2.1",
"-f",
"/kubevirt/values.yaml",
"--api-versions",
"batch/v1,apps/v1/Deployment",
"--kube-version",
"v1.29.0+rke2r1",
},
Expand All @@ -553,7 +557,7 @@ func TestTemplateCommand(t *testing.T) {

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
cmd := templateCommand(test.chart, test.repo, test.version, test.valuesPath, test.kubeVersion, test.targetNamespace, &stdout, &stderr)
cmd := templateCommand(test.chart, test.repo, test.version, test.valuesPath, test.kubeVersion, test.targetNamespace, test.apiVersions, &stdout, &stderr)

assert.Equal(t, test.expectedArgs, cmd.Args)
assert.Equal(t, &stdout, cmd.Stdout)
Expand Down
15 changes: 8 additions & 7 deletions pkg/image/definition.go
Original file line number Diff line number Diff line change
Expand Up @@ -210,13 +210,14 @@ type Helm struct {
}

type HelmChart struct {
Name string `yaml:"name"`
RepositoryName string `yaml:"repositoryName"`
Version string `yaml:"version"`
TargetNamespace string `yaml:"targetNamespace"`
CreateNamespace bool `yaml:"createNamespace"`
InstallationNamespace string `yaml:"installationNamespace"`
ValuesFile string `yaml:"valuesFile"`
Name string `yaml:"name"`
RepositoryName string `yaml:"repositoryName"`
Version string `yaml:"version"`
TargetNamespace string `yaml:"targetNamespace"`
CreateNamespace bool `yaml:"createNamespace"`
InstallationNamespace string `yaml:"installationNamespace"`
ValuesFile string `yaml:"valuesFile"`
APIVersions []string `yaml:"apiVersions"`
}

type HelmRepository struct {
Expand Down
2 changes: 2 additions & 0 deletions pkg/image/definition_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,8 @@ func TestParse(t *testing.T) {
assert.Equal(t, true, kubernetes.Helm.Charts[0].CreateNamespace)
assert.Equal(t, "apache-system", kubernetes.Helm.Charts[0].InstallationNamespace)
assert.Equal(t, "apache-values.yaml", kubernetes.Helm.Charts[0].ValuesFile)
assert.Equal(t, "batch/v1", kubernetes.Helm.Charts[0].APIVersions[0])
assert.Equal(t, "apps/v1/Deployment", kubernetes.Helm.Charts[0].APIVersions[1])

assert.Equal(t, "metallb", kubernetes.Helm.Charts[1].Name)
assert.Equal(t, "suse-edge", kubernetes.Helm.Charts[1].RepositoryName)
Expand Down
3 changes: 3 additions & 0 deletions pkg/image/testdata/full-valid-example.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,9 @@ kubernetes:
createNamespace: true
installationNamespace: apache-system
valuesFile: apache-values.yaml
apiVersions:
- batch/v1
- apps/v1/Deployment
- name: metallb
repositoryName: suse-edge
version: 0.14.3
Expand Down
2 changes: 1 addition & 1 deletion pkg/registry/helm.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ func (r *Registry) helmChartImages() ([]string, error) {
}

func (r *Registry) getChartContainerImages(chart *image.HelmChart, chartPath, valuesPath, kubeVersion string) ([]string, error) {
chartResources, err := r.helmClient.Template(chart.Name, chartPath, chart.Version, valuesPath, kubeVersion, chart.TargetNamespace)
chartResources, err := r.helmClient.Template(chart.Name, chartPath, chart.Version, valuesPath, kubeVersion, chart.TargetNamespace, chart.APIVersions)
if err != nil {
return nil, fmt.Errorf("templating chart: %w", err)
}
Expand Down
10 changes: 5 additions & 5 deletions pkg/registry/helm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ type mockHelmClient struct {
addRepoFunc func(repository *image.HelmRepository) error
registryLoginFunc func(repository *image.HelmRepository) error
pullFunc func(chart string, repository *image.HelmRepository, version, destDir string) (string, error)
templateFunc func(chart, repository, version, valuesFilePath, kubeVersion, targetNamespace string) ([]map[string]any, error)
templateFunc func(chart, repository, version, valuesFilePath, kubeVersion, targetNamespace string, apiVersions []string) ([]map[string]any, error)
}

func (m mockHelmClient) AddRepo(repository *image.HelmRepository) error {
Expand All @@ -40,9 +40,9 @@ func (m mockHelmClient) Pull(chart string, repository *image.HelmRepository, ver
panic("not implemented")
}

func (m mockHelmClient) Template(chart, repository, version, valuesFilePath, kubeVersion, targetNamespace string) ([]map[string]any, error) {
func (m mockHelmClient) Template(chart, repository, version, valuesFilePath, kubeVersion, targetNamespace string, apiVersions []string) ([]map[string]any, error) {
if m.templateFunc != nil {
return m.templateFunc(chart, repository, version, valuesFilePath, kubeVersion, targetNamespace)
return m.templateFunc(chart, repository, version, valuesFilePath, kubeVersion, targetNamespace, apiVersions)
}
panic("not implemented")
}
Expand All @@ -68,7 +68,7 @@ func TestRegistry_HelmChartImages_TemplateError(t *testing.T) {
},
},
helmClient: mockHelmClient{
templateFunc: func(chart, repository, version, valuesFilePath, kubeVersion, targetNamespace string) ([]map[string]any, error) {
templateFunc: func(chart, repository, version, valuesFilePath, kubeVersion, targetNamespace string, apiVersions []string) ([]map[string]any, error) {
return nil, fmt.Errorf("failed templating")
},
},
Expand All @@ -92,7 +92,7 @@ func TestRegistry_HelmChartImages(t *testing.T) {
},
},
helmClient: mockHelmClient{
templateFunc: func(chart, repository, version, valuesFilePath, kubeVersion, targetNamespace string) ([]map[string]any, error) {
templateFunc: func(chart, repository, version, valuesFilePath, kubeVersion, targetNamespace string, apiVersions []string) ([]map[string]any, error) {
return []map[string]any{
{
"kind": "Deployment",
Expand Down
2 changes: 1 addition & 1 deletion pkg/registry/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ type helmClient interface {
AddRepo(repository *image.HelmRepository) error
RegistryLogin(repository *image.HelmRepository) error
Pull(chart string, repository *image.HelmRepository, version, destDir string) (string, error)
Template(chart, repository, version, valuesFilePath, kubeVersion, targetNamespace string) ([]map[string]any, error)
Template(chart, repository, version, valuesFilePath, kubeVersion, targetNamespace string, apiVersions []string) ([]map[string]any, error)
}

type helmChart struct {
Expand Down
2 changes: 1 addition & 1 deletion pkg/registry/registry_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ func TestRegistry_ContainerImages(t *testing.T) {
},
},
helmClient: mockHelmClient{
templateFunc: func(chart, repository, version, valuesFilePath, kubeVersion, targetNamespace string) ([]map[string]any, error) {
templateFunc: func(chart, repository, version, valuesFilePath, kubeVersion, targetNamespace string, apiVersions []string) ([]map[string]any, error) {
return []map[string]any{
{
"kind": "Deployment",
Expand Down

0 comments on commit be1f355

Please sign in to comment.