diff --git a/pkg/lint/rules/template.go b/pkg/lint/rules/template.go index 287968340..89fbaaf46 100644 --- a/pkg/lint/rules/template.go +++ b/pkg/lint/rules/template.go @@ -32,6 +32,7 @@ import ( apipath "k8s.io/apimachinery/pkg/api/validation/path" "k8s.io/apimachinery/pkg/util/validation/field" "k8s.io/apimachinery/pkg/util/yaml" + "k8s.io/apiserver/pkg/storage/names" "helm.sh/helm/v4/pkg/chart/v2/loader" chartutil "helm.sh/helm/v4/pkg/chart/v2/util" @@ -235,11 +236,15 @@ func validateYamlContent(err error) error { func validateMetadataName(obj *K8sYamlStruct) error { fn := validateMetadataNameFunc(obj) allErrs := field.ErrorList{} - for _, msg := range fn(obj.Metadata.Name, false) { - allErrs = append(allErrs, field.Invalid(field.NewPath("metadata").Child("name"), obj.Metadata.Name, msg)) + name := obj.Metadata.Name + if len(name) == 0 && len(obj.Metadata.GenerateName) != 0 { + name = names.SimpleNameGenerator.GenerateName(obj.Metadata.GenerateName) + } + for _, msg := range fn(name, false) { + allErrs = append(allErrs, field.Invalid(field.NewPath("metadata").Child("name"), name, msg)) } if len(allErrs) > 0 { - return errors.Wrapf(allErrs.ToAggregate(), "object name does not conform to Kubernetes naming requirements: %q", obj.Metadata.Name) + return errors.Wrapf(allErrs.ToAggregate(), "object name does not conform to Kubernetes naming requirements: %q", name) } return nil } @@ -351,6 +356,7 @@ type K8sYamlStruct struct { } type k8sYamlMetadata struct { - Namespace string - Name string + Namespace string + Name string + GenerateName string } diff --git a/pkg/lint/rules/template_test.go b/pkg/lint/rules/template_test.go index 7205ace6d..599ee299c 100644 --- a/pkg/lint/rules/template_test.go +++ b/pkg/lint/rules/template_test.go @@ -119,6 +119,15 @@ func TestMultiTemplateFail(t *testing.T) { } } +func TestGenerateName(t *testing.T) { + linter := support.Linter{ChartDir: "./testdata/generate-name"} + Templates(&linter, values, namespace, strict) + res := linter.Messages + if len(res) != 0 { + t.Fatalf("Unexpected error: %s", res[0].Err) + } +} + func TestValidateMetadataName(t *testing.T) { tests := []struct { obj *K8sYamlStruct diff --git a/pkg/lint/rules/testdata/generate-name/Chart.yaml b/pkg/lint/rules/testdata/generate-name/Chart.yaml new file mode 100644 index 000000000..bb0eaf4e3 --- /dev/null +++ b/pkg/lint/rules/testdata/generate-name/Chart.yaml @@ -0,0 +1,21 @@ +apiVersion: v2 +name: generate-name +description: A Helm chart for Kubernetes + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +version: 0.1.0 + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application and it is recommended to use it with quotes. +appVersion: "1.16.0" diff --git a/pkg/lint/rules/testdata/generate-name/templates/multi-fail.yaml b/pkg/lint/rules/testdata/generate-name/templates/multi-fail.yaml new file mode 100644 index 000000000..e44e73d05 --- /dev/null +++ b/pkg/lint/rules/testdata/generate-name/templates/multi-fail.yaml @@ -0,0 +1,13 @@ +apiVersion: batch/v1 +kind: Job +metadata: + generateName: test- +spec: + template: + spec: + containers: + - name: pi + image: perl + command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"] + restartPolicy: Never + backoffLimit: 4