use new upstream deprecations

Signed-off-by: Joe Julian <me@joejulian.name>
pull/8608/head
Joe Julian 5 years ago
parent 160601e784
commit 629579069e
No known key found for this signature in database
GPG Key ID: FAB12BE0575D999B

@ -16,193 +16,64 @@ limitations under the License.
package rules // import "helm.sh/helm/v3/pkg/lint/rules" package rules // import "helm.sh/helm/v3/pkg/lint/rules"
import "fmt" import (
"fmt"
type deprecatedAPI struct { "k8s.io/apimachinery/pkg/runtime"
NewAPI string "k8s.io/apimachinery/pkg/runtime/schema"
DeprecatedIn string "k8s.io/apiserver/pkg/endpoints/deprecation"
RemovedIn string kscheme "k8s.io/client-go/kubernetes/scheme"
} )
// deprecatedAPIs lists APIs that are deprecated (key) with suggested alternatives (value). const (
var deprecatedAPIs = map[string]deprecatedAPI{ // This should be set based on the version of client-go being imported
"extensions/v1beta1 Deployment": { k8sVersionMajor = 1
NewAPI: "apps/v1 Deployment", k8sVersionMinor = 19
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",
},
}
// deprecatedAPIError indicates than an API is deprecated in Kubernetes // deprecatedAPIError indicates than an API is deprecated in Kubernetes
type deprecatedAPIError struct { type deprecatedAPIError struct {
Deprecated string Deprecated string
Alternative string Message string
In string
Removed string
} }
func (e deprecatedAPIError) Error() 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) msg := e.Message
if e.Alternative != "" {
msg += fmt.Sprintf(" in favor of %q", e.Alternative)
}
return msg return msg
} }
func validateNoDeprecations(resource *K8sYamlStruct) error { 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) gvk := fmt.Sprintf("%s %s", resource.APIVersion, resource.Kind)
if dep, ok := deprecatedAPIs[gvk]; ok {
return deprecatedAPIError{ return deprecatedAPIError{
Deprecated: gvk, Deprecated: gvk,
Alternative: dep.NewAPI, Message: deprecation.WarningMessage(runtimeObject),
In: dep.DeprecatedIn,
Removed: dep.RemovedIn,
} }
}
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
} }

@ -27,10 +27,9 @@ func TestValidateNoDeprecations(t *testing.T) {
if err == nil { if err == nil {
t.Fatal("Expected deprecated extension to be flagged") t.Fatal("Expected deprecated extension to be flagged")
} }
depErr := err.(deprecatedAPIError) depErr := err.(deprecatedAPIError)
if depErr.Alternative != "apps/v1 Deployment" { if depErr.Message == "" {
t.Errorf("Expected %q to be replaced by %q", depErr.Deprecated, depErr.Alternative) t.Fatal("Expected error message to be non-blank")
} }
if err := validateNoDeprecations(&K8sYamlStruct{ if err := validateNoDeprecations(&K8sYamlStruct{

Loading…
Cancel
Save