csmnamer/namer.go (47 lines of code) (raw):

// Copyright 2023 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // DO NOT EDIT: This code is a subset of services_platform/thetis/gateway/core/v1alpha2/common/appnettranslator/gsm/namer.go // and should not be modified to maintain functional consistency. package csmnamer import ( "fmt" "strings" "unicode" ) const ( // Length limit for hash created from fields that uniquely identify a GCE resource and // appended as a suffix to the resource name nHashLen = 12 // max length of a GCE resource name. resourceNameMaxLen = 63 // clusterUIDLen is the length of cluster UID, computed as a hash of ClusterName // prefix used for GCE resource names created by GAMMA mesh. clusterUIDLen = 4 // csmMeshPrefix is the prefix override used in the CSMMesh use cases. csmMeshPrefix = "gsmmesh" ) type MeshNamer struct { ClusterName string Location string } func (m *MeshNamer) GenerateMeshId() string { return readableResourceName(m.ClusterName, m.Location) } // Returns a readable resource name in the following format // {prefix}-{component#0}-{component#1}...-{hash} // The length of the returned resource name is guarantee to be within // resourceNameLen which is the maximum length of a GCE resource. A component // will only be included explicitly in the resource name if it doesn't have an // invalid character (any character that is not a letter, digit or '-'). // Components in the resource name maybe trimmed to fit the maximum length // requirement. {hash} uniquely identifies the component set. func readableResourceName(components ...string) string { // clusterHash enforces uniqueness of resources of different clusters in // the same project. clusterHash := Hash(strings.Join(components, ";"), clusterUIDLen) prefix := csmMeshPrefix + "-" + clusterHash // resourceHash enforces uniqueness of resources of the same cluster. resourceHash := Hash(strings.Join(components, ";"), nHashLen) // Ideally we explicitly include all components in the GCP resource name, so // it's easier to be related to the corresponding k8s resource(s). However, // only certain characters are allowed in a GCP resource name(e.g. a common // character '.' in hostnames is not allowed in GCP resource name). var explicitComponents []string for _, c := range components { // Only explicitly include a component in GCP resource name if all // characters in it are allowed. Omitting a component here is okay since // the resourceHash already represents the full component set. if allCharAllowedInResourceName(c) { explicitComponents = append(explicitComponents, c) } } // The maximum total length of components is determined by subtracting length // of the following substring from the maximum length of resource name: // * prefix // * separators "-". There will be len(explicitComponents) + 1 of them. // * hash componentsMaxLen := resourceNameMaxLen - len(prefix) - (len(explicitComponents) + 1) - len(resourceHash) // Drop components from the resource name if the allowed maximum total length // of them is less them the total number of components. (This happens when // there are too many components) if componentsMaxLen < len(explicitComponents) { return fmt.Sprintf("%s-%s", prefix, resourceHash) } // Trim components to fit the allowed maximum total length. trimmed := TrimFieldsEvenly(componentsMaxLen, explicitComponents...) return fmt.Sprintf("%s-%s-%s", prefix, strings.Join(trimmed, "-"), resourceHash) } func allCharAllowedInResourceName(s string) bool { if len(s) == 0 { return false } for _, r := range s { if !(unicode.IsDigit(r) || unicode.IsLetter(r) || r == '-') { return false } } return true }