github.com/kiali/kiali@v1.84.0/business/references/virtual_service_references.go (about) 1 package references 2 3 import ( 4 networking_v1beta1 "istio.io/client-go/pkg/apis/networking/v1beta1" 5 security_v1beta "istio.io/client-go/pkg/apis/security/v1beta1" 6 7 "github.com/kiali/kiali/kubernetes" 8 "github.com/kiali/kiali/models" 9 ) 10 11 type VirtualServiceReferences struct { 12 Namespace string 13 Namespaces models.Namespaces 14 VirtualServices []*networking_v1beta1.VirtualService 15 DestinationRules []*networking_v1beta1.DestinationRule 16 AuthorizationPolicies []*security_v1beta.AuthorizationPolicy 17 } 18 19 func (n VirtualServiceReferences) References() models.IstioReferencesMap { 20 result := models.IstioReferencesMap{} 21 22 for _, vs := range n.VirtualServices { 23 key := models.IstioReferenceKey{Namespace: vs.Namespace, Name: vs.Name, ObjectType: models.ObjectTypeSingular[kubernetes.VirtualServices]} 24 references := &models.IstioReferences{} 25 references.ServiceReferences = n.getServiceReferences(vs) 26 references.ObjectReferences = n.getConfigReferences(vs) 27 result.MergeReferencesMap(models.IstioReferencesMap{key: references}) 28 } 29 30 return result 31 } 32 33 func (n VirtualServiceReferences) getServiceReferences(vs *networking_v1beta1.VirtualService) []models.ServiceReference { 34 keys := make(map[string]bool) 35 allServices := make([]models.ServiceReference, 0) 36 result := make([]models.ServiceReference, 0) 37 namespace := vs.Namespace 38 39 for _, httpRoute := range vs.Spec.Http { 40 if httpRoute != nil { 41 for _, dest := range httpRoute.Route { 42 if dest != nil { 43 host := dest.Destination.Host 44 if host == "" { 45 continue 46 } 47 fqdn := kubernetes.GetHost(host, namespace, n.Namespaces.GetNames()) 48 if !fqdn.IsWildcard() { 49 allServices = append(allServices, models.ServiceReference{Name: fqdn.Service, Namespace: fqdn.Namespace}) 50 } 51 } 52 } 53 } 54 } 55 56 for _, tcpRoute := range vs.Spec.Tcp { 57 if tcpRoute != nil { 58 for _, dest := range tcpRoute.Route { 59 if dest != nil { 60 host := dest.Destination.Host 61 if host == "" { 62 continue 63 } 64 fqdn := kubernetes.GetHost(host, namespace, n.Namespaces.GetNames()) 65 if !fqdn.IsWildcard() { 66 allServices = append(allServices, models.ServiceReference{Name: fqdn.Service, Namespace: fqdn.Namespace}) 67 } 68 } 69 } 70 } 71 } 72 73 for _, tlsRoute := range vs.Spec.Tls { 74 if tlsRoute != nil { 75 for _, dest := range tlsRoute.Route { 76 if dest != nil { 77 host := dest.Destination.Host 78 if host == "" { 79 continue 80 } 81 fqdn := kubernetes.GetHost(host, namespace, n.Namespaces.GetNames()) 82 if !fqdn.IsWildcard() { 83 allServices = append(allServices, models.ServiceReference{Name: fqdn.Service, Namespace: fqdn.Namespace}) 84 } 85 } 86 } 87 } 88 } 89 // filter unique references 90 for _, sv := range allServices { 91 if !keys[sv.Name+"."+sv.Namespace] { 92 result = append(result, sv) 93 keys[sv.Name+"."+sv.Namespace] = true 94 } 95 } 96 return result 97 } 98 99 func (n VirtualServiceReferences) getConfigReferences(vs *networking_v1beta1.VirtualService) []models.IstioReference { 100 keys := make(map[string]bool) 101 result := make([]models.IstioReference, 0) 102 allGateways := getAllGateways(vs) 103 // filter unique references 104 for _, gw := range allGateways { 105 if !keys[gw.Name+"."+gw.Namespace+"/"+gw.ObjectType] { 106 result = append(result, gw) 107 keys[gw.Name+"."+gw.Namespace+"/"+gw.ObjectType] = true 108 } 109 } 110 allDRs := n.getAllDestinationRules(vs) 111 // filter unique references 112 for _, dr := range allDRs { 113 if !keys[dr.Name+"."+dr.Namespace+"/"+dr.ObjectType] { 114 result = append(result, dr) 115 keys[dr.Name+"."+dr.Namespace+"/"+dr.ObjectType] = true 116 } 117 } 118 allAuthPolicies := n.getAuthPolicies(vs) 119 // filter unique references 120 for _, ap := range allAuthPolicies { 121 if !keys[ap.Name+"."+ap.Namespace+"/"+ap.ObjectType] { 122 result = append(result, ap) 123 keys[ap.Name+"."+ap.Namespace+"/"+ap.ObjectType] = true 124 } 125 } 126 return result 127 } 128 129 func (n VirtualServiceReferences) getAllDestinationRules(virtualService *networking_v1beta1.VirtualService) []models.IstioReference { 130 allDRs := make([]models.IstioReference, 0) 131 for _, dr := range n.DestinationRules { 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 allDRs = append(allDRs, models.IstioReference{Name: dr.Name, Namespace: dr.Namespace, ObjectType: models.ObjectTypeSingular[kubernetes.DestinationRules]}) 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 allDRs = append(allDRs, models.IstioReference{Name: dr.Name, Namespace: dr.Namespace, ObjectType: models.ObjectTypeSingular[kubernetes.DestinationRules]}) 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 allDRs = append(allDRs, models.IstioReference{Name: dr.Name, Namespace: dr.Namespace, ObjectType: models.ObjectTypeSingular[kubernetes.DestinationRules]}) 189 } 190 } 191 } 192 } 193 } 194 } 195 return allDRs 196 } 197 198 func getAllGateways(vs *networking_v1beta1.VirtualService) []models.IstioReference { 199 allGateways := make([]models.IstioReference, 0) 200 namespace := vs.Namespace 201 if len(vs.Spec.Gateways) > 0 { 202 allGateways = append(allGateways, getGatewayReferences(vs.Spec.Gateways, namespace)...) 203 } 204 if len(vs.Spec.Http) > 0 { 205 for _, httpRoute := range vs.Spec.Http { 206 if httpRoute != nil { 207 for _, match := range httpRoute.Match { 208 if match != nil && match.Gateways != nil { 209 allGateways = append(allGateways, getGatewayReferences(match.Gateways, namespace)...) 210 } 211 } 212 } 213 } 214 } 215 // TODO TCPMatch is not completely supported in Istio yet 216 if len(vs.Spec.Tls) > 0 { 217 for _, tlsRoute := range vs.Spec.Tls { 218 if tlsRoute != nil { 219 for _, match := range tlsRoute.Match { 220 if match != nil { 221 allGateways = append(allGateways, getGatewayReferences(match.Gateways, namespace)...) 222 } 223 } 224 } 225 } 226 } 227 return allGateways 228 } 229 230 func getGatewayReferences(gateways []string, namespace string) []models.IstioReference { 231 result := make([]models.IstioReference, 0) 232 for _, gate := range gateways { 233 gw := kubernetes.ParseGatewayAsHost(gate, namespace) 234 if !gw.IsWildcard() { 235 if gate == "mesh" { 236 result = append(result, models.IstioReference{Name: gw.Service, ObjectType: models.ObjectTypeSingular[kubernetes.Gateways]}) 237 } else { 238 result = append(result, models.IstioReference{Name: gw.Service, Namespace: gw.Namespace, ObjectType: models.ObjectTypeSingular[kubernetes.Gateways]}) 239 } 240 } 241 } 242 return result 243 } 244 245 func (n VirtualServiceReferences) getAuthPolicies(vs *networking_v1beta1.VirtualService) []models.IstioReference { 246 result := make([]models.IstioReference, 0) 247 for _, ap := range n.AuthorizationPolicies { 248 namespace := ap.Namespace 249 for _, rule := range ap.Spec.Rules { 250 if rule == nil { 251 continue 252 } 253 if len(rule.To) > 0 { 254 for _, t := range rule.To { 255 if t == nil || t.Operation == nil || len(t.Operation.Hosts) == 0 { 256 continue 257 } 258 for _, h := range t.Operation.Hosts { 259 fqdn := kubernetes.GetHost(h, namespace, n.Namespaces.GetNames()) 260 if !fqdn.IsWildcard() { 261 for hostIdx := 0; hostIdx < len(vs.Spec.Hosts); hostIdx++ { 262 vHost := vs.Spec.Hosts[hostIdx] 263 264 hostS := kubernetes.ParseHost(vHost, vs.Namespace) 265 if hostS.String() == fqdn.String() { 266 result = append(result, models.IstioReference{Name: ap.Name, Namespace: ap.Namespace, ObjectType: models.ObjectTypeSingular[kubernetes.AuthorizationPolicies]}) 267 continue 268 } 269 } 270 } 271 } 272 } 273 } 274 } 275 } 276 return result 277 }