github.com/nginxinc/kubernetes-ingress@v1.12.5/internal/k8s/reference_checkers.go (about) 1 package k8s 2 3 import ( 4 "github.com/nginxinc/kubernetes-ingress/internal/configs" 5 v1 "github.com/nginxinc/kubernetes-ingress/pkg/apis/configuration/v1" 6 conf_v1alpha1 "github.com/nginxinc/kubernetes-ingress/pkg/apis/configuration/v1alpha1" 7 networking "k8s.io/api/networking/v1beta1" 8 9 "strings" 10 ) 11 12 type resourceReferenceChecker interface { 13 IsReferencedByIngress(namespace string, name string, ing *networking.Ingress) bool 14 IsReferencedByMinion(namespace string, name string, ing *networking.Ingress) bool 15 IsReferencedByVirtualServer(namespace string, name string, vs *v1.VirtualServer) bool 16 IsReferencedByVirtualServerRoute(namespace string, name string, vsr *v1.VirtualServerRoute) bool 17 IsReferencedByTransportServer(namespace string, name string, ts *conf_v1alpha1.TransportServer) bool 18 } 19 20 type secretReferenceChecker struct { 21 isPlus bool 22 } 23 24 func newSecretReferenceChecker(isPlus bool) *secretReferenceChecker { 25 return &secretReferenceChecker{isPlus} 26 } 27 28 func (rc *secretReferenceChecker) IsReferencedByIngress(secretNamespace string, secretName string, ing *networking.Ingress) bool { 29 if ing.Namespace != secretNamespace { 30 return false 31 } 32 33 for _, tls := range ing.Spec.TLS { 34 if tls.SecretName == secretName { 35 return true 36 } 37 } 38 39 if rc.isPlus { 40 if jwtKey, exists := ing.Annotations[configs.JWTKeyAnnotation]; exists { 41 if jwtKey == secretName { 42 return true 43 } 44 } 45 } 46 47 return false 48 } 49 50 func (rc *secretReferenceChecker) IsReferencedByMinion(secretNamespace string, secretName string, ing *networking.Ingress) bool { 51 if ing.Namespace != secretNamespace { 52 return false 53 } 54 55 if rc.isPlus { 56 if jwtKey, exists := ing.Annotations[configs.JWTKeyAnnotation]; exists { 57 if jwtKey == secretName { 58 return true 59 } 60 } 61 } 62 63 return false 64 } 65 66 func (rc *secretReferenceChecker) IsReferencedByVirtualServer(secretNamespace string, secretName string, vs *v1.VirtualServer) bool { 67 if vs.Namespace != secretNamespace { 68 return false 69 } 70 71 if vs.Spec.TLS != nil && vs.Spec.TLS.Secret == secretName { 72 return true 73 } 74 75 return false 76 } 77 78 func (rc *secretReferenceChecker) IsReferencedByVirtualServerRoute(secretNamespace string, secretName string, vsr *v1.VirtualServerRoute) bool { 79 return false 80 } 81 82 func (rc *secretReferenceChecker) IsReferencedByTransportServer(secretNamespace string, secretName string, ts *conf_v1alpha1.TransportServer) bool { 83 return false 84 } 85 86 type serviceReferenceChecker struct { 87 hasClusterIP bool 88 } 89 90 func newServiceReferenceChecker(hasClusterIP bool) *serviceReferenceChecker { 91 return &serviceReferenceChecker{hasClusterIP} 92 } 93 94 func (rc *serviceReferenceChecker) IsReferencedByIngress(svcNamespace string, svcName string, ing *networking.Ingress) bool { 95 if ing.Namespace != svcNamespace { 96 return false 97 } 98 99 if ing.Spec.Backend != nil { 100 if ing.Spec.Backend.ServiceName == svcName { 101 return true 102 } 103 } 104 for _, rules := range ing.Spec.Rules { 105 if rules.IngressRuleValue.HTTP == nil { 106 continue 107 } 108 for _, p := range rules.IngressRuleValue.HTTP.Paths { 109 if p.Backend.ServiceName == svcName { 110 return true 111 } 112 } 113 } 114 115 return false 116 } 117 118 func (rc *serviceReferenceChecker) IsReferencedByMinion(svcNamespace string, svcName string, ing *networking.Ingress) bool { 119 return rc.IsReferencedByIngress(svcNamespace, svcName, ing) 120 } 121 122 func (rc *serviceReferenceChecker) IsReferencedByVirtualServer(svcNamespace string, svcName string, vs *v1.VirtualServer) bool { 123 if vs.Namespace != svcNamespace { 124 return false 125 } 126 127 for _, u := range vs.Spec.Upstreams { 128 if rc.hasClusterIP && u.UseClusterIP { 129 continue 130 } 131 if u.Service == svcName { 132 return true 133 } 134 } 135 136 return false 137 } 138 139 func (rc *serviceReferenceChecker) IsReferencedByVirtualServerRoute(svcNamespace string, svcName string, vsr *v1.VirtualServerRoute) bool { 140 if vsr.Namespace != svcNamespace { 141 return false 142 } 143 144 for _, u := range vsr.Spec.Upstreams { 145 if rc.hasClusterIP && u.UseClusterIP { 146 continue 147 } 148 if u.Service == svcName { 149 return true 150 } 151 } 152 153 return false 154 } 155 156 func (rc *serviceReferenceChecker) IsReferencedByTransportServer(svcNamespace string, svcName string, ts *conf_v1alpha1.TransportServer) bool { 157 if ts.Namespace != svcNamespace { 158 return false 159 } 160 161 for _, u := range ts.Spec.Upstreams { 162 if u.Service == svcName { 163 return true 164 } 165 } 166 167 return false 168 } 169 170 type policyReferenceChecker struct{} 171 172 func newPolicyReferenceChecker() *policyReferenceChecker { 173 return &policyReferenceChecker{} 174 } 175 176 func (rc *policyReferenceChecker) IsReferencedByIngress(policyNamespace string, policyName string, ing *networking.Ingress) bool { 177 return false 178 } 179 180 func (rc *policyReferenceChecker) IsReferencedByMinion(policyNamespace string, policyName string, ing *networking.Ingress) bool { 181 return false 182 } 183 184 func (rc *policyReferenceChecker) IsReferencedByVirtualServer(policyNamespace string, policyName string, vs *v1.VirtualServer) bool { 185 if isPolicyReferenced(vs.Spec.Policies, vs.Namespace, policyNamespace, policyName) { 186 return true 187 } 188 189 for _, r := range vs.Spec.Routes { 190 if isPolicyReferenced(r.Policies, vs.Namespace, policyNamespace, policyName) { 191 return true 192 } 193 } 194 195 return false 196 } 197 198 func (rc *policyReferenceChecker) IsReferencedByVirtualServerRoute(policyNamespace string, policyName string, vsr *v1.VirtualServerRoute) bool { 199 for _, r := range vsr.Spec.Subroutes { 200 if isPolicyReferenced(r.Policies, vsr.Namespace, policyNamespace, policyName) { 201 return true 202 } 203 } 204 205 return false 206 } 207 208 func (rc *policyReferenceChecker) IsReferencedByTransportServer(policyNamespace string, policyName string, ts *conf_v1alpha1.TransportServer) bool { 209 return false 210 } 211 212 // appProtectResourceReferenceChecker is a reference checker for AppProtect related resources. 213 // Only Regular/Master Ingress can reference those resources. 214 type appProtectResourceReferenceChecker struct { 215 annotation string 216 } 217 218 func newAppProtectResourceReferenceChecker(annotation string) *appProtectResourceReferenceChecker { 219 return &appProtectResourceReferenceChecker{annotation} 220 } 221 222 // In App Protect logConfs can be a coma separated list. 223 func (rc *appProtectResourceReferenceChecker) IsReferencedByIngress(namespace string, name string, ing *networking.Ingress) bool { 224 if resName, exists := ing.Annotations[rc.annotation]; exists { 225 resNames := strings.Split(resName, ",") 226 for _, res := range resNames { 227 if res == namespace+"/"+name || (namespace == ing.Namespace && res == name) { 228 return true 229 } 230 } 231 } 232 return false 233 } 234 235 func (rc *appProtectResourceReferenceChecker) IsReferencedByMinion(namespace string, name string, ing *networking.Ingress) bool { 236 return false 237 } 238 239 func (rc *appProtectResourceReferenceChecker) IsReferencedByVirtualServer(namespace string, name string, vs *v1.VirtualServer) bool { 240 return false 241 } 242 243 func (rc *appProtectResourceReferenceChecker) IsReferencedByVirtualServerRoute(namespace string, name string, vsr *v1.VirtualServerRoute) bool { 244 return false 245 } 246 247 func (rc *appProtectResourceReferenceChecker) IsReferencedByTransportServer(namespace string, name string, ts *conf_v1alpha1.TransportServer) bool { 248 return false 249 } 250 251 func isPolicyReferenced(policies []v1.PolicyReference, resourceNamespace string, policyNamespace string, policyName string) bool { 252 for _, p := range policies { 253 namespace := p.Namespace 254 if namespace == "" { 255 namespace = resourceNamespace 256 } 257 258 if p.Name == policyName && namespace == policyNamespace { 259 return true 260 } 261 } 262 263 return false 264 }