blob: 5c7041dea2b8ee1ef59c8aae017a4caac7b5543d [file] [log] [blame]
Simon Murraya9d5de42016-11-03 15:06:44 +00001package hypervisors
2
3import (
4 "encoding/json"
5 "fmt"
Krzysztof Szukiełojć24a29ce2017-05-07 14:24:02 +02006 "gerrit.mcp.mirantis.net/debian/gophercloud.git/pagination"
Simon Murraya9d5de42016-11-03 15:06:44 +00007)
8
9type Topology struct {
10 Sockets int `json:"sockets"`
11 Cores int `json:"cores"`
12 Threads int `json:"threads"`
13}
14
15type CPUInfo struct {
16 Vendor string `json:"vendor"`
17 Arch string `json:"arch"`
18 Model string `json:"model"`
19 Features []string `json:"features"`
20 Topology Topology `json:"topology"`
21}
22
23type Service struct {
24 Host string `json:"host"`
25 ID int `json:"id"`
26 DisabledReason string `json:"disabled_reason"`
27}
28
29type Hypervisor struct {
30 // A structure that contains cpu information like arch, model, vendor, features and topology
31 CPUInfo CPUInfo `json:"-"`
32 // The current_workload is the number of tasks the hypervisor is responsible for.
33 // This will be equal or greater than the number of active VMs on the system
34 // (it can be greater when VMs are being deleted and the hypervisor is still cleaning up).
35 CurrentWorkload int `json:"current_workload"`
36 // Status of the hypervisor, either "enabled" or "disabled"
37 Status string `json:"status"`
38 // State of the hypervisor, either "up" or "down"
39 State string `json:"state"`
40 // Actual free disk on this hypervisor in GB
41 DiskAvailableLeast int `json:"disk_available_least"`
42 // The hypervisor's IP address
43 HostIP string `json:"host_ip"`
44 // The free disk remaining on this hypervisor in GB
45 FreeDiskGB int `json:"-"`
46 // The free RAM in this hypervisor in MB
47 FreeRamMB int `json:"free_ram_mb"`
48 // The hypervisor host name
49 HypervisorHostname string `json:"hypervisor_hostname"`
50 // The hypervisor type
51 HypervisorType string `json:"hypervisor_type"`
52 // The hypervisor version
53 HypervisorVersion int `json:"-"`
54 // Unique ID of the hypervisor
55 ID int `json:"id"`
56 // The disk in this hypervisor in GB
57 LocalGB int `json:"-"`
58 // The disk used in this hypervisor in GB
59 LocalGBUsed int `json:"local_gb_used"`
60 // The memory of this hypervisor in MB
61 MemoryMB int `json:"memory_mb"`
62 // The memory used in this hypervisor in MB
63 MemoryMBUsed int `json:"memory_mb_used"`
64 // The number of running vms on this hypervisor
65 RunningVMs int `json:"running_vms"`
66 // The hypervisor service object
67 Service Service `json:"service"`
68 // The number of vcpu in this hypervisor
69 VCPUs int `json:"vcpus"`
70 // The number of vcpu used in this hypervisor
71 VCPUsUsed int `json:"vcpus_used"`
72}
73
74type Aggregate struct{
75 Name string `json:name`
76 Hosts []string `json:hosts`
77 ID int `json:id`
78
79}
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
102 var tmpb []byte;
103
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) {
157 va, err := ExtractHypervisors(page)
158 return len(va) == 0, err
159}
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 }
173 fmt.Printf("AA: %s\n", p)
174 err := (p.(AggregatePage)).ExtractInto(&h)
175 return h.Aggregates, err
176}
177
178type AggregatePage struct {
179 pagination.SinglePageBase
180}