1package flavors 2 3import ( 4 "encoding/json" 5 "strconv" 6 7 "github.com/gophercloud/gophercloud" 8 "github.com/gophercloud/gophercloud/pagination" 9) 10 11type commonResult struct { 12 gophercloud.Result 13} 14 15// CreateResult is the response of a Get operations. Call its Extract method to 16// interpret it as a Flavor. 17type CreateResult struct { 18 commonResult 19} 20 21// GetResult is the response of a Get operations. Call its Extract method to 22// interpret it as a Flavor. 23type GetResult struct { 24 commonResult 25} 26 27// DeleteResult is the result from a Delete operation. Call its ExtractErr 28// method to determine if the call succeeded or failed. 29type DeleteResult struct { 30 gophercloud.ErrResult 31} 32 33// Extract provides access to the individual Flavor returned by the Get and 34// Create functions. 35func (r commonResult) Extract() (*Flavor, error) { 36 var s struct { 37 Flavor *Flavor `json:"flavor"` 38 } 39 err := r.ExtractInto(&s) 40 return s.Flavor, err 41} 42 43// Flavor represent (virtual) hardware configurations for server resources 44// in a region. 45type Flavor struct { 46 // ID is the flavor's unique ID. 47 ID string `json:"id"` 48 49 // Disk is the amount of root disk, measured in GB. 50 Disk int `json:"disk"` 51 52 // RAM is the amount of memory, measured in MB. 53 RAM int `json:"ram"` 54 55 // Name is the name of the flavor. 56 Name string `json:"name"` 57 58 // RxTxFactor describes bandwidth alterations of the flavor. 59 RxTxFactor float64 `json:"rxtx_factor"` 60 61 // Swap is the amount of swap space, measured in MB. 62 Swap int `json:"-"` 63 64 // VCPUs indicates how many (virtual) CPUs are available for this flavor. 65 VCPUs int `json:"vcpus"` 66 67 // IsPublic indicates whether the flavor is public. 68 IsPublic bool `json:"os-flavor-access:is_public"` 69 70 // Ephemeral is the amount of ephemeral disk space, measured in GB. 71 Ephemeral int `json:"OS-FLV-EXT-DATA:ephemeral"` 72} 73 74func (r *Flavor) UnmarshalJSON(b []byte) error { 75 type tmp Flavor 76 var s struct { 77 tmp 78 Swap interface{} `json:"swap"` 79 } 80 err := json.Unmarshal(b, &s) 81 if err != nil { 82 return err 83 } 84 85 *r = Flavor(s.tmp) 86 87 switch t := s.Swap.(type) { 88 case float64: 89 r.Swap = int(t) 90 case string: 91 switch t { 92 case "": 93 r.Swap = 0 94 default: 95 swap, err := strconv.ParseFloat(t, 64) 96 if err != nil { 97 return err 98 } 99 r.Swap = int(swap) 100 } 101 } 102 103 return nil 104} 105 106// FlavorPage contains a single page of all flavors from a ListDetails call. 107type FlavorPage struct { 108 pagination.LinkedPageBase 109} 110 111// IsEmpty determines if a FlavorPage contains any results. 112func (page FlavorPage) IsEmpty() (bool, error) { 113 flavors, err := ExtractFlavors(page) 114 return len(flavors) == 0, err 115} 116 117// NextPageURL uses the response's embedded link reference to navigate to the 118// next page of results. 119func (page FlavorPage) NextPageURL() (string, error) { 120 var s struct { 121 Links []gophercloud.Link `json:"flavors_links"` 122 } 123 err := page.ExtractInto(&s) 124 if err != nil { 125 return "", err 126 } 127 return gophercloud.ExtractNextURL(s.Links) 128} 129 130// ExtractFlavors provides access to the list of flavors in a page acquired 131// from the ListDetail operation. 132func ExtractFlavors(r pagination.Page) ([]Flavor, error) { 133 var s struct { 134 Flavors []Flavor `json:"flavors"` 135 } 136 err := (r.(FlavorPage)).ExtractInto(&s) 137 return s.Flavors, err 138} 139 140// AccessPage contains a single page of all FlavorAccess entries for a flavor. 141type AccessPage struct { 142 pagination.SinglePageBase 143} 144 145// IsEmpty indicates whether an AccessPage is empty. 146func (page AccessPage) IsEmpty() (bool, error) { 147 v, err := ExtractAccesses(page) 148 return len(v) == 0, err 149} 150 151// ExtractAccesses interprets a page of results as a slice of FlavorAccess. 152func ExtractAccesses(r pagination.Page) ([]FlavorAccess, error) { 153 var s struct { 154 FlavorAccesses []FlavorAccess `json:"flavor_access"` 155 } 156 err := (r.(AccessPage)).ExtractInto(&s) 157 return s.FlavorAccesses, err 158} 159 160type accessResult struct { 161 gophercloud.Result 162} 163 164// AddAccessResult is the response of an AddAccess operation. Call its 165// Extract method to interpret it as a slice of FlavorAccess. 166type AddAccessResult struct { 167 accessResult 168} 169 170// RemoveAccessResult is the response of a RemoveAccess operation. Call its 171// Extract method to interpret it as a slice of FlavorAccess. 172type RemoveAccessResult struct { 173 accessResult 174} 175 176// Extract provides access to the result of an access create or delete. 177// The result will be all accesses that the flavor has. 178func (r accessResult) Extract() ([]FlavorAccess, error) { 179 var s struct { 180 FlavorAccesses []FlavorAccess `json:"flavor_access"` 181 } 182 err := r.ExtractInto(&s) 183 return s.FlavorAccesses, err 184} 185 186// FlavorAccess represents an ACL of tenant access to a specific Flavor. 187type FlavorAccess struct { 188 // FlavorID is the unique ID of the flavor. 189 FlavorID string `json:"flavor_id"` 190 191 // TenantID is the unique ID of the tenant. 192 TenantID string `json:"tenant_id"` 193} 194 195// Extract interprets any extraSpecsResult as ExtraSpecs, if possible. 196func (r extraSpecsResult) Extract() (map[string]string, error) { 197 var s struct { 198 ExtraSpecs map[string]string `json:"extra_specs"` 199 } 200 err := r.ExtractInto(&s) 201 return s.ExtraSpecs, err 202} 203 204// extraSpecsResult contains the result of a call for (potentially) multiple 205// key-value pairs. Call its Extract method to interpret it as a 206// map[string]interface. 207type extraSpecsResult struct { 208 gophercloud.Result 209} 210 211// ListExtraSpecsResult contains the result of a Get operation. Call its Extract 212// method to interpret it as a map[string]interface. 213type ListExtraSpecsResult struct { 214 extraSpecsResult 215} 216 217// CreateExtraSpecResult contains the result of a Create operation. Call its 218// Extract method to interpret it as a map[string]interface. 219type CreateExtraSpecsResult struct { 220 extraSpecsResult 221} 222 223// extraSpecResult contains the result of a call for individual a single 224// key-value pair. 225type extraSpecResult struct { 226 gophercloud.Result 227} 228 229// GetExtraSpecResult contains the result of a Get operation. Call its Extract 230// method to interpret it as a map[string]interface. 231type GetExtraSpecResult struct { 232 extraSpecResult 233} 234 235// UpdateExtraSpecResult contains the result of an Update operation. Call its 236// Extract method to interpret it as a map[string]interface. 237type UpdateExtraSpecResult struct { 238 extraSpecResult 239} 240 241// DeleteExtraSpecResult contains the result of a Delete operation. Call its 242// ExtractErr method to determine if the call succeeded or failed. 243type DeleteExtraSpecResult struct { 244 gophercloud.ErrResult 245} 246 247// Extract interprets any extraSpecResult as an ExtraSpec, if possible. 248func (r extraSpecResult) Extract() (map[string]string, error) { 249 var s map[string]string 250 err := r.ExtractInto(&s) 251 return s, err 252} 253