// ExtractToken returns the just-created Token from a CreateResult. func (result CreateResult) 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"` Tenant tenants.Tenant `mapstructure:"tenant"` } `mapstructure:"token"` } `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, Tenant: response.Access.Token.Tenant, }, nil }
// ExtractToken interprets a commonResult as a Token. func (r commonResult) ExtractToken() (*Token, error) { if r.Err != nil { return nil, r.Err } var response struct { Token struct { ExpiresAt string `mapstructure:"expires_at"` } `mapstructure:"token"` } var token Token // Parse the token itself from the stored headers. token.ID = r.Header.Get("X-Subject-Token") err := mapstructure.Decode(r.Body, &response) if err != nil { return nil, err } // Attempt to parse the timestamp. token.ExpiresAt, err = time.Parse(gophercloud.RFC3339Milli, response.Token.ExpiresAt) return &token, err }
// ExtractVolumes extracts and returns Volumes. It is used while iterating over a volumes.List call. func ExtractVolumes(page pagination.Page) ([]Volume, error) { var response struct { Volumes []Volume `json:"volumes"` } err := mapstructure.Decode(page.(ListResult).Body, &response) return response.Volumes, err }
// ExtractSnapshots extracts and returns Snapshots. It is used while iterating over a snapshots.List call. func ExtractSnapshots(page pagination.Page) ([]Snapshot, error) { var response struct { Snapshots []Snapshot `json:"snapshots"` } err := mapstructure.Decode(page.(ListResult).Body, &response) return response.Snapshots, err }
// ExtractSubnets accepts a Page struct, specifically a SubnetPage struct, // and extracts the elements into a slice of Subnet structs. In other words, // a generic collection is mapped into a relevant slice. func ExtractSubnets(page pagination.Page) ([]Subnet, error) { var resp struct { Subnets []Subnet `mapstructure:"subnets" json:"subnets"` } err := mapstructure.Decode(page.(SubnetPage).Body, &resp) return resp.Subnets, err }
// ExtractImages converts a page of List results into a slice of usable Image structs. func ExtractImages(page pagination.Page) ([]Image, error) { casted := page.(ImagePage).Body var results struct { Images []Image `mapstructure:"images"` } err := mapstructure.Decode(casted, &results) return results.Images, err }
// ExtractPorts accepts a Page struct, specifically a PortPage struct, // and extracts the elements into a slice of Port structs. In other words, // a generic collection is mapped into a relevant slice. func ExtractPorts(page pagination.Page) ([]Port, error) { var resp struct { Ports []Port `mapstructure:"ports" json:"ports"` } err := mapstructure.Decode(page.(PortPage).Body, &resp) return resp.Ports, err }
// ExtractTenants returns a slice of Tenants contained in a single page of results. func ExtractTenants(page pagination.Page) ([]Tenant, error) { casted := page.(TenantPage).Body var response struct { Tenants []Tenant `mapstructure:"tenants"` } err := mapstructure.Decode(casted, &response) return response.Tenants, err }
// ExtractGroups accepts a Page struct, specifically a SecGroupPage struct, // and extracts the elements into a slice of SecGroup structs. In other words, // a generic collection is mapped into a relevant slice. func ExtractGroups(page pagination.Page) ([]SecGroup, error) { var resp struct { SecGroups []SecGroup `mapstructure:"security_groups" json:"security_groups"` } err := mapstructure.Decode(page.(SecGroupPage).Body, &resp) return resp.SecGroups, err }
// ExtractNetworks accepts a Page struct, specifically a NetworkPage struct, // and extracts the elements into a slice of Network structs. In other words, // a generic collection is mapped into a relevant slice. func ExtractNetworks(page pagination.Page) ([]Network, error) { var resp struct { Networks []Network `mapstructure:"networks" json:"networks"` } err := mapstructure.Decode(page.(NetworkPage).Body, &resp) return resp.Networks, err }
// ExtractInfo is a function that takes a page of objects and returns their full information. func ExtractInfo(page pagination.Page) ([]Object, error) { untyped := page.(ObjectPage).Body.([]interface{}) results := make([]Object, len(untyped)) for index, each := range untyped { object := each.(map[string]interface{}) err := mapstructure.Decode(object, &results[index]) if err != nil { return results, err } } return results, nil }
// Extract interprets any MetadatumResult as a Metadatum, if possible. func (r MetadatumResult) Extract() (map[string]string, error) { if r.Err != nil { return nil, r.Err } var response struct { Metadatum map[string]string `mapstructure:"meta"` } err := mapstructure.Decode(r.Body, &response) return response.Metadatum, err }
// Extract interprets any RescueResult as an AdminPass, if possible. func (r RescueResult) Extract() (string, error) { if r.Err != nil { return "", r.Err } var response struct { AdminPass string `mapstructure:"adminPass"` } err := mapstructure.Decode(r.Body, &response) return response.AdminPass, err }
// Extract is a method that attempts to interpret any VolumeAttachment resource // response as a VolumeAttachment struct. func (r VolumeAttachmentResult) Extract() (*VolumeAttachment, error) { if r.Err != nil { return nil, r.Err } var res struct { VolumeAttachment *VolumeAttachment `json:"volumeAttachment" mapstructure:"volumeAttachment"` } err := mapstructure.Decode(r.Body, &res) return res.VolumeAttachment, err }
// Extract is a method that attempts to interpret any KeyPair resource response as a KeyPair struct. func (r keyPairResult) Extract() (*KeyPair, error) { if r.Err != nil { return nil, r.Err } var res struct { KeyPair *KeyPair `json:"keypair" mapstructure:"keypair"` } err := mapstructure.Decode(r.Body, &res) return res.KeyPair, err }
func ExtractLinkedInts(page Page) ([]int, error) { var response struct { Ints []int `mapstructure:"ints"` } err := mapstructure.Decode(page.(LinkedPageResult).Body, &response) if err != nil { return nil, err } return response.Ints, nil }
// Extract interprets a GetResult as an Image. func (gr GetResult) Extract() (*Image, error) { if gr.Err != nil { return nil, gr.Err } var decoded struct { Image Image `mapstructure:"image"` } err := mapstructure.Decode(gr.Body, &decoded) return &decoded.Image, err }
// NextPageURL is invoked when a paginated collection of networks has reached // the end of a page and the pager seeks to traverse over a new one. In order // to do this, it needs to construct the next page's URL. func (p NetworkPage) NextPageURL() (string, error) { type resp struct { Links []gophercloud.Link `mapstructure:"networks_links"` } var r resp err := mapstructure.Decode(p.Body, &r) if err != nil { return "", err } return gophercloud.ExtractNextURL(r.Links) }
// Extract will get the Snapshot object out of the commonResult object. func (r commonResult) Extract() (*Snapshot, error) { if r.Err != nil { return nil, r.Err } var res struct { Snapshot *Snapshot `json:"snapshot"` } err := mapstructure.Decode(r.Body, &res) return res.Snapshot, err }
// Extract will get the Volume object out of the commonResult object. func (r commonResult) Extract() (*Volume, error) { if r.Err != nil { return nil, r.Err } var res struct { Volume *Volume `json:"volume"` } err := mapstructure.Decode(r.Body, &res) return res.Volume, err }
// Extract is a function that accepts a result and extracts a network resource. func (r commonResult) Extract() (*Network, error) { if r.Err != nil { return nil, r.Err } var res struct { Network *Network `json:"network"` } err := mapstructure.Decode(r.Body, &res) return res.Network, err }
// Extract is a function that accepts a result and extracts a port resource. func (r commonResult) Extract() (*Port, error) { if r.Err != nil { return nil, r.Err } var res struct { Port *Port `json:"port"` } err := mapstructure.Decode(r.Body, &res) return res.Port, err }
// Extract is a function that accepts a result and extracts a security group. func (r commonResult) Extract() (*SecGroup, error) { if r.Err != nil { return nil, r.Err } var res struct { SecGroup *SecGroup `mapstructure:"security_group" json:"security_group"` } err := mapstructure.Decode(r.Body, &res) return res.SecGroup, err }
// ExtractAddresses interprets the results of a single page from a ListAddresses() call, // producing a map of addresses. func ExtractAddresses(page pagination.Page) (map[string][]Address, error) { casted := page.(AddressPage).Body var response struct { Addresses map[string][]Address `mapstructure:"addresses"` } err := mapstructure.Decode(casted, &response) if err != nil { return nil, err } return response.Addresses, err }
func commonExtract(result gophercloud.Result) (*DiskConfig, error) { var resp struct { Server struct { DiskConfig string `mapstructure:"OS-DCF:diskConfig"` } `mapstructure:"server"` } err := mapstructure.Decode(result.Body, &resp) if err != nil { return nil, err } config := DiskConfig(resp.Server.DiskConfig) return &config, nil }
// ExtractNetworkAddresses interprets the results of a single page from a ListAddressesByNetwork() call, // producing a slice of addresses. func ExtractNetworkAddresses(page pagination.Page) ([]Address, error) { casted := page.(NetworkAddressPage).Body var response map[string][]Address err := mapstructure.Decode(casted, &response) if err != nil { return nil, err } var key string for k := range response { key = k } return response[key], err }
// ExtractKeyPairs interprets a page of results as a slice of KeyPairs. func ExtractKeyPairs(page pagination.Page) ([]KeyPair, error) { type pair struct { KeyPair KeyPair `mapstructure:"keypair"` } var resp struct { KeyPairs []pair `mapstructure:"keypairs"` } err := mapstructure.Decode(page.(KeyPairPage).Body, &resp) results := make([]KeyPair, len(resp.KeyPairs)) for i, pair := range resp.KeyPairs { results[i] = pair.KeyPair } return results, err }
// 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 }
// ExtractDiskConfig returns the DiskConfig setting for a specific server acquired from an // servers.ExtractServers call, while iterating through a Pager. func ExtractDiskConfig(page pagination.Page, index int) (*DiskConfig, error) { casted := page.(servers.ServerPage).Body type server struct { DiskConfig string `mapstructure:"OS-DCF:diskConfig"` } var response struct { Servers []server `mapstructure:"servers"` } err := mapstructure.Decode(casted, &response) if err != nil { return nil, err } config := DiskConfig(response.Servers[index].DiskConfig) return &config, nil }