modify according jrperritt's suggestion
diff --git a/openstack/identity/v2/tokens/results.go b/openstack/identity/v2/tokens/results.go
index dc09357..3903e39 100644
--- a/openstack/identity/v2/tokens/results.go
+++ b/openstack/identity/v2/tokens/results.go
@@ -23,6 +23,10 @@
// Tenant provides information about the tenant to which this token grants access.
Tenant tenants.Tenant
+
+ // the owner user of token
+ UserName string
+ UserID string
}
// Endpoint represents a single API endpoint offered by a service.
@@ -76,7 +80,7 @@
// GetResult is the deferred response from a Get call.
type GetResult struct {
- gophercloud.Result
+ gophercloud.Result
}
// ExtractToken returns the just-created Token from a CreateResult.
@@ -136,3 +140,40 @@
func createErr(err error) CreateResult {
return CreateResult{gophercloud.Result{Err: err}}
}
+
+// ExtractToken returns the Token from a GetResult.
+func (result GetResult) ExtractToken() (*Token, error) {
+ if result.Err != nil {
+ return nil, result.Err
+ }
+
+ var response struct {
+ Access struct {
+ Token struct {
+ Expires string `mapstructure:"expires"`
+ ID string `mapstructure:"id"`
+ } `mapstructure:"token"`
+ User struct {
+ ID string `mapstructure:"id"`
+ Name string `mapstructure:"name"`
+ } `mapstructure:"user"`
+ } `mapstructure:"access"`
+ }
+
+ err := mapstructure.Decode(result.Body, &response)
+ if err != nil {
+ return nil, err
+ }
+
+ expiresTs, err := time.Parse(gophercloud.RFC3339Milli, response.Access.Token.Expires)
+ if err != nil {
+ return nil, err
+ }
+
+ return &Token{
+ ID: response.Access.Token.ID,
+ ExpiresAt: expiresTs,
+ UserID: response.Access.User.ID,
+ UserName: response.Access.User.Name,
+ }, nil
+}