blob: 7ecd9c61a5e01e3d9cb354456247b8c606b60b9f [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 }
Ildar Svetlovde934122018-11-02 17:34:39 +0400115 if len(tmpb) > 0 {
116 err = json.Unmarshal(tmpb, &r.CPUInfo)
117 if err != nil {
118 return err
119 }
Simon Murraya9d5de42016-11-03 15:06:44 +0000120 }
121
122 // These fields may be passed in in scientific notation
123 switch t := s.HypervisorVersion.(type) {
124 case int:
125 r.HypervisorVersion = t
126 case float64:
127 r.HypervisorVersion = int(t)
Ildar Svetlov1f6dbd02019-04-29 15:39:25 +0400128 case nil:
129 r.HypervisorVersion = 0
Simon Murraya9d5de42016-11-03 15:06:44 +0000130 default:
131 return fmt.Errorf("Hypervisor version of unexpected type")
132 }
133
134 switch t := s.FreeDiskGB.(type) {
135 case int:
136 r.FreeDiskGB = t
137 case float64:
138 r.FreeDiskGB = int(t)
Ildar Svetlov1f6dbd02019-04-29 15:39:25 +0400139 case nil:
140 r.FreeDiskGB = 0
Simon Murraya9d5de42016-11-03 15:06:44 +0000141 default:
142 return fmt.Errorf("Free disk GB of unexpected type")
143 }
144
145 switch t := s.LocalGB.(type) {
146 case int:
147 r.LocalGB = t
148 case float64:
149 r.LocalGB = int(t)
Ildar Svetlov1f6dbd02019-04-29 15:39:25 +0400150 case nil:
151 r.LocalGB = 0
Simon Murraya9d5de42016-11-03 15:06:44 +0000152 default:
153 return fmt.Errorf("Local GB of unexpected type")
154 }
155
156 return nil
157}
158
159type HypervisorPage struct {
160 pagination.SinglePageBase
161}
162
163func (page HypervisorPage) IsEmpty() (bool, error) {
Krzysztof Szukiełojć2f616852017-05-12 16:24:00 +0200164 va, err := ExtractHypervisors(page)
165 return len(va) == 0, err
Simon Murraya9d5de42016-11-03 15:06:44 +0000166}
167
168func ExtractHypervisors(p pagination.Page) ([]Hypervisor, error) {
169 var h struct {
170 Hypervisors []Hypervisor `json:"hypervisors"`
171 }
172 err := (p.(HypervisorPage)).ExtractInto(&h)
173 return h.Hypervisors, err
174}
175
176func ExtractAggregates(p pagination.Page) ([]Aggregate, error) {
177 var h struct {
178 Aggregates []Aggregate `json:"aggregates"`
179 }
Simon Murraya9d5de42016-11-03 15:06:44 +0000180 err := (p.(AggregatePage)).ExtractInto(&h)
181 return h.Aggregates, err
182}
183
184type AggregatePage struct {
Krzysztof Szukiełojć2f616852017-05-12 16:24:00 +0200185 pagination.SinglePageBase
Simon Murraya9d5de42016-11-03 15:06:44 +0000186}