|
|
|
|
@ -9,7 +9,7 @@ import (
|
|
|
|
|
"github.com/gophercloud/gophercloud"
|
|
|
|
|
"github.com/gophercloud/gophercloud/openstack"
|
|
|
|
|
|
|
|
|
|
"gopkg.in/yaml.v2"
|
|
|
|
|
yaml "gopkg.in/yaml.v2"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// AuthType respresents a valid method of authentication.
|
|
|
|
|
@ -30,6 +30,9 @@ const (
|
|
|
|
|
AuthV3Password AuthType = "v3password"
|
|
|
|
|
// AuthV3Token defines version 3 of the token
|
|
|
|
|
AuthV3Token AuthType = "v3token"
|
|
|
|
|
|
|
|
|
|
// AuthV3ApplicationCredential defines version 3 of the application credential
|
|
|
|
|
AuthV3ApplicationCredential AuthType = "v3applicationcredential"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// ClientOpts represents options to customize the way a client is
|
|
|
|
|
@ -333,6 +336,8 @@ func determineIdentityAPI(cloud *Cloud, opts *ClientOpts) string {
|
|
|
|
|
identityAPI = "3"
|
|
|
|
|
case AuthV3Token:
|
|
|
|
|
identityAPI = "3"
|
|
|
|
|
case AuthV3ApplicationCredential:
|
|
|
|
|
identityAPI = "3"
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -353,40 +358,52 @@ func v2auth(cloud *Cloud, opts *ClientOpts) (*gophercloud.AuthOptions, error) {
|
|
|
|
|
envPrefix = opts.EnvPrefix
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if v := os.Getenv(envPrefix + "AUTH_URL"); v != "" {
|
|
|
|
|
cloud.AuthInfo.AuthURL = v
|
|
|
|
|
if cloud.AuthInfo.AuthURL == "" {
|
|
|
|
|
if v := os.Getenv(envPrefix + "AUTH_URL"); v != "" {
|
|
|
|
|
cloud.AuthInfo.AuthURL = v
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if v := os.Getenv(envPrefix + "TOKEN"); v != "" {
|
|
|
|
|
cloud.AuthInfo.Token = v
|
|
|
|
|
}
|
|
|
|
|
if cloud.AuthInfo.Token == "" {
|
|
|
|
|
if v := os.Getenv(envPrefix + "TOKEN"); v != "" {
|
|
|
|
|
cloud.AuthInfo.Token = v
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if v := os.Getenv(envPrefix + "AUTH_TOKEN"); v != "" {
|
|
|
|
|
cloud.AuthInfo.Token = v
|
|
|
|
|
if v := os.Getenv(envPrefix + "AUTH_TOKEN"); v != "" {
|
|
|
|
|
cloud.AuthInfo.Token = v
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if v := os.Getenv(envPrefix + "USERNAME"); v != "" {
|
|
|
|
|
cloud.AuthInfo.Username = v
|
|
|
|
|
if cloud.AuthInfo.Username == "" {
|
|
|
|
|
if v := os.Getenv(envPrefix + "USERNAME"); v != "" {
|
|
|
|
|
cloud.AuthInfo.Username = v
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if v := os.Getenv(envPrefix + "PASSWORD"); v != "" {
|
|
|
|
|
cloud.AuthInfo.Password = v
|
|
|
|
|
if cloud.AuthInfo.Password == "" {
|
|
|
|
|
if v := os.Getenv(envPrefix + "PASSWORD"); v != "" {
|
|
|
|
|
cloud.AuthInfo.Password = v
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if v := os.Getenv(envPrefix + "TENANT_ID"); v != "" {
|
|
|
|
|
cloud.AuthInfo.ProjectID = v
|
|
|
|
|
}
|
|
|
|
|
if cloud.AuthInfo.ProjectID == "" {
|
|
|
|
|
if v := os.Getenv(envPrefix + "TENANT_ID"); v != "" {
|
|
|
|
|
cloud.AuthInfo.ProjectID = v
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if v := os.Getenv(envPrefix + "PROJECT_ID"); v != "" {
|
|
|
|
|
cloud.AuthInfo.ProjectID = v
|
|
|
|
|
if v := os.Getenv(envPrefix + "PROJECT_ID"); v != "" {
|
|
|
|
|
cloud.AuthInfo.ProjectID = v
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if v := os.Getenv(envPrefix + "TENANT_NAME"); v != "" {
|
|
|
|
|
cloud.AuthInfo.ProjectName = v
|
|
|
|
|
}
|
|
|
|
|
if cloud.AuthInfo.ProjectName == "" {
|
|
|
|
|
if v := os.Getenv(envPrefix + "TENANT_NAME"); v != "" {
|
|
|
|
|
cloud.AuthInfo.ProjectName = v
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if v := os.Getenv(envPrefix + "PROJECT_NAME"); v != "" {
|
|
|
|
|
cloud.AuthInfo.ProjectName = v
|
|
|
|
|
if v := os.Getenv(envPrefix + "PROJECT_NAME"); v != "" {
|
|
|
|
|
cloud.AuthInfo.ProjectName = v
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ao := &gophercloud.AuthOptions{
|
|
|
|
|
@ -409,109 +426,161 @@ func v3auth(cloud *Cloud, opts *ClientOpts) (*gophercloud.AuthOptions, error) {
|
|
|
|
|
envPrefix = opts.EnvPrefix
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if v := os.Getenv(envPrefix + "AUTH_URL"); v != "" {
|
|
|
|
|
cloud.AuthInfo.AuthURL = v
|
|
|
|
|
if cloud.AuthInfo.AuthURL == "" {
|
|
|
|
|
if v := os.Getenv(envPrefix + "AUTH_URL"); v != "" {
|
|
|
|
|
cloud.AuthInfo.AuthURL = v
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if v := os.Getenv(envPrefix + "TOKEN"); v != "" {
|
|
|
|
|
cloud.AuthInfo.Token = v
|
|
|
|
|
if cloud.AuthInfo.Token == "" {
|
|
|
|
|
if v := os.Getenv(envPrefix + "TOKEN"); v != "" {
|
|
|
|
|
cloud.AuthInfo.Token = v
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if v := os.Getenv(envPrefix + "AUTH_TOKEN"); v != "" {
|
|
|
|
|
cloud.AuthInfo.Token = v
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if v := os.Getenv(envPrefix + "AUTH_TOKEN"); v != "" {
|
|
|
|
|
cloud.AuthInfo.Token = v
|
|
|
|
|
if cloud.AuthInfo.Username == "" {
|
|
|
|
|
if v := os.Getenv(envPrefix + "USERNAME"); v != "" {
|
|
|
|
|
cloud.AuthInfo.Username = v
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if v := os.Getenv(envPrefix + "USERNAME"); v != "" {
|
|
|
|
|
cloud.AuthInfo.Username = v
|
|
|
|
|
if cloud.AuthInfo.UserID == "" {
|
|
|
|
|
if v := os.Getenv(envPrefix + "USER_ID"); v != "" {
|
|
|
|
|
cloud.AuthInfo.UserID = v
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if v := os.Getenv(envPrefix + "USER_ID"); v != "" {
|
|
|
|
|
cloud.AuthInfo.UserID = v
|
|
|
|
|
if cloud.AuthInfo.Password == "" {
|
|
|
|
|
if v := os.Getenv(envPrefix + "PASSWORD"); v != "" {
|
|
|
|
|
cloud.AuthInfo.Password = v
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if v := os.Getenv(envPrefix + "PASSWORD"); v != "" {
|
|
|
|
|
cloud.AuthInfo.Password = v
|
|
|
|
|
if cloud.AuthInfo.ProjectID == "" {
|
|
|
|
|
if v := os.Getenv(envPrefix + "TENANT_ID"); v != "" {
|
|
|
|
|
cloud.AuthInfo.ProjectID = v
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if v := os.Getenv(envPrefix + "PROJECT_ID"); v != "" {
|
|
|
|
|
cloud.AuthInfo.ProjectID = v
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if v := os.Getenv(envPrefix + "TENANT_ID"); v != "" {
|
|
|
|
|
cloud.AuthInfo.ProjectID = v
|
|
|
|
|
if cloud.AuthInfo.ProjectName == "" {
|
|
|
|
|
if v := os.Getenv(envPrefix + "TENANT_NAME"); v != "" {
|
|
|
|
|
cloud.AuthInfo.ProjectName = v
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if v := os.Getenv(envPrefix + "PROJECT_NAME"); v != "" {
|
|
|
|
|
cloud.AuthInfo.ProjectName = v
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if v := os.Getenv(envPrefix + "PROJECT_ID"); v != "" {
|
|
|
|
|
cloud.AuthInfo.ProjectID = v
|
|
|
|
|
if cloud.AuthInfo.DomainID == "" {
|
|
|
|
|
if v := os.Getenv(envPrefix + "DOMAIN_ID"); v != "" {
|
|
|
|
|
cloud.AuthInfo.DomainID = v
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if v := os.Getenv(envPrefix + "TENANT_NAME"); v != "" {
|
|
|
|
|
cloud.AuthInfo.ProjectName = v
|
|
|
|
|
if cloud.AuthInfo.DomainName == "" {
|
|
|
|
|
if v := os.Getenv(envPrefix + "DOMAIN_NAME"); v != "" {
|
|
|
|
|
cloud.AuthInfo.DomainName = v
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if v := os.Getenv(envPrefix + "PROJECT_NAME"); v != "" {
|
|
|
|
|
cloud.AuthInfo.ProjectName = v
|
|
|
|
|
if cloud.AuthInfo.DefaultDomain == "" {
|
|
|
|
|
if v := os.Getenv(envPrefix + "DEFAULT_DOMAIN"); v != "" {
|
|
|
|
|
cloud.AuthInfo.DefaultDomain = v
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if v := os.Getenv(envPrefix + "DOMAIN_ID"); v != "" {
|
|
|
|
|
cloud.AuthInfo.DomainID = v
|
|
|
|
|
if cloud.AuthInfo.ProjectDomainID == "" {
|
|
|
|
|
if v := os.Getenv(envPrefix + "PROJECT_DOMAIN_ID"); v != "" {
|
|
|
|
|
cloud.AuthInfo.ProjectDomainID = v
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if v := os.Getenv(envPrefix + "DOMAIN_NAME"); v != "" {
|
|
|
|
|
cloud.AuthInfo.DomainName = v
|
|
|
|
|
if cloud.AuthInfo.ProjectDomainName == "" {
|
|
|
|
|
if v := os.Getenv(envPrefix + "PROJECT_DOMAIN_NAME"); v != "" {
|
|
|
|
|
cloud.AuthInfo.ProjectDomainName = v
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if v := os.Getenv(envPrefix + "DEFAULT_DOMAIN"); v != "" {
|
|
|
|
|
cloud.AuthInfo.DefaultDomain = v
|
|
|
|
|
if cloud.AuthInfo.UserDomainID == "" {
|
|
|
|
|
if v := os.Getenv(envPrefix + "USER_DOMAIN_ID"); v != "" {
|
|
|
|
|
cloud.AuthInfo.UserDomainID = v
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if v := os.Getenv(envPrefix + "PROJECT_DOMAIN_ID"); v != "" {
|
|
|
|
|
cloud.AuthInfo.ProjectDomainID = v
|
|
|
|
|
if cloud.AuthInfo.UserDomainName == "" {
|
|
|
|
|
if v := os.Getenv(envPrefix + "USER_DOMAIN_NAME"); v != "" {
|
|
|
|
|
cloud.AuthInfo.UserDomainName = v
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if v := os.Getenv(envPrefix + "PROJECT_DOMAIN_NAME"); v != "" {
|
|
|
|
|
cloud.AuthInfo.ProjectDomainName = v
|
|
|
|
|
if cloud.AuthInfo.ApplicationCredentialID == "" {
|
|
|
|
|
if v := os.Getenv(envPrefix + "APPLICATION_CREDENTIAL_ID"); v != "" {
|
|
|
|
|
cloud.AuthInfo.ApplicationCredentialID = v
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if v := os.Getenv(envPrefix + "USER_DOMAIN_ID"); v != "" {
|
|
|
|
|
cloud.AuthInfo.UserDomainID = v
|
|
|
|
|
if cloud.AuthInfo.ApplicationCredentialName == "" {
|
|
|
|
|
if v := os.Getenv(envPrefix + "APPLICATION_CREDENTIAL_NAME"); v != "" {
|
|
|
|
|
cloud.AuthInfo.ApplicationCredentialName = v
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if v := os.Getenv(envPrefix + "USER_DOMAIN_NAME"); v != "" {
|
|
|
|
|
cloud.AuthInfo.UserDomainName = v
|
|
|
|
|
if cloud.AuthInfo.ApplicationCredentialSecret == "" {
|
|
|
|
|
if v := os.Getenv(envPrefix + "APPLICATION_CREDENTIAL_SECRET"); v != "" {
|
|
|
|
|
cloud.AuthInfo.ApplicationCredentialSecret = v
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Build a scope and try to do it correctly.
|
|
|
|
|
// https://github.com/openstack/os-client-config/blob/master/os_client_config/config.py#L595
|
|
|
|
|
scope := new(gophercloud.AuthScope)
|
|
|
|
|
|
|
|
|
|
if !isProjectScoped(cloud.AuthInfo) {
|
|
|
|
|
if cloud.AuthInfo.DomainID != "" {
|
|
|
|
|
scope.DomainID = cloud.AuthInfo.DomainID
|
|
|
|
|
} else if cloud.AuthInfo.DomainName != "" {
|
|
|
|
|
scope.DomainName = cloud.AuthInfo.DomainName
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
// If Domain* is set, but UserDomain* or ProjectDomain* aren't,
|
|
|
|
|
// then use Domain* as the default setting.
|
|
|
|
|
cloud = setDomainIfNeeded(cloud)
|
|
|
|
|
|
|
|
|
|
if cloud.AuthInfo.ProjectID != "" {
|
|
|
|
|
scope.ProjectID = cloud.AuthInfo.ProjectID
|
|
|
|
|
// Application credentials don't support scope
|
|
|
|
|
if !isApplicationCredential(cloud.AuthInfo) {
|
|
|
|
|
if !isProjectScoped(cloud.AuthInfo) {
|
|
|
|
|
if cloud.AuthInfo.DomainID != "" {
|
|
|
|
|
scope.DomainID = cloud.AuthInfo.DomainID
|
|
|
|
|
} else if cloud.AuthInfo.DomainName != "" {
|
|
|
|
|
scope.DomainName = cloud.AuthInfo.DomainName
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
scope.ProjectName = cloud.AuthInfo.ProjectName
|
|
|
|
|
scope.DomainID = cloud.AuthInfo.ProjectDomainID
|
|
|
|
|
scope.DomainName = cloud.AuthInfo.ProjectDomainName
|
|
|
|
|
// If Domain* is set, but UserDomain* or ProjectDomain* aren't,
|
|
|
|
|
// then use Domain* as the default setting.
|
|
|
|
|
cloud = setDomainIfNeeded(cloud)
|
|
|
|
|
|
|
|
|
|
if cloud.AuthInfo.ProjectID != "" {
|
|
|
|
|
scope.ProjectID = cloud.AuthInfo.ProjectID
|
|
|
|
|
} else {
|
|
|
|
|
scope.ProjectName = cloud.AuthInfo.ProjectName
|
|
|
|
|
scope.DomainID = cloud.AuthInfo.ProjectDomainID
|
|
|
|
|
scope.DomainName = cloud.AuthInfo.ProjectDomainName
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ao := &gophercloud.AuthOptions{
|
|
|
|
|
Scope: scope,
|
|
|
|
|
IdentityEndpoint: cloud.AuthInfo.AuthURL,
|
|
|
|
|
TokenID: cloud.AuthInfo.Token,
|
|
|
|
|
Username: cloud.AuthInfo.Username,
|
|
|
|
|
UserID: cloud.AuthInfo.UserID,
|
|
|
|
|
Password: cloud.AuthInfo.Password,
|
|
|
|
|
TenantID: cloud.AuthInfo.ProjectID,
|
|
|
|
|
TenantName: cloud.AuthInfo.ProjectName,
|
|
|
|
|
DomainID: cloud.AuthInfo.UserDomainID,
|
|
|
|
|
DomainName: cloud.AuthInfo.UserDomainName,
|
|
|
|
|
Scope: scope,
|
|
|
|
|
IdentityEndpoint: cloud.AuthInfo.AuthURL,
|
|
|
|
|
TokenID: cloud.AuthInfo.Token,
|
|
|
|
|
Username: cloud.AuthInfo.Username,
|
|
|
|
|
UserID: cloud.AuthInfo.UserID,
|
|
|
|
|
Password: cloud.AuthInfo.Password,
|
|
|
|
|
TenantID: cloud.AuthInfo.ProjectID,
|
|
|
|
|
TenantName: cloud.AuthInfo.ProjectName,
|
|
|
|
|
DomainID: cloud.AuthInfo.UserDomainID,
|
|
|
|
|
DomainName: cloud.AuthInfo.UserDomainName,
|
|
|
|
|
ApplicationCredentialID: cloud.AuthInfo.ApplicationCredentialID,
|
|
|
|
|
ApplicationCredentialName: cloud.AuthInfo.ApplicationCredentialName,
|
|
|
|
|
ApplicationCredentialSecret: cloud.AuthInfo.ApplicationCredentialSecret,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// If an auth_type of "token" was specified, then make sure
|
|
|
|
|
@ -591,21 +660,20 @@ func NewServiceClient(service string, opts *ClientOpts) (*gophercloud.ServiceCli
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Determine the region to use.
|
|
|
|
|
// First, see if the cloud entry has one.
|
|
|
|
|
// First, check if the REGION_NAME environment variable is set.
|
|
|
|
|
var region string
|
|
|
|
|
if v := cloud.RegionName; v != "" {
|
|
|
|
|
if v := os.Getenv(envPrefix + "REGION_NAME"); v != "" {
|
|
|
|
|
region = v
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Next, see if one was specified in the ClientOpts.
|
|
|
|
|
// If so, this takes precedence.
|
|
|
|
|
if v := opts.RegionName; v != "" {
|
|
|
|
|
// Next, check if the cloud entry sets a region.
|
|
|
|
|
if v := cloud.RegionName; v != "" {
|
|
|
|
|
region = v
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Finally, see if there's an environment variable.
|
|
|
|
|
// This should always override prior settings.
|
|
|
|
|
if v := os.Getenv(envPrefix + "REGION_NAME"); v != "" {
|
|
|
|
|
// Finally, see if one was specified in the ClientOpts.
|
|
|
|
|
// If so, this takes precedence.
|
|
|
|
|
if v := opts.RegionName; v != "" {
|
|
|
|
|
region = v
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -722,3 +790,11 @@ func setDomainIfNeeded(cloud *Cloud) *Cloud {
|
|
|
|
|
|
|
|
|
|
return cloud
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// isApplicationCredential determines if an application credential is used to auth.
|
|
|
|
|
func isApplicationCredential(authInfo *AuthInfo) bool {
|
|
|
|
|
if authInfo.ApplicationCredentialID == "" && authInfo.ApplicationCredentialName == "" && authInfo.ApplicationCredentialSecret == "" {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
|