blob: dc093575321c7cfebc8eda037b92fab1038ab810 [file] [log] [blame]
Ash Wilson1f110512014-10-02 15:43:47 -04001package tokens
2
3import (
4 "time"
5
6 "github.com/mitchellh/mapstructure"
7 "github.com/rackspace/gophercloud"
8 "github.com/rackspace/gophercloud/openstack/identity/v2/tenants"
9)
10
11// Token provides only the most basic information related to an authentication token.
12type Token struct {
13 // ID provides the primary means of identifying a user to the OpenStack API.
14 // OpenStack defines this field as an opaque value, so do not depend on its content.
15 // It is safe, however, to compare for equality.
16 ID string
17
18 // ExpiresAt provides a timestamp in ISO 8601 format, indicating when the authentication token becomes invalid.
19 // After this point in time, future API requests made using this authentication token will respond with errors.
20 // Either the caller will need to reauthenticate manually, or more preferably, the caller should exploit automatic re-authentication.
21 // See the AuthOptions structure for more details.
22 ExpiresAt time.Time
23
24 // Tenant provides information about the tenant to which this token grants access.
25 Tenant tenants.Tenant
26}
27
Ash Wilsonab48bbc2014-10-03 09:57:03 -040028// Endpoint represents a single API endpoint offered by a service.
29// It provides the public and internal URLs, if supported, along with a region specifier, again if provided.
30// The significance of the Region field will depend upon your provider.
31//
32// In addition, the interface offered by the service will have version information associated with it
33// through the VersionId, VersionInfo, and VersionList fields, if provided or supported.
34//
35// In all cases, fields which aren't supported by the provider and service combined will assume a zero-value ("").
36type Endpoint struct {
37 TenantID string `mapstructure:"tenantId"`
38 PublicURL string `mapstructure:"publicURL"`
39 InternalURL string `mapstructure:"internalURL"`
40 AdminURL string `mapstructure:"adminURL"`
41 Region string `mapstructure:"region"`
42 VersionID string `mapstructure:"versionId"`
43 VersionInfo string `mapstructure:"versionInfo"`
44 VersionList string `mapstructure:"versionList"`
45}
46
47// CatalogEntry provides a type-safe interface to an Identity API V2 service catalog listing.
48// Each class of service, such as cloud DNS or block storage services, will have a single
49// CatalogEntry representing it.
50//
51// Note: when looking for the desired service, try, whenever possible, to key off the type field.
52// Otherwise, you'll tie the representation of the service to a specific provider.
53type CatalogEntry struct {
54 // Name will contain the provider-specified name for the service.
55 Name string `mapstructure:"name"`
56
57 // Type will contain a type string if OpenStack defines a type for the service.
58 // Otherwise, for provider-specific services, the provider may assign their own type strings.
59 Type string `mapstructure:"type"`
60
61 // Endpoints will let the caller iterate over all the different endpoints that may exist for
62 // the service.
63 Endpoints []Endpoint `mapstructure:"endpoints"`
64}
65
66// ServiceCatalog provides a view into the service catalog from a previous, successful authentication.
67type ServiceCatalog struct {
68 Entries []CatalogEntry
69}
70
Ash Wilson1f110512014-10-02 15:43:47 -040071// CreateResult defers the interpretation of a created token.
72// Use ExtractToken() to interpret it as a Token, or ExtractServiceCatalog() to interpret it as a service catalog.
73type CreateResult struct {
Ash Wilsonf548aad2014-10-20 08:35:34 -040074 gophercloud.Result
Ash Wilson1f110512014-10-02 15:43:47 -040075}
76
hzlouchaof6e29262015-10-27 12:51:08 +080077// GetResult is the deferred response from a Get call.
78type GetResult struct {
79 gophercloud.Result
80}
81
Ash Wilson1f110512014-10-02 15:43:47 -040082// ExtractToken returns the just-created Token from a CreateResult.
83func (result CreateResult) ExtractToken() (*Token, error) {
Ash Wilson27d29e22014-10-03 11:57:14 -040084 if result.Err != nil {
85 return nil, result.Err
86 }
87
Ash Wilson1f110512014-10-02 15:43:47 -040088 var response struct {
89 Access struct {
90 Token struct {
91 Expires string `mapstructure:"expires"`
92 ID string `mapstructure:"id"`
93 Tenant tenants.Tenant `mapstructure:"tenant"`
94 } `mapstructure:"token"`
95 } `mapstructure:"access"`
96 }
97
Ash Wilsond3dc2542014-10-20 10:10:48 -040098 err := mapstructure.Decode(result.Body, &response)
Ash Wilson1f110512014-10-02 15:43:47 -040099 if err != nil {
100 return nil, err
101 }
102
103 expiresTs, err := time.Parse(gophercloud.RFC3339Milli, response.Access.Token.Expires)
104 if err != nil {
105 return nil, err
106 }
107
108 return &Token{
109 ID: response.Access.Token.ID,
110 ExpiresAt: expiresTs,
111 Tenant: response.Access.Token.Tenant,
112 }, nil
113}
114
Ash Wilsonab48bbc2014-10-03 09:57:03 -0400115// ExtractServiceCatalog returns the ServiceCatalog that was generated along with the user's Token.
116func (result CreateResult) ExtractServiceCatalog() (*ServiceCatalog, error) {
Ash Wilson27d29e22014-10-03 11:57:14 -0400117 if result.Err != nil {
118 return nil, result.Err
119 }
120
Ash Wilsonab48bbc2014-10-03 09:57:03 -0400121 var response struct {
122 Access struct {
123 Entries []CatalogEntry `mapstructure:"serviceCatalog"`
124 } `mapstructure:"access"`
125 }
126
Ash Wilsond3dc2542014-10-20 10:10:48 -0400127 err := mapstructure.Decode(result.Body, &response)
Ash Wilsonab48bbc2014-10-03 09:57:03 -0400128 if err != nil {
129 return nil, err
130 }
131
132 return &ServiceCatalog{Entries: response.Access.Entries}, nil
133}
134
Ash Wilson1f110512014-10-02 15:43:47 -0400135// createErr quickly packs an error in a CreateResult.
136func createErr(err error) CreateResult {
Ash Wilsonf548aad2014-10-20 08:35:34 -0400137 return CreateResult{gophercloud.Result{Err: err}}
Ash Wilson1f110512014-10-02 15:43:47 -0400138}