github.com/kiali/kiali@v1.84.0/business/references/destination_rule_references.go (about)

     1  package references
     2  
     3  import (
     4  	networking_v1beta1 "istio.io/client-go/pkg/apis/networking/v1beta1"
     5  
     6  	"k8s.io/apimachinery/pkg/labels"
     7  
     8  	"github.com/kiali/kiali/kubernetes"
     9  	"github.com/kiali/kiali/models"
    10  )
    11  
    12  type DestinationRuleReferences struct {
    13  	Namespace             string
    14  	Namespaces            models.Namespaces
    15  	DestinationRules      []*networking_v1beta1.DestinationRule
    16  	VirtualServices       []*networking_v1beta1.VirtualService
    17  	WorkloadsPerNamespace map[string]models.WorkloadList
    18  	ServiceEntries        []*networking_v1beta1.ServiceEntry
    19  	RegistryServices      []*kubernetes.RegistryService
    20  }
    21  
    22  func (n DestinationRuleReferences) References() models.IstioReferencesMap {
    23  	result := models.IstioReferencesMap{}
    24  
    25  	for _, dr := range n.DestinationRules {
    26  		key := models.IstioReferenceKey{Namespace: dr.Namespace, Name: dr.Name, ObjectType: models.ObjectTypeSingular[kubernetes.DestinationRules]}
    27  		references := &models.IstioReferences{}
    28  		seRefs := n.getSEReferences(dr)
    29  		references.ObjectReferences = append(references.ObjectReferences, seRefs...)
    30  		if len(seRefs) == 0 {
    31  			references.ServiceReferences = n.getServiceReferences(dr)
    32  		}
    33  		references.WorkloadReferences = n.getWorkloadReferences(dr)
    34  		references.ObjectReferences = append(references.ObjectReferences, n.getConfigReferences(dr)...)
    35  		result.MergeReferencesMap(models.IstioReferencesMap{key: references})
    36  	}
    37  
    38  	return result
    39  }
    40  
    41  func (n DestinationRuleReferences) getServiceReferences(dr *networking_v1beta1.DestinationRule) []models.ServiceReference {
    42  	result := make([]models.ServiceReference, 0)
    43  
    44  	fqdn := kubernetes.GetHost(dr.Spec.Host, dr.Namespace, n.Namespaces.GetNames())
    45  	if !fqdn.IsWildcard() && kubernetes.HasMatchingRegistryService(dr.Namespace, fqdn.String(), n.RegistryServices) {
    46  		result = append(result, models.ServiceReference{Name: fqdn.Service, Namespace: fqdn.Namespace})
    47  	}
    48  	return result
    49  }
    50  
    51  func (n DestinationRuleReferences) getWorkloadReferences(dr *networking_v1beta1.DestinationRule) []models.WorkloadReference {
    52  	keys := make(map[string]bool)
    53  	allWorklaods := make([]models.WorkloadReference, 0)
    54  	result := make([]models.WorkloadReference, 0)
    55  
    56  	host := kubernetes.GetHost(dr.Spec.Host, dr.Namespace, n.Namespaces.GetNames())
    57  	if host.IsWildcard() {
    58  		return result
    59  	}
    60  
    61  	// Covering 'servicename.namespace' host format scenario
    62  	localSvc, localNs := kubernetes.ParseTwoPartHost(host)
    63  
    64  	var selectors map[string]string
    65  
    66  	// Find the correct service
    67  	for _, s := range n.RegistryServices {
    68  		if s.Attributes.Name == localSvc && s.Attributes.Namespace == localNs {
    69  			selectors = s.Attributes.LabelSelectors
    70  			break
    71  		}
    72  	}
    73  
    74  	// Check workloads
    75  	if len(selectors) == 0 {
    76  		return result
    77  	}
    78  
    79  	for _, subset := range dr.Spec.Subsets {
    80  		if len(subset.Labels) > 0 {
    81  			selector := labels.SelectorFromSet(labels.Set(selectors))
    82  
    83  			subsetLabelSet := labels.Set(subset.Labels)
    84  			subsetSelector := labels.SelectorFromSet(subsetLabelSet)
    85  
    86  			for _, wl := range n.WorkloadsPerNamespace[localNs].Workloads {
    87  				wlLabelSet := labels.Set(wl.Labels)
    88  				if selector.Matches(wlLabelSet) {
    89  					if subsetSelector.Matches(wlLabelSet) {
    90  						allWorklaods = append(allWorklaods, models.WorkloadReference{Name: wl.Name, Namespace: localNs})
    91  					}
    92  				}
    93  			}
    94  		}
    95  	}
    96  	// filter unique references
    97  	for _, wl := range allWorklaods {
    98  		if !keys[wl.Name+"/"+wl.Namespace] {
    99  			result = append(result, wl)
   100  			keys[wl.Name+"/"+wl.Namespace] = true
   101  		}
   102  	}
   103  	return result
   104  }
   105  
   106  func (n DestinationRuleReferences) getSEReferences(dr *networking_v1beta1.DestinationRule) []models.IstioReference {
   107  	result := make([]models.IstioReference, 0)
   108  
   109  	fqdn := kubernetes.GetHost(dr.Spec.Host, dr.Namespace, n.Namespaces.GetNames())
   110  	if !fqdn.IsWildcard() {
   111  		for _, se := range n.ServiceEntries {
   112  			for _, seHost := range se.Spec.Hosts {
   113  				if seHost == fqdn.String() {
   114  					result = append(result, models.IstioReference{Name: se.Name, Namespace: se.Namespace, ObjectType: models.ObjectTypeSingular[kubernetes.ServiceEntries]})
   115  					continue
   116  				}
   117  			}
   118  		}
   119  	}
   120  	return result
   121  }
   122  
   123  func (n DestinationRuleReferences) getConfigReferences(dr *networking_v1beta1.DestinationRule) []models.IstioReference {
   124  	keys := make(map[string]bool)
   125  	allConfigs := make([]models.IstioReference, 0)
   126  	result := make([]models.IstioReference, 0)
   127  
   128  	for _, subset := range dr.Spec.Subsets {
   129  		if len(subset.Labels) > 0 {
   130  			for _, virtualService := range n.VirtualServices {
   131  
   132  				if len(virtualService.Spec.Http) > 0 {
   133  					for _, httpRoute := range virtualService.Spec.Http {
   134  						if httpRoute == nil {
   135  							continue
   136  						}
   137  						if len(httpRoute.Route) > 0 {
   138  							for _, dest := range httpRoute.Route {
   139  								if dest == nil || dest.Destination == nil {
   140  									continue
   141  								}
   142  								host := dest.Destination.Host
   143  								drHost := kubernetes.GetHost(host, dr.Namespace, n.Namespaces.GetNames())
   144  								vsHost := kubernetes.GetHost(dr.Spec.Host, virtualService.Namespace, n.Namespaces.GetNames())
   145  								if kubernetes.FilterByHost(vsHost.String(), vsHost.Namespace, drHost.Service, drHost.Namespace) {
   146  									allConfigs = append(allConfigs, models.IstioReference{Name: virtualService.Name, Namespace: virtualService.Namespace, ObjectType: models.ObjectTypeSingular[kubernetes.VirtualServices]})
   147  								}
   148  							}
   149  						}
   150  					}
   151  				}
   152  
   153  				if len(virtualService.Spec.Tcp) > 0 {
   154  					for _, tcpRoute := range virtualService.Spec.Tcp {
   155  						if tcpRoute == nil {
   156  							continue
   157  						}
   158  						if len(tcpRoute.Route) > 0 {
   159  							for _, dest := range tcpRoute.Route {
   160  								if dest == nil || dest.Destination == nil {
   161  									continue
   162  								}
   163  								host := dest.Destination.Host
   164  								drHost := kubernetes.GetHost(host, dr.Namespace, n.Namespaces.GetNames())
   165  								vsHost := kubernetes.GetHost(dr.Spec.Host, virtualService.Namespace, n.Namespaces.GetNames())
   166  								if kubernetes.FilterByHost(vsHost.String(), vsHost.Namespace, drHost.Service, drHost.Namespace) {
   167  									allConfigs = append(allConfigs, models.IstioReference{Name: virtualService.Name, Namespace: virtualService.Namespace, ObjectType: models.ObjectTypeSingular[kubernetes.VirtualServices]})
   168  								}
   169  							}
   170  						}
   171  					}
   172  				}
   173  
   174  				if len(virtualService.Spec.Tls) > 0 {
   175  					for _, tlsRoute := range virtualService.Spec.Tls {
   176  						if tlsRoute == nil {
   177  							continue
   178  						}
   179  						if len(tlsRoute.Route) > 0 {
   180  							for _, dest := range tlsRoute.Route {
   181  								if dest == nil || dest.Destination == nil {
   182  									continue
   183  								}
   184  								host := dest.Destination.Host
   185  								drHost := kubernetes.GetHost(host, dr.Namespace, n.Namespaces.GetNames())
   186  								vsHost := kubernetes.GetHost(dr.Spec.Host, virtualService.Namespace, n.Namespaces.GetNames())
   187  								if kubernetes.FilterByHost(vsHost.String(), vsHost.Namespace, drHost.Service, drHost.Namespace) {
   188  									allConfigs = append(allConfigs, models.IstioReference{Name: virtualService.Name, Namespace: virtualService.Namespace, ObjectType: models.ObjectTypeSingular[kubernetes.VirtualServices]})
   189  								}
   190  							}
   191  						}
   192  					}
   193  				}
   194  			}
   195  		}
   196  	}
   197  	// filter unique references
   198  	for _, cf := range allConfigs {
   199  		if !keys[cf.Name+"."+cf.Namespace+"/"+cf.ObjectType] {
   200  			result = append(result, cf)
   201  			keys[cf.Name+"."+cf.Namespace+"/"+cf.ObjectType] = true
   202  		}
   203  	}
   204  	return result
   205  }