Samuel A. Falvo II | 8a549ef | 2014-01-24 15:20:54 -0800 | [diff] [blame] | 1 | package identity |
| 2 | |
| 3 | import ( |
Samuel A. Falvo II | 8a549ef | 2014-01-24 15:20:54 -0800 | [diff] [blame] | 4 | "github.com/mitchellh/mapstructure" |
| 5 | ) |
| 6 | |
Samuel A. Falvo II | 2b96321 | 2014-02-09 02:12:30 -0800 | [diff] [blame^] | 7 | // ExtensionDetails provides the details offered by the OpenStack Identity V2 extensions API |
| 8 | // for a named extension. |
| 9 | // |
| 10 | // Name provides the name, presumably the same as that used to query the API with. |
| 11 | // |
| 12 | // Updated provides, in a sense, the version of the extension supported. It gives the timestamp |
| 13 | // of the most recent extension deployment. |
| 14 | // |
| 15 | // Description provides a more customer-oriented description of the extension. |
Samuel A. Falvo II | 8a549ef | 2014-01-24 15:20:54 -0800 | [diff] [blame] | 16 | type ExtensionDetails struct { |
| 17 | Name string |
| 18 | Namespace string |
| 19 | Updated string |
| 20 | Description string |
| 21 | } |
| 22 | |
Samuel A. Falvo II | 2b96321 | 2014-02-09 02:12:30 -0800 | [diff] [blame^] | 23 | // ExtensionsResult encapsulates the raw data returned by a call to |
| 24 | // GetExtensions(). As OpenStack extensions may freely alter the response |
| 25 | // bodies of structures returned to the client, you may only safely access the |
| 26 | // data provided through separate, type-safe accessors or methods. |
| 27 | type ExtensionsResult map[string]interface{} |
Samuel A. Falvo II | 8a549ef | 2014-01-24 15:20:54 -0800 | [diff] [blame] | 28 | |
Samuel A. Falvo II | 2b96321 | 2014-02-09 02:12:30 -0800 | [diff] [blame^] | 29 | // IsExtensionAvailable returns true if and only if the provider supports the named extension. |
| 30 | func (er ExtensionsResult) IsExtensionAvailable(alias string) bool { |
| 31 | e, err := extensions(er) |
| 32 | if err != nil { |
| 33 | return false |
Samuel A. Falvo II | 8a549ef | 2014-01-24 15:20:54 -0800 | [diff] [blame] | 34 | } |
Samuel A. Falvo II | 2b96321 | 2014-02-09 02:12:30 -0800 | [diff] [blame^] | 35 | _, err = extensionIndexByAlias(e, alias) |
Samuel A. Falvo II | 8a549ef | 2014-01-24 15:20:54 -0800 | [diff] [blame] | 36 | return err == nil |
| 37 | } |
| 38 | |
Samuel A. Falvo II | 2b96321 | 2014-02-09 02:12:30 -0800 | [diff] [blame^] | 39 | // ExtensionDetailsByAlias returns more detail than the mere presence of an extension by the provider. |
| 40 | // See the ExtensionDetails structure. |
| 41 | func (er ExtensionsResult) ExtensionDetailsByAlias(alias string) (*ExtensionDetails, error) { |
| 42 | e, err := extensions(er) |
| 43 | if err != nil { |
| 44 | return nil, err |
| 45 | } |
Samuel A. Falvo II | 8a549ef | 2014-01-24 15:20:54 -0800 | [diff] [blame] | 46 | i, err := extensionIndexByAlias(e, alias) |
| 47 | if err != nil { |
| 48 | return nil, err |
| 49 | } |
| 50 | ed := &ExtensionDetails{} |
Samuel A. Falvo II | 2b96321 | 2014-02-09 02:12:30 -0800 | [diff] [blame^] | 51 | err = mapstructure.Decode(e[i], ed) |
Samuel A. Falvo II | 8a549ef | 2014-01-24 15:20:54 -0800 | [diff] [blame] | 52 | return ed, err |
| 53 | } |
Samuel A. Falvo II | 2b96321 | 2014-02-09 02:12:30 -0800 | [diff] [blame^] | 54 | |
| 55 | func extensionIndexByAlias(records []interface{}, alias string) (int, error) { |
| 56 | for i, er := range records { |
| 57 | extensionRecord := er.(map[string]interface{}) |
| 58 | if extensionRecord["alias"] == alias { |
| 59 | return i, nil |
| 60 | } |
| 61 | } |
| 62 | return 0, ErrNotImplemented |
| 63 | } |
| 64 | |
| 65 | func extensions(er ExtensionsResult) ([]interface{}, error) { |
| 66 | e, ok := er["extensions"] |
| 67 | if !ok { |
| 68 | return nil, ErrNotImplemented |
| 69 | } |
| 70 | return e.([]interface{}), nil |
| 71 | } |
| 72 | |
| 73 | // Aliases returns the set of extension handles, or "aliases" as OpenStack calls them. |
| 74 | // These are not the names of the extensions, but rather opaque, symbolic monikers for their corresponding extension. |
| 75 | // Use the ExtensionDetailsByAlias() method to query more information for an extension if desired. |
| 76 | func (er ExtensionsResult) Aliases() ([]string, error) { |
| 77 | e, err := extensions(er) |
| 78 | if err != nil { |
| 79 | return nil, err |
| 80 | } |
| 81 | aliases := make([]string, len(e)) |
| 82 | for i, ex := range e { |
| 83 | ext := ex.(map[string]interface{}) |
| 84 | extn, ok := ext["alias"] |
| 85 | if ok { |
| 86 | aliases[i] = extn.(string) |
| 87 | } |
| 88 | } |
| 89 | return aliases, nil |
| 90 | } |