From a708a96c056e7a2ce33ce8fa3c84e88f8d1a01c0 Mon Sep 17 00:00:00 2001 From: Ole Markus With Date: Tue, 4 Aug 2020 15:39:35 +0200 Subject: [PATCH] Adds support for using OS application credentials Application credentials allows you to export a purpose-specific set of credentials for a user instead of exposing user login credentials. Especially useful when using LDAP or similar for Openstack users. Also lets you rotate credentials more easily since multiple application credentials can be provisioned per user. Update pkg/model/bootstrapscript.go Co-authored-by: Ciprian Hacman --- nodeup/pkg/bootstrap/install.go | 2 ++ nodeup/pkg/model/cloudconfig.go | 2 ++ nodeup/pkg/model/protokube.go | 2 ++ pkg/model/bootstrapscript.go | 31 ++++++++++++++++++++++--------- util/pkg/env/standard.go | 2 ++ util/pkg/vfs/swiftfs.go | 4 ++++ 6 files changed, 34 insertions(+), 9 deletions(-) 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..4eab564315f99 100644 --- a/util/pkg/env/standard.go +++ b/util/pkg/env/standard.go @@ -60,6 +60,8 @@ func BuildSystemComponentEnvVars(spec *kops.ClusterSpec) EnvVars { vars.addEnvVariableIfExist("OS_PASSWORD") 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 }