From 629579069e0d55482bc1b513dd9535da8ed895d1 Mon Sep 17 00:00:00 2001 From: Joe Julian Date: Thu, 3 Sep 2020 15:23:40 -0700 Subject: [PATCH] use new upstream deprecations Signed-off-by: Joe Julian --- pkg/lint/rules/deprecations.go | 221 ++++++---------------------- pkg/lint/rules/deprecations_test.go | 5 +- 2 files changed, 48 insertions(+), 178 deletions(-) diff --git a/pkg/lint/rules/deprecations.go b/pkg/lint/rules/deprecations.go index acd6ad017..0c53e331b 100644 --- a/pkg/lint/rules/deprecations.go +++ b/pkg/lint/rules/deprecations.go @@ -16,193 +16,64 @@ limitations under the License. package rules // import "helm.sh/helm/v3/pkg/lint/rules" -import "fmt" +import ( + "fmt" -type deprecatedAPI struct { - NewAPI string - DeprecatedIn string - RemovedIn string -} + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apiserver/pkg/endpoints/deprecation" + kscheme "k8s.io/client-go/kubernetes/scheme" +) -// deprecatedAPIs lists APIs that are deprecated (key) with suggested alternatives (value). -var deprecatedAPIs = map[string]deprecatedAPI{ - "extensions/v1beta1 Deployment": { - NewAPI: "apps/v1 Deployment", - DeprecatedIn: "v1.9", - RemovedIn: "v1.16", - }, - "apps/v1beta1 Deployment": { - NewAPI: "apps/v1 Deployment", - DeprecatedIn: "v1.9", - RemovedIn: "v1.16", - }, - "apps/v1beta2 Deployment": { - NewAPI: "apps/v1 Deployment", - DeprecatedIn: "v1.9", - RemovedIn: "v1.16", - }, - "apps/v1beta1 StatefulSet": { - NewAPI: "apps/v1 StatefulSet", - DeprecatedIn: "v1.9", - RemovedIn: "v1.16", - }, - "apps/v1beta2 StatefulSet": { - NewAPI: "apps/v1 StatefulSet", - DeprecatedIn: "v1.9", - RemovedIn: "v1.16", - }, - "extensions/v1beta1 DaemonSet": { - NewAPI: "apps/v1 DaemonSet", - DeprecatedIn: "v1.9", - RemovedIn: "v1.16", - }, - "apps/v1beta2 DaemonSet": { - NewAPI: "apps/v1 DaemonSet", - DeprecatedIn: "v1.9", - RemovedIn: "v1.16", - }, - "extensions/v1beta1 ReplicaSet": { - NewAPI: "apps/v1 ReplicaSet", - DeprecatedIn: "v1.9", - RemovedIn: "v1.16", - }, - "apps/v1beta1 ReplicaSet": { - NewAPI: "apps/v1 ReplicaSet", - DeprecatedIn: "v1.9", - RemovedIn: "v1.16", - }, - "apps/v1beta2 ReplicaSet": { - NewAPI: "apps/v1 ReplicaSet", - DeprecatedIn: "v1.9", - RemovedIn: "v1.16", - }, - "extensions/v1beta1 NetworkPolicy": { - NewAPI: "networking.k8s.io/v1 NetworkPolicy", - DeprecatedIn: "v1.8", - RemovedIn: "v1.16", - }, - "extensions/v1beta1 PodSecurityPolicy": { - NewAPI: "policy/v1beta1 PodSecurityPolicy", - DeprecatedIn: "v1.10", - RemovedIn: "v1.16", - }, - "apiextensions.k8s.io/v1beta1 CustomResourceDefinition": { - NewAPI: "apiextensions.k8s.io/v1 CustomResourceDefinition", - DeprecatedIn: "v1.16", - RemovedIn: "v1.19", - }, - "extensions/v1beta1 Ingress": { - NewAPI: "networking.k8s.io/v1beta1 Ingress", - DeprecatedIn: "v1.14", - RemovedIn: "v1.22", - }, - "rbac.authorization.k8s.io/v1alpha1 ClusterRole": { - NewAPI: "rbac.authorization.k8s.io/v1 ClusterRole", - DeprecatedIn: "v1.17", - RemovedIn: "v1.22", - }, - "rbac.authorization.k8s.io/v1alpha1 ClusterRoleList": { - NewAPI: "rbac.authorization.k8s.io/v1 ClusterRoleList", - DeprecatedIn: "v1.17", - RemovedIn: "v1.22", - }, - "rbac.authorization.k8s.io/v1alpha1 ClusterRoleBinding": { - NewAPI: "rbac.authorization.k8s.io/v1 ClusterRoleBinding", - DeprecatedIn: "v1.17", - RemovedIn: "v1.22", - }, - "rbac.authorization.k8s.io/v1alpha1 ClusterRoleBindingList": { - NewAPI: "rbac.authorization.k8s.io/v1 ClusterRoleBindingList", - DeprecatedIn: "v1.17", - RemovedIn: "v1.22", - }, - "rbac.authorization.k8s.io/v1alpha1 Role": { - NewAPI: "rbac.authorization.k8s.io/v1 Role", - DeprecatedIn: "v1.17", - RemovedIn: "v1.22", - }, - "rbac.authorization.k8s.io/v1alpha1 RoleList": { - NewAPI: "rbac.authorization.k8s.io/v1 RoleList", - DeprecatedIn: "v1.17", - RemovedIn: "v1.22", - }, - "rbac.authorization.k8s.io/v1alpha1 RoleBinding": { - NewAPI: "rbac.authorization.k8s.io/v1 RoleBinding", - DeprecatedIn: "v1.17", - RemovedIn: "v1.22", - }, - "rbac.authorization.k8s.io/v1alpha1 RoleBindingList": { - NewAPI: "rbac.authorization.k8s.io/v1 RoleBindingList", - DeprecatedIn: "v1.17", - RemovedIn: "v1.22", - }, - "rbac.authorization.k8s.io/v1beta ClusterRole": { - NewAPI: "rbac.authorization.k8s.io/v1 ClusterRole", - DeprecatedIn: "v1.17", - RemovedIn: "v1.22", - }, - "rbac.authorization.k8s.io/v1beta1 ClusterRoleList": { - NewAPI: "rbac.authorization.k8s.io/v1 ClusterRoleList", - DeprecatedIn: "v1.17", - RemovedIn: "v1.22", - }, - "rbac.authorization.k8s.io/v1beta1 ClusterRoleBinding": { - NewAPI: "rbac.authorization.k8s.io/v1 ClusterRoleBinding", - DeprecatedIn: "v1.17", - RemovedIn: "v1.22", - }, - "rbac.authorization.k8s.io/v1beta1 ClusterRoleBindingList": { - NewAPI: "rbac.authorization.k8s.io/v1 ClusterRoleBindingList", - DeprecatedIn: "v1.17", - RemovedIn: "v1.22", - }, - "rbac.authorization.k8s.io/v1beta1 Role": { - NewAPI: "rbac.authorization.k8s.io/v1 Role", - DeprecatedIn: "v1.17", - RemovedIn: "v1.22", - }, - "rbac.authorization.k8s.io/v1beta1 RoleList": { - NewAPI: "rbac.authorization.k8s.io/v1 RoleList", - DeprecatedIn: "v1.17", - RemovedIn: "v1.22", - }, - "rbac.authorization.k8s.io/v1beta1 RoleBinding": { - NewAPI: "rbac.authorization.k8s.io/v1 RoleBinding", - DeprecatedIn: "v1.17", - RemovedIn: "v1.22", - }, - "rbac.authorization.k8s.io/v1beta1 RoleBindingList": { - NewAPI: "rbac.authorization.k8s.io/v1 RoleBindingList", - DeprecatedIn: "v1.17", - RemovedIn: "v1.22", - }, -} +const ( + // This should be set based on the version of client-go being imported + k8sVersionMajor = 1 + k8sVersionMinor = 19 +) // deprecatedAPIError indicates than an API is deprecated in Kubernetes type deprecatedAPIError struct { - Deprecated string - Alternative string - In string - Removed string + Deprecated string + Message string } func (e deprecatedAPIError) Error() string { - msg := fmt.Sprintf("the kind %q is deprecated as of %q and removed in %q", e.Deprecated, e.In, e.Removed) - if e.Alternative != "" { - msg += fmt.Sprintf(" in favor of %q", e.Alternative) - } + msg := e.Message return msg } func validateNoDeprecations(resource *K8sYamlStruct) error { + // resource is not a resource + if resource.APIVersion == "" { + return nil + } + if resource.Kind == "" { + return nil + } + + runtimeObject, err := resourceToRuntimeObject(resource) + if err != nil { + return err + } + if !deprecation.IsDeprecated(runtimeObject, k8sVersionMajor, k8sVersionMinor) { + return nil + } gvk := fmt.Sprintf("%s %s", resource.APIVersion, resource.Kind) - if dep, ok := deprecatedAPIs[gvk]; ok { - return deprecatedAPIError{ - Deprecated: gvk, - Alternative: dep.NewAPI, - In: dep.DeprecatedIn, - Removed: dep.RemovedIn, - } + return deprecatedAPIError{ + Deprecated: gvk, + Message: deprecation.WarningMessage(runtimeObject), + } +} + +func resourceToRuntimeObject(resource *K8sYamlStruct) (runtime.Object, error) { + scheme := runtime.NewScheme() + kscheme.AddToScheme(scheme) + + gvk := schema.FromAPIVersionAndKind(resource.APIVersion, resource.Kind) + out, err := scheme.New(gvk) + if err != nil { + return nil, err } - return nil + out.GetObjectKind().SetGroupVersionKind(gvk) + return out, nil } diff --git a/pkg/lint/rules/deprecations_test.go b/pkg/lint/rules/deprecations_test.go index 1e8d34702..ce2af78ba 100644 --- a/pkg/lint/rules/deprecations_test.go +++ b/pkg/lint/rules/deprecations_test.go @@ -27,10 +27,9 @@ func TestValidateNoDeprecations(t *testing.T) { if err == nil { t.Fatal("Expected deprecated extension to be flagged") } - depErr := err.(deprecatedAPIError) - if depErr.Alternative != "apps/v1 Deployment" { - t.Errorf("Expected %q to be replaced by %q", depErr.Deprecated, depErr.Alternative) + if depErr.Message == "" { + t.Fatal("Expected error message to be non-blank") } if err := validateNoDeprecations(&K8sYamlStruct{