in cmd/hub/api/cluster.go [315:558]
func importK8s(importConfig ImportConfig, kind, name, environmentSelector, templateSelector string,
autoCreateTemplate, createNewTemplate, waitAndTailDeployLogs, dryRun bool,
pems io.Reader, clusterBearerToken,
nativeRegion, nativeZone, nativeEndpoint, nativeClusterName,
ingressIpOrHost, azureResourceGroup string,
options ClusterOptions) error {
environment, err := environmentBy(environmentSelector)
if err != nil {
return fmt.Errorf("Unable to retrieve Environment: %v", err)
}
cloudAccount, err := cloudAccountById(environment.CloudAccount, false)
if err != nil {
return fmt.Errorf("Unable to retrieve Cloud Account: %v", err)
}
err = verifyClusterCloudAccountKind(kind, cloudAccount)
if err != nil {
return err
}
name, fqdn, err := verifyClusterBaseDomain(name, cloudAccount)
if err != nil {
return err
}
ingressIp := ""
ingressHost := ""
if kind == "eks" {
if nativeEndpoint == "" {
cac, err := awsCloudAccountCredentials(cloudAccount.Id)
if err != nil {
return err
}
regions := make([]string, 0, 2)
caRegion := cloudAccountRegion(cloudAccount)
if caRegion != "" {
if config.Debug {
log.Printf("Cloud Account `%s` default region is `%s`", cloudAccount.Id, caRegion)
}
regions = append(regions, caRegion)
}
if config.AwsRegion != "" && !util.Contains(regions, config.AwsRegion) {
regions = append(regions, config.AwsRegion)
}
for _, region := range regions {
endpoint, ca, err := aws.DescribeEKSClusterWithStaticCredentials(region, nativeClusterName,
cac.AccessKey, cac.SecretKey, cac.SessionToken)
if err != nil {
util.Warn("Unable to retrieve EKS cluster `%s` info in `%s` region: %v",
nativeClusterName, region, err)
continue
}
if endpoint != "" {
if config.Verbose {
log.Printf("Found EKS cluster `%s` in %s region with endpoint %s",
nativeClusterName, region, endpoint)
}
if strings.HasPrefix(endpoint, "https://") && len(endpoint) > 8 {
endpoint = endpoint[8:]
}
nativeEndpoint = endpoint
if len(ca) > 0 {
pems = bytes.NewReader(ca)
}
break
}
}
if nativeEndpoint == "" {
log.Fatal("EKS cluster endpoint (--eks-endpoint) must be provided")
}
}
} else if kind == "hybrid" {
if ingressIpOrHost == "" {
parts := strings.Split(nativeEndpoint, ":")
if len(parts) > 0 {
ingressIpOrHost = parts[0]
}
if ingressIpOrHost == "" {
log.Fatalf("Cannot determine ingress IP/hostname from API endpoint `%s`", nativeEndpoint)
}
}
if net.ParseIP(ingressIpOrHost) != nil {
ingressIp = ingressIpOrHost
} else {
ingressHost = ingressIpOrHost
}
}
secrets, err := readImportSecrets(importConfig.SecretsOrder, pems)
if err != nil {
if !(kind == "openshift" && secrets != nil) { // OpenShift CA is optional
return fmt.Errorf("Unable to read auth secrets: %v", err)
}
}
hasCaCert := false
for _, s := range secrets {
if s.Name == "kubernetes.api.caCert" {
hasCaCert = true
break
}
}
adapterTag := "adapter=" + kind
if templateSelector == "" && autoCreateTemplate {
templateSelector = fmt.Sprintf(importConfig.TemplateNameFormat, environment.Name)
}
var template *StackTemplate
if templateSelector != "" && !createNewTemplate {
template, err = templateBy(templateSelector)
if err != nil && !strings.HasSuffix(err.Error(), " found") {
return fmt.Errorf("Unable to retrieve adapter Template: %v", err)
}
if template != nil && !util.Contains(template.Tags, adapterTag) {
util.Warn("Template `%s` [%s] contain no `%s` tag", template.Name, template.Id, adapterTag)
}
}
if template == nil {
if !autoCreateTemplate {
return fmt.Errorf("No adapter Template found by `%s`", templateSelector)
}
asset := fmt.Sprintf("%s/%s-adapter-template.json.template", requestsBindata, kind)
templateBytes, err := adapterTemplateFiles.ReadFile(asset)
if err != nil {
return fmt.Errorf("No %s embedded: %v", asset, err)
}
var templateRequest StackTemplateRequest
err = json.Unmarshal(templateBytes, &templateRequest)
if err != nil {
return fmt.Errorf("Unable to unmarshall JSON into Template request: %v", err)
}
// TODO with createNewTemplate = true we can get a 400 HTTP
// due to duplicate Template name which should be unique across organization
templateRequest.Name = templateSelector // let use user-supplied selector as Template name, hope it's not id
templateRequest.Tags = []string{adapterTag}
templateRequest.TeamsPermissions = environment.TeamsPermissions // copy permissions from Environment
templateRequest.ComponentsEnabled = clusterComponents(options)
template, err = createTemplate(templateRequest)
if err != nil {
return fmt.Errorf("Unable to create adapter Template: %v", err)
}
err = initTemplate(template.Id)
if err != nil {
return fmt.Errorf("Unable to initialize adapter Template: %v", err)
}
if config.Verbose {
log.Printf("Created %s adapter template `%s`", kind, template.Name)
}
}
asset := fmt.Sprintf("%s/%s-adapter-instance.json.template", requestsBindata, kind)
instanceBytes, err := adapterInstanceFiles.ReadFile(asset)
if err != nil {
return fmt.Errorf("No %s embedded: %v", asset, err)
}
var instanceRequest StackInstanceRequest
err = json.Unmarshal(instanceBytes, &instanceRequest)
if err != nil {
return fmt.Errorf("Unable to unmarshall JSON into Stack Instance request: %v", err)
}
instanceRequest.Name = name
instanceRequest.Tags = template.Tags
instanceRequest.Environment = environment.Id
instanceRequest.Template = template.Id
parameters := make([]Parameter, 0, len(instanceRequest.Parameters))
for _, p := range instanceRequest.Parameters {
rm := false
switch p.Name {
case "dns.domain":
p.Value = fqdn
case "cloud.region":
if nativeRegion != "" {
p.Value = nativeRegion
} else {
rm = true
}
case "cloud.availabilityZone":
if nativeZone != "" {
p.Value = nativeZone
} else {
rm = true
}
case "kubernetes.api.endpoint":
if nativeEndpoint != "" {
p.Value = nativeEndpoint
} else {
rm = true
}
case "kubernetes.api.caCert":
if !hasCaCert {
rm = true
}
case "kubernetes.eks.cluster", "kubernetes.gke.cluster", "kubernetes.aks.cluster":
p.Value = nativeClusterName
case "component.ingress.staticIp":
p.Value = ingressIp
case "component.ingress.staticHost":
p.Value = ingressHost
case "cloud.azureResourceGroupName", "component.kubernetes.aks.resourceGroupName":
if azureResourceGroup != "" {
p.Value = azureResourceGroup
} else {
rm = true
}
}
p = clusterOptions(p, options)
if !rm {
parameters = append(parameters, p)
}
}
instanceRequest.Parameters = parameters
instance, err := createStackInstance(instanceRequest)
if err != nil {
return fmt.Errorf("Unable to create adapter Stack Instance: %v", err)
}
if kind == "openshift" && clusterBearerToken != "" {
secrets = append(secrets,
Secret{"kubernetes.api.token", "bearerToken", map[string]string{"bearerToken": clusterBearerToken}})
}
for _, secret := range secrets {
id, err := createSecret(stackInstancesResource, instance.Id, secret.Name, "", secret.Kind, secret.Values)
if err != nil {
return err
}
if config.Verbose {
log.Printf("Created %s secret with id %s", secret.Name, id)
}
}
_, err = commandStackInstance(instance.Id, "deploy", nil, waitAndTailDeployLogs, dryRun)
if err != nil {
return fmt.Errorf("Unable to deploy adapter Stack Instance: %v", err)
}
return nil
}