istio.io/istio@v0.0.0-20240520182934-d79c90f27776/pkg/config/analysis/analyzers/deprecation/deprecation.go (about) 1 // Copyright Istio Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package deprecation 16 17 import ( 18 "fmt" 19 20 k8sext "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" 21 22 "istio.io/api/networking/v1alpha3" 23 "istio.io/istio/pkg/config" 24 "istio.io/istio/pkg/config/analysis" 25 "istio.io/istio/pkg/config/analysis/msg" 26 "istio.io/istio/pkg/config/resource" 27 "istio.io/istio/pkg/config/schema/gvk" 28 ) 29 30 // FieldAnalyzer checks for deprecated Istio types and fields 31 type FieldAnalyzer struct{} 32 33 // Tracks Istio CRDs removed from manifests/charts/base/crds/crd-all.gen.yaml 34 var deprecatedCRDs = []k8sext.CustomResourceDefinitionSpec{ 35 { 36 Group: "rbac.istio.io", 37 Names: k8sext.CustomResourceDefinitionNames{Kind: "ClusterRbacConfig"}, 38 }, 39 { 40 Group: "rbac.istio.io", 41 Names: k8sext.CustomResourceDefinitionNames{Kind: "RbacConfig"}, 42 }, 43 { 44 Group: "rbac.istio.io", 45 Names: k8sext.CustomResourceDefinitionNames{Kind: "ServiceRole"}, 46 }, 47 { 48 Group: "rbac.istio.io", 49 Names: k8sext.CustomResourceDefinitionNames{Kind: "ServiceRoleBinding"}, 50 }, 51 } 52 53 // Currently we don't have an Istio API that tells which Istio API fields are deprecated. 54 // Run `find . -name "*.proto" -exec grep -i "deprecated=true" \{\} \; -print` 55 // to see what is deprecated. This analyzer is hand-crafted. 56 57 // Metadata implements analyzer.Analyzer 58 func (*FieldAnalyzer) Metadata() analysis.Metadata { 59 deprecationInputs := []config.GroupVersionKind{ 60 gvk.VirtualService, 61 gvk.Sidecar, 62 gvk.CustomResourceDefinition, 63 } 64 65 return analysis.Metadata{ 66 Name: "deprecation.DeprecationAnalyzer", 67 Description: "Checks for deprecated Istio types and fields", 68 Inputs: deprecationInputs, 69 } 70 } 71 72 // Analyze implements analysis.Analyzer 73 func (fa *FieldAnalyzer) Analyze(ctx analysis.Context) { 74 ctx.ForEach(gvk.VirtualService, func(r *resource.Instance) bool { 75 fa.analyzeVirtualService(r, ctx) 76 return true 77 }) 78 ctx.ForEach(gvk.Sidecar, func(r *resource.Instance) bool { 79 fa.analyzeSidecar(r, ctx) 80 return true 81 }) 82 ctx.ForEach(gvk.CustomResourceDefinition, func(r *resource.Instance) bool { 83 fa.analyzeCRD(r, ctx) 84 return true 85 }) 86 } 87 88 func (*FieldAnalyzer) analyzeCRD(r *resource.Instance, ctx analysis.Context) { 89 for _, depCRD := range deprecatedCRDs { 90 var group, kind string 91 switch crd := r.Message.(type) { 92 case *k8sext.CustomResourceDefinition: 93 group = crd.Spec.Group 94 kind = crd.Spec.Names.Kind 95 case *k8sext.CustomResourceDefinitionSpec: 96 group = crd.Group 97 kind = crd.Names.Kind 98 } 99 if group == depCRD.Group && kind == depCRD.Names.Kind { 100 ctx.Report(gvk.CustomResourceDefinition, 101 msg.NewDeprecated(r, crRemovedMessage(depCRD.Group, depCRD.Names.Kind))) 102 } 103 } 104 } 105 106 func (*FieldAnalyzer) analyzeSidecar(r *resource.Instance, ctx analysis.Context) { 107 sc := r.Message.(*v1alpha3.Sidecar) 108 109 if sc.OutboundTrafficPolicy != nil { 110 if sc.OutboundTrafficPolicy.EgressProxy != nil { 111 ctx.Report(gvk.VirtualService, 112 msg.NewDeprecated(r, ignoredMessage("OutboundTrafficPolicy.EgressProxy"))) 113 } 114 } 115 } 116 117 func (*FieldAnalyzer) analyzeVirtualService(r *resource.Instance, ctx analysis.Context) { 118 vs := r.Message.(*v1alpha3.VirtualService) 119 120 for _, httpRoute := range vs.Http { 121 if httpRoute.Fault != nil { 122 if httpRoute.Fault.Delay != nil { 123 // nolint: staticcheck 124 if httpRoute.Fault.Delay.Percent > 0 { 125 ctx.Report(gvk.VirtualService, 126 msg.NewDeprecated(r, replacedMessage("HTTPRoute.fault.delay.percent", "HTTPRoute.fault.delay.percentage"))) 127 } 128 } 129 } 130 } 131 } 132 133 func replacedMessage(deprecated, replacement string) string { 134 return fmt.Sprintf("%s is deprecated; use %s", deprecated, replacement) 135 } 136 137 func ignoredMessage(field string) string { 138 return fmt.Sprintf("%s ignored", field) 139 } 140 141 func crRemovedMessage(group, kind string) string { 142 return fmt.Sprintf("Custom resource type %s %s is removed", group, kind) 143 }