Skip to content
This repository was archived by the owner on Aug 31, 2021. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions auth_aksk_options.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,15 @@ type AKSKAuthOptions struct {

AccessKey string //Access Key
SecretKey string //Secret key

// AgencyNmae is the name of agnecy
AgencyName string

// AgencyDomainName is the name of domain who created the agency
AgencyDomainName string

// DelegatedProject is the name of delegated project
DelegatedProject string
}

// Implements the method of AuthOptionsProvider
Expand Down
9 changes: 9 additions & 0 deletions auth_options.go
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,10 @@ func (opts *AuthOptions) AuthTokenID() string {
return ""
}

func (opts *AuthOptions) AuthHeaderDomainID() string {
return ""
}

// Implements the method of AuthOptionsProvider
func (opts AuthOptions) GetIdentityEndpoint() string {
return opts.IdentityEndpoint
Expand Down Expand Up @@ -381,6 +385,7 @@ func (scope *scopeInfo) BuildTokenV3ScopeMap() (map[string]interface{}, error) {

type AgencyAuthOptions struct {
TokenID string
DomainID string
AgencyName string
AgencyDomainName string
DelegatedProject string
Expand All @@ -394,6 +399,10 @@ func (opts *AgencyAuthOptions) AuthTokenID() string {
return opts.TokenID
}

func (opts *AgencyAuthOptions) AuthHeaderDomainID() string {
return opts.DomainID
}

func (opts *AgencyAuthOptions) ToTokenV3ScopeMap() (map[string]interface{}, error) {
scope := scopeInfo{
ProjectName: opts.DelegatedProject,
Expand Down
126 changes: 125 additions & 1 deletion openstack/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (

"github.com/huaweicloud/golangsdk"
tokens2 "github.com/huaweicloud/golangsdk/openstack/identity/v2/tokens"
"github.com/huaweicloud/golangsdk/openstack/identity/v3/domains"
"github.com/huaweicloud/golangsdk/openstack/identity/v3/endpoints"
"github.com/huaweicloud/golangsdk/openstack/identity/v3/projects"
"github.com/huaweicloud/golangsdk/openstack/identity/v3/services"
Expand Down Expand Up @@ -130,7 +131,12 @@ func Authenticate(client *golangsdk.ProviderClient, options golangsdk.AuthOption
akskAuthOptions, isAkSkOptions := options.(golangsdk.AKSKAuthOptions)

if isAkSkOptions {
return v3AKSKAuth(client, endpoint, akskAuthOptions, golangsdk.EndpointOpts{})
if akskAuthOptions.AgencyDomainName != "" && akskAuthOptions.AgencyName != "" {
return authWithAgencyByAKSK(client, endpoint, akskAuthOptions, golangsdk.EndpointOpts{})
} else {
return v3AKSKAuth(client, endpoint, akskAuthOptions, golangsdk.EndpointOpts{})
}

} else {
return fmt.Errorf("Unrecognized auth options provider: %s", reflect.TypeOf(options))
}
Expand Down Expand Up @@ -373,6 +379,124 @@ func v3AKSKAuth(client *golangsdk.ProviderClient, endpoint string, options golan
return nil
}

func authWithAgencyByAKSK(client *golangsdk.ProviderClient, endpoint string, opts golangsdk.AKSKAuthOptions, eo golangsdk.EndpointOpts) error {

err := v3AKSKAuth(client, endpoint, opts, eo)
if err != nil {
return err
}

v3Client, err := NewIdentityV3(client, eo)
if err != nil {
return err
}

domainID, err := getDomainID(opts.Domain, v3Client)
if err != nil {
return err
}

opts2 := golangsdk.AgencyAuthOptions{
DomainID: domainID,
AgencyName: opts.AgencyName,
AgencyDomainName: opts.AgencyDomainName,
DelegatedProject: opts.DelegatedProject,
}
result := tokens3.Create(v3Client, &opts2)
token, err := result.ExtractToken()
if err != nil {
return err
}

project, err := result.ExtractProject()
if err != nil {
return err
}

catalog, err := result.ExtractServiceCatalog()
if err != nil {
return err
}

client.TokenID = token.ID
if project != nil {
client.ProjectID = project.ID
}

client.ReauthFunc = func() error {
client.TokenID = ""
return authWithAgencyByAKSK(client, endpoint, opts, eo)
}

client.EndpointLocator = func(opts golangsdk.EndpointOpts) (string, error) {
return V3EndpointURL(catalog, opts)
}

client.AKSKAuthOptions.AccessKey = ""
return nil
}

func getDomainID(name string, client *golangsdk.ServiceClient) (string, error) {
old := client.Endpoint
defer func() { client.Endpoint = old }()

endpoint, err := client.EndpointLocator(
golangsdk.EndpointOpts{
Type: "identity",
Availability: golangsdk.AvailabilityPublic,
})
if err != nil {
if v, ok := err.(ErrMultipleMatchingEndpointsV3); ok {
e := ""
for _, i := range v.Endpoints {
if i.Region == "" {
e = golangsdk.NormalizeURL(i.URL) + "auth/"
break
}
}

if e == "" {
return "", err
}
client.Endpoint = e
} else {
return "", err
}
} else {
client.Endpoint = endpoint + "auth/"
}

opts := domains.ListOpts{
Name: name,
}
allPages, err := domains.List(client, &opts).AllPages()
if err != nil {
return "", fmt.Errorf("List domains failed, err=%s", err)
}

all, err := domains.ExtractDomains(allPages)
if err != nil {
return "", fmt.Errorf("Extract domains failed, err=%s", err)
}

count := len(all)
switch count {
case 0:
err := &golangsdk.ErrResourceNotFound{}
err.ResourceType = "iam"
err.Name = name
return "", err
case 1:
return all[0].ID, nil
default:
err := &golangsdk.ErrMultipleResourcesFound{}
err.ResourceType = "iam"
err.Name = name
err.Count = count
return "", err
}
}

// NewIdentityV2 creates a ServiceClient that may be used to interact with the
// v2 identity service.
func NewIdentityV2(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
Expand Down
10 changes: 9 additions & 1 deletion openstack/identity/v3/tokens/requests.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ type AuthOptionsBuilder interface {
ToTokenV3ScopeMap() (map[string]interface{}, error)
CanReauth() bool
AuthTokenID() string
AuthHeaderDomainID() string
}

// AuthOptions represents options for authenticating a user.
Expand Down Expand Up @@ -149,6 +150,10 @@ func (opts *AuthOptions) AuthTokenID() string {
return ""
}

func (opts *AuthOptions) AuthHeaderDomainID() string {
return ""
}

func subjectTokenHeaders(c *golangsdk.ServiceClient, subjectToken string) map[string]string {
return map[string]string{
"X-Subject-Token": subjectToken,
Expand All @@ -171,7 +176,10 @@ func Create(c *golangsdk.ServiceClient, opts AuthOptionsBuilder) (r CreateResult
}

resp, err := c.Post(tokenURL(c), b, &r.Body, &golangsdk.RequestOpts{
MoreHeaders: map[string]string{"X-Auth-Token": opts.AuthTokenID()},
MoreHeaders: map[string]string{
"X-Auth-Token": opts.AuthTokenID(),
"X-Domain-Id": opts.AuthHeaderDomainID(),
},
})
r.Err = err
if resp != nil {
Expand Down