sigs.k8s.io/cluster-api@v1.7.1/internal/topology/names/names.go (about) 1 /* 2 Copyright 2023 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 // Package names implements name generators for managed topology. 18 package names 19 20 import ( 21 "bytes" 22 "fmt" 23 "text/template" 24 25 "github.com/pkg/errors" 26 utilrand "k8s.io/apimachinery/pkg/util/rand" 27 ) 28 29 // This is a copy of the constants at k8s.io/apiserver/pkg/storage/names. 30 const ( 31 maxNameLength = 63 32 randomLength = 5 33 maxGeneratedNameLength = maxNameLength - randomLength 34 ) 35 36 type simpleNameGenerator struct { 37 base string 38 } 39 40 func (s *simpleNameGenerator) GenerateName() (string, error) { 41 base := s.base 42 if len(base) > maxGeneratedNameLength { 43 base = base[:maxGeneratedNameLength] 44 } 45 return fmt.Sprintf("%s%s", base, utilrand.String(randomLength)), nil 46 } 47 48 // NameGenerator generates names for objects. 49 type NameGenerator interface { 50 // GenerateName generates a valid name. The generator is responsible for 51 // knowing the maximum valid name length. 52 GenerateName() (string, error) 53 } 54 55 // SimpleNameGenerator returns a NameGenerator which is based on 56 // k8s.io/apiserver/pkg/storage/names.SimpleNameGenerator. 57 func SimpleNameGenerator(base string) NameGenerator { 58 return &simpleNameGenerator{ 59 base: base, 60 } 61 } 62 63 // ControlPlaneNameGenerator returns a generator for creating a control plane name. 64 func ControlPlaneNameGenerator(templateString, clusterName string) NameGenerator { 65 return newTemplateGenerator(templateString, clusterName, 66 map[string]interface{}{}) 67 } 68 69 // MachineDeploymentNameGenerator returns a generator for creating a machinedeployment name. 70 func MachineDeploymentNameGenerator(templateString, clusterName, topologyName string) NameGenerator { 71 return newTemplateGenerator(templateString, clusterName, 72 map[string]interface{}{ 73 "machineDeployment": map[string]interface{}{ 74 "topologyName": topologyName, 75 }, 76 }) 77 } 78 79 // MachinePoolNameGenerator returns a generator for creating a machinepool name. 80 func MachinePoolNameGenerator(templateString, clusterName, topologyName string) NameGenerator { 81 return newTemplateGenerator(templateString, clusterName, 82 map[string]interface{}{ 83 "machinePool": map[string]interface{}{ 84 "topologyName": topologyName, 85 }, 86 }) 87 } 88 89 // templateGenerator parses the template string as text/template and executes it using 90 // the passed data to generate a name. 91 type templateGenerator struct { 92 template string 93 data map[string]interface{} 94 } 95 96 func newTemplateGenerator(template, clusterName string, data map[string]interface{}) NameGenerator { 97 data["cluster"] = map[string]interface{}{ 98 "name": clusterName, 99 } 100 data["random"] = utilrand.String(randomLength) 101 102 return &templateGenerator{ 103 template: template, 104 data: data, 105 } 106 } 107 108 func (g *templateGenerator) GenerateName() (string, error) { 109 tpl, err := template.New("template name generator").Option("missingkey=error").Parse(g.template) 110 if err != nil { 111 return "", errors.Wrapf(err, "parsing template %q", g.template) 112 } 113 114 var buf bytes.Buffer 115 if err := tpl.Execute(&buf, g.data); err != nil { 116 return "", errors.Wrap(err, "rendering template") 117 } 118 119 name := buf.String() 120 121 // If the name exceeds the maxNameLength: trim to maxGeneratedNameLength and add 122 // a random suffix. 123 if len(name) > maxNameLength { 124 name = name[:maxGeneratedNameLength] + utilrand.String(randomLength) 125 } 126 127 return name, nil 128 } 129 130 // BootstrapTemplateNamePrefix calculates the name prefix for a BootstrapTemplate. 131 func BootstrapTemplateNamePrefix(clusterName, machineDeploymentTopologyName string) string { 132 return fmt.Sprintf("%s-%s-", clusterName, machineDeploymentTopologyName) 133 } 134 135 // InfrastructureMachineTemplateNamePrefix calculates the name prefix for a InfrastructureMachineTemplate. 136 func InfrastructureMachineTemplateNamePrefix(clusterName, machineDeploymentTopologyName string) string { 137 return fmt.Sprintf("%s-%s-", clusterName, machineDeploymentTopologyName) 138 } 139 140 // BootstrapConfigNamePrefix calculates the name prefix for a BootstrapConfig. 141 func BootstrapConfigNamePrefix(clusterName, machinePoolTopologyName string) string { 142 return fmt.Sprintf("%s-%s-", clusterName, machinePoolTopologyName) 143 } 144 145 // InfrastructureMachinePoolNamePrefix calculates the name prefix for a InfrastructureMachinePool. 146 func InfrastructureMachinePoolNamePrefix(clusterName, machinePoolTopologyName string) string { 147 return fmt.Sprintf("%s-%s-", clusterName, machinePoolTopologyName) 148 } 149 150 // ControlPlaneInfrastructureMachineTemplateNamePrefix calculates the name prefix for a InfrastructureMachineTemplate. 151 func ControlPlaneInfrastructureMachineTemplateNamePrefix(clusterName string) string { 152 return fmt.Sprintf("%s-", clusterName) 153 }