istio.io/istio@v0.0.0-20240520182934-d79c90f27776/pilot/pkg/model/cluster_local.go (about) 1 // Copyright Istio Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package model 16 17 import ( 18 "strings" 19 "sync" 20 21 "istio.io/istio/pkg/config/host" 22 "istio.io/istio/pkg/util/sets" 23 ) 24 25 var ( 26 defaultClusterLocalNamespaces = []string{"kube-system"} 27 defaultClusterLocalServices = []string{"kubernetes.default.svc"} 28 ) 29 30 // ClusterLocalHosts is a map of host names or wildcard patterns which should only 31 // be made accessible from within the same cluster. 32 type ClusterLocalHosts struct { 33 specific sets.Set[host.Name] 34 wildcard sets.Set[host.Name] 35 } 36 37 // IsClusterLocal indicates whether the given host should be treated as a 38 // cluster-local destination. 39 func (c ClusterLocalHosts) IsClusterLocal(h host.Name) bool { 40 _, _, ok := MostSpecificHostMatch(h, c.specific, c.wildcard) 41 return ok 42 } 43 44 // ClusterLocalProvider provides the cluster-local hosts. 45 type ClusterLocalProvider interface { 46 // GetClusterLocalHosts returns the list of cluster-local hosts, sorted in 47 // ascending order. The caller must not modify the returned list. 48 GetClusterLocalHosts() ClusterLocalHosts 49 } 50 51 // NewClusterLocalProvider returns a new ClusterLocalProvider for the Environment. 52 func NewClusterLocalProvider(e *Environment) ClusterLocalProvider { 53 c := &clusterLocalProvider{} 54 55 // Register a handler to update the environment when the mesh config is updated. 56 e.AddMeshHandler(func() { 57 c.onMeshUpdated(e) 58 }) 59 60 // Update the cluster-local hosts now. 61 c.onMeshUpdated(e) 62 return c 63 } 64 65 var _ ClusterLocalProvider = &clusterLocalProvider{} 66 67 type clusterLocalProvider struct { 68 mutex sync.RWMutex 69 hosts ClusterLocalHosts 70 } 71 72 func (c *clusterLocalProvider) GetClusterLocalHosts() ClusterLocalHosts { 73 c.mutex.RLock() 74 out := c.hosts 75 c.mutex.RUnlock() 76 return out 77 } 78 79 func (c *clusterLocalProvider) onMeshUpdated(e *Environment) { 80 // Create the default list of cluster-local hosts. 81 domainSuffix := e.DomainSuffix 82 defaultClusterLocalHosts := make([]host.Name, 0) 83 for _, n := range defaultClusterLocalNamespaces { 84 defaultClusterLocalHosts = append(defaultClusterLocalHosts, host.Name("*."+n+".svc."+domainSuffix)) 85 } 86 for _, s := range defaultClusterLocalServices { 87 defaultClusterLocalHosts = append(defaultClusterLocalHosts, host.Name(s+"."+domainSuffix)) 88 } 89 90 if discoveryHost, _, err := e.GetDiscoveryAddress(); err != nil { 91 log.Errorf("failed to make discoveryAddress cluster-local: %v", err) 92 } else { 93 if !strings.HasSuffix(string(discoveryHost), domainSuffix) { 94 discoveryHost += host.Name("." + domainSuffix) 95 } 96 defaultClusterLocalHosts = append(defaultClusterLocalHosts, discoveryHost) 97 } 98 99 // Collect the cluster-local hosts. 100 hosts := ClusterLocalHosts{ 101 specific: make(map[host.Name]struct{}, 0), 102 wildcard: make(map[host.Name]struct{}, 0), 103 } 104 for _, serviceSettings := range e.Mesh().ServiceSettings { 105 if serviceSettings.GetSettings().GetClusterLocal() { 106 for _, h := range serviceSettings.GetHosts() { 107 hostname := host.Name(h) 108 if hostname.IsWildCarded() { 109 hosts.wildcard.Insert(hostname) 110 } else { 111 hosts.specific.Insert(hostname) 112 } 113 } 114 } else { 115 // Remove defaults if specified to be non-cluster-local. 116 for _, h := range serviceSettings.GetHosts() { 117 for i, defaultClusterLocalHost := range defaultClusterLocalHosts { 118 if len(defaultClusterLocalHost) > 0 { 119 if h == string(defaultClusterLocalHost) || 120 (defaultClusterLocalHost.IsWildCarded() && 121 strings.HasSuffix(h, string(defaultClusterLocalHost[1:]))) { 122 // This default was explicitly overridden, so remove it. 123 defaultClusterLocalHosts[i] = "" 124 } 125 } 126 } 127 } 128 } 129 } 130 131 // Add any remaining defaults to the end of the list. 132 for _, defaultClusterLocalHost := range defaultClusterLocalHosts { 133 if len(defaultClusterLocalHost) > 0 { 134 if defaultClusterLocalHost.IsWildCarded() { 135 hosts.wildcard.Insert(defaultClusterLocalHost) 136 } else { 137 hosts.specific.Insert(defaultClusterLocalHost) 138 } 139 } 140 } 141 142 c.mutex.Lock() 143 c.hosts = hosts 144 c.mutex.Unlock() 145 }