Repository: helm/helm

Issue #9197: Helm lint fails due to ":" character in .metadata.name
Created: 2021-01-06T13:14:45Z
Many default clusterroles and clusterrolebindings contain the character : in .metadata.name, for instance system:coredns, system:controller:deployment-controller etc.
Helm validation is throwing the following error for object names containing : :
[ERROR] templates/clusterrolebinding.yaml: object name does not conform to Kubernetes naming requirements: "eks:kube-proxy": invalid metadata name, must match regex ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ and the length must not be longer than 253

I believe this is a bug as these objects are accepted by the kube-apiserver.
This bug exists from Helm version 3.3.0 on.
In Helm version 3.2.4 linting for the objects with : works fine.
Output of helm version:
version.BuildInfo{Version:"v3.4.2", GitCommit:"23dd3af5e19a02d4f4baa5b2f242645a1a3af629", GitTreeState:"dirty", GoVersion:"go1.15.5"}
Output of kubectl version:
Client Version: version.Info{Major:"1", Minor:"19", GitVersion:"v1.19.4", GitCommit:"d360454c9bcd1634cf4cc52d1867af5491dc9c5f", GitTreeState:"clean", BuildDate:"2020-11-12T01:09:16Z", GoVersion:"go1.15.4", Compiler:"gc", Platform:"darwin/amd64"}
Server Version: version.Info{Major:"1", Minor:"18+", GitVersion:"v1.18.9-eks-d1db3c", GitCommit:"d1db3c46e55f95d6a7d3e5578689371318f95ff9", GitTreeState:"clean", BuildDate:"2020-10-20T22:18:07Z", GoVersion:"go1.13.15", Compiler:"gc", Platform:"linux/amd64"}
Cloud Provider/Platform (AKS, GKE, Minikube etc.):
AWS

Duplicate issue #9203: Lint: helm/pkg/lint validation rule mismatch k8s validation rule
Created: 2021-01-07T11:37:36Z
Output of helm version:
version.BuildInfo{Version:"v3.4.2", GitCommit:"23dd3af5e19a02d4f4baa5b2f242645a1a3af629", GitTreeState:"clean", GoVersion:"go1.14.13"}
Output of kubectl version:
Client Version: version.Info{Major:"1", Minor:"19", GitVersion:"v1.19.0", GitCommit:"e19964183377d0ec2052d1f1fa930c4d7575bd50", GitTreeState:"clean", BuildDate:"2020-08-26T14:30:33Z", GoVersion:"go1.15", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"19", GitVersion:"v1.19.0", GitCommit:"e19964183377d0ec2052d1f1fa930c4d7575bd50", GitTreeState:"clean", BuildDate:"2020-08-26T14:23:04Z", GoVersion:"go1.15", Compiler:"gc", Platform:"linux/amd64"}
Cloud Provider/Platform (AKS, GKE, Minikube etc.):
self-building Kubernetes cluster
Reproduce step:

get tidb-opeartor.tgz helm package here: http://charts.pingcap.org/tidb-operator-v1.1.5.tgz
decompress the archive package
helm lint tidb-operato
it shows:

==> Linting tidb-operator
[INFO] Chart.yaml: icon is recommended
[ERROR] templates/controller-manager-rbac.yaml: object name does not conform to Kubernetes naming requirements: "test-release:tidb-controller-manager": invalid metadata name, must match regex ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ and the length must not be longer than 253
[ERROR] templates/controller-manager-rbac.yaml: the kind "rbac.authorization.k8s.io/v1beta1 ClusterRole" is deprecated in favor of "rbac.authorization.k8s.io/v1 ClusterRole"
[ERROR] templates/controller-manager-rbac.yaml: object name does not conform to Kubernetes naming requirements: "test-release:tidb-controller-manager": invalid metadata name, must match regex ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ and the length must not be longer than 253
[ERROR] templates/controller-manager-rbac.yaml: the kind "rbac.authorization.k8s.io/v1beta1 ClusterRoleBinding" is deprecated in favor of "rbac.authorization.k8s.io/v1 ClusterRoleBinding"
[ERROR] templates/scheduler-rbac.yaml: object name does not conform to Kubernetes naming requirements: "test-release:tidb-scheduler": invalid metadata name, must match regex ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ and the length must not be longer than 253
[ERROR] templates/scheduler-rbac.yaml: the kind "rbac.authorization.k8s.io/v1beta1 ClusterRole" is deprecated in favor of "rbac.authorization.k8s.io/v1 ClusterRole"
[ERROR] templates/scheduler-rbac.yaml: object name does not conform to Kubernetes naming requirements: "test-release:tidb-scheduler": invalid metadata name, must match regex ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ and the length must not be longer than 253
[ERROR] templates/scheduler-rbac.yaml: the kind "rbac.authorization.k8s.io/v1beta1 ClusterRoleBinding" is deprecated in favor of "rbac.authorization.k8s.io/v1 ClusterRoleBinding"
[ERROR] templates/scheduler-rbac.yaml: object name does not conform to Kubernetes naming requirements: "test-release:kube-scheduler": invalid metadata name, must match regex ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ and the length must not be longer than 253
[ERROR] templates/scheduler-rbac.yaml: the kind "rbac.authorization.k8s.io/v1beta1 ClusterRoleBinding" is deprecated in favor of "rbac.authorization.k8s.io/v1 ClusterRoleBinding"
[ERROR] templates/scheduler-rbac.yaml: object name does not conform to Kubernetes naming requirements: "test-release:volume-scheduler": invalid metadata name, must match regex ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ and the length must not be longer than 253
[ERROR] templates/scheduler-rbac.yaml: the kind "rbac.authorization.k8s.io/v1beta1 ClusterRoleBinding" is deprecated in favor of "rbac.authorization.k8s.io/v1 ClusterRoleBinding"

Error: 1 chart(s) linted, 1 chart(s) failed
Bug:
I have dig into helm3  implementation and got the pr and backaground of the following code:
pr：https://github.com/helm/helm/pull/8011/files#diff-99d16582249b9bc470365aac41d280cf0bd6a14ccac1a96151b45479e05d2c2bR133
relative issue：#7672
  if yamlStruct != nil {
	  linter.RunLinterRule(support.ErrorSev, fpath, validateMetadataName(yamlStruct))
	  linter.RunLinterRule(support.ErrorSev, fpath, validateNoDeprecations(yamlStruct))
	  linter.RunLinterRule(support.ErrorSev, fpath, validateMatchSelector(yamlStruct, renderedContent))
  }

  func validateMetadataName(obj *K8sYamlStruct) error {
	  if len(obj.Metadata.Name) == 0 || len(obj.Metadata.Name) > 253 {
		  return fmt.Errorf("object name must be between 0 and 253 characters: %q", obj.Metadata.Name)
	  }
	  // This will return an error if the characters do not abide by the standard OR if the
	  // name is left empty.
	  if err := chartutil.ValidateMetadataName(obj.Metadata.Name); err != nil {
		  return errors.Wrapf(err, "object name does not conform to Kubernetes naming requirements: %q", obj.Metadata.Name)
	  }
	  return nil
  }

  // ValidateMetadataName validates the name field of a Kubernetes metadata object.
  //
  // Empty strings, strings longer than 253 chars, or strings that don't match the regexp
  // will fail.
  //
  // According to the Kubernetes help text, the regular expression it uses is:
  //
  //	[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*
  //
  // This follows the above regular expression (but requires a full string match, not partial).
  //
  // The Kubernetes documentation is here, though it is not entirely correct:
  // https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
  func ValidateMetadataName(name string) error {
	  if name == "" || len(name) > maxMetadataNameLen || !validName.MatchString(name) {
		  return errInvalidKubernetesName
	  }
	  return nil
  }

// validName is a regular expression for resource names.
//
// According to the Kubernetes help text, the regular expression it uses is:
//
//	[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*
//
// This follows the above regular expression (but requires a full string match, not partial).
//
// The Kubernetes documentation is here, though it is not entirely correct:
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
var validName = regexp.MustCompile(`^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$`)
It's clear that helmv3（after release-3.3） check all the name value  under metadata domain with RFC 1123.  It simply assume that  all the kubernetes-object name obey the RFC 1123 rule. However, kubernetes does not require all the object's metadata name obey the RFC 1123. Just like
rbac name-ValidateRBACName
UT
I think helmv3 deal with the metadata name too simply and rudely. Shall we keep track of Kubernetes'  step?

Closing comment (2021-01-07T16:16:59Z): closing as a duplicate of #9197.