// Extract returns a pointer to a Resource object and is called after a // Get operation. func (r GetResult) Extract() (*Resource, error) { if r.Err != nil { return nil, r.Err } var res struct { Res *Resource `mapstructure:"resource"` } if err := mapstructure.Decode(r.Body, &res); err != nil { return nil, err } resource := r.Body.(map[string]interface{})["resource"].(map[string]interface{}) if date, ok := resource["updated_time"]; ok && date != nil { t, err := time.Parse(time.RFC3339, date.(string)) if err != nil { return nil, err } res.Res.UpdatedTime = t } return res.Res, nil }
// Extract returns a slice of Event objects and is called after a // Find operation. func (r FindResult) Extract() ([]Event, error) { if r.Err != nil { return nil, r.Err } var res struct { Res []Event `mapstructure:"events"` } if err := mapstructure.Decode(r.Body, &res); err != nil { return nil, err } events := r.Body.(map[string]interface{})["events"].([]interface{}) for i, eventRaw := range events { event := eventRaw.(map[string]interface{}) if date, ok := event["event_time"]; ok && date != nil { t, err := time.Parse(time.RFC3339, date.(string)) if err != nil { return nil, err } res.Res[i].Time = t } } return res.Res, nil }
// ExtractEvents interprets the results of a single page from a List() call, producing a slice of Event entities. func ExtractEvents(page pagination.Page) ([]Event, error) { casted := page.(EventPage).Body var res struct { Res []Event `mapstructure:"events"` } if err := mapstructure.Decode(casted, &res); err != nil { return nil, err } var events []interface{} switch casted.(type) { case map[string]interface{}: events = casted.(map[string]interface{})["events"].([]interface{}) case map[string][]interface{}: events = casted.(map[string][]interface{})["events"] default: return res.Res, fmt.Errorf("Unknown type: %v", reflect.TypeOf(casted)) } for i, eventRaw := range events { event := eventRaw.(map[string]interface{}) if date, ok := event["event_time"]; ok && date != nil { t, err := time.Parse(time.RFC3339, date.(string)) if err != nil { return nil, err } res.Res[i].Time = t } } return res.Res, nil }
// Extract returns a pointer to an Event object and is called after a // Get operation. func (r GetResult) Extract() (*Event, error) { if r.Err != nil { return nil, r.Err } var res struct { Res *Event `mapstructure:"event"` } if err := mapstructure.Decode(r.Body, &res); err != nil { return nil, err } event := r.Body.(map[string]interface{})["event"].(map[string]interface{}) if date, ok := event["event_time"]; ok && date != nil { t, err := time.Parse(time.RFC3339, date.(string)) if err != nil { return nil, err } res.Res.Time = t } return res.Res, nil }
// Extract returns a slice of Resource objects and is called after a // Find operation. func (r FindResult) Extract() ([]Resource, error) { if r.Err != nil { return nil, r.Err } var res struct { Res []Resource `mapstructure:"resources"` } if err := mapstructure.Decode(r.Body, &res); err != nil { return nil, err } resources := r.Body.(map[string]interface{})["resources"].([]interface{}) for i, resourceRaw := range resources { resource := resourceRaw.(map[string]interface{}) if date, ok := resource["updated_time"]; ok && date != nil { t, err := time.Parse(time.RFC3339, date.(string)) if err != nil { return nil, err } res.Res[i].UpdatedTime = t } } return res.Res, nil }
// ExtractResources interprets the results of a single page from a List() call, producing a slice of Resource entities. func ExtractResources(page pagination.Page) ([]Resource, error) { casted := page.(ResourcePage).Body var response struct { Resources []Resource `mapstructure:"resources"` } err := mapstructure.Decode(casted, &response) var resources []interface{} switch casted.(type) { case map[string]interface{}: resources = casted.(map[string]interface{})["resources"].([]interface{}) case map[string][]interface{}: resources = casted.(map[string][]interface{})["resources"] default: return response.Resources, fmt.Errorf("Unknown type: %v", reflect.TypeOf(casted)) } for i, resourceRaw := range resources { resource := resourceRaw.(map[string]interface{}) if date, ok := resource["updated_time"]; ok && date != nil { t, err := time.Parse(time.RFC3339, date.(string)) if err != nil { return nil, err } response.Resources[i].UpdatedTime = t } } return response.Resources, err }
// 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 }
// 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 }
// 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 }
// ExtractResourceTypes extracts and returns resource types. func ExtractResourceTypes(page pagination.Page) ([]string, error) { var response struct { ResourceTypes []string `mapstructure:"resource_types"` } err := mapstructure.Decode(page.(ResourceTypePage).Body, &response) return response.ResourceTypes, 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 }
// 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 }
// ExtractAPIVersions takes a collection page, extracts all of the elements, // and returns them a slice of APIVersion structs. It is effectively a cast. func ExtractAPIVersions(page pagination.Page) ([]APIVersion, error) { var resp struct { Versions []APIVersion `mapstructure:"versions"` } err := mapstructure.Decode(page.(APIVersionPage).Body, &resp) return resp.Versions, err }
// ExtractRules accepts a Page struct, specifically a SecGroupRulePage struct, // and extracts the elements into a slice of SecGroupRule structs. In other words, // a generic collection is mapped into a relevant slice. func ExtractRules(page pagination.Page) ([]SecGroupRule, error) { var resp struct { SecGroupRules []SecGroupRule `mapstructure:"security_group_rules" json:"security_group_rules"` } err := mapstructure.Decode(page.(SecGroupRulePage).Body, &resp) return resp.SecGroupRules, 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 }
// 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 }
// 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 }
// 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 }
// 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 }
// Extract returns a pointer to a BuildInfo object and is called after a // Get operation. func (r GetResult) Extract() (*BuildInfo, error) { if r.Err != nil { return nil, r.Err } var res BuildInfo if err := mapstructure.Decode(r.Body, &res); err != nil { return nil, err } return &res, nil }
// Extract returns a pointer to a ValidatedTemplate object and is called after a // Validate operation. func (r ValidateResult) Extract() (*ValidatedTemplate, error) { if r.Err != nil { return nil, r.Err } var res ValidatedTemplate if err := mapstructure.Decode(r.Body, &res); err != nil { return nil, err } return &res, nil }
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 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 }
// 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 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 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 }
// 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 }
// 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 }
// NextPageURL uses the response's embedded link reference to navigate to the next page of results. func (p FlavorPage) NextPageURL() (string, error) { type resp struct { Links []gophercloud.Link `mapstructure:"flavors_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 }