diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 93d13558..7ac3052f 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -13,6 +13,7 @@ ## Bug Fixes * [#352](https://github.com/suse-edge/edge-image-builder/issues/352) - Resizing raw images results in dracut-pre-mount failure +* [#359](https://github.com/suse-edge/edge-image-builder/issues/359) - Helm validation does not check if a chart uses an undefined repository --- diff --git a/pkg/image/validation/kubernetes.go b/pkg/image/validation/kubernetes.go index 0c45734b..3f0671c9 100644 --- a/pkg/image/validation/kubernetes.go +++ b/pkg/image/validation/kubernetes.go @@ -161,6 +161,11 @@ func validateHelm(k8s *image.Kubernetes, imageConfigDir string) []FailedValidati return failures } + var helmRepositoryNames []string + for _, repo := range k8s.Helm.Repositories { + helmRepositoryNames = append(helmRepositoryNames, repo.Name) + } + if failure := validateHelmChartDuplicates(k8s.Helm.Charts); failure != "" { failures = append(failures, FailedValidation{ UserMessage: failure, @@ -170,7 +175,7 @@ func validateHelm(k8s *image.Kubernetes, imageConfigDir string) []FailedValidati seenHelmRepos := make(map[string]bool) for _, chart := range k8s.Helm.Charts { c := chart - failures = append(failures, validateChart(&c, imageConfigDir)...) + failures = append(failures, validateChart(&c, helmRepositoryNames, imageConfigDir)...) seenHelmRepos[chart.RepositoryName] = true } @@ -183,7 +188,7 @@ func validateHelm(k8s *image.Kubernetes, imageConfigDir string) []FailedValidati return failures } -func validateChart(chart *image.HelmChart, imageConfigDir string) []FailedValidation { +func validateChart(chart *image.HelmChart, repositoryNames []string, imageConfigDir string) []FailedValidation { var failures []FailedValidation if chart.Name == "" { @@ -196,6 +201,10 @@ func validateChart(chart *image.HelmChart, imageConfigDir string) []FailedValida failures = append(failures, FailedValidation{ UserMessage: fmt.Sprintf("Helm chart 'repositoryName' field for %q must be defined.", chart.Name), }) + } else if !slices.Contains(repositoryNames, chart.RepositoryName) { + failures = append(failures, FailedValidation{ + UserMessage: fmt.Sprintf("Helm chart 'repositoryName' %q for Helm chart %q does not match the name of any defined repository.", chart.RepositoryName, chart.Name), + }) } if chart.Version == "" { diff --git a/pkg/image/validation/kubernetes_test.go b/pkg/image/validation/kubernetes_test.go index 5a16e85c..19e0dbfc 100644 --- a/pkg/image/validation/kubernetes_test.go +++ b/pkg/image/validation/kubernetes_test.go @@ -97,6 +97,7 @@ func TestValidateKubernetes(t *testing.T) { "Entries in 'urls' must begin with either 'http://' or 'https://'.", "Helm chart 'name' field must be defined.", "Helm repository 'name' field for \"apache-repo\" must match the 'repositoryName' field in at least one defined Helm chart.", + "Helm chart 'repositoryName' \"another-apache-repo\" for Helm chart \"\" does not match the name of any defined repository.", }, }, } @@ -481,7 +482,7 @@ func TestValidateHelmCharts(t *testing.T) { "Helm chart 'name' field must be defined.", }, }, - `helm chart no repository name`: { + `helm chart undefined repository name`: { K8s: image.Kubernetes{ Helm: image.Helm{ Charts: []image.HelmChart{ @@ -508,6 +509,33 @@ func TestValidateHelmCharts(t *testing.T) { "Helm chart 'repositoryName' field for \"metallb\" must be defined.", }, }, + `helm chart no matching repository name`: { + K8s: image.Kubernetes{ + Helm: image.Helm{ + Charts: []image.HelmChart{ + { + Name: "kubevirt", + RepositoryName: "suse-edge", + Version: "0.2.2", + }, + { + Name: "metallb", + RepositoryName: "this-is-not-suse-edge", + Version: "0.14.3", + }, + }, + Repositories: []image.HelmRepository{ + { + Name: "suse-edge", + URL: "https://suse-edge.github.io/charts", + }, + }, + }, + }, + ExpectedFailedMessages: []string{ + "Helm chart 'repositoryName' \"this-is-not-suse-edge\" for Helm chart \"metallb\" does not match the name of any defined repository.", + }, + }, `helm chart no version`: { K8s: image.Kubernetes{ Helm: image.Helm{