Refactor ClusterComplexName
This change includes various code cleanups which improve the way that a developer creates and interacts with ClusterComplexNames. Change-Id: If3c4326f3ca46db7fd307b50ca260cdb1a82f3f3
This commit is contained in:
parent
cbc1e931ae
commit
567e063589
@ -60,14 +60,13 @@ func TestSetClusterWithCAFile(t *testing.T) {
|
||||
|
||||
expected.Clusters[tname] = config.NewClusterPurpose()
|
||||
expected.Clusters[tname].ClusterTypes[tctype] = config.NewCluster()
|
||||
clusterName := config.NewClusterComplexName()
|
||||
clusterName.WithType(tname, tctype)
|
||||
expected.Clusters[tname].ClusterTypes[tctype].NameInKubeconf = clusterName.Name()
|
||||
clusterName := config.NewClusterComplexName(tname, tctype)
|
||||
expected.Clusters[tname].ClusterTypes[tctype].NameInKubeconf = clusterName.String()
|
||||
|
||||
expkCluster := kubeconfig.NewCluster()
|
||||
expkCluster.CertificateAuthority = certFile
|
||||
expkCluster.InsecureSkipTLSVerify = false
|
||||
expected.KubeConfig().Clusters[clusterName.Name()] = expkCluster
|
||||
expected.KubeConfig().Clusters[clusterName.String()] = expkCluster
|
||||
|
||||
test := setClusterTest{
|
||||
description: "Testing 'airshipctl config set-cluster' with a new cluster",
|
||||
@ -98,9 +97,8 @@ func TestSetClusterWithCAFileData(t *testing.T) {
|
||||
|
||||
expected.Clusters[tname] = config.NewClusterPurpose()
|
||||
expected.Clusters[tname].ClusterTypes[tctype] = config.NewCluster()
|
||||
clusterName := config.NewClusterComplexName()
|
||||
clusterName.WithType(tname, tctype)
|
||||
expected.Clusters[tname].ClusterTypes[tctype].NameInKubeconf = clusterName.Name()
|
||||
clusterName := config.NewClusterComplexName(tname, tctype)
|
||||
expected.Clusters[tname].ClusterTypes[tctype].NameInKubeconf = clusterName.String()
|
||||
|
||||
expkCluster := kubeconfig.NewCluster()
|
||||
readData, err := ioutil.ReadFile(certFile)
|
||||
@ -108,7 +106,7 @@ func TestSetClusterWithCAFileData(t *testing.T) {
|
||||
|
||||
expkCluster.CertificateAuthorityData = readData
|
||||
expkCluster.InsecureSkipTLSVerify = false
|
||||
expected.KubeConfig().Clusters[clusterName.Name()] = expkCluster
|
||||
expected.KubeConfig().Clusters[clusterName.String()] = expkCluster
|
||||
|
||||
test := setClusterTest{
|
||||
description: "Testing 'airshipctl config set-cluster' with a new cluster",
|
||||
@ -138,14 +136,13 @@ func TestSetCluster(t *testing.T) {
|
||||
|
||||
expected.Clusters[tname] = config.NewClusterPurpose()
|
||||
expected.Clusters[tname].ClusterTypes[tctype] = config.NewCluster()
|
||||
clusterName := config.NewClusterComplexName()
|
||||
clusterName.WithType(tname, tctype)
|
||||
expected.Clusters[tname].ClusterTypes[tctype].NameInKubeconf = clusterName.Name()
|
||||
clusterName := config.NewClusterComplexName(tname, tctype)
|
||||
expected.Clusters[tname].ClusterTypes[tctype].NameInKubeconf = clusterName.String()
|
||||
|
||||
expkCluster := kubeconfig.NewCluster()
|
||||
expkCluster.Server = "https://192.168.0.11"
|
||||
expkCluster.InsecureSkipTLSVerify = false
|
||||
expected.KubeConfig().Clusters[clusterName.Name()] = expkCluster
|
||||
expected.KubeConfig().Clusters[clusterName.String()] = expkCluster
|
||||
|
||||
test := setClusterTest{
|
||||
description: "Testing 'airshipctl config set-cluster' with a new cluster",
|
||||
@ -170,13 +167,12 @@ func TestModifyCluster(t *testing.T) {
|
||||
defer cleanupGiven(t)
|
||||
|
||||
given.Clusters[tname] = config.NewClusterPurpose()
|
||||
clusterName := config.NewClusterComplexName()
|
||||
clusterName.WithType(tname, tctype)
|
||||
clusterName := config.NewClusterComplexName(tname, tctype)
|
||||
given.Clusters[tname].ClusterTypes[tctype] = config.NewCluster()
|
||||
given.Clusters[tname].ClusterTypes[tctype].NameInKubeconf = clusterName.Name()
|
||||
given.Clusters[tname].ClusterTypes[tctype].NameInKubeconf = clusterName.String()
|
||||
cluster := kubeconfig.NewCluster()
|
||||
cluster.Server = "https://192.168.0.10"
|
||||
given.KubeConfig().Clusters[clusterName.Name()] = cluster
|
||||
given.KubeConfig().Clusters[clusterName.String()] = cluster
|
||||
given.Clusters[tname].ClusterTypes[tctype].SetKubeCluster(cluster)
|
||||
|
||||
expected, cleanupExpected := testutil.InitConfig(t)
|
||||
@ -184,10 +180,10 @@ func TestModifyCluster(t *testing.T) {
|
||||
|
||||
expected.Clusters[tname] = config.NewClusterPurpose()
|
||||
expected.Clusters[tname].ClusterTypes[tctype] = config.NewCluster()
|
||||
expected.Clusters[tname].ClusterTypes[tctype].NameInKubeconf = clusterName.Name()
|
||||
expected.Clusters[tname].ClusterTypes[tctype].NameInKubeconf = clusterName.String()
|
||||
expkCluster := kubeconfig.NewCluster()
|
||||
expkCluster.Server = "https://192.168.0.10"
|
||||
expected.KubeConfig().Clusters[clusterName.Name()] = expkCluster
|
||||
expected.KubeConfig().Clusters[clusterName.String()] = expkCluster
|
||||
expected.Clusters[tname].ClusterTypes[tctype].SetKubeCluster(expkCluster)
|
||||
|
||||
test := setClusterTest{
|
||||
|
@ -153,19 +153,17 @@ func (c *Config) reconcileClusters() (map[string]string, bool) {
|
||||
|
||||
persistIt := false
|
||||
for clusterName, cluster := range c.kubeConfig.Clusters {
|
||||
clusterComplexName := NewClusterComplexName()
|
||||
clusterComplexName.FromName(clusterName)
|
||||
clusterComplexName := NewClusterComplexNameFromKubeClusterName(clusterName)
|
||||
// Check if the cluster from the kubeconfig file complies with
|
||||
// the airship naming convention
|
||||
if !clusterComplexName.validName() {
|
||||
clusterComplexName.SetDefaultType()
|
||||
if clusterName != clusterComplexName.String() {
|
||||
// Update the kubeconfig with proper airship name
|
||||
c.kubeConfig.Clusters[clusterComplexName.Name()] = cluster
|
||||
c.kubeConfig.Clusters[clusterComplexName.String()] = cluster
|
||||
delete(c.kubeConfig.Clusters, clusterName)
|
||||
|
||||
// We also need to save the mapping from the old name
|
||||
// so we can update the context in the kubeconfig later
|
||||
updatedClusterNames[clusterName] = clusterComplexName.Name()
|
||||
updatedClusterNames[clusterName] = clusterComplexName.String()
|
||||
|
||||
// Since we've modified the kubeconfig object, we'll
|
||||
// need to let the caller know that the kubeconfig file
|
||||
@ -179,17 +177,16 @@ func (c *Config) reconcileClusters() (map[string]string, bool) {
|
||||
}
|
||||
|
||||
// Update the airship config file
|
||||
if c.Clusters[clusterComplexName.ClusterName()] == nil {
|
||||
c.Clusters[clusterComplexName.ClusterName()] = NewClusterPurpose()
|
||||
if c.Clusters[clusterComplexName.Name] == nil {
|
||||
c.Clusters[clusterComplexName.Name] = NewClusterPurpose()
|
||||
}
|
||||
if c.Clusters[clusterComplexName.ClusterName()].ClusterTypes[clusterComplexName.ClusterType()] == nil {
|
||||
c.Clusters[clusterComplexName.ClusterName()].ClusterTypes[clusterComplexName.ClusterType()] = NewCluster()
|
||||
}
|
||||
configCluster := c.Clusters[clusterComplexName.ClusterName()].ClusterTypes[clusterComplexName.ClusterType()]
|
||||
if configCluster.NameInKubeconf != clusterComplexName.Name() {
|
||||
configCluster.NameInKubeconf = clusterComplexName.Name()
|
||||
// TODO What do we do with the BOOTSTRAP CONFIG
|
||||
if c.Clusters[clusterComplexName.Name].ClusterTypes[clusterComplexName.Type] == nil {
|
||||
c.Clusters[clusterComplexName.Name].ClusterTypes[clusterComplexName.Type] = NewCluster()
|
||||
}
|
||||
configCluster := c.Clusters[clusterComplexName.Name].ClusterTypes[clusterComplexName.Type]
|
||||
configCluster.NameInKubeconf = clusterComplexName.String()
|
||||
// TODO What do we do with the BOOTSTRAP CONFIG
|
||||
|
||||
// Store the reference to the KubeConfig Cluster in the Airship Config
|
||||
configCluster.SetKubeCluster(cluster)
|
||||
}
|
||||
@ -239,11 +236,10 @@ func (c *Config) reconcileContexts(updatedClusterNames map[string]string) {
|
||||
c.Contexts[key].NameInKubeconf = context.Cluster
|
||||
c.Contexts[key].SetKubeContext(context)
|
||||
|
||||
// What about if a Context refers to a properly named cluster
|
||||
// that does not exist in airship config
|
||||
clusterName := NewClusterComplexName()
|
||||
clusterName.FromName(context.Cluster)
|
||||
if clusterName.validName() && c.Clusters[clusterName.ClusterName()] == nil {
|
||||
// What about if a Context refers to a cluster that does not
|
||||
// exist in airship config
|
||||
clusterName := NewClusterComplexNameFromKubeClusterName(context.Cluster)
|
||||
if c.Clusters[clusterName.Name] == nil {
|
||||
// I cannot create this cluster, it will have empty information
|
||||
// Best course of action is to delete it I think
|
||||
delete(c.kubeConfig.Contexts, key)
|
||||
@ -446,12 +442,11 @@ func (c *Config) AddCluster(theCluster *ClusterOptions) (*Cluster, error) {
|
||||
c.Clusters[theCluster.Name].ClusterTypes[theCluster.ClusterType] = nCluster
|
||||
// Create a new KubeConfig Cluster object as well
|
||||
kcluster := clientcmdapi.NewCluster()
|
||||
clusterName := NewClusterComplexName()
|
||||
clusterName.WithType(theCluster.Name, theCluster.ClusterType)
|
||||
nCluster.NameInKubeconf = clusterName.Name()
|
||||
clusterName := NewClusterComplexName(theCluster.Name, theCluster.ClusterType)
|
||||
nCluster.NameInKubeconf = clusterName.String()
|
||||
nCluster.SetKubeCluster(kcluster)
|
||||
|
||||
c.KubeConfig().Clusters[clusterName.Name()] = kcluster
|
||||
c.KubeConfig().Clusters[clusterName.String()] = kcluster
|
||||
|
||||
// Ok , I have initialized structs for the Cluster information
|
||||
// We can use Modify to populate the correct information
|
||||
@ -556,8 +551,6 @@ func (c *Config) AddContext(theContext *ContextOptions) *Context {
|
||||
// Create a new KubeConfig Context object as well
|
||||
context := clientcmdapi.NewContext()
|
||||
nContext.NameInKubeconf = theContext.Name
|
||||
contextName := NewClusterComplexName()
|
||||
contextName.WithType(theContext.Name, theContext.ClusterType)
|
||||
|
||||
nContext.SetKubeContext(context)
|
||||
c.KubeConfig().Contexts[theContext.Name] = context
|
||||
@ -610,10 +603,9 @@ func (c *Config) CurrentContextCluster() (*Cluster, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
clusterName := NewClusterComplexName()
|
||||
clusterName.FromName(currentContext.KubeContext().Cluster)
|
||||
clusterName := NewClusterComplexNameFromKubeClusterName(currentContext.KubeContext().Cluster)
|
||||
|
||||
return c.Clusters[clusterName.ClusterName()].ClusterTypes[currentContext.ClusterType()], nil
|
||||
return c.Clusters[clusterName.Name].ClusterTypes[currentContext.ClusterType()], nil
|
||||
}
|
||||
|
||||
func (c *Config) CurrentContextAuthInfo() (*AuthInfo, error) {
|
||||
@ -755,11 +747,8 @@ func (c *Cluster) String() string {
|
||||
}
|
||||
|
||||
func (c *Cluster) PrettyString() string {
|
||||
clusterName := NewClusterComplexName()
|
||||
clusterName.FromName(c.NameInKubeconf)
|
||||
|
||||
return fmt.Sprintf("Cluster: %s\n%s:\n%s",
|
||||
clusterName.ClusterName(), clusterName.ClusterType(), c)
|
||||
clusterName := NewClusterComplexNameFromKubeClusterName(c.NameInKubeconf)
|
||||
return fmt.Sprintf("Cluster: %s\n%s:\n%s", clusterName.Name, clusterName.Type, c)
|
||||
}
|
||||
|
||||
func (c *Cluster) KubeCluster() *clientcmdapi.Cluster {
|
||||
@ -784,11 +773,8 @@ func (c *Context) String() string {
|
||||
}
|
||||
|
||||
func (c *Context) PrettyString() string {
|
||||
clusterName := NewClusterComplexName()
|
||||
clusterName.FromName(c.NameInKubeconf)
|
||||
|
||||
return fmt.Sprintf("Context: %s\n%s\n",
|
||||
clusterName.ClusterName(), c.String())
|
||||
clusterName := NewClusterComplexNameFromKubeClusterName(c.NameInKubeconf)
|
||||
return fmt.Sprintf("Context: %s\n%s\n", clusterName.Name, c)
|
||||
}
|
||||
|
||||
func (c *Context) KubeContext() *clientcmdapi.Context {
|
||||
@ -800,9 +786,7 @@ func (c *Context) SetKubeContext(kc *clientcmdapi.Context) {
|
||||
}
|
||||
|
||||
func (c *Context) ClusterType() string {
|
||||
clusterName := NewClusterComplexName()
|
||||
clusterName.FromName(c.NameInKubeconf)
|
||||
return clusterName.ClusterType()
|
||||
return NewClusterComplexNameFromKubeClusterName(c.NameInKubeconf).Type
|
||||
}
|
||||
|
||||
// AuthInfo functions
|
||||
@ -867,60 +851,10 @@ func (b *Builder) String() string {
|
||||
return string(yamlData)
|
||||
}
|
||||
|
||||
// ClusterComplexName functions
|
||||
func (c *ClusterComplexName) validName() bool {
|
||||
err := ValidClusterType(c.clusterType)
|
||||
return c.clusterName != "" && err == nil
|
||||
}
|
||||
|
||||
func (c *ClusterComplexName) FromName(clusterName string) {
|
||||
if clusterName == "" {
|
||||
return
|
||||
}
|
||||
|
||||
userNameSplit := strings.Split(clusterName, AirshipClusterNameSep)
|
||||
if len(userNameSplit) == 1 {
|
||||
c.clusterName = clusterName
|
||||
return
|
||||
}
|
||||
|
||||
for _, cType := range AllClusterTypes {
|
||||
if userNameSplit[len(userNameSplit)-1] == cType {
|
||||
c.clusterType = userNameSplit[len(userNameSplit)-1]
|
||||
c.clusterName = strings.Join(userNameSplit[:len(userNameSplit)-1], AirshipClusterNameSep)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (c *ClusterComplexName) WithType(clusterName string, clusterType string) {
|
||||
c.FromName(clusterName)
|
||||
c.SetClusterType(clusterType)
|
||||
}
|
||||
func (c *ClusterComplexName) Name() string {
|
||||
s := []string{c.clusterName, c.clusterType}
|
||||
return strings.Join(s, AirshipClusterNameSep)
|
||||
}
|
||||
func (c *ClusterComplexName) ClusterName() string {
|
||||
return c.clusterName
|
||||
}
|
||||
|
||||
func (c *ClusterComplexName) ClusterType() string {
|
||||
return c.clusterType
|
||||
}
|
||||
func (c *ClusterComplexName) SetClusterName(cn string) {
|
||||
c.clusterName = cn
|
||||
}
|
||||
|
||||
func (c *ClusterComplexName) SetClusterType(ct string) {
|
||||
c.clusterType = ct
|
||||
}
|
||||
func (c *ClusterComplexName) SetDefaultType() {
|
||||
c.SetClusterType(AirshipClusterDefaultType)
|
||||
}
|
||||
func (c *ClusterComplexName) String() string {
|
||||
return fmt.Sprintf("clusterName:%s, clusterType:%s", c.clusterName, c.clusterType)
|
||||
return strings.Join([]string{c.Name, c.Type}, AirshipClusterNameSeparator)
|
||||
}
|
||||
|
||||
func ValidClusterType(clusterType string) error {
|
||||
for _, validType := range AllClusterTypes {
|
||||
if clusterType == validType {
|
||||
|
@ -307,23 +307,6 @@ func TestPurge(t *testing.T) {
|
||||
assert.Falsef(t, os.IsExist(err), "Purge failed to remove file at %v", conf.LoadedConfigPath())
|
||||
}
|
||||
|
||||
func TestComplexName(t *testing.T) {
|
||||
cName := "aCluster"
|
||||
ctName := config.Ephemeral
|
||||
clusterName := config.NewClusterComplexName()
|
||||
clusterName.WithType(cName, ctName)
|
||||
assert.EqualValues(t, cName+"_"+ctName, clusterName.Name())
|
||||
assert.EqualValues(t, cName, clusterName.ClusterName())
|
||||
assert.EqualValues(t, ctName, clusterName.ClusterType())
|
||||
|
||||
cName = "bCluster"
|
||||
clusterName.SetClusterName(cName)
|
||||
clusterName.SetDefaultType()
|
||||
ctName = clusterName.ClusterType()
|
||||
assert.EqualValues(t, cName+"_"+ctName, clusterName.Name())
|
||||
assert.EqualValues(t, "clusterName:"+cName+", clusterType:"+ctName, clusterName.String())
|
||||
}
|
||||
|
||||
func TestValidClusterTypeFail(t *testing.T) {
|
||||
err := config.ValidClusterType("Fake")
|
||||
assert.Error(t, err)
|
||||
@ -626,3 +609,46 @@ func TestModifyAuthInfo(t *testing.T) {
|
||||
assert.EqualValues(t, conf.AuthInfos[co.Name].KubeAuthInfo().Token, co.Token)
|
||||
assert.EqualValues(t, conf.AuthInfos[co.Name], authinfo)
|
||||
}
|
||||
|
||||
func TestNewClusterComplexNameFromKubeClusterName(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
inputName string
|
||||
expectedName string
|
||||
expectedType string
|
||||
}{
|
||||
{
|
||||
name: "single-word",
|
||||
inputName: "myCluster",
|
||||
expectedName: "myCluster",
|
||||
expectedType: config.AirshipDefaultClusterType,
|
||||
},
|
||||
{
|
||||
name: "multi-word",
|
||||
inputName: "myCluster_two",
|
||||
expectedName: "myCluster_two",
|
||||
expectedType: config.AirshipDefaultClusterType,
|
||||
},
|
||||
{
|
||||
name: "cluster-appended",
|
||||
inputName: "myCluster_ephemeral",
|
||||
expectedName: "myCluster",
|
||||
expectedType: config.Ephemeral,
|
||||
},
|
||||
{
|
||||
name: "multi-word-cluster-appended",
|
||||
inputName: "myCluster_two_ephemeral",
|
||||
expectedName: "myCluster_two",
|
||||
expectedType: config.Ephemeral,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
tt := tt
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
complexName := config.NewClusterComplexNameFromKubeClusterName(tt.inputName)
|
||||
assert.Equal(t, tt.expectedName, complexName.Name)
|
||||
assert.Equal(t, tt.expectedType, complexName.Type)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -2,10 +2,10 @@ package config
|
||||
|
||||
// Constants related to the ClusterType type
|
||||
const (
|
||||
Ephemeral = "ephemeral"
|
||||
Target = "target"
|
||||
AirshipClusterNameSep = "_"
|
||||
AirshipClusterDefaultType = Target
|
||||
Ephemeral = "ephemeral"
|
||||
Target = "target"
|
||||
AirshipClusterNameSeparator = "_"
|
||||
AirshipDefaultClusterType = Target
|
||||
)
|
||||
|
||||
// Constants related to Phases
|
||||
|
@ -182,8 +182,8 @@ type RepoCheckout struct {
|
||||
// Holds the complex cluster name information
|
||||
// Encapsulates the different operations around using it.
|
||||
type ClusterComplexName struct {
|
||||
clusterName string
|
||||
clusterType string
|
||||
Name string
|
||||
Type string
|
||||
}
|
||||
|
||||
// Bootstrap holds configurations for bootstrap steps
|
||||
|
@ -16,6 +16,8 @@ limitations under the License.
|
||||
|
||||
package config
|
||||
|
||||
import "strings"
|
||||
|
||||
const (
|
||||
DefaultTestPrimaryRepo = "primary"
|
||||
)
|
||||
@ -112,6 +114,40 @@ func NewClusterPurpose() *ClusterPurpose {
|
||||
}
|
||||
}
|
||||
|
||||
func NewClusterComplexName() *ClusterComplexName {
|
||||
return &ClusterComplexName{}
|
||||
// NewClusterComplexName returns a ClusterComplexName with the given name and type.
|
||||
func NewClusterComplexName(clusterName, clusterType string) ClusterComplexName {
|
||||
return ClusterComplexName{
|
||||
Name: clusterName,
|
||||
Type: clusterType,
|
||||
}
|
||||
}
|
||||
|
||||
// NewClusterComplexNameFromKubeClusterName takes the name of a cluster in a
|
||||
// format which might be found in a kubeconfig file. This may be a simple
|
||||
// string (e.g. myCluster), or it may be prepended with the type of the cluster
|
||||
// (e.g. myCluster_target)
|
||||
//
|
||||
// If a valid cluster type was appended, the returned ClusterComplexName will
|
||||
// have that type. If no cluster type is provided, the
|
||||
// AirshipDefaultClusterType will be used.
|
||||
func NewClusterComplexNameFromKubeClusterName(kubeClusterName string) ClusterComplexName {
|
||||
parts := strings.Split(kubeClusterName, AirshipClusterNameSeparator)
|
||||
|
||||
if len(parts) == 1 {
|
||||
return NewClusterComplexName(kubeClusterName, AirshipDefaultClusterType)
|
||||
}
|
||||
|
||||
// kubeClusterName matches the format myCluster_something.
|
||||
// Let's check if "something" is a clusterType.
|
||||
potentialType := parts[len(parts)-1]
|
||||
for _, ct := range AllClusterTypes {
|
||||
if potentialType == ct {
|
||||
// Rejoin the parts in the case of "my_cluster_etc_etc_<clusterType>"
|
||||
name := strings.Join(parts[:len(parts)-1], AirshipClusterNameSeparator)
|
||||
return NewClusterComplexName(name, potentialType)
|
||||
}
|
||||
}
|
||||
|
||||
// "something" is not a valid clusterType, so just use the default
|
||||
return NewClusterComplexName(kubeClusterName, AirshipDefaultClusterType)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user