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