diff --git a/nodeup/pkg/bootstrap/install.go b/nodeup/pkg/bootstrap/install.go index ab9c9970c297c..6b758d06cc71b 100644 --- a/nodeup/pkg/bootstrap/install.go +++ b/nodeup/pkg/bootstrap/install.go @@ -150,6 +150,8 @@ func (i *Installation) buildSystemdJob() *nodetasks.Service { "OS_PASSWORD", "OS_AUTH_URL", "OS_REGION_NAME", + "OS_APPLICATION_CREDENTIAL_ID", + "OS_APPLICATION_CREDENTIAL_SECRET", } { buffer.WriteString("'") buffer.WriteString(envVar) diff --git a/nodeup/pkg/model/cloudconfig.go b/nodeup/pkg/model/cloudconfig.go index 1e6d9453aa6ff..23da22ba7df34 100644 --- a/nodeup/pkg/model/cloudconfig.go +++ b/nodeup/pkg/model/cloudconfig.go @@ -92,6 +92,8 @@ func (b *CloudConfigBuilder) Build(c *fi.ModelBuilderContext) error { fmt.Sprintf("tenant-name=\"%s\"", tenantName), fmt.Sprintf("domain-name=\"%s\"", os.Getenv("OS_DOMAIN_NAME")), fmt.Sprintf("domain-id=\"%s\"", os.Getenv("OS_DOMAIN_ID")), + fmt.Sprintf("application-credential-id=\"%s\"", os.Getenv("OS_APPLICATION_CREDENTIAL_ID")), + fmt.Sprintf("application-credential-secret=\"%s\"", os.Getenv("OS_APPLICATION_CREDENTIAL_SECRET")), "", ) diff --git a/nodeup/pkg/model/protokube.go b/nodeup/pkg/model/protokube.go index e583e938d65f7..c1f14c8164382 100644 --- a/nodeup/pkg/model/protokube.go +++ b/nodeup/pkg/model/protokube.go @@ -614,6 +614,8 @@ func (t *ProtokubeBuilder) ProtokubeEnvironmentVariables() string { "OS_PASSWORD", "OS_AUTH_URL", "OS_REGION_NAME", + "OS_APPLICATION_CREDENTIAL_ID", + "OS_APPLICATION_CREDENTIAL_SECRET", } { buffer.WriteString(" --env '") buffer.WriteString(envVar) diff --git a/pkg/model/bootstrapscript.go b/pkg/model/bootstrapscript.go index aa258f0975992..4040b16c204a5 100644 --- a/pkg/model/bootstrapscript.go +++ b/pkg/model/bootstrapscript.go @@ -108,17 +108,30 @@ func (b *BootstrapScript) buildEnvironmentVariables(cluster *kops.Cluster) (map[ env["S3_SECRET_ACCESS_KEY"] = os.Getenv("S3_SECRET_ACCESS_KEY") } - // Pass in required credentials when using user-defined swift endpoint - if os.Getenv("OS_AUTH_URL") != "" { - for _, envVar := range []string{ - "OS_TENANT_ID", "OS_TENANT_NAME", "OS_PROJECT_ID", "OS_PROJECT_NAME", - "OS_PROJECT_DOMAIN_NAME", "OS_PROJECT_DOMAIN_ID", - "OS_DOMAIN_NAME", "OS_DOMAIN_ID", + osEnvs := []string{ + "OS_TENANT_ID", "OS_TENANT_NAME", "OS_PROJECT_ID", "OS_PROJECT_NAME", + "OS_PROJECT_DOMAIN_NAME", "OS_PROJECT_DOMAIN_ID", + "OS_DOMAIN_NAME", "OS_DOMAIN_ID", + "OS_AUTH_URL", + "OS_REGION_NAME", + } + + if os.Getenv("OS_APPLICATION_CREDENTIAL_ID") != "" && os.Getenv("OS_APPLICATION_CREDENTIAL_SECRET") != "" { + osEnvs = append(osEnvs, + "OS_APPLICATION_CREDENTIAL_ID", + "OS_APPLICATION_CREDENTIAL_SECRET", + ) + } else { + klog.Warning("exporting username and password. Consider using application credentials instead.") + osEnvs = append(osEnvs, "OS_USERNAME", "OS_PASSWORD", - "OS_AUTH_URL", - "OS_REGION_NAME", - } { + ) + } + + // Pass in required credentials when using user-defined swift endpoint + if os.Getenv("OS_AUTH_URL") != "" { + for _, envVar := range osEnvs { env[envVar] = fmt.Sprintf("'%s'", os.Getenv(envVar)) } } diff --git a/util/pkg/env/standard.go b/util/pkg/env/standard.go index 68d56e92ce47f..fa0eff15d6989 100644 --- a/util/pkg/env/standard.go +++ b/util/pkg/env/standard.go @@ -58,8 +58,12 @@ func BuildSystemComponentEnvVars(spec *kops.ClusterSpec) EnvVars { vars.addEnvVariableIfExist("OS_DOMAIN_ID") vars.addEnvVariableIfExist("OS_USERNAME") vars.addEnvVariableIfExist("OS_PASSWORD") + vars.addEnvVariableIfExist("OS_APPLICATION_CREDENTIAL_ID") + vars.addEnvVariableIfExist("OS_APPLICATION_CREDENTIAL_SECRET") vars.addEnvVariableIfExist("OS_AUTH_URL") vars.addEnvVariableIfExist("OS_REGION_NAME") + vars.addEnvVariableIfExist("OS_APPLICATION_CREDENTIAL_ID") + vars.addEnvVariableIfExist("OS_APPLICATION_CREDENTIAL_SECRET") // Digital Ocean related values. vars.addEnvVariableIfExist("DIGITALOCEAN_ACCESS_TOKEN") diff --git a/util/pkg/vfs/swiftfs.go b/util/pkg/vfs/swiftfs.go index 06c0c2c7ffb0f..33a892c080455 100644 --- a/util/pkg/vfs/swiftfs.go +++ b/util/pkg/vfs/swiftfs.go @@ -139,6 +139,10 @@ func (oc OpenstackConfig) GetCredential() (gophercloud.AuthOptions, error) { // fallback to config file return oc.getCredentialFromFile() } + + if env.ApplicationCredentialID != "" && env.Username == "" { + env.Scope = &gophercloud.AuthScope{} + } return env, nil }