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 }