github.com/kiali/kiali@v1.84.0/business/checkers/virtualservices/no_gateway_checker.go (about)

     1  package virtualservices
     2  
     3  import (
     4  	"fmt"
     5  	"strings"
     6  
     7  	networking_v1beta1 "istio.io/client-go/pkg/apis/networking/v1beta1"
     8  
     9  	"github.com/kiali/kiali/kubernetes"
    10  	"github.com/kiali/kiali/models"
    11  )
    12  
    13  type NoGatewayChecker struct {
    14  	VirtualService *networking_v1beta1.VirtualService
    15  	GatewayNames   map[string]struct{}
    16  }
    17  
    18  // Check validates that all the VirtualServices are pointing to an existing Gateway
    19  func (s NoGatewayChecker) Check() ([]*models.IstioCheck, bool) {
    20  	validations := make([]*models.IstioCheck, 0)
    21  
    22  	valid := s.ValidateVirtualServiceGateways(&validations)
    23  
    24  	return validations, valid
    25  }
    26  
    27  // ValidateVirtualServiceGateways checks all VirtualService gateways (except mesh, which is reserved word) and checks that they're found from the given list of gatewayNames. Also return index of missing gatways to show clearer error path in editor
    28  func (s NoGatewayChecker) ValidateVirtualServiceGateways(validations *[]*models.IstioCheck) bool {
    29  	namespace := s.VirtualService.Namespace
    30  	valid := true
    31  
    32  	if len(s.VirtualService.Spec.Gateways) > 0 {
    33  		valid = s.checkGateways(s.VirtualService.Spec.Gateways, namespace, validations, "spec")
    34  	}
    35  	if len(s.VirtualService.Spec.Http) > 0 {
    36  		for index, httpRoute := range s.VirtualService.Spec.Http {
    37  			if httpRoute != nil {
    38  				for _, match := range httpRoute.Match {
    39  					if match != nil {
    40  						valid = valid && s.checkGateways(match.Gateways, namespace, validations, fmt.Sprintf("spec/http[%d]/match", index))
    41  					}
    42  				}
    43  			}
    44  		}
    45  	}
    46  	return valid
    47  }
    48  
    49  func (s NoGatewayChecker) checkGateways(gateways []string, namespace string, validations *[]*models.IstioCheck, location string) bool {
    50  	result := true
    51  GatewaySearch:
    52  	for index, gate := range gateways {
    53  		if gate == "mesh" {
    54  			continue GatewaySearch
    55  		}
    56  
    57  		// Gateways should be using <namespace>/<gateway>
    58  		checkNomenclature(gate, index, validations)
    59  
    60  		hostname := kubernetes.ParseGatewayAsHost(gate, namespace)
    61  		for gw := range s.GatewayNames {
    62  			gwHostname := kubernetes.ParseHost(gw, namespace)
    63  			if found := kubernetes.FilterByHost(hostname.String(), hostname.Namespace, gw, gwHostname.Namespace); found {
    64  				continue GatewaySearch
    65  			}
    66  		}
    67  		path := fmt.Sprintf("%s/gateways[%d]", location, index)
    68  		validation := models.Build("virtualservices.nogateway", path)
    69  		*validations = append(*validations, &validation)
    70  		result = false
    71  	}
    72  	return result
    73  }
    74  
    75  func checkNomenclature(gateway string, index int, validations *[]*models.IstioCheck) {
    76  	if strings.Contains(gateway, ".") {
    77  		path := fmt.Sprintf("spec/gateways[%d]", index)
    78  		validation := models.Build("virtualservices.gateway.oldnomenclature", path)
    79  		*validations = append(*validations, &validation)
    80  	}
    81  }