Privatize 'k8sYamlStruct'

Signed-off-by: George Jenkins <gvjenkins@gmail.com>
pull/31029/head
George Jenkins 3 months ago
parent edd0dabe02
commit 4c674728d2

@ -47,7 +47,7 @@ func (e deprecatedAPIError) Error() string {
return msg return msg
} }
func validateNoDeprecations(resource *K8sYamlStruct, kubeVersion *chartutil.KubeVersion) error { func validateNoDeprecations(resource *k8sYamlStruct, kubeVersion *chartutil.KubeVersion) error {
// if `resource` does not have an APIVersion or Kind, we cannot test it for deprecation // if `resource` does not have an APIVersion or Kind, we cannot test it for deprecation
if resource.APIVersion == "" { if resource.APIVersion == "" {
return nil return nil
@ -92,7 +92,7 @@ func validateNoDeprecations(resource *K8sYamlStruct, kubeVersion *chartutil.Kube
} }
} }
func resourceToRuntimeObject(resource *K8sYamlStruct) (runtime.Object, error) { func resourceToRuntimeObject(resource *k8sYamlStruct) (runtime.Object, error) {
scheme := runtime.NewScheme() scheme := runtime.NewScheme()
kscheme.AddToScheme(scheme) kscheme.AddToScheme(scheme)

@ -19,7 +19,7 @@ package rules // import "helm.sh/helm/v4/pkg/lint/rules"
import "testing" import "testing"
func TestValidateNoDeprecations(t *testing.T) { func TestValidateNoDeprecations(t *testing.T) {
deprecated := &K8sYamlStruct{ deprecated := &k8sYamlStruct{
APIVersion: "extensions/v1beta1", APIVersion: "extensions/v1beta1",
Kind: "Deployment", Kind: "Deployment",
} }
@ -32,7 +32,7 @@ func TestValidateNoDeprecations(t *testing.T) {
t.Fatalf("Expected error message to be non-blank: %v", err) t.Fatalf("Expected error message to be non-blank: %v", err)
} }
if err := validateNoDeprecations(&K8sYamlStruct{ if err := validateNoDeprecations(&k8sYamlStruct{
APIVersion: "v1", APIVersion: "v1",
Kind: "Pod", Kind: "Pod",
}, nil); err != nil { }, nil); err != nil {

@ -139,9 +139,9 @@ func TemplatesWithSkipSchemaValidation(linter *support.Linter, values map[string
// Lint all resources if the file contains multiple documents separated by --- // Lint all resources if the file contains multiple documents separated by ---
for { for {
// Even though K8sYamlStruct only defines a few fields, an error in any other // Even though k8sYamlStruct only defines a few fields, an error in any other
// key will be raised as well // key will be raised as well
var yamlStruct *K8sYamlStruct var yamlStruct *k8sYamlStruct
err := decoder.Decode(&yamlStruct) err := decoder.Decode(&yamlStruct)
if err == io.EOF { if err == io.EOF {
@ -224,7 +224,7 @@ func validateYamlContent(err error) error {
// validateMetadataName uses the correct validation function for the object // validateMetadataName uses the correct validation function for the object
// Kind, or if not set, defaults to the standard definition of a subdomain in // Kind, or if not set, defaults to the standard definition of a subdomain in
// DNS (RFC 1123), used by most resources. // DNS (RFC 1123), used by most resources.
func validateMetadataName(obj *K8sYamlStruct) error { func validateMetadataName(obj *k8sYamlStruct) error {
fn := validateMetadataNameFunc(obj) fn := validateMetadataNameFunc(obj)
allErrs := field.ErrorList{} allErrs := field.ErrorList{}
for _, msg := range fn(obj.Metadata.Name, false) { for _, msg := range fn(obj.Metadata.Name, false) {
@ -249,7 +249,7 @@ func validateMetadataName(obj *K8sYamlStruct) error {
// If no mapping is defined, returns NameIsDNSSubdomain. This is used by object // If no mapping is defined, returns NameIsDNSSubdomain. This is used by object
// kinds that don't have special requirements, so is the most likely to work if // kinds that don't have special requirements, so is the most likely to work if
// new kinds are added. // new kinds are added.
func validateMetadataNameFunc(obj *K8sYamlStruct) validation.ValidateNameFunc { func validateMetadataNameFunc(obj *k8sYamlStruct) validation.ValidateNameFunc {
switch strings.ToLower(obj.Kind) { switch strings.ToLower(obj.Kind) {
case "pod", "node", "secret", "endpoints", "resourcequota", // core case "pod", "node", "secret", "endpoints", "resourcequota", // core
"controllerrevision", "daemonset", "deployment", "replicaset", "statefulset", // apps "controllerrevision", "daemonset", "deployment", "replicaset", "statefulset", // apps
@ -285,7 +285,7 @@ func validateMetadataNameFunc(obj *K8sYamlStruct) validation.ValidateNameFunc {
// validateMatchSelector ensures that template specs have a selector declared. // validateMatchSelector ensures that template specs have a selector declared.
// See https://github.com/helm/helm/issues/1990 // See https://github.com/helm/helm/issues/1990
func validateMatchSelector(yamlStruct *K8sYamlStruct, manifest string) error { func validateMatchSelector(yamlStruct *k8sYamlStruct, manifest string) error {
switch yamlStruct.Kind { switch yamlStruct.Kind {
case "Deployment", "ReplicaSet", "DaemonSet", "StatefulSet": case "Deployment", "ReplicaSet", "DaemonSet", "StatefulSet":
// verify that matchLabels or matchExpressions is present // verify that matchLabels or matchExpressions is present
@ -296,7 +296,7 @@ func validateMatchSelector(yamlStruct *K8sYamlStruct, manifest string) error {
return nil return nil
} }
func validateListAnnotations(yamlStruct *K8sYamlStruct, manifest string) error { func validateListAnnotations(yamlStruct *k8sYamlStruct, manifest string) error {
if yamlStruct.Kind == "List" { if yamlStruct.Kind == "List" {
m := struct { m := struct {
Items []struct { Items []struct {
@ -319,11 +319,8 @@ func validateListAnnotations(yamlStruct *K8sYamlStruct, manifest string) error {
return nil return nil
} }
// K8sYamlStruct stubs a Kubernetes YAML file. // k8sYamlStruct stubs a Kubernetes YAML file.
// type k8sYamlStruct struct {
// DEPRECATED: In Helm 4, this will be made a private type, as it is for use only within
// the rules package.
type K8sYamlStruct struct {
APIVersion string `json:"apiVersion"` APIVersion string `json:"apiVersion"`
Kind string Kind string
Metadata k8sYamlMetadata Metadata k8sYamlMetadata

@ -101,76 +101,76 @@ func TestMultiTemplateFail(t *testing.T) {
func TestValidateMetadataName(t *testing.T) { func TestValidateMetadataName(t *testing.T) {
tests := []struct { tests := []struct {
obj *K8sYamlStruct obj *k8sYamlStruct
wantErr bool wantErr bool
}{ }{
// Most kinds use IsDNS1123Subdomain. // Most kinds use IsDNS1123Subdomain.
{&K8sYamlStruct{Kind: "Pod", Metadata: k8sYamlMetadata{Name: ""}}, true}, {&k8sYamlStruct{Kind: "Pod", Metadata: k8sYamlMetadata{Name: ""}}, true},
{&K8sYamlStruct{Kind: "Pod", Metadata: k8sYamlMetadata{Name: "foo"}}, false}, {&k8sYamlStruct{Kind: "Pod", Metadata: k8sYamlMetadata{Name: "foo"}}, false},
{&K8sYamlStruct{Kind: "Pod", Metadata: k8sYamlMetadata{Name: "foo.bar1234baz.seventyone"}}, false}, {&k8sYamlStruct{Kind: "Pod", Metadata: k8sYamlMetadata{Name: "foo.bar1234baz.seventyone"}}, false},
{&K8sYamlStruct{Kind: "Pod", Metadata: k8sYamlMetadata{Name: "FOO"}}, true}, {&k8sYamlStruct{Kind: "Pod", Metadata: k8sYamlMetadata{Name: "FOO"}}, true},
{&K8sYamlStruct{Kind: "Pod", Metadata: k8sYamlMetadata{Name: "123baz"}}, false}, {&k8sYamlStruct{Kind: "Pod", Metadata: k8sYamlMetadata{Name: "123baz"}}, false},
{&K8sYamlStruct{Kind: "Pod", Metadata: k8sYamlMetadata{Name: "foo.BAR.baz"}}, true}, {&k8sYamlStruct{Kind: "Pod", Metadata: k8sYamlMetadata{Name: "foo.BAR.baz"}}, true},
{&K8sYamlStruct{Kind: "Pod", Metadata: k8sYamlMetadata{Name: "one-two"}}, false}, {&k8sYamlStruct{Kind: "Pod", Metadata: k8sYamlMetadata{Name: "one-two"}}, false},
{&K8sYamlStruct{Kind: "Pod", Metadata: k8sYamlMetadata{Name: "-two"}}, true}, {&k8sYamlStruct{Kind: "Pod", Metadata: k8sYamlMetadata{Name: "-two"}}, true},
{&K8sYamlStruct{Kind: "Pod", Metadata: k8sYamlMetadata{Name: "one_two"}}, true}, {&k8sYamlStruct{Kind: "Pod", Metadata: k8sYamlMetadata{Name: "one_two"}}, true},
{&K8sYamlStruct{Kind: "Pod", Metadata: k8sYamlMetadata{Name: "a..b"}}, true}, {&k8sYamlStruct{Kind: "Pod", Metadata: k8sYamlMetadata{Name: "a..b"}}, true},
{&K8sYamlStruct{Kind: "Pod", Metadata: k8sYamlMetadata{Name: "%^&#$%*@^*@&#^"}}, true}, {&k8sYamlStruct{Kind: "Pod", Metadata: k8sYamlMetadata{Name: "%^&#$%*@^*@&#^"}}, true},
{&K8sYamlStruct{Kind: "Pod", Metadata: k8sYamlMetadata{Name: "operator:pod"}}, true}, {&k8sYamlStruct{Kind: "Pod", Metadata: k8sYamlMetadata{Name: "operator:pod"}}, true},
{&K8sYamlStruct{Kind: "ServiceAccount", Metadata: k8sYamlMetadata{Name: "foo"}}, false}, {&k8sYamlStruct{Kind: "ServiceAccount", Metadata: k8sYamlMetadata{Name: "foo"}}, false},
{&K8sYamlStruct{Kind: "ServiceAccount", Metadata: k8sYamlMetadata{Name: "foo.bar1234baz.seventyone"}}, false}, {&k8sYamlStruct{Kind: "ServiceAccount", Metadata: k8sYamlMetadata{Name: "foo.bar1234baz.seventyone"}}, false},
{&K8sYamlStruct{Kind: "ServiceAccount", Metadata: k8sYamlMetadata{Name: "FOO"}}, true}, {&k8sYamlStruct{Kind: "ServiceAccount", Metadata: k8sYamlMetadata{Name: "FOO"}}, true},
{&K8sYamlStruct{Kind: "ServiceAccount", Metadata: k8sYamlMetadata{Name: "operator:sa"}}, true}, {&k8sYamlStruct{Kind: "ServiceAccount", Metadata: k8sYamlMetadata{Name: "operator:sa"}}, true},
// Service uses IsDNS1035Label. // Service uses IsDNS1035Label.
{&K8sYamlStruct{Kind: "Service", Metadata: k8sYamlMetadata{Name: "foo"}}, false}, {&k8sYamlStruct{Kind: "Service", Metadata: k8sYamlMetadata{Name: "foo"}}, false},
{&K8sYamlStruct{Kind: "Service", Metadata: k8sYamlMetadata{Name: "123baz"}}, true}, {&k8sYamlStruct{Kind: "Service", Metadata: k8sYamlMetadata{Name: "123baz"}}, true},
{&K8sYamlStruct{Kind: "Service", Metadata: k8sYamlMetadata{Name: "foo.bar"}}, true}, {&k8sYamlStruct{Kind: "Service", Metadata: k8sYamlMetadata{Name: "foo.bar"}}, true},
// Namespace uses IsDNS1123Label. // Namespace uses IsDNS1123Label.
{&K8sYamlStruct{Kind: "Namespace", Metadata: k8sYamlMetadata{Name: "foo"}}, false}, {&k8sYamlStruct{Kind: "Namespace", Metadata: k8sYamlMetadata{Name: "foo"}}, false},
{&K8sYamlStruct{Kind: "Namespace", Metadata: k8sYamlMetadata{Name: "123baz"}}, false}, {&k8sYamlStruct{Kind: "Namespace", Metadata: k8sYamlMetadata{Name: "123baz"}}, false},
{&K8sYamlStruct{Kind: "Namespace", Metadata: k8sYamlMetadata{Name: "foo.bar"}}, true}, {&k8sYamlStruct{Kind: "Namespace", Metadata: k8sYamlMetadata{Name: "foo.bar"}}, true},
{&K8sYamlStruct{Kind: "Namespace", Metadata: k8sYamlMetadata{Name: "foo-bar"}}, false}, {&k8sYamlStruct{Kind: "Namespace", Metadata: k8sYamlMetadata{Name: "foo-bar"}}, false},
// CertificateSigningRequest has no validation. // CertificateSigningRequest has no validation.
{&K8sYamlStruct{Kind: "CertificateSigningRequest", Metadata: k8sYamlMetadata{Name: ""}}, false}, {&k8sYamlStruct{Kind: "CertificateSigningRequest", Metadata: k8sYamlMetadata{Name: ""}}, false},
{&K8sYamlStruct{Kind: "CertificateSigningRequest", Metadata: k8sYamlMetadata{Name: "123baz"}}, false}, {&k8sYamlStruct{Kind: "CertificateSigningRequest", Metadata: k8sYamlMetadata{Name: "123baz"}}, false},
{&K8sYamlStruct{Kind: "CertificateSigningRequest", Metadata: k8sYamlMetadata{Name: "%^&#$%*@^*@&#^"}}, false}, {&k8sYamlStruct{Kind: "CertificateSigningRequest", Metadata: k8sYamlMetadata{Name: "%^&#$%*@^*@&#^"}}, false},
// RBAC uses path validation. // RBAC uses path validation.
{&K8sYamlStruct{Kind: "Role", Metadata: k8sYamlMetadata{Name: "foo"}}, false}, {&k8sYamlStruct{Kind: "Role", Metadata: k8sYamlMetadata{Name: "foo"}}, false},
{&K8sYamlStruct{Kind: "Role", Metadata: k8sYamlMetadata{Name: "123baz"}}, false}, {&k8sYamlStruct{Kind: "Role", Metadata: k8sYamlMetadata{Name: "123baz"}}, false},
{&K8sYamlStruct{Kind: "Role", Metadata: k8sYamlMetadata{Name: "foo.bar"}}, false}, {&k8sYamlStruct{Kind: "Role", Metadata: k8sYamlMetadata{Name: "foo.bar"}}, false},
{&K8sYamlStruct{Kind: "Role", Metadata: k8sYamlMetadata{Name: "operator:role"}}, false}, {&k8sYamlStruct{Kind: "Role", Metadata: k8sYamlMetadata{Name: "operator:role"}}, false},
{&K8sYamlStruct{Kind: "Role", Metadata: k8sYamlMetadata{Name: "operator/role"}}, true}, {&k8sYamlStruct{Kind: "Role", Metadata: k8sYamlMetadata{Name: "operator/role"}}, true},
{&K8sYamlStruct{Kind: "Role", Metadata: k8sYamlMetadata{Name: "operator%role"}}, true}, {&k8sYamlStruct{Kind: "Role", Metadata: k8sYamlMetadata{Name: "operator%role"}}, true},
{&K8sYamlStruct{Kind: "ClusterRole", Metadata: k8sYamlMetadata{Name: "foo"}}, false}, {&k8sYamlStruct{Kind: "ClusterRole", Metadata: k8sYamlMetadata{Name: "foo"}}, false},
{&K8sYamlStruct{Kind: "ClusterRole", Metadata: k8sYamlMetadata{Name: "123baz"}}, false}, {&k8sYamlStruct{Kind: "ClusterRole", Metadata: k8sYamlMetadata{Name: "123baz"}}, false},
{&K8sYamlStruct{Kind: "ClusterRole", Metadata: k8sYamlMetadata{Name: "foo.bar"}}, false}, {&k8sYamlStruct{Kind: "ClusterRole", Metadata: k8sYamlMetadata{Name: "foo.bar"}}, false},
{&K8sYamlStruct{Kind: "ClusterRole", Metadata: k8sYamlMetadata{Name: "operator:role"}}, false}, {&k8sYamlStruct{Kind: "ClusterRole", Metadata: k8sYamlMetadata{Name: "operator:role"}}, false},
{&K8sYamlStruct{Kind: "ClusterRole", Metadata: k8sYamlMetadata{Name: "operator/role"}}, true}, {&k8sYamlStruct{Kind: "ClusterRole", Metadata: k8sYamlMetadata{Name: "operator/role"}}, true},
{&K8sYamlStruct{Kind: "ClusterRole", Metadata: k8sYamlMetadata{Name: "operator%role"}}, true}, {&k8sYamlStruct{Kind: "ClusterRole", Metadata: k8sYamlMetadata{Name: "operator%role"}}, true},
{&K8sYamlStruct{Kind: "RoleBinding", Metadata: k8sYamlMetadata{Name: "operator:role"}}, false}, {&k8sYamlStruct{Kind: "RoleBinding", Metadata: k8sYamlMetadata{Name: "operator:role"}}, false},
{&K8sYamlStruct{Kind: "ClusterRoleBinding", Metadata: k8sYamlMetadata{Name: "operator:role"}}, false}, {&k8sYamlStruct{Kind: "ClusterRoleBinding", Metadata: k8sYamlMetadata{Name: "operator:role"}}, false},
// Unknown Kind // Unknown Kind
{&K8sYamlStruct{Kind: "FutureKind", Metadata: k8sYamlMetadata{Name: ""}}, true}, {&k8sYamlStruct{Kind: "FutureKind", Metadata: k8sYamlMetadata{Name: ""}}, true},
{&K8sYamlStruct{Kind: "FutureKind", Metadata: k8sYamlMetadata{Name: "foo"}}, false}, {&k8sYamlStruct{Kind: "FutureKind", Metadata: k8sYamlMetadata{Name: "foo"}}, false},
{&K8sYamlStruct{Kind: "FutureKind", Metadata: k8sYamlMetadata{Name: "foo.bar1234baz.seventyone"}}, false}, {&k8sYamlStruct{Kind: "FutureKind", Metadata: k8sYamlMetadata{Name: "foo.bar1234baz.seventyone"}}, false},
{&K8sYamlStruct{Kind: "FutureKind", Metadata: k8sYamlMetadata{Name: "FOO"}}, true}, {&k8sYamlStruct{Kind: "FutureKind", Metadata: k8sYamlMetadata{Name: "FOO"}}, true},
{&K8sYamlStruct{Kind: "FutureKind", Metadata: k8sYamlMetadata{Name: "123baz"}}, false}, {&k8sYamlStruct{Kind: "FutureKind", Metadata: k8sYamlMetadata{Name: "123baz"}}, false},
{&K8sYamlStruct{Kind: "FutureKind", Metadata: k8sYamlMetadata{Name: "foo.BAR.baz"}}, true}, {&k8sYamlStruct{Kind: "FutureKind", Metadata: k8sYamlMetadata{Name: "foo.BAR.baz"}}, true},
{&K8sYamlStruct{Kind: "FutureKind", Metadata: k8sYamlMetadata{Name: "one-two"}}, false}, {&k8sYamlStruct{Kind: "FutureKind", Metadata: k8sYamlMetadata{Name: "one-two"}}, false},
{&K8sYamlStruct{Kind: "FutureKind", Metadata: k8sYamlMetadata{Name: "-two"}}, true}, {&k8sYamlStruct{Kind: "FutureKind", Metadata: k8sYamlMetadata{Name: "-two"}}, true},
{&K8sYamlStruct{Kind: "FutureKind", Metadata: k8sYamlMetadata{Name: "one_two"}}, true}, {&k8sYamlStruct{Kind: "FutureKind", Metadata: k8sYamlMetadata{Name: "one_two"}}, true},
{&K8sYamlStruct{Kind: "FutureKind", Metadata: k8sYamlMetadata{Name: "a..b"}}, true}, {&k8sYamlStruct{Kind: "FutureKind", Metadata: k8sYamlMetadata{Name: "a..b"}}, true},
{&K8sYamlStruct{Kind: "FutureKind", Metadata: k8sYamlMetadata{Name: "%^&#$%*@^*@&#^"}}, true}, {&k8sYamlStruct{Kind: "FutureKind", Metadata: k8sYamlMetadata{Name: "%^&#$%*@^*@&#^"}}, true},
{&K8sYamlStruct{Kind: "FutureKind", Metadata: k8sYamlMetadata{Name: "operator:pod"}}, true}, {&k8sYamlStruct{Kind: "FutureKind", Metadata: k8sYamlMetadata{Name: "operator:pod"}}, true},
// No kind // No kind
{&K8sYamlStruct{Metadata: k8sYamlMetadata{Name: "foo"}}, false}, {&k8sYamlStruct{Metadata: k8sYamlMetadata{Name: "foo"}}, false},
{&K8sYamlStruct{Metadata: k8sYamlMetadata{Name: "operator:pod"}}, true}, {&k8sYamlStruct{Metadata: k8sYamlMetadata{Name: "operator:pod"}}, true},
} }
for _, tt := range tests { for _, tt := range tests {
t.Run(fmt.Sprintf("%s/%s", tt.obj.Kind, tt.obj.Metadata.Name), func(t *testing.T) { t.Run(fmt.Sprintf("%s/%s", tt.obj.Kind, tt.obj.Metadata.Name), func(t *testing.T) {
@ -273,7 +273,7 @@ func TestStrictTemplateParsingMapError(t *testing.T) {
} }
func TestValidateMatchSelector(t *testing.T) { func TestValidateMatchSelector(t *testing.T) {
md := &K8sYamlStruct{ md := &k8sYamlStruct{
APIVersion: "apps/v1", APIVersion: "apps/v1",
Kind: "Deployment", Kind: "Deployment",
Metadata: k8sYamlMetadata{ Metadata: k8sYamlMetadata{
@ -401,7 +401,7 @@ func TestEmptyWithCommentsManifests(t *testing.T) {
} }
} }
func TestValidateListAnnotations(t *testing.T) { func TestValidateListAnnotations(t *testing.T) {
md := &K8sYamlStruct{ md := &k8sYamlStruct{
APIVersion: "v1", APIVersion: "v1",
Kind: "List", Kind: "List",
Metadata: k8sYamlMetadata{ Metadata: k8sYamlMetadata{

Loading…
Cancel
Save