github.com/kiali/kiali@v1.84.0/kubernetes/cache/kube_cache.go (about) 1 package cache 2 3 import ( 4 "errors" 5 "fmt" 6 "sync" 7 "time" 8 9 "golang.org/x/exp/slices" 10 11 extentions_v1alpha1 "istio.io/client-go/pkg/apis/extensions/v1alpha1" 12 networking_v1alpha3 "istio.io/client-go/pkg/apis/networking/v1alpha3" 13 networking_v1beta1 "istio.io/client-go/pkg/apis/networking/v1beta1" 14 security_v1beta1 "istio.io/client-go/pkg/apis/security/v1beta1" 15 "istio.io/client-go/pkg/apis/telemetry/v1alpha1" 16 istio "istio.io/client-go/pkg/informers/externalversions" 17 istioext_v1alpha1_listers "istio.io/client-go/pkg/listers/extensions/v1alpha1" 18 istionet_v1alpha3_listers "istio.io/client-go/pkg/listers/networking/v1alpha3" 19 istionet_v1beta1_listers "istio.io/client-go/pkg/listers/networking/v1beta1" 20 istiosec_v1beta1_listers "istio.io/client-go/pkg/listers/security/v1beta1" 21 istiotelem_v1alpha1_listers "istio.io/client-go/pkg/listers/telemetry/v1alpha1" 22 apps_v1 "k8s.io/api/apps/v1" 23 core_v1 "k8s.io/api/core/v1" 24 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 25 "k8s.io/apimachinery/pkg/labels" 26 "k8s.io/client-go/informers" 27 apps_v1_listers "k8s.io/client-go/listers/apps/v1" 28 core_v1_listers "k8s.io/client-go/listers/core/v1" 29 "k8s.io/client-go/tools/cache" 30 gatewayapi_v1 "sigs.k8s.io/gateway-api/apis/v1" 31 gatewayapi_v1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2" 32 gatewayapi_v1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1" 33 gateway "sigs.k8s.io/gateway-api/pkg/client/informers/externalversions" 34 k8s_v1_listers "sigs.k8s.io/gateway-api/pkg/client/listers/apis/v1" 35 k8s_v1alpha2_listers "sigs.k8s.io/gateway-api/pkg/client/listers/apis/v1alpha2" 36 k8s_v1beta1_listers "sigs.k8s.io/gateway-api/pkg/client/listers/apis/v1beta1" 37 38 "github.com/kiali/kiali/config" 39 "github.com/kiali/kiali/kubernetes" 40 "github.com/kiali/kiali/log" 41 ) 42 43 // checkIstioAPIsExist checks if the istio APIs are present in the cluster 44 // and returns an error if they are not. 45 func checkIstioAPIsExist(client kubernetes.ClientInterface) error { 46 if !client.IsIstioAPI() { 47 return fmt.Errorf("istio APIs and resources are not present in cluster [%s]", client.ClusterInfo().Name) 48 } 49 return nil 50 } 51 52 const K8sExpGatewayAPIMessage = "k8s experimental Gateway API CRD is needed to be installed" 53 54 const K8sGatewayAPIMessage = "k8s Gateway API CRDs are installed, Kiali needs to be restarted to apply" 55 56 type KubeCache interface { 57 // Refresh will recreate the necessary cache. If the cache is cluster-scoped the "namespace" argument 58 // is ignored and the whole cache is recreated, otherwise only the namespace-specific cache is updated. 59 Refresh(namespace string) 60 61 // Stop all caches 62 Stop() 63 64 // Client returns the underlying client for the KubeCache. 65 // This is useful for when you want to talk directly to the kube API 66 // using the Kiali Service Account client. 67 Client() kubernetes.ClientInterface 68 69 GetConfigMap(namespace, name string) (*core_v1.ConfigMap, error) 70 GetDaemonSets(namespace string) ([]apps_v1.DaemonSet, error) 71 GetDaemonSet(namespace, name string) (*apps_v1.DaemonSet, error) 72 GetDaemonSetsWithSelector(namespace string, labelSelector map[string]string) ([]*apps_v1.DaemonSet, error) 73 GetDeployments(namespace string) ([]apps_v1.Deployment, error) 74 GetDeploymentsWithSelector(namespace string, labelSelector string) ([]apps_v1.Deployment, error) 75 GetDeployment(namespace, name string) (*apps_v1.Deployment, error) 76 GetEndpoints(namespace, name string) (*core_v1.Endpoints, error) 77 GetStatefulSets(namespace string) ([]apps_v1.StatefulSet, error) 78 GetStatefulSet(namespace, name string) (*apps_v1.StatefulSet, error) 79 GetServicesBySelectorLabels(namespace string, selectorLabels map[string]string) ([]core_v1.Service, error) 80 GetServices(namespace string, labelSelector string) ([]core_v1.Service, error) 81 GetService(namespace string, name string) (*core_v1.Service, error) 82 GetPods(namespace, labelSelector string) ([]core_v1.Pod, error) 83 GetReplicaSets(namespace string) ([]apps_v1.ReplicaSet, error) 84 85 GetDestinationRule(namespace, name string) (*networking_v1beta1.DestinationRule, error) 86 GetDestinationRules(namespace, labelSelector string) ([]*networking_v1beta1.DestinationRule, error) 87 GetEnvoyFilter(namespace, name string) (*networking_v1alpha3.EnvoyFilter, error) 88 GetEnvoyFilters(namespace, labelSelector string) ([]*networking_v1alpha3.EnvoyFilter, error) 89 GetGateway(namespace, name string) (*networking_v1beta1.Gateway, error) 90 GetGateways(namespace, labelSelector string) ([]*networking_v1beta1.Gateway, error) 91 GetServiceEntry(namespace, name string) (*networking_v1beta1.ServiceEntry, error) 92 GetServiceEntries(namespace, labelSelector string) ([]*networking_v1beta1.ServiceEntry, error) 93 GetSidecar(namespace, name string) (*networking_v1beta1.Sidecar, error) 94 GetSidecars(namespace, labelSelector string) ([]*networking_v1beta1.Sidecar, error) 95 GetVirtualService(namespace, name string) (*networking_v1beta1.VirtualService, error) 96 GetVirtualServices(namespace, labelSelector string) ([]*networking_v1beta1.VirtualService, error) 97 GetWorkloadEntry(namespace, name string) (*networking_v1beta1.WorkloadEntry, error) 98 GetWorkloadEntries(namespace, labelSelector string) ([]*networking_v1beta1.WorkloadEntry, error) 99 GetWorkloadGroup(namespace, name string) (*networking_v1beta1.WorkloadGroup, error) 100 GetWorkloadGroups(namespace, labelSelector string) ([]*networking_v1beta1.WorkloadGroup, error) 101 GetWasmPlugin(namespace, name string) (*extentions_v1alpha1.WasmPlugin, error) 102 GetWasmPlugins(namespace, labelSelector string) ([]*extentions_v1alpha1.WasmPlugin, error) 103 GetTelemetry(namespace, name string) (*v1alpha1.Telemetry, error) 104 GetTelemetries(namespace, labelSelector string) ([]*v1alpha1.Telemetry, error) 105 106 GetK8sGateway(namespace, name string) (*gatewayapi_v1.Gateway, error) 107 GetK8sGateways(namespace, labelSelector string) ([]*gatewayapi_v1.Gateway, error) 108 GetK8sGRPCRoute(namespace, name string) (*gatewayapi_v1alpha2.GRPCRoute, error) 109 GetK8sGRPCRoutes(namespace, labelSelector string) ([]*gatewayapi_v1alpha2.GRPCRoute, error) 110 GetK8sHTTPRoute(namespace, name string) (*gatewayapi_v1.HTTPRoute, error) 111 GetK8sHTTPRoutes(namespace, labelSelector string) ([]*gatewayapi_v1.HTTPRoute, error) 112 GetK8sReferenceGrant(namespace, name string) (*gatewayapi_v1beta1.ReferenceGrant, error) 113 GetK8sReferenceGrants(namespace, labelSelector string) ([]*gatewayapi_v1beta1.ReferenceGrant, error) 114 GetK8sTCPRoute(namespace, name string) (*gatewayapi_v1alpha2.TCPRoute, error) 115 GetK8sTCPRoutes(namespace, labelSelector string) ([]*gatewayapi_v1alpha2.TCPRoute, error) 116 GetK8sTLSRoute(namespace, name string) (*gatewayapi_v1alpha2.TLSRoute, error) 117 GetK8sTLSRoutes(namespace, labelSelector string) ([]*gatewayapi_v1alpha2.TLSRoute, error) 118 119 GetAuthorizationPolicy(namespace, name string) (*security_v1beta1.AuthorizationPolicy, error) 120 GetAuthorizationPolicies(namespace, labelSelector string) ([]*security_v1beta1.AuthorizationPolicy, error) 121 GetPeerAuthentication(namespace, name string) (*security_v1beta1.PeerAuthentication, error) 122 GetPeerAuthentications(namespace, labelSelector string) ([]*security_v1beta1.PeerAuthentication, error) 123 GetRequestAuthentication(namespace, name string) (*security_v1beta1.RequestAuthentication, error) 124 GetRequestAuthentications(namespace, labelSelector string) ([]*security_v1beta1.RequestAuthentication, error) 125 } 126 127 // cacheLister combines a bunch of lister types into one. 128 // This can probably be simplified or turned into an interface 129 // with go generics. 130 type cacheLister struct { 131 // Kube listers 132 configMapLister core_v1_listers.ConfigMapLister 133 daemonSetLister apps_v1_listers.DaemonSetLister 134 deploymentLister apps_v1_listers.DeploymentLister 135 endpointLister core_v1_listers.EndpointsLister 136 podLister core_v1_listers.PodLister 137 replicaSetLister apps_v1_listers.ReplicaSetLister 138 serviceLister core_v1_listers.ServiceLister 139 statefulSetLister apps_v1_listers.StatefulSetLister 140 141 cachesSynced []cache.InformerSynced 142 143 // Istio listers 144 authzLister istiosec_v1beta1_listers.AuthorizationPolicyLister 145 destinationRuleLister istionet_v1beta1_listers.DestinationRuleLister 146 envoyFilterLister istionet_v1alpha3_listers.EnvoyFilterLister 147 gatewayLister istionet_v1beta1_listers.GatewayLister 148 k8sgatewayLister k8s_v1_listers.GatewayLister 149 k8sgrpcrouteLister k8s_v1alpha2_listers.GRPCRouteLister 150 k8shttprouteLister k8s_v1_listers.HTTPRouteLister 151 k8sreferencegrantLister k8s_v1beta1_listers.ReferenceGrantLister 152 k8stcprouteLister k8s_v1alpha2_listers.TCPRouteLister 153 k8stlsrouteLister k8s_v1alpha2_listers.TLSRouteLister 154 peerAuthnLister istiosec_v1beta1_listers.PeerAuthenticationLister 155 requestAuthnLister istiosec_v1beta1_listers.RequestAuthenticationLister 156 serviceEntryLister istionet_v1beta1_listers.ServiceEntryLister 157 sidecarLister istionet_v1beta1_listers.SidecarLister 158 telemetryLister istiotelem_v1alpha1_listers.TelemetryLister 159 virtualServiceLister istionet_v1beta1_listers.VirtualServiceLister 160 wasmPluginLister istioext_v1alpha1_listers.WasmPluginLister 161 workloadEntryLister istionet_v1beta1_listers.WorkloadEntryLister 162 workloadGroupLister istionet_v1beta1_listers.WorkloadGroupLister 163 } 164 165 // kubeCache is a local cache of kube objects. Manages informers and listers. 166 type kubeCache struct { 167 cacheLock sync.RWMutex 168 cfg config.Config 169 client kubernetes.ClientInterface 170 clusterCacheLister *cacheLister 171 clusterScoped bool 172 // used in methods before calling Gateway API listers 173 // added because of potential nil issue when CRDs are applied after Kiali pod starts 174 hasExpGatewayAPIStarted bool 175 hasGatewayAPIStarted bool 176 nsCacheLister map[string]*cacheLister 177 refreshDuration time.Duration 178 // Stops the cluster scoped informers when a refresh is necessary. 179 // Close this channel to stop the cluster-scoped informers. 180 stopClusterScopedChan chan struct{} 181 // Stops the namespace scoped informers when a refresh is necessary. 182 stopNSChans map[string]chan struct{} 183 } 184 185 // Starts all informers. These run until context is cancelled. 186 func NewKubeCache(kialiClient kubernetes.ClientInterface, cfg config.Config) (*kubeCache, error) { 187 refreshDuration := time.Duration(cfg.KubernetesConfig.CacheDuration) * time.Second 188 189 c := &kubeCache{ 190 cfg: cfg, 191 client: kialiClient, 192 // Only when all namespaces are accessible should the cache be cluster scoped. 193 // Otherwise, kiali may not have access to all namespaces since 194 // the operator only grants clusterroles when all namespaces are accessible. 195 clusterScoped: cfg.AllNamespacesAccessible(), 196 refreshDuration: refreshDuration, 197 } 198 199 if c.clusterScoped { 200 log.Debug("[Kiali Cache] Using 'cluster' scoped Kiali Cache") 201 if err := c.startInformers(""); err != nil { 202 return nil, err 203 } 204 } else { 205 log.Debug("[Kiali Cache] Using 'namespace' scoped Kiali Cache") 206 c.nsCacheLister = make(map[string]*cacheLister) 207 c.stopNSChans = make(map[string]chan struct{}) 208 for _, ns := range cfg.Deployment.AccessibleNamespaces { 209 if err := c.startInformers(ns); err != nil { 210 return nil, err 211 } 212 } 213 } 214 215 return c, nil 216 } 217 218 // It will indicate if a namespace should have a cache 219 func (c *kubeCache) isCached(namespace string) bool { 220 if namespace != "" { 221 return slices.Contains(c.cfg.Deployment.AccessibleNamespaces, namespace) 222 } 223 return false 224 } 225 226 // Client returns the underlying client for the KubeCache. 227 // This is useful for when you want to talk directly to the kube API 228 // using the Kiali Service Account client. 229 func (c *kubeCache) Client() kubernetes.ClientInterface { 230 c.cacheLock.RLock() 231 defer c.cacheLock.RUnlock() 232 return c.client 233 } 234 235 // UpdateClient will update the client and refresh the cache. 236 // This is used when the client is updated with a new token. 237 func (c *kubeCache) UpdateClient(kialiClient kubernetes.ClientInterface) error { 238 log.Debug("[Kiali Cache] Updating Kiali client. Refreshing cache.") 239 c.cacheLock.Lock() 240 defer c.cacheLock.Unlock() 241 242 c.client = kialiClient 243 if c.clusterScoped { 244 if err := c.refresh(""); err != nil { 245 return err 246 } 247 } else { 248 for ns := range c.nsCacheLister { 249 if err := c.refresh(ns); err != nil { 250 return err 251 } 252 } 253 } 254 255 return nil 256 } 257 258 // Stop will stop either the cluster wide cache or all of the namespace caches. 259 func (c *kubeCache) Stop() { 260 log.Infof("Stopping Kiali Cache") 261 c.cacheLock.Lock() 262 defer c.cacheLock.Unlock() 263 264 if c.clusterScoped { 265 c.stop("") 266 } else { 267 for namespace := range c.stopNSChans { 268 c.stop(namespace) 269 } 270 } 271 } 272 273 func (c *kubeCache) stop(namespace string) { 274 if c.clusterScoped { 275 close(c.stopClusterScopedChan) 276 } else { 277 if nsChan, exist := c.stopNSChans[namespace]; exist { 278 close(nsChan) 279 delete(c.stopNSChans, namespace) 280 delete(c.nsCacheLister, namespace) 281 } 282 } 283 } 284 285 // Refresh will recreate the necessary cache. If the cache is cluster-scoped the "namespace" argument 286 // is ignored and the whole cache is recreated, otherwise only the namespace-specific cache is updated. 287 func (c *kubeCache) Refresh(namespace string) { 288 c.cacheLock.Lock() 289 defer c.cacheLock.Unlock() 290 291 if err := c.refresh(namespace); err != nil { 292 log.Errorf("[Kiali Cache] Error refreshing cache for namespace: %s. Err: %s", namespace, err) 293 } 294 } 295 296 func (c *kubeCache) refresh(namespace string) error { 297 if c.clusterScoped { 298 namespace = "" 299 } 300 301 c.stop(namespace) 302 return c.startInformers(namespace) 303 } 304 305 // starter is a small interface around the different informer factories that 306 // allows us to start them all. 307 type starter interface { 308 Start(stopCh <-chan struct{}) 309 } 310 311 func (c *kubeCache) startInformers(namespace string) error { 312 informers := []starter{ 313 c.createKubernetesInformers(namespace), 314 c.createIstioInformers(namespace), 315 c.createGatewayInformers(namespace), 316 } 317 318 var scope string 319 stop := make(chan struct{}) 320 if c.clusterScoped { 321 scope = "cluster-scoped" 322 c.stopClusterScopedChan = stop 323 } else { 324 scope = fmt.Sprintf("namespace-scoped for namespace: %s", namespace) 325 c.stopNSChans[namespace] = stop 326 } 327 328 log.Debugf("[Kiali Cache] Starting %s informers", scope) 329 330 // TODO: This calls should not happen. At the moment, prevent the errors from these calls 331 if !c.clusterScoped && namespace == "" { 332 log.Errorf("[Kiali Cache] Error starting namespace-scoped cache for empty namespace") 333 return nil 334 } 335 336 for _, informer := range informers { 337 go informer.Start(stop) 338 } 339 340 log.Infof("[Kiali Cache] Waiting for %s cache to sync", scope) 341 if !cache.WaitForCacheSync(stop, c.getCacheLister(namespace).cachesSynced...) { 342 log.Errorf("[Kiali Cache] Failed to sync %s cache", scope) 343 return errors.New("failed to sync cache") 344 } 345 346 log.Info("[Kiali Cache] Started") 347 return nil 348 } 349 350 func (c *kubeCache) createIstioInformers(namespace string) istio.SharedInformerFactory { 351 var opts []istio.SharedInformerOption 352 if namespace != "" { 353 opts = append(opts, istio.WithNamespace(namespace)) 354 } 355 356 sharedInformers := istio.NewSharedInformerFactoryWithOptions(c.client.Istio(), c.refreshDuration, opts...) 357 lister := c.getCacheLister(namespace) 358 359 if c.client.IsIstioAPI() { 360 lister.authzLister = sharedInformers.Security().V1beta1().AuthorizationPolicies().Lister() 361 lister.cachesSynced = append(lister.cachesSynced, sharedInformers.Security().V1beta1().AuthorizationPolicies().Informer().HasSynced) 362 363 lister.destinationRuleLister = sharedInformers.Networking().V1beta1().DestinationRules().Lister() 364 lister.cachesSynced = append(lister.cachesSynced, sharedInformers.Networking().V1beta1().DestinationRules().Informer().HasSynced) 365 366 lister.envoyFilterLister = sharedInformers.Networking().V1alpha3().EnvoyFilters().Lister() 367 lister.cachesSynced = append(lister.cachesSynced, sharedInformers.Networking().V1alpha3().EnvoyFilters().Informer().HasSynced) 368 369 lister.gatewayLister = sharedInformers.Networking().V1beta1().Gateways().Lister() 370 lister.cachesSynced = append(lister.cachesSynced, sharedInformers.Networking().V1beta1().Gateways().Informer().HasSynced) 371 372 lister.peerAuthnLister = sharedInformers.Security().V1beta1().PeerAuthentications().Lister() 373 lister.cachesSynced = append(lister.cachesSynced, sharedInformers.Security().V1beta1().PeerAuthentications().Informer().HasSynced) 374 375 lister.requestAuthnLister = sharedInformers.Security().V1beta1().RequestAuthentications().Lister() 376 lister.cachesSynced = append(lister.cachesSynced, sharedInformers.Security().V1beta1().RequestAuthentications().Informer().HasSynced) 377 378 lister.serviceEntryLister = sharedInformers.Networking().V1beta1().ServiceEntries().Lister() 379 lister.cachesSynced = append(lister.cachesSynced, sharedInformers.Networking().V1beta1().ServiceEntries().Informer().HasSynced) 380 381 lister.sidecarLister = sharedInformers.Networking().V1beta1().Sidecars().Lister() 382 lister.cachesSynced = append(lister.cachesSynced, sharedInformers.Networking().V1beta1().Sidecars().Informer().HasSynced) 383 384 lister.telemetryLister = sharedInformers.Telemetry().V1alpha1().Telemetries().Lister() 385 lister.cachesSynced = append(lister.cachesSynced, sharedInformers.Telemetry().V1alpha1().Telemetries().Informer().HasSynced) 386 387 lister.virtualServiceLister = sharedInformers.Networking().V1beta1().VirtualServices().Lister() 388 lister.cachesSynced = append(lister.cachesSynced, sharedInformers.Networking().V1beta1().VirtualServices().Informer().HasSynced) 389 390 lister.wasmPluginLister = sharedInformers.Extensions().V1alpha1().WasmPlugins().Lister() 391 lister.cachesSynced = append(lister.cachesSynced, sharedInformers.Extensions().V1alpha1().WasmPlugins().Informer().HasSynced) 392 393 lister.workloadEntryLister = sharedInformers.Networking().V1beta1().WorkloadEntries().Lister() 394 lister.cachesSynced = append(lister.cachesSynced, sharedInformers.Networking().V1beta1().WorkloadEntries().Informer().HasSynced) 395 396 lister.workloadGroupLister = sharedInformers.Networking().V1beta1().WorkloadGroups().Lister() 397 lister.cachesSynced = append(lister.cachesSynced, sharedInformers.Networking().V1beta1().WorkloadGroups().Informer().HasSynced) 398 } 399 400 return sharedInformers 401 } 402 403 func (c *kubeCache) createGatewayInformers(namespace string) gateway.SharedInformerFactory { 404 var opts []gateway.SharedInformerOption 405 if namespace != "" { 406 opts = append(opts, gateway.WithNamespace(namespace)) 407 } 408 409 sharedInformers := gateway.NewSharedInformerFactoryWithOptions(c.client.GatewayAPI(), c.refreshDuration, opts...) 410 lister := c.getCacheLister(namespace) 411 412 if c.client.IsGatewayAPI() { 413 lister.k8sgatewayLister = sharedInformers.Gateway().V1().Gateways().Lister() 414 lister.cachesSynced = append(lister.cachesSynced, sharedInformers.Gateway().V1().Gateways().Informer().HasSynced) 415 416 lister.k8shttprouteLister = sharedInformers.Gateway().V1().HTTPRoutes().Lister() 417 lister.cachesSynced = append(lister.cachesSynced, sharedInformers.Gateway().V1().HTTPRoutes().Informer().HasSynced) 418 419 lister.k8sreferencegrantLister = sharedInformers.Gateway().V1beta1().ReferenceGrants().Lister() 420 lister.cachesSynced = append(lister.cachesSynced, sharedInformers.Gateway().V1beta1().ReferenceGrants().Informer().HasSynced) 421 c.hasGatewayAPIStarted = true 422 423 if c.client.IsExpGatewayAPI() { 424 lister.k8sgrpcrouteLister = sharedInformers.Gateway().V1alpha2().GRPCRoutes().Lister() 425 lister.cachesSynced = append(lister.cachesSynced, sharedInformers.Gateway().V1alpha2().GRPCRoutes().Informer().HasSynced) 426 427 lister.k8stcprouteLister = sharedInformers.Gateway().V1alpha2().TCPRoutes().Lister() 428 lister.cachesSynced = append(lister.cachesSynced, sharedInformers.Gateway().V1alpha2().TCPRoutes().Informer().HasSynced) 429 430 lister.k8stlsrouteLister = sharedInformers.Gateway().V1alpha2().TLSRoutes().Lister() 431 lister.cachesSynced = append(lister.cachesSynced, sharedInformers.Gateway().V1alpha2().TLSRoutes().Informer().HasSynced) 432 c.hasExpGatewayAPIStarted = true 433 } 434 } 435 return sharedInformers 436 } 437 438 // createKubernetesInformers creates kube informers for all objects kiali watches and 439 // saves them to the typeCache. If namespace is not empty, the informers are scoped 440 // to the namespace. Otherwise, the informers are cluster-wide. 441 func (c *kubeCache) createKubernetesInformers(namespace string) informers.SharedInformerFactory { 442 var opts []informers.SharedInformerOption 443 if namespace != "" { 444 opts = append(opts, informers.WithNamespace(namespace)) 445 } 446 447 sharedInformers := informers.NewSharedInformerFactoryWithOptions(c.client.Kube(), c.refreshDuration, opts...) 448 449 lister := &cacheLister{ 450 deploymentLister: sharedInformers.Apps().V1().Deployments().Lister(), 451 statefulSetLister: sharedInformers.Apps().V1().StatefulSets().Lister(), 452 daemonSetLister: sharedInformers.Apps().V1().DaemonSets().Lister(), 453 serviceLister: sharedInformers.Core().V1().Services().Lister(), 454 endpointLister: sharedInformers.Core().V1().Endpoints().Lister(), 455 podLister: sharedInformers.Core().V1().Pods().Lister(), 456 replicaSetLister: sharedInformers.Apps().V1().ReplicaSets().Lister(), 457 configMapLister: sharedInformers.Core().V1().ConfigMaps().Lister(), 458 } 459 lister.cachesSynced = append(lister.cachesSynced, 460 sharedInformers.Apps().V1().Deployments().Informer().HasSynced, 461 sharedInformers.Apps().V1().StatefulSets().Informer().HasSynced, 462 sharedInformers.Apps().V1().DaemonSets().Informer().HasSynced, 463 sharedInformers.Core().V1().Services().Informer().HasSynced, 464 sharedInformers.Core().V1().Endpoints().Informer().HasSynced, 465 sharedInformers.Core().V1().Pods().Informer().HasSynced, 466 sharedInformers.Apps().V1().ReplicaSets().Informer().HasSynced, 467 sharedInformers.Core().V1().ConfigMaps().Informer().HasSynced, 468 ) 469 470 if c.clusterScoped { 471 c.clusterCacheLister = lister 472 } else { 473 c.nsCacheLister[namespace] = lister 474 } 475 476 return sharedInformers 477 } 478 479 func (c *kubeCache) getCacheLister(namespace string) *cacheLister { 480 if c.clusterScoped { 481 return c.clusterCacheLister 482 } 483 return c.nsCacheLister[namespace] 484 } 485 486 func (c *kubeCache) GetConfigMap(namespace, name string) (*core_v1.ConfigMap, error) { 487 // Read lock will prevent the cache from being refreshed while we are reading from the lister 488 // but it won't prevent other routines from reading from the lister. 489 defer c.cacheLock.RUnlock() 490 c.cacheLock.RLock() 491 log.Tracef("[Kiali Cache] Get [resource: ConfigMap] for [namespace: %s] [name: %s]", namespace, name) 492 cfg, err := c.getCacheLister(namespace).configMapLister.ConfigMaps(namespace).Get(name) 493 if err != nil { 494 return nil, err 495 } 496 497 // Do not modify what is returned by the lister since that is shared and will cause data races. 498 retCM := cfg.DeepCopy() 499 retCM.Kind = kubernetes.ConfigMapType 500 return retCM, nil 501 } 502 503 func (c *kubeCache) GetDaemonSets(namespace string) ([]apps_v1.DaemonSet, error) { 504 // Read lock will prevent the cache from being refreshed while we are reading from the lister 505 // but it won't prevent other routines from reading from the lister. 506 defer c.cacheLock.RUnlock() 507 c.cacheLock.RLock() 508 daemonSets, err := c.getCacheLister(namespace).daemonSetLister.DaemonSets(namespace).List(labels.Everything()) 509 if err != nil { 510 return nil, err 511 } 512 log.Tracef("[Kiali Cache] Get [resource: DaemonSet] for [namespace: %s] = %d", namespace, len(daemonSets)) 513 514 retSets := []apps_v1.DaemonSet{} 515 for _, ds := range daemonSets { 516 // Do not modify what is returned by the lister since that is shared and will cause data races. 517 d := ds.DeepCopy() 518 d.Kind = kubernetes.DaemonSetType 519 retSets = append(retSets, *d) 520 } 521 return retSets, nil 522 } 523 524 func (c *kubeCache) GetDaemonSet(namespace, name string) (*apps_v1.DaemonSet, error) { 525 // Read lock will prevent the cache from being refreshed while we are reading from the lister 526 // but it won't prevent other routines from reading from the lister. 527 defer c.cacheLock.RUnlock() 528 c.cacheLock.RLock() 529 log.Tracef("[Kiali Cache] Get [resource: DaemonSet] for [namespace: %s] [name: %s]", namespace, name) 530 ds, err := c.getCacheLister(namespace).daemonSetLister.DaemonSets(namespace).Get(name) 531 if err != nil { 532 return nil, err 533 } 534 535 // Do not modify what is returned by the lister since that is shared and will cause data races. 536 retDS := ds.DeepCopy() 537 retDS.Kind = kubernetes.DaemonSetType 538 return retDS, nil 539 } 540 541 func (c *kubeCache) GetDaemonSetsWithSelector(namespace string, selectorLabels map[string]string) ([]*apps_v1.DaemonSet, error) { 542 defer c.cacheLock.RUnlock() 543 c.cacheLock.RLock() 544 545 var daemonSets []*apps_v1.DaemonSet 546 var err error 547 selector := labels.Set(selectorLabels) 548 549 if namespace == metav1.NamespaceAll { 550 if c.clusterScoped { 551 daemonSets, err = c.getCacheLister(namespace).daemonSetLister.DaemonSets(namespace).List(labels.Everything()) 552 if err != nil { 553 return nil, err 554 } 555 } else { 556 for _, nsCacheLister := range c.nsCacheLister { 557 daemonSets, err = nsCacheLister.daemonSetLister.List(labels.Everything()) 558 if err != nil { 559 return nil, err 560 } 561 } 562 } 563 } else { 564 daemonSets, err = c.getCacheLister(namespace).daemonSetLister.DaemonSets(namespace).List(labels.Everything()) 565 if err != nil { 566 return nil, err 567 } 568 } 569 570 // Now, filter by selector 571 retDS := []*apps_v1.DaemonSet{} 572 for _, ds := range daemonSets { 573 574 labelMap, err := metav1.LabelSelectorAsMap(ds.Spec.Selector) 575 if err != nil { 576 return nil, err 577 } 578 labelSet := labels.Set(labelMap) 579 580 svcSelector := labelSet.AsSelector() 581 // selector match is done after listing all daemonSets, similar to registry reading 582 if selector.AsSelector().Empty() || (!svcSelector.Empty() && svcSelector.Matches(selector)) { 583 // Do not modify what is returned by the lister since that is shared and will cause data races. 584 svc := ds.DeepCopy() 585 svc.Kind = kubernetes.DaemonSetType 586 retDS = append(retDS, svc) 587 } 588 } 589 return retDS, nil 590 } 591 592 func (c *kubeCache) GetDeployments(namespace string) ([]apps_v1.Deployment, error) { 593 // Read lock will prevent the cache from being refreshed while we are reading from the lister 594 // but it won't prevent other routines from reading from the lister. 595 defer c.cacheLock.RUnlock() 596 c.cacheLock.RLock() 597 deployments, err := c.getCacheLister(namespace).deploymentLister.Deployments(namespace).List(labels.Everything()) 598 if err != nil { 599 return nil, err 600 } 601 log.Tracef("[Kiali Cache] Get [resource: Deployment] for [namespace: %s] = %d", namespace, len(deployments)) 602 603 retDeployments := []apps_v1.Deployment{} 604 for _, deployment := range deployments { 605 // Do not modify what is returned by the lister since that is shared and will cause data races. 606 d := deployment.DeepCopy() 607 d.Kind = kubernetes.DeploymentType 608 retDeployments = append(retDeployments, *d) 609 } 610 return retDeployments, nil 611 } 612 613 func (c *kubeCache) GetDeploymentsWithSelector(namespace string, labelSelector string) ([]apps_v1.Deployment, error) { 614 selector, err := labels.Parse(labelSelector) 615 if err != nil { 616 return nil, err 617 } 618 619 // Read lock will prevent the cache from being refreshed while we are reading from the lister 620 // but it won't prevent other routines from reading from the lister. 621 defer c.cacheLock.RUnlock() 622 c.cacheLock.RLock() 623 624 deployments := []*apps_v1.Deployment{} 625 if namespace == metav1.NamespaceAll { 626 if c.clusterScoped { 627 deployments, err = c.clusterCacheLister.deploymentLister.List(selector) 628 if err != nil { 629 return nil, err 630 } 631 } else { 632 for _, nsCacheLister := range c.nsCacheLister { 633 deploymentsNS, err := nsCacheLister.deploymentLister.List(selector) 634 if err != nil { 635 return nil, err 636 } 637 deployments = append(deployments, deploymentsNS...) 638 } 639 } 640 } else { 641 deployments, err = c.getCacheLister(namespace).deploymentLister.Deployments(namespace).List(selector) 642 if err != nil { 643 return nil, err 644 } 645 } 646 647 var retDeployments []apps_v1.Deployment 648 for _, ds := range deployments { 649 d := ds.DeepCopy() 650 d.Kind = kubernetes.DeploymentType 651 retDeployments = append(retDeployments, *d) 652 } 653 return retDeployments, nil 654 } 655 656 func (c *kubeCache) GetDeployment(namespace, name string) (*apps_v1.Deployment, error) { 657 // Read lock will prevent the cache from being refreshed while we are reading from the lister 658 // but it won't prevent other routines from reading from the lister. 659 defer c.cacheLock.RUnlock() 660 c.cacheLock.RLock() 661 log.Tracef("[Kiali Cache] Get [resource: Deployment] for [namespace: %s] [name: %s]", namespace, name) 662 deployment, err := c.getCacheLister(namespace).deploymentLister.Deployments(namespace).Get(name) 663 if err != nil { 664 return nil, err 665 } 666 667 // Do not modify what is returned by the lister since that is shared and will cause data races. 668 retDep := deployment.DeepCopy() 669 retDep.Kind = kubernetes.DeploymentType 670 return retDep, nil 671 } 672 673 func (c *kubeCache) GetEndpoints(namespace, name string) (*core_v1.Endpoints, error) { 674 // Read lock will prevent the cache from being refreshed while we are reading from the lister 675 // but it won't prevent other routines from reading from the lister. 676 defer c.cacheLock.RUnlock() 677 c.cacheLock.RLock() 678 log.Tracef("[Kiali Cache] Get [resource: Endpoints] for [namespace: %s] [name: %s]", namespace, name) 679 endpoints, err := c.getCacheLister(namespace).endpointLister.Endpoints(namespace).Get(name) 680 if err != nil { 681 return nil, err 682 } 683 684 // Do not modify what is returned by the lister since that is shared and will cause data races. 685 retEnd := endpoints.DeepCopy() 686 retEnd.Kind = kubernetes.EndpointsType 687 return retEnd, nil 688 } 689 690 func (c *kubeCache) GetStatefulSets(namespace string) ([]apps_v1.StatefulSet, error) { 691 // Read lock will prevent the cache from being refreshed while we are reading from the lister 692 // but it won't prevent other routines from reading from the lister. 693 defer c.cacheLock.RUnlock() 694 c.cacheLock.RLock() 695 statefulSets, err := c.getCacheLister(namespace).statefulSetLister.StatefulSets(namespace).List(labels.Everything()) 696 if err != nil { 697 return nil, err 698 } 699 log.Tracef("[Kiali Cache] Get [resource: StatefulSet] for [namespace: %s] = %d", namespace, len(statefulSets)) 700 701 retSets := []apps_v1.StatefulSet{} 702 for _, ss := range statefulSets { 703 // Do not modify what is returned by the lister since that is shared and will cause data races. 704 s := ss.DeepCopy() 705 s.Kind = kubernetes.StatefulSetType 706 retSets = append(retSets, *s) 707 } 708 return retSets, nil 709 } 710 711 func (c *kubeCache) GetStatefulSet(namespace, name string) (*apps_v1.StatefulSet, error) { 712 // Read lock will prevent the cache from being refreshed while we are reading from the lister 713 // but it won't prevent other routines from reading from the lister. 714 defer c.cacheLock.RUnlock() 715 c.cacheLock.RLock() 716 log.Tracef("[Kiali Cache] Get [resource: StatefulSet] for [namespace: %s] [name: %s]", namespace, name) 717 statefulSet, err := c.getCacheLister(namespace).statefulSetLister.StatefulSets(namespace).Get(name) 718 if err != nil { 719 return nil, err 720 } 721 722 // Do not modify what is returned by the lister since that is shared and will cause data races. 723 retSet := statefulSet.DeepCopy() 724 retSet.Kind = kubernetes.StatefulSetType 725 return retSet, nil 726 } 727 728 // GetServices returns list of services filtered by the labelSelector. 729 func (c *kubeCache) GetServices(namespace string, labelSelector string) ([]core_v1.Service, error) { 730 // Read lock will prevent the cache from being refreshed while we are reading from the lister 731 // but it won't prevent other routines from reading from the lister. 732 defer c.cacheLock.RUnlock() 733 c.cacheLock.RLock() 734 735 selector, err := labels.Parse(labelSelector) 736 if err != nil { 737 return nil, err 738 } 739 740 services := []*core_v1.Service{} 741 if namespace == metav1.NamespaceAll { 742 if c.clusterScoped { 743 services, err = c.clusterCacheLister.serviceLister.List(selector) 744 if err != nil { 745 return nil, err 746 } 747 } else { 748 for _, nsCacheLister := range c.nsCacheLister { 749 servicesNamespaced, err := nsCacheLister.serviceLister.List(selector) 750 if err != nil { 751 return nil, err 752 } 753 services = append(services, servicesNamespaced...) 754 } 755 } 756 } else { 757 services, err = c.getCacheLister(namespace).serviceLister.Services(namespace).List(selector) 758 if err != nil { 759 return nil, err 760 } 761 } 762 763 log.Tracef("[Kiali Cache] Get [resource: Service] for [namespace: %s] = %d", namespace, len(services)) 764 765 var retServices []core_v1.Service 766 for _, ss := range services { 767 s := ss.DeepCopy() 768 s.Kind = kubernetes.ServiceType 769 retServices = append(retServices, *s) 770 } 771 return retServices, nil 772 } 773 774 // GetServicesBySelectorLabels returns list of services filtered by Spec.Selector instead of Metadata.Labels 775 func (c *kubeCache) GetServicesBySelectorLabels(namespace string, selectorLabels map[string]string) ([]core_v1.Service, error) { 776 // Read lock will prevent the cache from being refreshed while we are reading from the lister 777 // but it won't prevent other routines from reading from the lister. 778 defer c.cacheLock.RUnlock() 779 c.cacheLock.RLock() 780 781 services, err := c.GetServices(namespace, labels.Everything().String()) 782 if err != nil { 783 return nil, err 784 } 785 786 selector := labels.Set(selectorLabels) 787 retServices := []core_v1.Service{} 788 for _, service := range services { 789 svcSelector := labels.Set(service.Spec.Selector).AsSelector() 790 // selector match is done after listing all services, similar to registry reading 791 // empty selector is loading all services, or match the service selector 792 if selector.AsSelector().Empty() || (!svcSelector.Empty() && svcSelector.Matches(selector)) { 793 // Do not modify what is returned by the lister since that is shared and will cause data races. 794 svc := service.DeepCopy() 795 svc.Kind = kubernetes.ServiceType 796 retServices = append(retServices, *svc) 797 } 798 } 799 return retServices, nil 800 } 801 802 func (c *kubeCache) GetService(namespace, name string) (*core_v1.Service, error) { 803 // Read lock will prevent the cache from being refreshed while we are reading from the lister 804 // but it won't prevent other routines from reading from the lister. 805 defer c.cacheLock.RUnlock() 806 c.cacheLock.RLock() 807 log.Tracef("[Kiali Cache] Get [resource: Service] for [namespace: %s] [name: %s]", namespace, name) 808 service, err := c.getCacheLister(namespace).serviceLister.Services(namespace).Get(name) 809 if err != nil { 810 return nil, err 811 } 812 813 // Do not modify what is returned by the lister since that is shared and will cause data races. 814 retSvc := service.DeepCopy() 815 retSvc.Kind = kubernetes.ServiceType 816 return retSvc, nil 817 } 818 819 func (c *kubeCache) GetPods(namespace, labelSelector string) ([]core_v1.Pod, error) { 820 // Read lock will prevent the cache from being refreshed while we are reading from the lister 821 // but it won't prevent other routines from reading from the lister. 822 defer c.cacheLock.RUnlock() 823 c.cacheLock.RLock() 824 selector, err := labels.Parse(labelSelector) 825 if err != nil { 826 return nil, err 827 } 828 829 pods, err := c.getCacheLister(namespace).podLister.Pods(namespace).List(selector) 830 if err != nil { 831 return nil, err 832 } 833 log.Tracef("[Kiali Cache] Get [resource: Pod] for [namespace: %s] = %d", namespace, len(pods)) 834 835 retPods := []core_v1.Pod{} 836 for _, pod := range pods { 837 // Do not modify what is returned by the lister since that is shared and will cause data races. 838 p := pod.DeepCopy() 839 p.Kind = kubernetes.PodType 840 retPods = append(retPods, *p) 841 } 842 return retPods, nil 843 } 844 845 // GetReplicaSets returns the cached ReplicaSets for the namespace. For any given RS for a given 846 // Owner (i.e. Deployment), only the most recent version of the RS will be included in the returned list. 847 // When an owning Deployment is configured with revisionHistoryLimit > 0, then k8s may return multiple 848 // versions of the RS for the same Deployment (current and older revisions). Note that it is still possible 849 // to have multiple RS for the same owner. In which case the most recent version of each is returned. 850 // see also: ../kubernetes.go 851 func (c *kubeCache) GetReplicaSets(namespace string) ([]apps_v1.ReplicaSet, error) { 852 // Read lock will prevent the cache from being refreshed while we are reading from the lister 853 // but it won't prevent other routines from reading from the lister. 854 defer c.cacheLock.RUnlock() 855 c.cacheLock.RLock() 856 reps, err := c.getCacheLister(namespace).replicaSetLister.ReplicaSets(namespace).List(labels.Everything()) 857 if err != nil { 858 return nil, err 859 } 860 861 result := []apps_v1.ReplicaSet{} 862 if len(reps) > 0 { 863 activeRSMap := map[string]*apps_v1.ReplicaSet{} 864 for _, rs := range reps { 865 if len(rs.OwnerReferences) > 0 { 866 for _, ownerRef := range rs.OwnerReferences { 867 if ownerRef.Controller != nil && *ownerRef.Controller { 868 key := fmt.Sprintf("%s_%s_%s", ownerRef.Name, rs.Name, rs.ResourceVersion) 869 if currRS, ok := activeRSMap[key]; ok { 870 if currRS.CreationTimestamp.Time.Before(rs.CreationTimestamp.Time) { 871 activeRSMap[key] = rs 872 } 873 } else { 874 activeRSMap[key] = rs 875 } 876 } 877 } 878 } else { 879 // it is it's own controller 880 activeRSMap[rs.Name] = rs 881 } 882 } 883 884 lenRS := len(activeRSMap) 885 result = make([]apps_v1.ReplicaSet, lenRS) 886 i := 0 887 for _, activeRS := range activeRSMap { 888 // Do not modify what is returned by the lister since that is shared and will cause data races. 889 rs := activeRS.DeepCopy() 890 rs.Kind = kubernetes.ReplicaSetType 891 result[i] = *rs 892 i = i + 1 893 } 894 log.Tracef("[Kiali Cache] Get [resource: ReplicaSet] for [namespace: %s] = %d", namespace, lenRS) 895 } 896 return result, nil 897 } 898 899 func (c *kubeCache) GetDestinationRule(namespace, name string) (*networking_v1beta1.DestinationRule, error) { 900 if err := checkIstioAPIsExist(c.client); err != nil { 901 return nil, err 902 } 903 904 // Read lock will prevent the cache from being refreshed while we are reading from the lister 905 // but it won't prevent other routines from reading from the lister. 906 defer c.cacheLock.RUnlock() 907 c.cacheLock.RLock() 908 dr, err := c.getCacheLister(namespace).destinationRuleLister.DestinationRules(namespace).Get(name) 909 if err != nil { 910 return nil, err 911 } 912 913 // Do not modify what is returned by the lister since that is shared and will cause data races. 914 retDR := dr.DeepCopy() 915 retDR.Kind = kubernetes.DestinationRuleType 916 return retDR, nil 917 } 918 919 func (c *kubeCache) GetDestinationRules(namespace, labelSelector string) ([]*networking_v1beta1.DestinationRule, error) { 920 if err := checkIstioAPIsExist(c.client); err != nil { 921 return nil, err 922 } 923 924 selector, err := labels.Parse(labelSelector) 925 if err != nil { 926 return nil, err 927 } 928 929 // Read lock will prevent the cache from being refreshed while we are reading from the lister 930 // but it won't prevent other routines from reading from the lister. 931 defer c.cacheLock.RUnlock() 932 c.cacheLock.RLock() 933 934 drs := []*networking_v1beta1.DestinationRule{} 935 if namespace == metav1.NamespaceAll { 936 if c.clusterScoped { 937 drs, err = c.clusterCacheLister.destinationRuleLister.List(selector) 938 if err != nil { 939 return nil, err 940 } 941 } else { 942 for _, nsCacheLister := range c.nsCacheLister { 943 drsNS, err := nsCacheLister.destinationRuleLister.List(selector) 944 if err != nil { 945 return nil, err 946 } 947 drs = append(drs, drsNS...) 948 } 949 } 950 } else { 951 drs, err = c.getCacheLister(namespace).destinationRuleLister.DestinationRules(namespace).List(selector) 952 if err != nil { 953 return nil, err 954 } 955 } 956 957 // Do not modify what is returned by the lister since that is shared and will cause data races. 958 var retDRs []*networking_v1beta1.DestinationRule 959 for _, dr := range drs { 960 d := dr.DeepCopy() 961 d.Kind = kubernetes.DestinationRuleType 962 retDRs = append(retDRs, d) 963 } 964 return retDRs, nil 965 } 966 967 func (c *kubeCache) GetEnvoyFilter(namespace, name string) (*networking_v1alpha3.EnvoyFilter, error) { 968 if err := checkIstioAPIsExist(c.client); err != nil { 969 return nil, err 970 } 971 972 // Read lock will prevent the cache from being refreshed while we are reading from the lister 973 // but it won't prevent other routines from reading from the lister. 974 defer c.cacheLock.RUnlock() 975 c.cacheLock.RLock() 976 ef, err := c.getCacheLister(namespace).envoyFilterLister.EnvoyFilters(namespace).Get(name) 977 if err != nil { 978 return nil, err 979 } 980 981 // Do not modify what is returned by the lister since that is shared and will cause data races. 982 retEF := ef.DeepCopy() 983 retEF.Kind = kubernetes.EnvoyFilterType 984 return retEF, nil 985 } 986 987 func (c *kubeCache) GetEnvoyFilters(namespace, labelSelector string) ([]*networking_v1alpha3.EnvoyFilter, error) { 988 if err := checkIstioAPIsExist(c.client); err != nil { 989 return nil, err 990 } 991 992 selector, err := labels.Parse(labelSelector) 993 if err != nil { 994 return nil, err 995 } 996 997 // Read lock will prevent the cache from being refreshed while we are reading from the lister 998 // but it won't prevent other routines from reading from the lister. 999 defer c.cacheLock.RUnlock() 1000 c.cacheLock.RLock() 1001 1002 envoyFilters := []*networking_v1alpha3.EnvoyFilter{} 1003 if namespace == metav1.NamespaceAll { 1004 if c.clusterScoped { 1005 envoyFilters, err = c.clusterCacheLister.envoyFilterLister.List(selector) 1006 if err != nil { 1007 return nil, err 1008 } 1009 } else { 1010 for _, nsCacheLister := range c.nsCacheLister { 1011 filterNamespaced, err := nsCacheLister.envoyFilterLister.List(selector) 1012 if err != nil { 1013 return nil, err 1014 } 1015 envoyFilters = append(envoyFilters, filterNamespaced...) 1016 } 1017 } 1018 } else { 1019 envoyFilters, err = c.getCacheLister(namespace).envoyFilterLister.EnvoyFilters(namespace).List(selector) 1020 if err != nil { 1021 return nil, err 1022 } 1023 } 1024 1025 var retEnvoyFilters []*networking_v1alpha3.EnvoyFilter 1026 for _, ef := range envoyFilters { 1027 efCopy := ef.DeepCopy() 1028 efCopy.Kind = kubernetes.EnvoyFilterType 1029 retEnvoyFilters = append(retEnvoyFilters, efCopy) 1030 } 1031 return retEnvoyFilters, nil 1032 } 1033 1034 func (c *kubeCache) GetGateway(namespace, name string) (*networking_v1beta1.Gateway, error) { 1035 if err := checkIstioAPIsExist(c.client); err != nil { 1036 return nil, err 1037 } 1038 1039 // Read lock will prevent the cache from being refreshed while we are reading from the lister 1040 // but it won't prevent other routines from reading from the lister. 1041 defer c.cacheLock.RUnlock() 1042 c.cacheLock.RLock() 1043 gw, err := c.getCacheLister(namespace).gatewayLister.Gateways(namespace).Get(name) 1044 if err != nil { 1045 return nil, err 1046 } 1047 1048 retGW := gw.DeepCopy() 1049 retGW.Kind = kubernetes.GatewayType 1050 return retGW, nil 1051 } 1052 1053 func (c *kubeCache) GetGateways(namespace, labelSelector string) ([]*networking_v1beta1.Gateway, error) { 1054 if err := checkIstioAPIsExist(c.client); err != nil { 1055 return nil, err 1056 } 1057 1058 selector, err := labels.Parse(labelSelector) 1059 if err != nil { 1060 return nil, err 1061 } 1062 1063 // Read lock will prevent the cache from being refreshed while we are reading from the lister 1064 // but it won't prevent other routines from reading from the lister. 1065 defer c.cacheLock.RUnlock() 1066 c.cacheLock.RLock() 1067 1068 gateways := []*networking_v1beta1.Gateway{} 1069 if namespace == metav1.NamespaceAll { 1070 if c.clusterScoped { 1071 gateways, err = c.clusterCacheLister.gatewayLister.List(selector) 1072 if err != nil { 1073 return nil, err 1074 } 1075 } else { 1076 for _, nsCacheLister := range c.nsCacheLister { 1077 gNS, err := nsCacheLister.gatewayLister.List(selector) 1078 if err != nil { 1079 return nil, err 1080 } 1081 gateways = append(gateways, gNS...) 1082 } 1083 } 1084 } else { 1085 gateways, err = c.getCacheLister(namespace).gatewayLister.Gateways(namespace).List(selector) 1086 if err != nil { 1087 return nil, err 1088 } 1089 } 1090 1091 var retGateways []*networking_v1beta1.Gateway 1092 for _, gw := range gateways { 1093 g := gw.DeepCopy() 1094 g.Kind = kubernetes.GatewayType 1095 retGateways = append(retGateways, g) 1096 } 1097 return retGateways, nil 1098 } 1099 1100 func (c *kubeCache) GetServiceEntry(namespace, name string) (*networking_v1beta1.ServiceEntry, error) { 1101 if err := checkIstioAPIsExist(c.client); err != nil { 1102 return nil, err 1103 } 1104 1105 // Read lock will prevent the cache from being refreshed while we are reading from the lister 1106 // but it won't prevent other routines from reading from the lister. 1107 defer c.cacheLock.RUnlock() 1108 c.cacheLock.RLock() 1109 se, err := c.getCacheLister(namespace).serviceEntryLister.ServiceEntries(namespace).Get(name) 1110 if err != nil { 1111 return nil, err 1112 } 1113 1114 retSE := se.DeepCopy() 1115 retSE.Kind = kubernetes.ServiceEntryType 1116 return retSE, nil 1117 } 1118 1119 func (c *kubeCache) GetServiceEntries(namespace, labelSelector string) ([]*networking_v1beta1.ServiceEntry, error) { 1120 if err := checkIstioAPIsExist(c.client); err != nil { 1121 return nil, err 1122 } 1123 1124 selector, err := labels.Parse(labelSelector) 1125 if err != nil { 1126 return nil, err 1127 } 1128 1129 // Read lock will prevent the cache from being refreshed while we are reading from the lister 1130 // but it won't prevent other routines from reading from the lister. 1131 defer c.cacheLock.RUnlock() 1132 c.cacheLock.RLock() 1133 1134 serviceEntries := []*networking_v1beta1.ServiceEntry{} 1135 if namespace == metav1.NamespaceAll { 1136 if c.clusterScoped { 1137 serviceEntries, err = c.clusterCacheLister.serviceEntryLister.List(selector) 1138 if err != nil { 1139 return nil, err 1140 } 1141 } else { 1142 for _, nsCacheLister := range c.nsCacheLister { 1143 serviceEntriesNamespaced, err := nsCacheLister.serviceEntryLister.List(selector) 1144 if err != nil { 1145 return nil, err 1146 } 1147 serviceEntries = append(serviceEntries, serviceEntriesNamespaced...) 1148 } 1149 } 1150 } else { 1151 serviceEntries, err = c.getCacheLister(namespace).serviceEntryLister.ServiceEntries(namespace).List(selector) 1152 if err != nil { 1153 return nil, err 1154 } 1155 } 1156 1157 var retSEs []*networking_v1beta1.ServiceEntry 1158 for _, se := range serviceEntries { 1159 s := se.DeepCopy() 1160 s.Kind = kubernetes.ServiceEntryType 1161 retSEs = append(retSEs, s) 1162 } 1163 return retSEs, nil 1164 } 1165 1166 func (c *kubeCache) GetSidecar(namespace, name string) (*networking_v1beta1.Sidecar, error) { 1167 if err := checkIstioAPIsExist(c.client); err != nil { 1168 return nil, err 1169 } 1170 1171 // Read lock will prevent the cache from being refreshed while we are reading from the lister 1172 // but it won't prevent other routines from reading from the lister. 1173 defer c.cacheLock.RUnlock() 1174 c.cacheLock.RLock() 1175 sc, err := c.getCacheLister(namespace).sidecarLister.Sidecars(namespace).Get(name) 1176 if err != nil { 1177 return nil, err 1178 } 1179 1180 retSC := sc.DeepCopy() 1181 retSC.Kind = kubernetes.SidecarType 1182 return retSC, nil 1183 } 1184 1185 func (c *kubeCache) GetSidecars(namespace, labelSelector string) ([]*networking_v1beta1.Sidecar, error) { 1186 if err := checkIstioAPIsExist(c.client); err != nil { 1187 return nil, err 1188 } 1189 1190 selector, err := labels.Parse(labelSelector) 1191 if err != nil { 1192 return nil, err 1193 } 1194 1195 // Read lock will prevent the cache from being refreshed while we are reading from the lister 1196 // but it won't prevent other routines from reading from the lister. 1197 defer c.cacheLock.RUnlock() 1198 c.cacheLock.RLock() 1199 1200 sidecars := []*networking_v1beta1.Sidecar{} 1201 if namespace == metav1.NamespaceAll { 1202 if c.clusterScoped { 1203 sidecars, err = c.clusterCacheLister.sidecarLister.List(selector) 1204 if err != nil { 1205 return nil, err 1206 } 1207 } else { 1208 for _, nsCacheLister := range c.nsCacheLister { 1209 sidecarsNamespaced, err := nsCacheLister.sidecarLister.List(selector) 1210 if err != nil { 1211 return nil, err 1212 } 1213 sidecars = append(sidecars, sidecarsNamespaced...) 1214 } 1215 } 1216 } else { 1217 sidecars, err = c.getCacheLister(namespace).sidecarLister.Sidecars(namespace).List(selector) 1218 if err != nil { 1219 return nil, err 1220 } 1221 } 1222 1223 var retSC []*networking_v1beta1.Sidecar 1224 for _, sc := range sidecars { 1225 s := sc.DeepCopy() 1226 s.Kind = kubernetes.SidecarType 1227 retSC = append(retSC, s) 1228 } 1229 return retSC, nil 1230 } 1231 1232 func (c *kubeCache) GetVirtualService(namespace, name string) (*networking_v1beta1.VirtualService, error) { 1233 if err := checkIstioAPIsExist(c.client); err != nil { 1234 return nil, err 1235 } 1236 1237 // Read lock will prevent the cache from being refreshed while we are reading from the lister 1238 // but it won't prevent other routines from reading from the lister. 1239 defer c.cacheLock.RUnlock() 1240 c.cacheLock.RLock() 1241 vs, err := c.getCacheLister(namespace).virtualServiceLister.VirtualServices(namespace).Get(name) 1242 if err != nil { 1243 return nil, err 1244 } 1245 1246 retVS := vs.DeepCopy() 1247 retVS.Kind = kubernetes.VirtualServiceType 1248 return retVS, nil 1249 } 1250 1251 func (c *kubeCache) GetVirtualServices(namespace, labelSelector string) ([]*networking_v1beta1.VirtualService, error) { 1252 if err := checkIstioAPIsExist(c.client); err != nil { 1253 return nil, err 1254 } 1255 1256 selector, err := labels.Parse(labelSelector) 1257 if err != nil { 1258 return nil, err 1259 } 1260 1261 // Read lock will prevent the cache from being refreshed while we are reading from the lister 1262 // but it won't prevent other routines from reading from the lister. 1263 defer c.cacheLock.RUnlock() 1264 c.cacheLock.RLock() 1265 1266 vs := []*networking_v1beta1.VirtualService{} 1267 if namespace == metav1.NamespaceAll { 1268 if c.clusterScoped { 1269 vs, err = c.clusterCacheLister.virtualServiceLister.List(selector) 1270 if err != nil { 1271 return nil, err 1272 } 1273 } else { 1274 for _, nsCacheLister := range c.nsCacheLister { 1275 vsNS, err := nsCacheLister.virtualServiceLister.List(selector) 1276 if err != nil { 1277 return nil, err 1278 } 1279 vs = append(vs, vsNS...) 1280 } 1281 } 1282 } else { 1283 vs, err = c.getCacheLister(namespace).virtualServiceLister.VirtualServices(namespace).List(selector) 1284 if err != nil { 1285 return nil, err 1286 } 1287 } 1288 1289 var retVS []*networking_v1beta1.VirtualService 1290 for _, v := range vs { 1291 vv := v.DeepCopy() 1292 vv.Kind = kubernetes.VirtualServiceType 1293 retVS = append(retVS, vv) 1294 } 1295 return retVS, nil 1296 } 1297 1298 func (c *kubeCache) GetWorkloadEntry(namespace, name string) (*networking_v1beta1.WorkloadEntry, error) { 1299 if err := checkIstioAPIsExist(c.client); err != nil { 1300 return nil, err 1301 } 1302 1303 // Read lock will prevent the cache from being refreshed while we are reading from the lister 1304 // but it won't prevent other routines from reading from the lister. 1305 defer c.cacheLock.RUnlock() 1306 c.cacheLock.RLock() 1307 we, err := c.getCacheLister(namespace).workloadEntryLister.WorkloadEntries(namespace).Get(name) 1308 if err != nil { 1309 return nil, err 1310 } 1311 1312 retWE := we.DeepCopy() 1313 retWE.Kind = kubernetes.WorkloadEntryType 1314 return retWE, nil 1315 } 1316 1317 func (c *kubeCache) GetWorkloadEntries(namespace, labelSelector string) ([]*networking_v1beta1.WorkloadEntry, error) { 1318 if err := checkIstioAPIsExist(c.client); err != nil { 1319 return nil, err 1320 } 1321 1322 selector, err := labels.Parse(labelSelector) 1323 if err != nil { 1324 return nil, err 1325 } 1326 1327 // Read lock will prevent the cache from being refreshed while we are reading from the lister 1328 // but it won't prevent other routines from reading from the lister. 1329 defer c.cacheLock.RUnlock() 1330 c.cacheLock.RLock() 1331 1332 workloadEntries := []*networking_v1beta1.WorkloadEntry{} 1333 if namespace == metav1.NamespaceAll { 1334 if c.clusterScoped { 1335 workloadEntries, err = c.clusterCacheLister.workloadEntryLister.List(selector) 1336 if err != nil { 1337 return nil, err 1338 } 1339 } else { 1340 for _, nsCacheLister := range c.nsCacheLister { 1341 workloadEntriesNamespaced, err := nsCacheLister.workloadEntryLister.List(selector) 1342 if err != nil { 1343 return nil, err 1344 } 1345 workloadEntries = append(workloadEntries, workloadEntriesNamespaced...) 1346 } 1347 } 1348 } else { 1349 workloadEntries, err = c.getCacheLister(namespace).workloadEntryLister.WorkloadEntries(namespace).List(selector) 1350 if err != nil { 1351 return nil, err 1352 } 1353 } 1354 1355 var retWE []*networking_v1beta1.WorkloadEntry 1356 for _, w := range workloadEntries { 1357 ww := w.DeepCopy() 1358 ww.Kind = kubernetes.WorkloadEntryType 1359 retWE = append(retWE, ww) 1360 } 1361 return retWE, nil 1362 } 1363 1364 func (c *kubeCache) GetWorkloadGroup(namespace, name string) (*networking_v1beta1.WorkloadGroup, error) { 1365 if err := checkIstioAPIsExist(c.client); err != nil { 1366 return nil, err 1367 } 1368 1369 // Read lock will prevent the cache from being refreshed while we are reading from the lister 1370 // but it won't prevent other routines from reading from the lister. 1371 defer c.cacheLock.RUnlock() 1372 c.cacheLock.RLock() 1373 wg, err := c.getCacheLister(namespace).workloadGroupLister.WorkloadGroups(namespace).Get(name) 1374 if err != nil { 1375 return nil, err 1376 } 1377 1378 retWG := wg.DeepCopy() 1379 retWG.Kind = kubernetes.WorkloadGroupType 1380 return retWG, nil 1381 } 1382 1383 func (c *kubeCache) GetWorkloadGroups(namespace, labelSelector string) ([]*networking_v1beta1.WorkloadGroup, error) { 1384 if err := checkIstioAPIsExist(c.client); err != nil { 1385 return nil, err 1386 } 1387 1388 selector, err := labels.Parse(labelSelector) 1389 if err != nil { 1390 return nil, err 1391 } 1392 1393 // Read lock will prevent the cache from being refreshed while we are reading from the lister 1394 // but it won't prevent other routines from reading from the lister. 1395 defer c.cacheLock.RUnlock() 1396 c.cacheLock.RLock() 1397 1398 workloadGroups := []*networking_v1beta1.WorkloadGroup{} 1399 if namespace == metav1.NamespaceAll { 1400 if c.clusterScoped { 1401 workloadGroups, err = c.clusterCacheLister.workloadGroupLister.List(selector) 1402 if err != nil { 1403 return nil, err 1404 } 1405 } else { 1406 for _, nsCacheLister := range c.nsCacheLister { 1407 workloadGroupsNamespaced, err := nsCacheLister.workloadGroupLister.List(selector) 1408 if err != nil { 1409 return nil, err 1410 } 1411 workloadGroups = append(workloadGroups, workloadGroupsNamespaced...) 1412 } 1413 } 1414 } else { 1415 workloadGroups, err = c.getCacheLister(namespace).workloadGroupLister.WorkloadGroups(namespace).List(selector) 1416 if err != nil { 1417 return nil, err 1418 } 1419 } 1420 1421 var retWG []*networking_v1beta1.WorkloadGroup 1422 for _, w := range workloadGroups { 1423 ww := w.DeepCopy() 1424 ww.Kind = kubernetes.WorkloadGroupType 1425 retWG = append(retWG, ww) 1426 } 1427 return retWG, nil 1428 } 1429 1430 func (c *kubeCache) GetWasmPlugin(namespace, name string) (*extentions_v1alpha1.WasmPlugin, error) { 1431 if err := checkIstioAPIsExist(c.client); err != nil { 1432 return nil, err 1433 } 1434 1435 // Read lock will prevent the cache from being refreshed while we are reading from the lister 1436 // but it won't prevent other routines from reading from the lister. 1437 defer c.cacheLock.RUnlock() 1438 c.cacheLock.RLock() 1439 wp, err := c.getCacheLister(namespace).wasmPluginLister.WasmPlugins(namespace).Get(name) 1440 if err != nil { 1441 return nil, err 1442 } 1443 1444 retWP := wp.DeepCopy() 1445 retWP.Kind = kubernetes.WasmPluginType 1446 return retWP, nil 1447 } 1448 1449 func (c *kubeCache) GetWasmPlugins(namespace, labelSelector string) ([]*extentions_v1alpha1.WasmPlugin, error) { 1450 if err := checkIstioAPIsExist(c.client); err != nil { 1451 return nil, err 1452 } 1453 1454 selector, err := labels.Parse(labelSelector) 1455 if err != nil { 1456 return nil, err 1457 } 1458 1459 // Read lock will prevent the cache from being refreshed while we are reading from the lister 1460 // but it won't prevent other routines from reading from the lister. 1461 defer c.cacheLock.RUnlock() 1462 c.cacheLock.RLock() 1463 1464 wasmPlugins := []*extentions_v1alpha1.WasmPlugin{} 1465 if namespace == metav1.NamespaceAll { 1466 if c.clusterScoped { 1467 wasmPlugins, err = c.clusterCacheLister.wasmPluginLister.List(selector) 1468 if err != nil { 1469 return nil, err 1470 } 1471 } else { 1472 for _, nsCacheLister := range c.nsCacheLister { 1473 wasmPluginsNamespaced, err := nsCacheLister.wasmPluginLister.List(selector) 1474 if err != nil { 1475 return nil, err 1476 } 1477 wasmPlugins = append(wasmPlugins, wasmPluginsNamespaced...) 1478 } 1479 } 1480 } else { 1481 wasmPlugins, err = c.getCacheLister(namespace).wasmPluginLister.WasmPlugins(namespace).List(selector) 1482 if err != nil { 1483 return nil, err 1484 } 1485 } 1486 1487 var retWP []*extentions_v1alpha1.WasmPlugin 1488 for _, wp := range wasmPlugins { 1489 ww := wp.DeepCopy() 1490 ww.Kind = kubernetes.WasmPluginType 1491 retWP = append(retWP, ww) 1492 } 1493 return retWP, nil 1494 } 1495 1496 func (c *kubeCache) GetTelemetry(namespace, name string) (*v1alpha1.Telemetry, error) { 1497 if err := checkIstioAPIsExist(c.client); err != nil { 1498 return nil, err 1499 } 1500 1501 // Read lock will prevent the cache from being refreshed while we are reading from the lister 1502 // but it won't prevent other routines from reading from the lister. 1503 defer c.cacheLock.RUnlock() 1504 c.cacheLock.RLock() 1505 t, err := c.getCacheLister(namespace).telemetryLister.Telemetries(namespace).Get(name) 1506 if err != nil { 1507 return nil, err 1508 } 1509 1510 retT := t.DeepCopy() 1511 retT.Kind = kubernetes.TelemetryType 1512 return retT, nil 1513 } 1514 1515 func (c *kubeCache) GetTelemetries(namespace, labelSelector string) ([]*v1alpha1.Telemetry, error) { 1516 if err := checkIstioAPIsExist(c.client); err != nil { 1517 return nil, err 1518 } 1519 1520 selector, err := labels.Parse(labelSelector) 1521 if err != nil { 1522 return nil, err 1523 } 1524 1525 // Read lock will prevent the cache from being refreshed while we are reading from the lister 1526 // but it won't prevent other routines from reading from the lister. 1527 defer c.cacheLock.RUnlock() 1528 c.cacheLock.RLock() 1529 1530 telemetries := []*v1alpha1.Telemetry{} 1531 if namespace == metav1.NamespaceAll { 1532 if c.clusterScoped { 1533 telemetries, err = c.clusterCacheLister.telemetryLister.List(selector) 1534 if err != nil { 1535 return nil, err 1536 } 1537 } else { 1538 for _, nsCacheLister := range c.nsCacheLister { 1539 telemetriesNamespaced, err := nsCacheLister.telemetryLister.List(selector) 1540 if err != nil { 1541 return nil, err 1542 } 1543 telemetries = append(telemetries, telemetriesNamespaced...) 1544 } 1545 } 1546 } else { 1547 telemetries, err = c.getCacheLister(namespace).telemetryLister.Telemetries(namespace).List(selector) 1548 if err != nil { 1549 return nil, err 1550 } 1551 } 1552 1553 var retTelemetries []*v1alpha1.Telemetry 1554 for _, t := range telemetries { 1555 tt := t.DeepCopy() 1556 tt.Kind = kubernetes.TelemetryType 1557 retTelemetries = append(retTelemetries, tt) 1558 } 1559 return retTelemetries, nil 1560 } 1561 1562 func (c *kubeCache) isK8sGatewayListerInit(namespace string) bool { 1563 // potential issue can happen when CRDs are created after Kiali start 1564 if !c.hasGatewayAPIStarted { 1565 log.Info(K8sGatewayAPIMessage) 1566 return false 1567 } 1568 return true 1569 } 1570 1571 func (c *kubeCache) isK8sExpGatewayListerInit(namespace string) bool { 1572 // GW API Experimental features are optional and CRDs can be not created 1573 return c.hasExpGatewayAPIStarted 1574 } 1575 1576 func (c *kubeCache) GetK8sGateway(namespace, name string) (*gatewayapi_v1.Gateway, error) { 1577 if err := checkIstioAPIsExist(c.client); err != nil { 1578 return nil, err 1579 } 1580 // Read lock will prevent the cache from being refreshed while we are reading from the lister 1581 // but it won't prevent other routines from reading from the lister. 1582 defer c.cacheLock.RUnlock() 1583 c.cacheLock.RLock() 1584 if !c.isK8sGatewayListerInit(namespace) { 1585 return nil, errors.New(K8sGatewayAPIMessage) 1586 } 1587 g, err := c.getCacheLister(namespace).k8sgatewayLister.Gateways(namespace).Get(name) 1588 if err != nil { 1589 return nil, err 1590 } 1591 1592 retG := g.DeepCopy() 1593 retG.Kind = kubernetes.K8sGatewayType 1594 return retG, nil 1595 } 1596 1597 func (c *kubeCache) GetK8sGateways(namespace, labelSelector string) ([]*gatewayapi_v1.Gateway, error) { 1598 if err := checkIstioAPIsExist(c.client); err != nil { 1599 return nil, err 1600 } 1601 1602 selector, err := labels.Parse(labelSelector) 1603 if err != nil { 1604 return nil, err 1605 } 1606 1607 k8sGateways := []*gatewayapi_v1.Gateway{} 1608 // Read lock will prevent the cache from being refreshed while we are reading from the lister 1609 // but it won't prevent other routines from reading from the lister. 1610 defer c.cacheLock.RUnlock() 1611 c.cacheLock.RLock() 1612 if !c.isK8sGatewayListerInit(namespace) { 1613 return k8sGateways, nil 1614 } 1615 if namespace == metav1.NamespaceAll { 1616 if c.clusterScoped { 1617 k8sGateways, err = c.clusterCacheLister.k8sgatewayLister.List(selector) 1618 if err != nil { 1619 return nil, err 1620 } 1621 } else { 1622 for _, nsCacheLister := range c.nsCacheLister { 1623 gatewaysNamespaced, err := nsCacheLister.k8sgatewayLister.List(selector) 1624 if err != nil { 1625 return nil, err 1626 } 1627 k8sGateways = append(k8sGateways, gatewaysNamespaced...) 1628 } 1629 } 1630 } else { 1631 k8sGateways, err = c.getCacheLister(namespace).k8sgatewayLister.Gateways(namespace).List(selector) 1632 if err != nil { 1633 return nil, err 1634 } 1635 } 1636 1637 var retK8sGateways []*gatewayapi_v1.Gateway 1638 for _, gw := range k8sGateways { 1639 ggw := gw.DeepCopy() 1640 ggw.Kind = kubernetes.K8sGatewayType 1641 retK8sGateways = append(retK8sGateways, ggw) 1642 } 1643 return retK8sGateways, nil 1644 } 1645 1646 func (c *kubeCache) GetK8sGRPCRoute(namespace, name string) (*gatewayapi_v1alpha2.GRPCRoute, error) { 1647 if err := checkIstioAPIsExist(c.client); err != nil { 1648 return nil, err 1649 } 1650 1651 // Read lock will prevent the cache from being refreshed while we are reading from the lister 1652 // but it won't prevent other routines from reading from the lister. 1653 defer c.cacheLock.RUnlock() 1654 c.cacheLock.RLock() 1655 if !c.isK8sExpGatewayListerInit(namespace) { 1656 return nil, errors.New(K8sExpGatewayAPIMessage) 1657 } 1658 g, err := c.getCacheLister(namespace).k8sgrpcrouteLister.GRPCRoutes(namespace).Get(name) 1659 if err != nil { 1660 return nil, err 1661 } 1662 1663 retG := g.DeepCopy() 1664 retG.Kind = kubernetes.K8sGRPCRouteType 1665 return retG, nil 1666 } 1667 1668 func (c *kubeCache) GetK8sGRPCRoutes(namespace, labelSelector string) ([]*gatewayapi_v1alpha2.GRPCRoute, error) { 1669 if err := checkIstioAPIsExist(c.client); err != nil { 1670 return nil, err 1671 } 1672 1673 selector, err := labels.Parse(labelSelector) 1674 if err != nil { 1675 return nil, err 1676 } 1677 k8sGRPCRoutes := []*gatewayapi_v1alpha2.GRPCRoute{} 1678 // Read lock will prevent the cache from being refreshed while we are reading from the lister 1679 // but it won't prevent other routines from reading from the lister. 1680 defer c.cacheLock.RUnlock() 1681 c.cacheLock.RLock() 1682 if !c.isK8sExpGatewayListerInit(namespace) { 1683 return k8sGRPCRoutes, nil 1684 } 1685 if namespace == metav1.NamespaceAll { 1686 if c.clusterScoped { 1687 k8sGRPCRoutes, err = c.clusterCacheLister.k8sgrpcrouteLister.List(selector) 1688 if err != nil { 1689 return nil, err 1690 } 1691 } else { 1692 for _, nsCacheLister := range c.nsCacheLister { 1693 grpcRoutesNamespaced, err := nsCacheLister.k8sgrpcrouteLister.List(selector) 1694 if err != nil { 1695 return nil, err 1696 } 1697 k8sGRPCRoutes = append(k8sGRPCRoutes, grpcRoutesNamespaced...) 1698 } 1699 } 1700 } else { 1701 k8sGRPCRoutes, err = c.getCacheLister(namespace).k8sgrpcrouteLister.GRPCRoutes(namespace).List(selector) 1702 if err != nil { 1703 return nil, err 1704 } 1705 } 1706 1707 var retK8sGRPCRoutes []*gatewayapi_v1alpha2.GRPCRoute 1708 for _, hr := range k8sGRPCRoutes { 1709 hrCopy := hr.DeepCopy() 1710 hrCopy.Kind = kubernetes.K8sGRPCRouteType 1711 retK8sGRPCRoutes = append(retK8sGRPCRoutes, hrCopy) 1712 } 1713 return retK8sGRPCRoutes, nil 1714 } 1715 1716 func (c *kubeCache) GetK8sHTTPRoute(namespace, name string) (*gatewayapi_v1.HTTPRoute, error) { 1717 if err := checkIstioAPIsExist(c.client); err != nil { 1718 return nil, err 1719 } 1720 1721 // Read lock will prevent the cache from being refreshed while we are reading from the lister 1722 // but it won't prevent other routines from reading from the lister. 1723 defer c.cacheLock.RUnlock() 1724 c.cacheLock.RLock() 1725 if !c.isK8sGatewayListerInit(namespace) { 1726 return nil, errors.New(K8sGatewayAPIMessage) 1727 } 1728 g, err := c.getCacheLister(namespace).k8shttprouteLister.HTTPRoutes(namespace).Get(name) 1729 if err != nil { 1730 return nil, err 1731 } 1732 1733 retG := g.DeepCopy() 1734 retG.Kind = kubernetes.K8sHTTPRouteType 1735 return retG, nil 1736 } 1737 1738 func (c *kubeCache) GetK8sHTTPRoutes(namespace, labelSelector string) ([]*gatewayapi_v1.HTTPRoute, error) { 1739 if err := checkIstioAPIsExist(c.client); err != nil { 1740 return nil, err 1741 } 1742 1743 selector, err := labels.Parse(labelSelector) 1744 if err != nil { 1745 return nil, err 1746 } 1747 k8sHTTPRoutes := []*gatewayapi_v1.HTTPRoute{} 1748 // Read lock will prevent the cache from being refreshed while we are reading from the lister 1749 // but it won't prevent other routines from reading from the lister. 1750 defer c.cacheLock.RUnlock() 1751 c.cacheLock.RLock() 1752 if !c.isK8sGatewayListerInit(namespace) { 1753 return k8sHTTPRoutes, nil 1754 } 1755 if namespace == metav1.NamespaceAll { 1756 if c.clusterScoped { 1757 k8sHTTPRoutes, err = c.clusterCacheLister.k8shttprouteLister.List(selector) 1758 if err != nil { 1759 return nil, err 1760 } 1761 } else { 1762 for _, nsCacheLister := range c.nsCacheLister { 1763 httpRoutesNamespaced, err := nsCacheLister.k8shttprouteLister.List(selector) 1764 if err != nil { 1765 return nil, err 1766 } 1767 k8sHTTPRoutes = append(k8sHTTPRoutes, httpRoutesNamespaced...) 1768 } 1769 } 1770 } else { 1771 k8sHTTPRoutes, err = c.getCacheLister(namespace).k8shttprouteLister.HTTPRoutes(namespace).List(selector) 1772 if err != nil { 1773 return nil, err 1774 } 1775 } 1776 1777 var retK8sHTTPRoutes []*gatewayapi_v1.HTTPRoute 1778 for _, hr := range k8sHTTPRoutes { 1779 hrCopy := hr.DeepCopy() 1780 hrCopy.Kind = kubernetes.K8sHTTPRouteType 1781 retK8sHTTPRoutes = append(retK8sHTTPRoutes, hrCopy) 1782 } 1783 return retK8sHTTPRoutes, nil 1784 } 1785 1786 func (c *kubeCache) GetK8sReferenceGrant(namespace, name string) (*gatewayapi_v1beta1.ReferenceGrant, error) { 1787 if err := checkIstioAPIsExist(c.client); err != nil { 1788 return nil, err 1789 } 1790 1791 // Read lock will prevent the cache from being refreshed while we are reading from the lister 1792 // but it won't prevent other routines from reading from the lister. 1793 defer c.cacheLock.RUnlock() 1794 c.cacheLock.RLock() 1795 if !c.isK8sGatewayListerInit(namespace) { 1796 return nil, errors.New(K8sGatewayAPIMessage) 1797 } 1798 g, err := c.getCacheLister(namespace).k8sreferencegrantLister.ReferenceGrants(namespace).Get(name) 1799 if err != nil { 1800 return nil, err 1801 } 1802 1803 retG := g.DeepCopy() 1804 retG.Kind = kubernetes.K8sReferenceGrantType 1805 return retG, nil 1806 } 1807 1808 func (c *kubeCache) GetK8sReferenceGrants(namespace, labelSelector string) ([]*gatewayapi_v1beta1.ReferenceGrant, error) { 1809 if err := checkIstioAPIsExist(c.client); err != nil { 1810 return nil, err 1811 } 1812 1813 selector, err := labels.Parse(labelSelector) 1814 if err != nil { 1815 return nil, err 1816 } 1817 k8sReferenceGrants := []*gatewayapi_v1beta1.ReferenceGrant{} 1818 // Read lock will prevent the cache from being refreshed while we are reading from the lister 1819 // but it won't prevent other routines from reading from the lister. 1820 defer c.cacheLock.RUnlock() 1821 c.cacheLock.RLock() 1822 if !c.isK8sGatewayListerInit(namespace) { 1823 return k8sReferenceGrants, nil 1824 } 1825 if namespace == metav1.NamespaceAll { 1826 if c.clusterScoped { 1827 k8sReferenceGrants, err = c.clusterCacheLister.k8sreferencegrantLister.List(selector) 1828 if err != nil { 1829 return nil, err 1830 } 1831 } else { 1832 for _, nsCacheLister := range c.nsCacheLister { 1833 referenceGrantsNamespaced, err := nsCacheLister.k8sreferencegrantLister.List(selector) 1834 if err != nil { 1835 return nil, err 1836 } 1837 k8sReferenceGrants = append(k8sReferenceGrants, referenceGrantsNamespaced...) 1838 } 1839 } 1840 } else { 1841 k8sReferenceGrants, err = c.getCacheLister(namespace).k8sreferencegrantLister.ReferenceGrants(namespace).List(selector) 1842 if err != nil { 1843 return nil, err 1844 } 1845 } 1846 1847 var retK8sReferenceGrants []*gatewayapi_v1beta1.ReferenceGrant 1848 for _, hr := range k8sReferenceGrants { 1849 hrCopy := hr.DeepCopy() 1850 hrCopy.Kind = kubernetes.K8sReferenceGrantType 1851 retK8sReferenceGrants = append(retK8sReferenceGrants, hrCopy) 1852 } 1853 return retK8sReferenceGrants, nil 1854 } 1855 1856 func (c *kubeCache) GetK8sTCPRoute(namespace, name string) (*gatewayapi_v1alpha2.TCPRoute, error) { 1857 if err := checkIstioAPIsExist(c.client); err != nil { 1858 return nil, err 1859 } 1860 1861 // Read lock will prevent the cache from being refreshed while we are reading from the lister 1862 // but it won't prevent other routines from reading from the lister. 1863 defer c.cacheLock.RUnlock() 1864 c.cacheLock.RLock() 1865 if !c.isK8sExpGatewayListerInit(namespace) { 1866 return nil, errors.New(K8sExpGatewayAPIMessage) 1867 } 1868 g, err := c.getCacheLister(namespace).k8stcprouteLister.TCPRoutes(namespace).Get(name) 1869 if err != nil { 1870 return nil, err 1871 } 1872 1873 retG := g.DeepCopy() 1874 retG.Kind = kubernetes.K8sTCPRouteType 1875 return retG, nil 1876 } 1877 1878 func (c *kubeCache) GetK8sTCPRoutes(namespace, labelSelector string) ([]*gatewayapi_v1alpha2.TCPRoute, error) { 1879 if err := checkIstioAPIsExist(c.client); err != nil { 1880 return nil, err 1881 } 1882 1883 selector, err := labels.Parse(labelSelector) 1884 if err != nil { 1885 return nil, err 1886 } 1887 k8sTCPRoutes := []*gatewayapi_v1alpha2.TCPRoute{} 1888 // Read lock will prevent the cache from being refreshed while we are reading from the lister 1889 // but it won't prevent other routines from reading from the lister. 1890 defer c.cacheLock.RUnlock() 1891 c.cacheLock.RLock() 1892 if !c.isK8sExpGatewayListerInit(namespace) { 1893 return k8sTCPRoutes, nil 1894 } 1895 if namespace == metav1.NamespaceAll { 1896 if c.clusterScoped { 1897 k8sTCPRoutes, err = c.clusterCacheLister.k8stcprouteLister.List(selector) 1898 if err != nil { 1899 return nil, err 1900 } 1901 } else { 1902 for _, nsCacheLister := range c.nsCacheLister { 1903 tcpRoutesNamespaced, err := nsCacheLister.k8stcprouteLister.List(selector) 1904 if err != nil { 1905 return nil, err 1906 } 1907 k8sTCPRoutes = append(k8sTCPRoutes, tcpRoutesNamespaced...) 1908 } 1909 } 1910 } else { 1911 k8sTCPRoutes, err = c.getCacheLister(namespace).k8stcprouteLister.TCPRoutes(namespace).List(selector) 1912 if err != nil { 1913 return nil, err 1914 } 1915 } 1916 1917 var retK8sTCPRoutes []*gatewayapi_v1alpha2.TCPRoute 1918 for _, hr := range k8sTCPRoutes { 1919 hrCopy := hr.DeepCopy() 1920 hrCopy.Kind = kubernetes.K8sTCPRouteType 1921 retK8sTCPRoutes = append(retK8sTCPRoutes, hrCopy) 1922 } 1923 return retK8sTCPRoutes, nil 1924 } 1925 1926 func (c *kubeCache) GetK8sTLSRoute(namespace, name string) (*gatewayapi_v1alpha2.TLSRoute, error) { 1927 if err := checkIstioAPIsExist(c.client); err != nil { 1928 return nil, err 1929 } 1930 1931 // Read lock will prevent the cache from being refreshed while we are reading from the lister 1932 // but it won't prevent other routines from reading from the lister. 1933 defer c.cacheLock.RUnlock() 1934 c.cacheLock.RLock() 1935 if !c.isK8sExpGatewayListerInit(namespace) { 1936 return nil, errors.New(K8sExpGatewayAPIMessage) 1937 } 1938 g, err := c.getCacheLister(namespace).k8stlsrouteLister.TLSRoutes(namespace).Get(name) 1939 if err != nil { 1940 return nil, err 1941 } 1942 1943 retG := g.DeepCopy() 1944 retG.Kind = kubernetes.K8sTLSRouteType 1945 return retG, nil 1946 } 1947 1948 func (c *kubeCache) GetK8sTLSRoutes(namespace, labelSelector string) ([]*gatewayapi_v1alpha2.TLSRoute, error) { 1949 if err := checkIstioAPIsExist(c.client); err != nil { 1950 return nil, err 1951 } 1952 1953 selector, err := labels.Parse(labelSelector) 1954 if err != nil { 1955 return nil, err 1956 } 1957 k8sTLSRoutes := []*gatewayapi_v1alpha2.TLSRoute{} 1958 // Read lock will prevent the cache from being refreshed while we are reading from the lister 1959 // but it won't prevent other routines from reading from the lister. 1960 defer c.cacheLock.RUnlock() 1961 c.cacheLock.RLock() 1962 if !c.isK8sExpGatewayListerInit(namespace) { 1963 return k8sTLSRoutes, nil 1964 } 1965 if namespace == metav1.NamespaceAll { 1966 if c.clusterScoped { 1967 k8sTLSRoutes, err = c.clusterCacheLister.k8stlsrouteLister.List(selector) 1968 if err != nil { 1969 return nil, err 1970 } 1971 } else { 1972 for _, nsCacheLister := range c.nsCacheLister { 1973 grpcRoutesNamespaced, err := nsCacheLister.k8stlsrouteLister.List(selector) 1974 if err != nil { 1975 return nil, err 1976 } 1977 k8sTLSRoutes = append(k8sTLSRoutes, grpcRoutesNamespaced...) 1978 } 1979 } 1980 } else { 1981 k8sTLSRoutes, err = c.getCacheLister(namespace).k8stlsrouteLister.TLSRoutes(namespace).List(selector) 1982 if err != nil { 1983 return nil, err 1984 } 1985 } 1986 1987 var retK8sTLSRoutes []*gatewayapi_v1alpha2.TLSRoute 1988 for _, hr := range k8sTLSRoutes { 1989 hrCopy := hr.DeepCopy() 1990 hrCopy.Kind = kubernetes.K8sTLSRouteType 1991 retK8sTLSRoutes = append(retK8sTLSRoutes, hrCopy) 1992 } 1993 return retK8sTLSRoutes, nil 1994 } 1995 1996 func (c *kubeCache) GetAuthorizationPolicy(namespace, name string) (*security_v1beta1.AuthorizationPolicy, error) { 1997 if err := checkIstioAPIsExist(c.client); err != nil { 1998 return nil, err 1999 } 2000 2001 // Read lock will prevent the cache from being refreshed while we are reading from the lister 2002 // but it won't prevent other routines from reading from the lister. 2003 defer c.cacheLock.RUnlock() 2004 c.cacheLock.RLock() 2005 ap, err := c.getCacheLister(namespace).authzLister.AuthorizationPolicies(namespace).Get(name) 2006 if err != nil { 2007 return nil, err 2008 } 2009 2010 retAP := ap.DeepCopy() 2011 retAP.Kind = kubernetes.AuthorizationPoliciesType 2012 return retAP, nil 2013 } 2014 2015 func (c *kubeCache) GetAuthorizationPolicies(namespace, labelSelector string) ([]*security_v1beta1.AuthorizationPolicy, error) { 2016 if err := checkIstioAPIsExist(c.client); err != nil { 2017 return nil, err 2018 } 2019 2020 selector, err := labels.Parse(labelSelector) 2021 if err != nil { 2022 return nil, err 2023 } 2024 2025 // Read lock will prevent the cache from being refreshed while we are reading from the lister 2026 // but it won't prevent other routines from reading from the lister. 2027 defer c.cacheLock.RUnlock() 2028 c.cacheLock.RLock() 2029 2030 authorizationPolicies := []*security_v1beta1.AuthorizationPolicy{} 2031 if namespace == metav1.NamespaceAll { 2032 if c.clusterScoped { 2033 authorizationPolicies, err = c.clusterCacheLister.authzLister.List(selector) 2034 if err != nil { 2035 return nil, err 2036 } 2037 } else { 2038 for _, nsCacheLister := range c.nsCacheLister { 2039 policiesNamespaced, err := nsCacheLister.authzLister.List(selector) 2040 if err != nil { 2041 return nil, err 2042 } 2043 authorizationPolicies = append(authorizationPolicies, policiesNamespaced...) 2044 } 2045 } 2046 } else { 2047 authorizationPolicies, err = c.getCacheLister(namespace).authzLister.AuthorizationPolicies(namespace).List(selector) 2048 if err != nil { 2049 return nil, err 2050 } 2051 } 2052 2053 var retAuthorizationPolicies []*security_v1beta1.AuthorizationPolicy 2054 for _, ap := range authorizationPolicies { 2055 apCopy := ap.DeepCopy() 2056 apCopy.Kind = kubernetes.AuthorizationPoliciesType 2057 retAuthorizationPolicies = append(retAuthorizationPolicies, apCopy) 2058 } 2059 return retAuthorizationPolicies, nil 2060 } 2061 2062 func (c *kubeCache) GetPeerAuthentication(namespace, name string) (*security_v1beta1.PeerAuthentication, error) { 2063 if err := checkIstioAPIsExist(c.client); err != nil { 2064 return nil, err 2065 } 2066 2067 // Read lock will prevent the cache from being refreshed while we are reading from the lister 2068 // but it won't prevent other routines from reading from the lister. 2069 defer c.cacheLock.RUnlock() 2070 c.cacheLock.RLock() 2071 pa, err := c.getCacheLister(namespace).peerAuthnLister.PeerAuthentications(namespace).Get(name) 2072 if err != nil { 2073 return nil, err 2074 } 2075 2076 retPA := pa.DeepCopy() 2077 retPA.Kind = kubernetes.PeerAuthenticationsType 2078 return retPA, nil 2079 } 2080 2081 func (c *kubeCache) GetPeerAuthentications(namespace, labelSelector string) ([]*security_v1beta1.PeerAuthentication, error) { 2082 if err := checkIstioAPIsExist(c.client); err != nil { 2083 return nil, err 2084 } 2085 2086 selector, err := labels.Parse(labelSelector) 2087 if err != nil { 2088 return nil, err 2089 } 2090 2091 // Read lock will prevent the cache from being refreshed while we are reading from the lister 2092 // but it won't prevent other routines from reading from the lister. 2093 defer c.cacheLock.RUnlock() 2094 c.cacheLock.RLock() 2095 2096 peerAuthentications := []*security_v1beta1.PeerAuthentication{} 2097 if namespace == metav1.NamespaceAll { 2098 if c.clusterScoped { 2099 peerAuthentications, err = c.clusterCacheLister.peerAuthnLister.List(selector) 2100 if err != nil { 2101 return nil, err 2102 } 2103 } else { 2104 for _, nsCacheLister := range c.nsCacheLister { 2105 authenticationsNamespaced, err := nsCacheLister.peerAuthnLister.List(selector) 2106 if err != nil { 2107 return nil, err 2108 } 2109 peerAuthentications = append(peerAuthentications, authenticationsNamespaced...) 2110 } 2111 } 2112 } else { 2113 peerAuthentications, err = c.getCacheLister(namespace).peerAuthnLister.PeerAuthentications(namespace).List(selector) 2114 if err != nil { 2115 return nil, err 2116 } 2117 } 2118 2119 var retPeerAuthentications []*security_v1beta1.PeerAuthentication 2120 for _, pa := range peerAuthentications { 2121 paCopy := pa.DeepCopy() 2122 paCopy.Kind = kubernetes.PeerAuthenticationsType 2123 retPeerAuthentications = append(retPeerAuthentications, paCopy) 2124 } 2125 return retPeerAuthentications, nil 2126 } 2127 2128 func (c *kubeCache) GetRequestAuthentication(namespace, name string) (*security_v1beta1.RequestAuthentication, error) { 2129 if err := checkIstioAPIsExist(c.client); err != nil { 2130 return nil, err 2131 } 2132 2133 // Read lock will prevent the cache from being refreshed while we are reading from the lister 2134 // but it won't prevent other routines from reading from the lister. 2135 defer c.cacheLock.RUnlock() 2136 c.cacheLock.RLock() 2137 ra, err := c.getCacheLister(namespace).requestAuthnLister.RequestAuthentications(namespace).Get(name) 2138 if err != nil { 2139 return nil, err 2140 } 2141 2142 retRA := ra.DeepCopy() 2143 retRA.Kind = kubernetes.RequestAuthenticationsType 2144 return retRA, nil 2145 } 2146 2147 func (c *kubeCache) GetRequestAuthentications(namespace, labelSelector string) ([]*security_v1beta1.RequestAuthentication, error) { 2148 if err := checkIstioAPIsExist(c.client); err != nil { 2149 return nil, err 2150 } 2151 2152 selector, err := labels.Parse(labelSelector) 2153 if err != nil { 2154 return nil, err 2155 } 2156 2157 // Read lock will prevent the cache from being refreshed while we are reading from the lister 2158 // but it won't prevent other routines from reading from the lister. 2159 defer c.cacheLock.RUnlock() 2160 c.cacheLock.RLock() 2161 2162 requestAuthentications := []*security_v1beta1.RequestAuthentication{} 2163 if namespace == metav1.NamespaceAll { 2164 if c.clusterScoped { 2165 requestAuthentications, err = c.clusterCacheLister.requestAuthnLister.List(selector) 2166 if err != nil { 2167 return nil, err 2168 } 2169 } else { 2170 for _, nsCacheLister := range c.nsCacheLister { 2171 authenticationsNamespaced, err := nsCacheLister.requestAuthnLister.List(selector) 2172 if err != nil { 2173 return nil, err 2174 } 2175 requestAuthentications = append(requestAuthentications, authenticationsNamespaced...) 2176 } 2177 } 2178 } else { 2179 requestAuthentications, err = c.getCacheLister(namespace).requestAuthnLister.RequestAuthentications(namespace).List(selector) 2180 if err != nil { 2181 return nil, err 2182 } 2183 } 2184 2185 var retRequestAuthentications []*security_v1beta1.RequestAuthentication 2186 for _, ra := range requestAuthentications { 2187 raCopy := ra.DeepCopy() 2188 raCopy.Kind = kubernetes.RequestAuthenticationsType 2189 retRequestAuthentications = append(retRequestAuthentications, raCopy) 2190 } 2191 return retRequestAuthentications, nil 2192 }