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  }