Extract Keystone v3 service catalog
Fix #407
diff --git a/openstack/identity/v3/tokens/results.go b/openstack/identity/v3/tokens/results.go
index d1fff4c..d134f7d 100644
--- a/openstack/identity/v3/tokens/results.go
+++ b/openstack/identity/v3/tokens/results.go
@@ -7,13 +7,58 @@
"github.com/rackspace/gophercloud"
)
+// Endpoint represents a single API endpoint offered by a service.
+// It matches either a public, internal or admin URL.
+// If supported, it contains a region specifier, again if provided.
+// The significance of the Region field will depend upon your provider.
+type Endpoint struct {
+ ID string `mapstructure:"id"`
+ Region string `mapstructure:"region"`
+ Interface string `mapstructure:"interface"`
+ URL string `mapstructure:"url"`
+}
+
+// CatalogEntry provides a type-safe interface to an Identity API V3 service catalog listing.
+// Each class of service, such as cloud DNS or block storage services, could have multiple
+// CatalogEntry representing it (one by interface type, e.g public, admin or internal).
+//
+// Note: when looking for the desired service, try, whenever possible, to key off the type field.
+// Otherwise, you'll tie the representation of the service to a specific provider.
+type CatalogEntry struct {
+
+ // Service ID
+ ID string `mapstructure:"id"`
+
+ // Name will contain the provider-specified name for the service.
+ Name string `mapstructure:"name"`
+
+ // Type will contain a type string if OpenStack defines a type for the service.
+ // Otherwise, for provider-specific services, the provider may assign their own type strings.
+ Type string `mapstructure:"type"`
+
+ // Endpoints will let the caller iterate over all the different endpoints that may exist for
+ // the service.
+ Endpoints []Endpoint `mapstructure:"endpoints"`
+}
+
+// ServiceCatalog provides a view into the service catalog from a previous, successful authentication.
+type ServiceCatalog struct {
+ Entries []CatalogEntry
+}
+
// commonResult is the deferred result of a Create or a Get call.
type commonResult struct {
gophercloud.Result
}
-// Extract interprets a commonResult as a Token.
+// Extract is a shortcut for ExtractToken.
+// This function is deprecated and still present for backward compatibility.
func (r commonResult) Extract() (*Token, error) {
+ return r.ExtractToken()
+}
+
+// ExtractToken interprets a commonResult as a Token.
+func (r commonResult) ExtractToken() (*Token, error) {
if r.Err != nil {
return nil, r.Err
}
@@ -40,7 +85,28 @@
return &token, err
}
-// CreateResult is the deferred response from a Create call.
+// ExtractServiceCatalog returns the ServiceCatalog that was generated along with the user's Token.
+func (result CreateResult) ExtractServiceCatalog() (*ServiceCatalog, error) {
+ if result.Err != nil {
+ return nil, result.Err
+ }
+
+ var response struct {
+ Token struct {
+ Entries []CatalogEntry `mapstructure:"catalog"`
+ } `mapstructure:"token"`
+ }
+
+ err := mapstructure.Decode(result.Body, &response)
+ if err != nil {
+ return nil, err
+ }
+
+ return &ServiceCatalog{Entries: response.Token.Entries}, nil
+}
+
+// CreateResult defers the interpretation of a created token.
+// Use ExtractToken() to interpret it as a Token, or ExtractServiceCatalog() to interpret it as a service catalog.
type CreateResult struct {
commonResult
}