blob: 035f671964e1204656f65454abf3c0ad97c98bd6 [file] [log] [blame]
Samuel A. Falvo II8a549ef2014-01-24 15:20:54 -08001package identity
2
3import "github.com/mitchellh/mapstructure"
4
Samuel A. Falvo II2b963212014-02-09 02:12:30 -08005// ServiceCatalog provides a view into the service catalog from a previous, successful authentication.
6// OpenStack extensions may alter the structure of the service catalog in ways unpredictable to Go at compile-time,
7// so this structure serves as a convenient anchor for type-safe accessors and methods.
8type ServiceCatalog struct {
Samuel A. Falvo II8a549ef2014-01-24 15:20:54 -08009 serviceDescriptions []interface{}
10}
11
Samuel A. Falvo II2b963212014-02-09 02:12:30 -080012// CatalogEntry provides a type-safe interface to an Identity API V2 service
13// catalog listing. Each class of service, such as cloud DNS or block storage
14// services, will have a single CatalogEntry representing it.
15//
16// Name will contain the provider-specified name for the service.
17//
18// If OpenStack defines a type for the service, this field will contain that
19// type string. Otherwise, for provider-specific services, the provider may
20// assign their own type strings.
21//
22// Endpoints will let the caller iterate over all the different endpoints that
23// may exist for the service.
24//
25// Note: when looking for the desired service, try, whenever possible, to key
26// off the type field. Otherwise, you'll tie the representation of the service
27// to a specific provider.
Samuel A. Falvo II8a549ef2014-01-24 15:20:54 -080028type CatalogEntry struct {
Samuel A. Falvo II0262e972014-01-24 16:06:56 -080029 Name string
30 Type string
Samuel A. Falvo II8a549ef2014-01-24 15:20:54 -080031 Endpoints []Endpoint
32}
33
Samuel A. Falvo II2b963212014-02-09 02:12:30 -080034// Endpoint represents a single API endpoint offered by a service.
35// It provides the public and internal URLs, if supported, along with a region specifier, again if provided.
36// The significance of the Region field will depend upon your provider.
37//
38// In addition, the interface offered by the service will have version information associated with it
39// through the VersionId, VersionInfo, and VersionList fields, if provided or supported.
40//
41// In all cases, fields which aren't supported by the provider and service combined will assume a zero-value ("").
Samuel A. Falvo II8a549ef2014-01-24 15:20:54 -080042type Endpoint struct {
Samuel A. Falvo II0262e972014-01-24 16:06:56 -080043 TenantId string
44 PublicURL string
Samuel A. Falvo II8a549ef2014-01-24 15:20:54 -080045 InternalURL string
Samuel A. Falvo II0262e972014-01-24 16:06:56 -080046 Region string
47 VersionId string
Samuel A. Falvo II8a549ef2014-01-24 15:20:54 -080048 VersionInfo string
49 VersionList string
50}
51
Samuel A. Falvo II2b963212014-02-09 02:12:30 -080052// GetServiceCatalog acquires the service catalog from a successful authentication's results.
53func GetServiceCatalog(ar AuthResults) (*ServiceCatalog, error) {
Samuel A. Falvo II8a549ef2014-01-24 15:20:54 -080054 access := ar["access"].(map[string]interface{})
55 sds := access["serviceCatalog"].([]interface{})
Samuel A. Falvo II2b963212014-02-09 02:12:30 -080056 sc := &ServiceCatalog{
Samuel A. Falvo II8a549ef2014-01-24 15:20:54 -080057 serviceDescriptions: sds,
58 }
59 return sc, nil
60}
61
Samuel A. Falvo II2b963212014-02-09 02:12:30 -080062// NumberOfServices yields the number of services the caller may use. Note
63// that this does not necessarily equal the number of endpoints available for
64// use.
65func (sc *ServiceCatalog) NumberOfServices() int {
Samuel A. Falvo II8a549ef2014-01-24 15:20:54 -080066 return len(sc.serviceDescriptions)
67}
68
Samuel A. Falvo II2b963212014-02-09 02:12:30 -080069// CatalogEntries returns a slice of service catalog entries.
70// Each entry corresponds to a specific class of service offered by the API provider.
71// See the CatalogEntry structure for more details.
72func (sc *ServiceCatalog) CatalogEntries() ([]CatalogEntry, error) {
Samuel A. Falvo II8a549ef2014-01-24 15:20:54 -080073 var err error
74 ces := make([]CatalogEntry, sc.NumberOfServices())
75 for i, sd := range sc.serviceDescriptions {
76 d := sd.(map[string]interface{})
77 eps, err := parseEndpoints(d["endpoints"].([]interface{}))
78 if err != nil {
79 return ces, err
80 }
81 ces[i] = CatalogEntry{
Samuel A. Falvo II0262e972014-01-24 16:06:56 -080082 Name: d["name"].(string),
83 Type: d["type"].(string),
Samuel A. Falvo II8a549ef2014-01-24 15:20:54 -080084 Endpoints: eps,
85 }
86 }
87 return ces, err
88}
89
90func parseEndpoints(eps []interface{}) ([]Endpoint, error) {
91 var err error
92 result := make([]Endpoint, len(eps))
93 for i, ep := range eps {
94 e := Endpoint{}
95 err = mapstructure.Decode(ep, &e)
96 if err != nil {
97 return result, err
98 }
99 result[i] = e
100 }
101 return result, err
102}