github.com/kiali/kiali@v1.84.0/business/checkers/k8shttproutes/no_host_checker.go (about) 1 package k8shttproutes 2 3 import ( 4 "fmt" 5 "strings" 6 7 k8s_networking_v1 "sigs.k8s.io/gateway-api/apis/v1" 8 k8s_networking_v1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1" 9 10 "github.com/kiali/kiali/kubernetes" 11 "github.com/kiali/kiali/models" 12 ) 13 14 type NoHostChecker struct { 15 K8sHTTPRoute *k8s_networking_v1.HTTPRoute 16 K8sReferenceGrants []*k8s_networking_v1beta1.ReferenceGrant 17 Namespaces models.Namespaces 18 RegistryServices []*kubernetes.RegistryService 19 } 20 21 func (n NoHostChecker) Check() ([]*models.IstioCheck, bool) { 22 validations := make([]*models.IstioCheck, 0) 23 valid := true 24 25 for k, httpRoute := range n.K8sHTTPRoute.Spec.Rules { 26 for i, ref := range httpRoute.BackendRefs { 27 if ref.Kind == nil || string(*ref.Kind) != "Service" { 28 continue 29 } 30 namespace := n.K8sHTTPRoute.Namespace 31 if ref.Namespace != nil && string(*ref.Namespace) != "" { 32 namespace = string(*ref.Namespace) 33 } 34 fqdn := kubernetes.GetHost(string(ref.Name), namespace, n.Namespaces.GetNames()) 35 //service name should not be set in fqdn format 36 // if the http route is referencing to a service from the same namespace, then service should exist there 37 // if the http route is referencing to a service from other namespace, then a ReferenceGrant should exist to cross namespace reference, and the service should exist in remote namespace 38 if strings.Contains(string(ref.Name), ".") || 39 (namespace == n.K8sHTTPRoute.Namespace && !n.checkDestination(fqdn.String(), namespace)) || 40 (namespace != n.K8sHTTPRoute.Namespace && (!n.checkReferenceGrant(n.K8sHTTPRoute.Namespace, namespace) || !n.checkDestination(fqdn.String(), namespace))) { 41 path := fmt.Sprintf("spec/rules[%d]/backendRefs[%d]/name", k, i) 42 validation := models.Build("k8shttproutes.nohost.namenotfound", path) 43 validations = append(validations, &validation) 44 valid = false 45 } 46 } 47 } 48 49 return validations, valid 50 } 51 52 func (n NoHostChecker) checkDestination(sHost string, itemNamespace string) bool { 53 // Use RegistryService to check destinations that may not be covered with previous check 54 // i.e. Multi-cluster or Federation validations 55 return kubernetes.HasMatchingRegistryService(itemNamespace, sHost, n.RegistryServices) 56 } 57 58 func (n NoHostChecker) checkReferenceGrant(fromNamespace string, toNamespace string) bool { 59 // Use ReferenceGrant objects to check if cross namespace reference exists 60 return kubernetes.HasMatchingReferenceGrant(fromNamespace, toNamespace, kubernetes.K8sActualHTTPRouteType, kubernetes.ServiceType, n.K8sReferenceGrants) 61 }