github.com/gophercloud/gophercloud@v1.11.0/openstack/compute/v2/extensions/hypervisors/results.go (about) 1 package hypervisors 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "strconv" 7 8 "github.com/gophercloud/gophercloud" 9 "github.com/gophercloud/gophercloud/pagination" 10 ) 11 12 // Topology represents a CPU Topology. 13 type Topology struct { 14 Sockets int `json:"sockets"` 15 Cores int `json:"cores"` 16 Threads int `json:"threads"` 17 } 18 19 // CPUInfo represents CPU information of the hypervisor. 20 type CPUInfo struct { 21 Vendor string `json:"vendor"` 22 Arch string `json:"arch"` 23 Model string `json:"model"` 24 Features []string `json:"features"` 25 Topology Topology `json:"topology"` 26 } 27 28 // Service represents a Compute service running on the hypervisor. 29 type Service struct { 30 Host string `json:"host"` 31 ID string `json:"-"` 32 DisabledReason string `json:"disabled_reason"` 33 } 34 35 func (r *Service) UnmarshalJSON(b []byte) error { 36 type tmp Service 37 var s struct { 38 tmp 39 ID interface{} `json:"id"` 40 } 41 42 err := json.Unmarshal(b, &s) 43 if err != nil { 44 return err 45 } 46 47 *r = Service(s.tmp) 48 49 // OpenStack Compute service returns ID in string representation since 50 // 2.53 microversion API (Pike release). 51 switch t := s.ID.(type) { 52 case int: 53 r.ID = strconv.Itoa(t) 54 case float64: 55 r.ID = strconv.Itoa(int(t)) 56 case string: 57 r.ID = t 58 default: 59 return fmt.Errorf("ID has unexpected type: %T", t) 60 } 61 62 return nil 63 } 64 65 // Server represents an instance running on the hypervisor 66 type Server struct { 67 Name string `json:"name"` 68 UUID string `json:"uuid"` 69 } 70 71 // Hypervisor represents a hypervisor in the OpenStack cloud. 72 type Hypervisor struct { 73 // A structure that contains cpu information like arch, model, vendor, 74 // features and topology. 75 CPUInfo CPUInfo `json:"-"` 76 77 // The current_workload is the number of tasks the hypervisor is responsible 78 // for. This will be equal or greater than the number of active VMs on the 79 // system (it can be greater when VMs are being deleted and the hypervisor is 80 // still cleaning up). 81 CurrentWorkload int `json:"current_workload"` 82 83 // Status of the hypervisor, either "enabled" or "disabled". 84 Status string `json:"status"` 85 86 // State of the hypervisor, either "up" or "down". 87 State string `json:"state"` 88 89 // DiskAvailableLeast is the actual free disk on this hypervisor, 90 // measured in GB. 91 DiskAvailableLeast int `json:"disk_available_least"` 92 93 // HostIP is the hypervisor's IP address. 94 HostIP string `json:"host_ip"` 95 96 // FreeDiskGB is the free disk remaining on the hypervisor, measured in GB. 97 FreeDiskGB int `json:"-"` 98 99 // FreeRAMMB is the free RAM in the hypervisor, measured in MB. 100 FreeRamMB int `json:"free_ram_mb"` 101 102 // HypervisorHostname is the hostname of the hypervisor. 103 HypervisorHostname string `json:"hypervisor_hostname"` 104 105 // HypervisorType is the type of hypervisor. 106 HypervisorType string `json:"hypervisor_type"` 107 108 // HypervisorVersion is the version of the hypervisor. 109 HypervisorVersion int `json:"-"` 110 111 // ID is the unique ID of the hypervisor. 112 ID string `json:"-"` 113 114 // LocalGB is the disk space in the hypervisor, measured in GB. 115 LocalGB int `json:"-"` 116 117 // LocalGBUsed is the used disk space of the hypervisor, measured in GB. 118 LocalGBUsed int `json:"local_gb_used"` 119 120 // MemoryMB is the total memory of the hypervisor, measured in MB. 121 MemoryMB int `json:"memory_mb"` 122 123 // MemoryMBUsed is the used memory of the hypervisor, measured in MB. 124 MemoryMBUsed int `json:"memory_mb_used"` 125 126 // RunningVMs is the The number of running vms on the hypervisor. 127 RunningVMs int `json:"running_vms"` 128 129 // Service is the service this hypervisor represents. 130 Service Service `json:"service"` 131 132 // Servers is a list of Server object. 133 // The requires microversion 2.53 or later. 134 Servers *[]Server `json:"servers"` 135 136 // VCPUs is the total number of vcpus on the hypervisor. 137 VCPUs int `json:"vcpus"` 138 139 // VCPUsUsed is the number of used vcpus on the hypervisor. 140 VCPUsUsed int `json:"vcpus_used"` 141 } 142 143 func (r *Hypervisor) UnmarshalJSON(b []byte) error { 144 type tmp Hypervisor 145 var s struct { 146 tmp 147 ID interface{} `json:"id"` 148 CPUInfo interface{} `json:"cpu_info"` 149 HypervisorVersion interface{} `json:"hypervisor_version"` 150 FreeDiskGB interface{} `json:"free_disk_gb"` 151 LocalGB interface{} `json:"local_gb"` 152 } 153 154 err := json.Unmarshal(b, &s) 155 if err != nil { 156 return err 157 } 158 159 *r = Hypervisor(s.tmp) 160 161 // Newer versions return the CPU info as the correct type. 162 // Older versions return the CPU info as a string and need to be 163 // unmarshalled by the json parser. 164 var tmpb []byte 165 166 switch t := s.CPUInfo.(type) { 167 case string: 168 tmpb = []byte(t) 169 case map[string]interface{}: 170 tmpb, err = json.Marshal(t) 171 if err != nil { 172 return err 173 } 174 default: 175 return fmt.Errorf("CPUInfo has unexpected type: %T", t) 176 } 177 178 if len(tmpb) != 0 { 179 err = json.Unmarshal(tmpb, &r.CPUInfo) 180 if err != nil { 181 return err 182 } 183 } 184 185 // These fields may be returned as a scientific notation, so they need 186 // converted to int. 187 switch t := s.HypervisorVersion.(type) { 188 case int: 189 r.HypervisorVersion = t 190 case float64: 191 r.HypervisorVersion = int(t) 192 default: 193 return fmt.Errorf("Hypervisor version has unexpected type: %T", t) 194 } 195 196 switch t := s.FreeDiskGB.(type) { 197 case int: 198 r.FreeDiskGB = t 199 case float64: 200 r.FreeDiskGB = int(t) 201 default: 202 return fmt.Errorf("Free disk GB has unexpected type: %T", t) 203 } 204 205 switch t := s.LocalGB.(type) { 206 case int: 207 r.LocalGB = t 208 case float64: 209 r.LocalGB = int(t) 210 default: 211 return fmt.Errorf("Local GB has unexpected type: %T", t) 212 } 213 214 // OpenStack Compute service returns ID in string representation since 215 // 2.53 microversion API (Pike release). 216 switch t := s.ID.(type) { 217 case int: 218 r.ID = strconv.Itoa(t) 219 case float64: 220 r.ID = strconv.Itoa(int(t)) 221 case string: 222 r.ID = t 223 default: 224 return fmt.Errorf("ID has unexpected type: %T", t) 225 } 226 227 return nil 228 } 229 230 // HypervisorPage represents a single page of all Hypervisors from a List 231 // request. 232 type HypervisorPage struct { 233 pagination.SinglePageBase 234 } 235 236 // IsEmpty determines whether or not a HypervisorPage is empty. 237 func (page HypervisorPage) IsEmpty() (bool, error) { 238 if page.StatusCode == 204 { 239 return true, nil 240 } 241 242 va, err := ExtractHypervisors(page) 243 return len(va) == 0, err 244 } 245 246 // ExtractHypervisors interprets a page of results as a slice of Hypervisors. 247 func ExtractHypervisors(p pagination.Page) ([]Hypervisor, error) { 248 var h struct { 249 Hypervisors []Hypervisor `json:"hypervisors"` 250 } 251 err := (p.(HypervisorPage)).ExtractInto(&h) 252 return h.Hypervisors, err 253 } 254 255 type HypervisorResult struct { 256 gophercloud.Result 257 } 258 259 // Extract interprets any HypervisorResult as a Hypervisor, if possible. 260 func (r HypervisorResult) Extract() (*Hypervisor, error) { 261 var s struct { 262 Hypervisor Hypervisor `json:"hypervisor"` 263 } 264 err := r.ExtractInto(&s) 265 return &s.Hypervisor, err 266 } 267 268 // Statistics represents a summary statistics for all enabled 269 // hypervisors over all compute nodes in the OpenStack cloud. 270 type Statistics struct { 271 // The number of hypervisors. 272 Count int `json:"count"` 273 274 // The current_workload is the number of tasks the hypervisor is responsible for 275 CurrentWorkload int `json:"current_workload"` 276 277 // The actual free disk on this hypervisor(in GB). 278 DiskAvailableLeast int `json:"disk_available_least"` 279 280 // The free disk remaining on this hypervisor(in GB). 281 FreeDiskGB int `json:"free_disk_gb"` 282 283 // The free RAM in this hypervisor(in MB). 284 FreeRamMB int `json:"free_ram_mb"` 285 286 // The disk in this hypervisor(in GB). 287 LocalGB int `json:"local_gb"` 288 289 // The disk used in this hypervisor(in GB). 290 LocalGBUsed int `json:"local_gb_used"` 291 292 // The memory of this hypervisor(in MB). 293 MemoryMB int `json:"memory_mb"` 294 295 // The memory used in this hypervisor(in MB). 296 MemoryMBUsed int `json:"memory_mb_used"` 297 298 // The total number of running vms on all hypervisors. 299 RunningVMs int `json:"running_vms"` 300 301 // The number of vcpu in this hypervisor. 302 VCPUs int `json:"vcpus"` 303 304 // The number of vcpu used in this hypervisor. 305 VCPUsUsed int `json:"vcpus_used"` 306 } 307 308 type StatisticsResult struct { 309 gophercloud.Result 310 } 311 312 // Extract interprets any StatisticsResult as a Statistics, if possible. 313 func (r StatisticsResult) Extract() (*Statistics, error) { 314 var s struct { 315 Stats Statistics `json:"hypervisor_statistics"` 316 } 317 err := r.ExtractInto(&s) 318 return &s.Stats, err 319 } 320 321 // Uptime represents uptime and additional info for a specific hypervisor. 322 type Uptime struct { 323 // The hypervisor host name provided by the Nova virt driver. 324 // For the Ironic driver, it is the Ironic node uuid. 325 HypervisorHostname string `json:"hypervisor_hostname"` 326 327 // The id of the hypervisor. 328 ID string `json:"-"` 329 330 // The state of the hypervisor. One of up or down. 331 State string `json:"state"` 332 333 // The status of the hypervisor. One of enabled or disabled. 334 Status string `json:"status"` 335 336 // The total uptime of the hypervisor and information about average load. 337 Uptime string `json:"uptime"` 338 } 339 340 func (r *Uptime) UnmarshalJSON(b []byte) error { 341 type tmp Uptime 342 var s struct { 343 tmp 344 ID interface{} `json:"id"` 345 } 346 347 err := json.Unmarshal(b, &s) 348 if err != nil { 349 return err 350 } 351 352 *r = Uptime(s.tmp) 353 354 // OpenStack Compute service returns ID in string representation since 355 // 2.53 microversion API (Pike release). 356 switch t := s.ID.(type) { 357 case int: 358 r.ID = strconv.Itoa(t) 359 case float64: 360 r.ID = strconv.Itoa(int(t)) 361 case string: 362 r.ID = t 363 default: 364 return fmt.Errorf("ID has unexpected type: %T", t) 365 } 366 367 return nil 368 } 369 370 type UptimeResult struct { 371 gophercloud.Result 372 } 373 374 // Extract interprets any UptimeResult as a Uptime, if possible. 375 func (r UptimeResult) Extract() (*Uptime, error) { 376 var s struct { 377 Uptime Uptime `json:"hypervisor"` 378 } 379 err := r.ExtractInto(&s) 380 return &s.Uptime, err 381 }