Skip to content
This repository has been archived by the owner on Jun 28, 2023. It is now read-only.

Introduces ExistingClusterKubeconfig option to unmanaged-cluster #2918

Merged
merged 1 commit into from
Jan 27, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 18 additions & 15 deletions cli/cmd/plugin/unmanaged-cluster/cmd/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,15 @@ import (
)

type createUnmanagedOpts struct {
skipPreflightChecks bool
clusterConfigFile string
infrastructureProvider string
tkrLocation string
cni string
podcidr string
servicecidr string
portMapping []string
skipPreflightChecks bool
clusterConfigFile string
existingClusterKubeconfig string
infrastructureProvider string
tkrLocation string
cni string
podcidr string
servicecidr string
portMapping []string
}

const createDesc = `
Expand Down Expand Up @@ -52,6 +53,7 @@ var co = createUnmanagedOpts{}

func init() {
CreateCmd.Flags().StringVarP(&co.clusterConfigFile, "config", "f", "", "A config file describing how to create the Tanzu environment")
CreateCmd.Flags().StringVarP(&co.existingClusterKubeconfig, "existing-cluster-kubeconfig", "e", "", "Use an existing kubeconfg to tanzu-ify a clsuter")
CreateCmd.Flags().StringVar(&co.infrastructureProvider, "provider", "", "The infrastructure provider for cluster creation; default is kind")
CreateCmd.Flags().StringVarP(&co.tkrLocation, "tkr", "t", "", "The URL to the image containing a Tanzu Kubernetes release")
CreateCmd.Flags().StringVarP(&co.cni, "cni", "c", "", "The CNI to deploy; default is antrea")
Expand All @@ -75,13 +77,14 @@ func create(cmd *cobra.Command, args []string) error {

// Determine our configuration to use
configArgs := map[string]string{
config.ClusterConfigFile: co.clusterConfigFile,
config.ClusterName: clusterName,
config.Provider: co.infrastructureProvider,
config.TKRLocation: co.tkrLocation,
config.Cni: co.cni,
config.PodCIDR: co.podcidr,
config.ServiceCIDR: co.servicecidr,
config.ClusterConfigFile: co.clusterConfigFile,
config.ExistingClusterKubeconfig: co.existingClusterKubeconfig,
config.ClusterName: clusterName,
config.Provider: co.infrastructureProvider,
config.TKRLocation: co.tkrLocation,
config.Cni: co.cni,
config.PodCIDR: co.podcidr,
config.ServiceCIDR: co.servicecidr,
}
clusterConfig, err := config.InitializeConfiguration(configArgs)
if err != nil {
Expand Down
36 changes: 20 additions & 16 deletions cli/cmd/plugin/unmanaged-cluster/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,21 @@ import (
)

const (
ClusterConfigFile = "ClusterConfigFile"
ClusterName = "ClusterName"
Tty = "Tty"
TKRLocation = "TkrLocation"
Provider = "Provider"
Cni = "Cni"
PodCIDR = "PodCidr"
ServiceCIDR = "ServiceCidr"
configDir = ".config"
tanzuConfigDir = "tanzu"
yamlIndent = 2
ProtocolTCP = "tcp"
ProtocolUDP = "udp"
ProtocolSCTP = "sctp"
ClusterConfigFile = "ClusterConfigFile"
ExistingClusterKubeconfig = "ExistingClusterKubeconfig"
ClusterName = "ClusterName"
Tty = "Tty"
TKRLocation = "TkrLocation"
Provider = "Provider"
Cni = "Cni"
PodCIDR = "PodCidr"
ServiceCIDR = "ServiceCidr"
configDir = ".config"
tanzuConfigDir = "tanzu"
yamlIndent = 2
ProtocolTCP = "tcp"
ProtocolUDP = "udp"
ProtocolSCTP = "sctp"
)

var defaultConfigValues = map[string]string{
Expand All @@ -60,8 +61,11 @@ type PortMap struct {
type UnmanagedClusterConfig struct {
// ClusterName is the name of the cluster.
ClusterName string `yaml:"ClusterName"`
// KubeconfigPath is the serialized path to the kubeconfig to use.
// KubeconfigPath is the location where the Kubeconfig will be persisted
// after the cluster is created.
KubeconfigPath string `yaml:"KubeconfigPath"`
// ExistingClusterKubeconfig is the serialized path to the kubeconfig to use of an existing cluster.
ExistingClusterKubeconfig string `yaml:"ExistingClusterKubeconfig"`
// NodeImage is the host OS image to use for Kubernetes nodes.
// It is typically resolved, automatically, in the Taznu Kubernetes Release (TKR) BOM,
// but also can be overridden in configuration.
Expand Down Expand Up @@ -161,7 +165,7 @@ func InitializeConfiguration(commandArgs map[string]string) (*UnmanagedClusterCo
}

// Sanatize the filepath for the provided kubeconfig
config.KubeconfigPath = sanatizeKubeconfigPath(config.KubeconfigPath)
config.ExistingClusterKubeconfig = sanatizeKubeconfigPath(config.ExistingClusterKubeconfig)

return config, nil
}
Expand Down
46 changes: 34 additions & 12 deletions cli/cmd/plugin/unmanaged-cluster/tanzu/tanzu.go
Original file line number Diff line number Diff line change
Expand Up @@ -173,13 +173,23 @@ func (t *UnmanagedCluster) Deploy(scConfig *config.UnmanagedClusterConfig) error
log.Style(outputIndent, color.Faint).Infof("%s\n", t.kappControllerBundle.GetRegistryURL())

// 4. Create the cluster
log.Eventf(logger.RocketEmoji, "Creating cluster %s\n", scConfig.ClusterName)
createdCluster, err := runClusterCreate(scConfig)
if err != nil {
return fmt.Errorf("failed to create cluster, Error: %s", err.Error())
var clusterToUse *cluster.KubernetesCluster

if scConfig.ExistingClusterKubeconfig != "" {
log.Eventf(logger.RocketEmoji, "Using existing cluster\n")
clusterToUse, err = useExistingCluster(scConfig)
if err != nil {
return fmt.Errorf("failed to use existing cluster, Error: %s", err.Error())
}
} else {
log.Eventf(logger.RocketEmoji, "Creating cluster %s\n", scConfig.ClusterName)
clusterToUse, err = runClusterCreate(scConfig)
if err != nil {
return fmt.Errorf("failed to create cluster, Error: %s", err.Error())
}
}

kcBytes := createdCluster.Kubeconfig
kcBytes := clusterToUse.Kubeconfig
log.Style(outputIndent, color.Faint).Info("To troubleshoot, use:\n")
log.Style(outputIndent, color.Faint).Infof("kubectl ${COMMAND} --kubeconfig %s\n", scConfig.KubeconfigPath)

Expand Down Expand Up @@ -568,13 +578,11 @@ func resolveKappBundle(t *UnmanagedCluster) error {
}

func runClusterCreate(scConfig *config.UnmanagedClusterConfig) (*cluster.KubernetesCluster, error) {
if scConfig.KubeconfigPath == "" {
clusterDir, err := resolveClusterDir(scConfig.ClusterName)
if err != nil {
return nil, err
}
scConfig.KubeconfigPath = filepath.Join(clusterDir, "kube.conf")
clusterDir, err := resolveClusterDir(scConfig.ClusterName)
if err != nil {
return nil, err
}
scConfig.KubeconfigPath = filepath.Join(clusterDir, "kube.conf")

clusterManager := cluster.NewClusterManager(scConfig)

Expand All @@ -584,7 +592,7 @@ func runClusterCreate(scConfig *config.UnmanagedClusterConfig) (*cluster.Kuberne
}
}

err := blockForPullingBaseImage(clusterManager, scConfig)
err = blockForPullingBaseImage(clusterManager, scConfig)
if err != nil {
return nil, err
}
Expand All @@ -597,6 +605,20 @@ func runClusterCreate(scConfig *config.UnmanagedClusterConfig) (*cluster.Kuberne
return kc, nil
}

func useExistingCluster(scConfig *config.UnmanagedClusterConfig) (*cluster.KubernetesCluster, error) {
scConfig.KubeconfigPath = scConfig.ExistingClusterKubeconfig
noopManager := cluster.NewNoopClusterManager()

kc, err := noopManager.Create(scConfig)
if err != nil {
return nil, err
}

log.Style(outputIndent, color.FgYellow).Warn("Warning: Components installed using this method will need to be manually removed.\n")

return kc, nil
}

func blockForPullingBaseImage(cm cluster.Manager, scConfig *config.UnmanagedClusterConfig) error {
// start a go routine to animate the downloading logs while the docker exec gets the image
ctx, cancel := context.WithCancel(context.Background())
Expand Down