istio.io/istio@v0.0.0-20240520182934-d79c90f27776/pkg/config/analysis/analyzers/util/hosts.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 util 16 17 import ( 18 "strings" 19 20 "istio.io/istio/pkg/config/resource" 21 ) 22 23 type ScopedFqdn string 24 25 // GetScopeAndFqdn splits ScopedFqdn back to scope namespace and fqdn parts 26 func (s ScopedFqdn) GetScopeAndFqdn() (string, string) { 27 parts := strings.SplitN(string(s), "/", 2) 28 return parts[0], parts[1] 29 } 30 31 // InScopeOf returns true if ns is in the scope of ScopedFqdn 32 func (s ScopedFqdn) InScopeOf(ns string) bool { 33 scope, fqdn := s.GetScopeAndFqdn() 34 fn := GetFullNameFromFQDN(fqdn) 35 return scope == "*" || scope == "." && ns == fn.Namespace.String() || scope == ns 36 } 37 38 // NewScopedFqdn converts the passed host to FQDN if needed and applies the passed scope. 39 func NewScopedFqdn(scope string, namespace resource.Namespace, host string) ScopedFqdn { 40 fqdn := ConvertHostToFQDN(namespace, host) 41 return ScopedFqdn(scope + "/" + fqdn) 42 } 43 44 // GetResourceNameFromHost figures out the resource.FullName to look up from the provided host string 45 // We need to handle two possible formats: short name and FQDN 46 // https://istio.io/docs/reference/config/networking/v1alpha3/virtual-service/#Destination 47 func GetResourceNameFromHost(defaultNamespace resource.Namespace, host string) resource.FullName { 48 // First, try to parse as FQDN (which can be cross-namespace) 49 name := GetFullNameFromFQDN(host) 50 51 // Otherwise, treat this as a short name and use the assumed namespace 52 if name.Namespace == "" { 53 name.Namespace = defaultNamespace 54 name.Name = resource.LocalName(host) 55 } 56 return name 57 } 58 59 // GetFullNameFromFQDN tries to parse namespace and name from a fqdn. 60 // Empty strings are returned if either namespace or name cannot be parsed. 61 func GetFullNameFromFQDN(fqdn string) resource.FullName { 62 result := fqdnPattern.FindAllStringSubmatch(fqdn, -1) 63 if len(result) == 0 { 64 return resource.FullName{ 65 Namespace: "", 66 Name: "", 67 } 68 } 69 return resource.FullName{ 70 Namespace: resource.Namespace(result[0][2]), 71 Name: resource.LocalName(result[0][1]), 72 } 73 } 74 75 // ConvertHostToFQDN returns the given host as a FQDN, if it isn't already. 76 func ConvertHostToFQDN(namespace resource.Namespace, host string) string { 77 fqdn := host 78 // Convert to FQDN only if host is not a wildcard or a FQDN 79 if !strings.HasPrefix(host, "*") && 80 !strings.Contains(host, ".") { 81 fqdn = host + "." + string(namespace) + "." + DefaultClusterLocalDomain 82 } 83 return fqdn 84 }