blob: 356bf8709e003f6d1f0e294f578a029b1dd0f556 [file] [log] [blame]
Ash Wilson1f110512014-10-02 15:43:47 -04001package tokens
2
jrperritt95b74c82015-07-28 20:39:27 -06003import (
4 "fmt"
5
6 "github.com/rackspace/gophercloud"
7)
Ash Wilson1f110512014-10-02 15:43:47 -04008
Ash Wilson40095f02014-10-07 15:46:40 -04009// AuthOptionsBuilder describes any argument that may be passed to the Create call.
10type AuthOptionsBuilder interface {
Ash Wilsonaa197a92014-10-03 11:38:08 -040011
Ash Wilson40095f02014-10-07 15:46:40 -040012 // ToTokenCreateMap assembles the Create request body, returning an error if parameters are
13 // missing or inconsistent.
14 ToTokenCreateMap() (map[string]interface{}, error)
15}
Ash Wilson1f110512014-10-02 15:43:47 -040016
Ash Wilson40095f02014-10-07 15:46:40 -040017// AuthOptions wraps a gophercloud AuthOptions in order to adhere to the AuthOptionsBuilder
18// interface.
19type AuthOptions struct {
20 gophercloud.AuthOptions
21}
22
Ash Wilson22397242014-10-07 16:10:21 -040023// WrapOptions embeds a root AuthOptions struct in a package-specific one.
24func WrapOptions(original gophercloud.AuthOptions) AuthOptions {
25 return AuthOptions{AuthOptions: original}
26}
27
Ash Wilson40095f02014-10-07 15:46:40 -040028// ToTokenCreateMap converts AuthOptions into nested maps that can be serialized into a JSON
29// request.
30func (auth AuthOptions) ToTokenCreateMap() (map[string]interface{}, error) {
Ash Wilson1f110512014-10-02 15:43:47 -040031 // Error out if an unsupported auth option is present.
32 if auth.UserID != "" {
Ash Wilson40095f02014-10-07 15:46:40 -040033 return nil, ErrUserIDProvided
Ash Wilson1f110512014-10-02 15:43:47 -040034 }
Ash Wilson1cf4d5f2014-10-07 14:16:18 -040035 if auth.APIKey != "" {
Ash Wilson40095f02014-10-07 15:46:40 -040036 return nil, ErrAPIKeyProvided
Ash Wilson1cf4d5f2014-10-07 14:16:18 -040037 }
Ash Wilson1f110512014-10-02 15:43:47 -040038 if auth.DomainID != "" {
Ash Wilson40095f02014-10-07 15:46:40 -040039 return nil, ErrDomainIDProvided
Ash Wilson1f110512014-10-02 15:43:47 -040040 }
41 if auth.DomainName != "" {
Ash Wilson40095f02014-10-07 15:46:40 -040042 return nil, ErrDomainNameProvided
Ash Wilson1f110512014-10-02 15:43:47 -040043 }
44
Ash Wilson40095f02014-10-07 15:46:40 -040045 // Populate the request map.
46 authMap := make(map[string]interface{})
47
jrperritt95b74c82015-07-28 20:39:27 -060048 if auth.Username != "" {
49 if auth.Password != "" {
50 authMap["passwordCredentials"] = map[string]interface{}{
51 "username": auth.Username,
52 "password": auth.Password,
53 }
54 } else {
55 return nil, ErrPasswordRequired
56 }
57 } else if auth.Token != "" {
58 authMap["token"] = map[string]interface{}{
59 "id": auth.Token,
60 }
61 } else {
62 return nil, fmt.Errorf("You must provide either username/password or tenantID/token values.")
Ash Wilson1cf4d5f2014-10-07 14:16:18 -040063 }
Ash Wilson40095f02014-10-07 15:46:40 -040064
65 if auth.TenantID != "" {
66 authMap["tenantId"] = auth.TenantID
67 }
68 if auth.TenantName != "" {
69 authMap["tenantName"] = auth.TenantName
70 }
71
72 return map[string]interface{}{"auth": authMap}, nil
73}
74
75// Create authenticates to the identity service and attempts to acquire a Token.
76// If successful, the CreateResult
77// Generally, rather than interact with this call directly, end users should call openstack.AuthenticatedClient(),
78// which abstracts all of the gory details about navigating service catalogs and such.
79func Create(client *gophercloud.ServiceClient, auth AuthOptionsBuilder) CreateResult {
80 request, err := auth.ToTokenCreateMap()
81 if err != nil {
Ash Wilsonf548aad2014-10-20 08:35:34 -040082 return CreateResult{gophercloud.Result{Err: err}}
Ash Wilson40095f02014-10-07 15:46:40 -040083 }
Ash Wilson1f110512014-10-02 15:43:47 -040084
85 var result CreateResult
Jamie Hannaford562a7d52015-03-24 16:20:16 +010086 _, result.Err = client.Post(CreateURL(client), request, &result.Body, &gophercloud.RequestOpts{
87 OkCodes: []int{200, 203},
Ash Wilson1f110512014-10-02 15:43:47 -040088 })
89 return result
90}