blob: 46638cb4d79259cc6cae99da2c52955a76ffdea1 [file] [log] [blame]
Simon Murraya9d5de42016-11-03 15:06:44 +00001package hypervisors
2
3import (
4 "encoding/json"
5 "fmt"
Krzysztof Szukiełojć2f616852017-05-12 16:24:00 +02006
Krzysztof Szukiełojć24a29ce2017-05-07 14:24:02 +02007 "gerrit.mcp.mirantis.net/debian/gophercloud.git/pagination"
Simon Murraya9d5de42016-11-03 15:06:44 +00008)
9
10type Topology struct {
11 Sockets int `json:"sockets"`
12 Cores int `json:"cores"`
13 Threads int `json:"threads"`
14}
15
16type CPUInfo struct {
17 Vendor string `json:"vendor"`
18 Arch string `json:"arch"`
19 Model string `json:"model"`
20 Features []string `json:"features"`
21 Topology Topology `json:"topology"`
22}
23
24type Service struct {
25 Host string `json:"host"`
26 ID int `json:"id"`
27 DisabledReason string `json:"disabled_reason"`
28}
29
30type Hypervisor struct {
31 // A structure that contains cpu information like arch, model, vendor, features and topology
32 CPUInfo CPUInfo `json:"-"`
33 // The current_workload is the number of tasks the hypervisor is responsible for.
34 // This will be equal or greater than the number of active VMs on the system
35 // (it can be greater when VMs are being deleted and the hypervisor is still cleaning up).
36 CurrentWorkload int `json:"current_workload"`
37 // Status of the hypervisor, either "enabled" or "disabled"
38 Status string `json:"status"`
39 // State of the hypervisor, either "up" or "down"
40 State string `json:"state"`
41 // Actual free disk on this hypervisor in GB
42 DiskAvailableLeast int `json:"disk_available_least"`
43 // The hypervisor's IP address
44 HostIP string `json:"host_ip"`
45 // The free disk remaining on this hypervisor in GB
46 FreeDiskGB int `json:"-"`
47 // The free RAM in this hypervisor in MB
48 FreeRamMB int `json:"free_ram_mb"`
49 // The hypervisor host name
50 HypervisorHostname string `json:"hypervisor_hostname"`
51 // The hypervisor type
52 HypervisorType string `json:"hypervisor_type"`
53 // The hypervisor version
54 HypervisorVersion int `json:"-"`
55 // Unique ID of the hypervisor
56 ID int `json:"id"`
57 // The disk in this hypervisor in GB
58 LocalGB int `json:"-"`
59 // The disk used in this hypervisor in GB
60 LocalGBUsed int `json:"local_gb_used"`
61 // The memory of this hypervisor in MB
62 MemoryMB int `json:"memory_mb"`
63 // The memory used in this hypervisor in MB
64 MemoryMBUsed int `json:"memory_mb_used"`
65 // The number of running vms on this hypervisor
66 RunningVMs int `json:"running_vms"`
67 // The hypervisor service object
68 Service Service `json:"service"`
69 // The number of vcpu in this hypervisor
70 VCPUs int `json:"vcpus"`
71 // The number of vcpu used in this hypervisor
72 VCPUsUsed int `json:"vcpus_used"`
73}
74
Krzysztof Szukiełojć2f616852017-05-12 16:24:00 +020075type Aggregate struct {
76 Name string `json:name`
77 Hosts []string `json:hosts`
78 ID int `json:id`
Simon Murraya9d5de42016-11-03 15:06:44 +000079}
80
81func (r *Hypervisor) UnmarshalJSON(b []byte) error {
82
83 type tmp Hypervisor
84 var s *struct {
85 tmp
86 CPUInfo interface{} `json:"cpu_info"`
87 HypervisorVersion interface{} `json:"hypervisor_version"`
88 FreeDiskGB interface{} `json:"free_disk_gb"`
89 LocalGB interface{} `json:"local_gb"`
90 }
91
92 err := json.Unmarshal(b, &s)
93 if err != nil {
94 return err
95 }
96
97 *r = Hypervisor(s.tmp)
98
99 // Newer versions pass the CPU into around as the correct types, this just needs
100 // converting and copying into place. Older versions pass CPU info around as a string
101 // and can simply be unmarshalled by the json parser
Krzysztof Szukiełojć2f616852017-05-12 16:24:00 +0200102 var tmpb []byte
Simon Murraya9d5de42016-11-03 15:06:44 +0000103
104 switch t := s.CPUInfo.(type) {
105 case string:
106 tmpb = []byte(t)
107 case map[string]interface{}:
108 tmpb, err = json.Marshal(t)
109 if err != nil {
110 return err
111 }
112 default:
113 return fmt.Errorf("CPUInfo has unexpected type: %T", t)
114 }
115
116 err = json.Unmarshal(tmpb, &r.CPUInfo)
117 if err != nil {
118 return err
119 }
120
121 // These fields may be passed in in scientific notation
122 switch t := s.HypervisorVersion.(type) {
123 case int:
124 r.HypervisorVersion = t
125 case float64:
126 r.HypervisorVersion = int(t)
127 default:
128 return fmt.Errorf("Hypervisor version of unexpected type")
129 }
130
131 switch t := s.FreeDiskGB.(type) {
132 case int:
133 r.FreeDiskGB = t
134 case float64:
135 r.FreeDiskGB = int(t)
136 default:
137 return fmt.Errorf("Free disk GB of unexpected type")
138 }
139
140 switch t := s.LocalGB.(type) {
141 case int:
142 r.LocalGB = t
143 case float64:
144 r.LocalGB = int(t)
145 default:
146 return fmt.Errorf("Local GB of unexpected type")
147 }
148
149 return nil
150}
151
152type HypervisorPage struct {
153 pagination.SinglePageBase
154}
155
156func (page HypervisorPage) IsEmpty() (bool, error) {
Krzysztof Szukiełojć2f616852017-05-12 16:24:00 +0200157 va, err := ExtractHypervisors(page)
158 return len(va) == 0, err
Simon Murraya9d5de42016-11-03 15:06:44 +0000159}
160
161func ExtractHypervisors(p pagination.Page) ([]Hypervisor, error) {
162 var h struct {
163 Hypervisors []Hypervisor `json:"hypervisors"`
164 }
165 err := (p.(HypervisorPage)).ExtractInto(&h)
166 return h.Hypervisors, err
167}
168
169func ExtractAggregates(p pagination.Page) ([]Aggregate, error) {
170 var h struct {
171 Aggregates []Aggregate `json:"aggregates"`
172 }
Simon Murraya9d5de42016-11-03 15:06:44 +0000173 err := (p.(AggregatePage)).ExtractInto(&h)
174 return h.Aggregates, err
175}
176
177type AggregatePage struct {
Krzysztof Szukiełojć2f616852017-05-12 16:24:00 +0200178 pagination.SinglePageBase
Simon Murraya9d5de42016-11-03 15:06:44 +0000179}