blob: 93c0554ae1720603ed3a39896ba578f74aa3c581 [file] [log] [blame]
Ash Wilson1f110512014-10-02 15:43:47 -04001package tokens
2
3import (
4 "time"
5
Jon Perritt27249f42016-02-18 10:35:59 -06006 "github.com/gophercloud/gophercloud"
7 "github.com/gophercloud/gophercloud/openstack/identity/v2/tenants"
Ash Wilson1f110512014-10-02 15:43:47 -04008)
9
10// Token provides only the most basic information related to an authentication token.
11type Token struct {
12 // ID provides the primary means of identifying a user to the OpenStack API.
13 // OpenStack defines this field as an opaque value, so do not depend on its content.
14 // It is safe, however, to compare for equality.
15 ID string
16
17 // ExpiresAt provides a timestamp in ISO 8601 format, indicating when the authentication token becomes invalid.
18 // After this point in time, future API requests made using this authentication token will respond with errors.
19 // Either the caller will need to reauthenticate manually, or more preferably, the caller should exploit automatic re-authentication.
20 // See the AuthOptions structure for more details.
21 ExpiresAt time.Time
22
23 // Tenant provides information about the tenant to which this token grants access.
24 Tenant tenants.Tenant
hzlouchao04543602015-11-30 18:44:15 +080025}
hzlouchaob7640892015-11-04 21:37:20 +080026
Jon Perritt3c166472016-02-25 03:07:41 -060027// Role is a role for a user.
hzlouchao04543602015-11-30 18:44:15 +080028type Role struct {
Jon Perritt3c166472016-02-25 03:07:41 -060029 Name string `json:"name"`
hzlouchao04543602015-11-30 18:44:15 +080030}
Jon Perritt3c166472016-02-25 03:07:41 -060031
32// User is an OpenStack user.
hzlouchao04543602015-11-30 18:44:15 +080033type User struct {
Jon Perritt3c166472016-02-25 03:07:41 -060034 ID string `json:"id"`
35 Name string `json:"name"`
36 UserName string `json:"username"`
37 Roles []Role `json:"roles"`
Ash Wilson1f110512014-10-02 15:43:47 -040038}
39
Ash Wilsonab48bbc2014-10-03 09:57:03 -040040// Endpoint represents a single API endpoint offered by a service.
41// It provides the public and internal URLs, if supported, along with a region specifier, again if provided.
42// The significance of the Region field will depend upon your provider.
43//
44// In addition, the interface offered by the service will have version information associated with it
45// through the VersionId, VersionInfo, and VersionList fields, if provided or supported.
46//
47// In all cases, fields which aren't supported by the provider and service combined will assume a zero-value ("").
48type Endpoint struct {
Jon Perritt3c166472016-02-25 03:07:41 -060049 TenantID string `json:"tenantId"`
50 PublicURL string `json:"publicURL"`
51 InternalURL string `json:"internalURL"`
52 AdminURL string `json:"adminURL"`
53 Region string `json:"region"`
54 VersionID string `json:"versionId"`
55 VersionInfo string `json:"versionInfo"`
56 VersionList string `json:"versionList"`
Ash Wilsonab48bbc2014-10-03 09:57:03 -040057}
58
59// CatalogEntry provides a type-safe interface to an Identity API V2 service catalog listing.
60// Each class of service, such as cloud DNS or block storage services, will have a single
61// CatalogEntry representing it.
62//
63// Note: when looking for the desired service, try, whenever possible, to key off the type field.
64// Otherwise, you'll tie the representation of the service to a specific provider.
65type CatalogEntry struct {
66 // Name will contain the provider-specified name for the service.
Jon Perritt3c166472016-02-25 03:07:41 -060067 Name string `json:"name"`
Ash Wilsonab48bbc2014-10-03 09:57:03 -040068
69 // Type will contain a type string if OpenStack defines a type for the service.
70 // Otherwise, for provider-specific services, the provider may assign their own type strings.
Jon Perritt3c166472016-02-25 03:07:41 -060071 Type string `json:"type"`
Ash Wilsonab48bbc2014-10-03 09:57:03 -040072
73 // Endpoints will let the caller iterate over all the different endpoints that may exist for
74 // the service.
Jon Perritt3c166472016-02-25 03:07:41 -060075 Endpoints []Endpoint `json:"endpoints"`
Ash Wilsonab48bbc2014-10-03 09:57:03 -040076}
77
78// ServiceCatalog provides a view into the service catalog from a previous, successful authentication.
79type ServiceCatalog struct {
80 Entries []CatalogEntry
81}
82
Ash Wilson1f110512014-10-02 15:43:47 -040083// CreateResult defers the interpretation of a created token.
84// Use ExtractToken() to interpret it as a Token, or ExtractServiceCatalog() to interpret it as a service catalog.
85type CreateResult struct {
Ash Wilsonf548aad2014-10-20 08:35:34 -040086 gophercloud.Result
Ash Wilson1f110512014-10-02 15:43:47 -040087}
88
hzlouchao04543602015-11-30 18:44:15 +080089// GetResult is the deferred response from a Get call, which is the same with a Created token.
90// Use ExtractUser() to interpret it as a User.
hzlouchaof6e29262015-10-27 12:51:08 +080091type GetResult struct {
hzlouchao04543602015-11-30 18:44:15 +080092 CreateResult
hzlouchaof6e29262015-10-27 12:51:08 +080093}
94
Ash Wilson1f110512014-10-02 15:43:47 -040095// ExtractToken returns the just-created Token from a CreateResult.
Jon Perritt3c166472016-02-25 03:07:41 -060096func (r CreateResult) ExtractToken() (*Token, error) {
97 var s struct {
Ash Wilson1f110512014-10-02 15:43:47 -040098 Access struct {
99 Token struct {
Jon Perritt3c166472016-02-25 03:07:41 -0600100 Expires string `json:"expires"`
101 ID string `json:"id"`
102 Tenant tenants.Tenant `json:"tenant"`
103 } `json:"token"`
104 } `json:"access"`
Ash Wilson1f110512014-10-02 15:43:47 -0400105 }
106
Jon Perritt3c166472016-02-25 03:07:41 -0600107 err := r.ExtractInto(&s)
Ash Wilson1f110512014-10-02 15:43:47 -0400108 if err != nil {
109 return nil, err
110 }
111
Jon Perritt3c166472016-02-25 03:07:41 -0600112 expiresTs, err := time.Parse(gophercloud.RFC3339Milli, s.Access.Token.Expires)
Ash Wilson1f110512014-10-02 15:43:47 -0400113 if err != nil {
114 return nil, err
115 }
116
117 return &Token{
Jon Perritt3c166472016-02-25 03:07:41 -0600118 ID: s.Access.Token.ID,
Ash Wilson1f110512014-10-02 15:43:47 -0400119 ExpiresAt: expiresTs,
Jon Perritt3c166472016-02-25 03:07:41 -0600120 Tenant: s.Access.Token.Tenant,
Ash Wilson1f110512014-10-02 15:43:47 -0400121 }, nil
122}
123
Ash Wilsonab48bbc2014-10-03 09:57:03 -0400124// ExtractServiceCatalog returns the ServiceCatalog that was generated along with the user's Token.
Jon Perritt3c166472016-02-25 03:07:41 -0600125func (r CreateResult) ExtractServiceCatalog() (*ServiceCatalog, error) {
126 var s struct {
Ash Wilsonab48bbc2014-10-03 09:57:03 -0400127 Access struct {
Jon Perritt3c166472016-02-25 03:07:41 -0600128 Entries []CatalogEntry `json:"serviceCatalog"`
129 } `json:"access"`
Ash Wilsonab48bbc2014-10-03 09:57:03 -0400130 }
Jon Perritt3c166472016-02-25 03:07:41 -0600131 err := r.ExtractInto(&s)
132 return &ServiceCatalog{Entries: s.Access.Entries}, err
Ash Wilsonab48bbc2014-10-03 09:57:03 -0400133}
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}
hzlouchaob7640892015-11-04 21:37:20 +0800139
hzlouchao04543602015-11-30 18:44:15 +0800140// ExtractUser returns the User from a GetResult.
Jon Perritt3c166472016-02-25 03:07:41 -0600141func (r GetResult) ExtractUser() (*User, error) {
142 var s struct {
hzlouchaob7640892015-11-04 21:37:20 +0800143 Access struct {
Jon Perritt3c166472016-02-25 03:07:41 -0600144 User User `json:"user"`
145 } `json:"access"`
hzlouchaob7640892015-11-04 21:37:20 +0800146 }
Jon Perritt3c166472016-02-25 03:07:41 -0600147 err := r.ExtractInto(&s)
148 return &s.Access.User, err
hzlouchaob7640892015-11-04 21:37:20 +0800149}