in cmd/hub/kube/kubernetes.go [155:363]
func SetupKubernetes(params parameters.LockedParameters,
provider string, outputs parameters.CapturedOutputs,
context string, overwrite, keepPems bool) {
kubectl := "kubectl"
domain, _ := mayOutput(params, outputs, provider, stackDomainOutput)
if domain == "" {
util.Debug("Parameters from %s are not providing: %s", provider, stackDomainOutput) // try to get domain from environment
name, val := getFirstEnviron("HUB_DOMAIN_NAME", "DOMAIN_NAME")
if val != "" {
util.Debug("Using %s from %s variable as %s", val, name, stackDomainOutput)
domain = val
} else {
// Porting fuzzy logic here from extensions, for compatibility
// When stack doesn't have a ingress domain.
// In this case user will declare only a stack name
util.Debug("Cannot find dns.domain from variables")
util.Debug("Trying %s instead for stack that doesn't use ingress", stackNameOutput)
stackName, _ := mayOutput(params, outputs, provider, stackNameOutput)
if stackName != "" {
domain = stackName
} else {
util.Debug("Trying environment variables")
name, val = getFirstEnviron("HUB_STACK_NAME", "STACK_NAME")
if val != "" {
util.Debug("Using %s from %s variable as %s", val, name, stackNameOutput)
domain = val
} else {
util.Warn("Giving up with domain name from %s", provider)
}
}
}
}
if domain == "" {
util.Errors("Unable to setup Kubeconfig: no domain name found")
os.Exit(1)
return
}
if context != "" {
util.Debug("Using kube context: %s", context)
}
if context == "" {
context = domain
}
flavor, _ := mayOutput(params, outputs, provider, kubernetesFlavorOutput)
if flavor == "" {
flavor = "k8s-aws"
}
eksClusterName := ""
bearerToken := ""
switch flavor {
case "eks":
eksClusterName = mustOutput(params, outputs, provider, kubernetesEksClusterOutput)
bearerToken, _ = mayOutput(params, outputs, provider, kubernetesApiTokenOutput)
case "openshift", "gke", "aks":
bearerToken = mustOutput(params, outputs, provider, kubernetesApiTokenOutput)
}
configFilename, err := kubeconfigFilename()
if err != nil {
util.WarnOnce("Unable to setup Kubeconfig: %v", err)
return
}
var configCmd string
if config.SwitchKubeconfigContext {
if config.Verbose {
log.Printf("Changing Kubeconfig context to `%s`", context)
}
configCmd = "use-context"
} else {
if config.Verbose {
log.Printf("Checking Kubeconfig context `%s`", context)
}
configCmd = "get-contexts"
}
outBytes, err := execOutput(kubectl, "config", configCmd, context)
if err == nil {
if !overwrite {
// check CA cert match to
// catch Kubeconfig leftovers from previous deployment to the same domain name
if ca, exist := mayOutput(params, outputs, provider, kubernetesApiCaCertOutput); exist && ca != "" {
warnClusterCaCertMismatch(configFilename, context, ca)
}
return
}
} else {
out := string(outBytes)
if !strings.Contains(out, "no context exists") && !strings.Contains(out, "not found") {
util.MaybeFatalf("kubectl failed: %v", err)
}
}
if config.Verbose {
if provider != "" {
log.Printf("Setting up Kubeconfig from `%s` outputs", provider)
if config.Debug {
parameters.PrintCapturedOutputsByComponent(outputs, provider)
}
} else {
log.Printf("Setting up Kubeconfig from stack parameters")
}
}
filenameBase := filepath.Join(filepath.Dir(configFilename), strings.Replace(domain, ".", "-", -1))
caCertFile := filenameBase + kubernetesApiKeysFileSuf[kubernetesApiCaCertOutput]
clientCertFile := filenameBase + kubernetesApiKeysFileSuf[kubernetesApiClientCertOutput]
clientKeyFile := filenameBase + kubernetesApiKeysFileSuf[kubernetesApiClientKeyOutput]
var caCert string
caCertExist := true
if flavor != "openshift" {
caCert = mustOutput(params, outputs, provider, kubernetesApiCaCertOutput)
} else {
caCert, caCertExist = mayOutput(params, outputs, provider, kubernetesApiCaCertOutput)
}
var pemsWritten []string
if caCertExist {
writeFile(caCertFile, caCert)
pemsWritten = append(pemsWritten, caCertFile)
}
if util.Contains([]string{"k8s-aws", "hybrid", "metal"}, flavor) {
writeFile(clientCertFile,
mustOutput(params, outputs, provider, kubernetesApiClientCertOutput))
writeFile(clientKeyFile,
mustOutput(params, outputs, provider, kubernetesApiClientKeyOutput))
pemsWritten = append(pemsWritten, clientCertFile, clientKeyFile)
}
apiEndpoint := domain
if endpoint, exist := mayOutput(params, outputs, provider, kubernetesApiEndpointOutput); exist && endpoint != "" {
apiEndpoint = endpoint
}
clusterArgs := []string{"config", "set-cluster", domain, "--server=https://" + apiEndpoint}
if caCertExist {
clusterArgs = append(clusterArgs, "--embed-certs=true", "--certificate-authority="+caCertFile)
}
mustExec(kubectl, clusterArgs...)
user := ""
switch flavor {
case "k8s-aws", "hybrid", "metal":
user = "admin@" + domain
mustExec(kubectl, "config", "set-credentials", user,
"--embed-certs=true",
"--client-key="+clientKeyFile,
"--client-certificate="+clientCertFile)
case "eks":
user = "eks-" + eksClusterName
if bearerToken != "" {
mustExec(kubectl, "config", "set-credentials", user,
"--token="+bearerToken)
mustExec(kubectl, "config", "unset", fmt.Sprintf("users.%s.exec", user))
} else {
mustExec(kubectl, "config", "set-credentials", user,
"--exec-api-version=client.authentication.k8s.io/v1alpha1",
"--exec-command=aws-iam-authenticator",
"--exec-arg=token",
"--exec-arg=-i",
"--exec-arg="+eksClusterName)
mustExec(kubectl, "config", "unset", fmt.Sprintf("users.%s.token", user))
}
case "openshift", "gke", "aks":
user = fmt.Sprintf("%s-%s", flavor, domain)
mustExec(kubectl, "config", "set-credentials", user,
"--token="+bearerToken)
}
mustExec(kubectl, "config", "set-context", context,
"--cluster="+domain,
"--user="+user,
"--namespace=kube-system")
switchContext := config.SwitchKubeconfigContext
if os.Getenv("HUB_KUBECONFIG") != "" {
kubeconfig := os.Getenv("HUB_KUBECONFIG")
os.Setenv("KUBECONFIG", kubeconfig)
}
if !switchContext && os.Getenv("KUBECONFIG") != "" {
// Hub CTL extensions expects a private Kubeconfig with current-context set
outBytes, err := execOutput(kubectl, "config", "current-context")
out := string(outBytes)
if strings.Contains(out, "current-context is not set") {
switchContext = true
}
if !switchContext && err != nil {
if processErr, ok := err.(*exec.ExitError); ok && processErr.ExitCode() == 1 {
switchContext = true
}
}
}
if switchContext {
mustExec(kubectl, "config", "use-context", context)
}
if !keepPems {
for _, filename := range pemsWritten {
if err := os.Remove(filename); err != nil {
util.WarnOnce("Unable to remove `%s`: %v", filename, err)
} else if config.Debug {
log.Printf("Removed `%s`", filename)
}
}
}
}