/
results.go
183 lines (145 loc) · 5.31 KB
/
results.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
package usage
import (
"encoding/json"
"time"
"github.com/gophercloud/gophercloud"
"github.com/gophercloud/gophercloud/pagination"
)
// TenantUsage is a set of usage information about a tenant over the sampling window
type TenantUsage struct {
// ServerUsages is an array of ServerUsage maps
ServerUsages []ServerUsage `json:"server_usages"`
// Start is the beginning time to calculate usage statistics on compute and storage resources
Start time.Time `json:"-"`
// Stop is the ending time to calculate usage statistics on compute and storage resources
Stop time.Time `json:"-"`
// TenantID is the ID of the tenant whose usage is being reported on
TenantID string `json:"tenant_id"`
// TotalHours is the total duration that servers exist (in hours)
TotalHours float64 `json:"total_hours"`
// TotalLocalGBUsage multiplies the server disk size (in GiB) by hours the server exists, and then adding that all together for each server
TotalLocalGBUsage float64 `json:"total_local_gb_usage"`
// TotalMemoryMBUsage multiplies the server memory size (in MB) by hours the server exists, and then adding that all together for each server
TotalMemoryMBUsage float64 `json:"total_memory_mb_usage"`
// TotalVCPUsUsage multiplies the number of virtual CPUs of the server by hours the server exists, and then adding that all together for each server
TotalVCPUsUsage float64 `json:"total_vcpus_usage"`
}
// UnmarshalJSON sets *u to a copy of data.
func (u *TenantUsage) UnmarshalJSON(b []byte) error {
type tmp TenantUsage
var s struct {
tmp
Start gophercloud.JSONRFC3339MilliNoZ `json:"start"`
Stop gophercloud.JSONRFC3339MilliNoZ `json:"stop"`
}
if err := json.Unmarshal(b, &s); err != nil {
return err
}
*u = TenantUsage(s.tmp)
u.Start = time.Time(s.Start)
u.Stop = time.Time(s.Stop)
return nil
}
// ServerUsage is a detailed set of information about a specific instance inside a tenant
type ServerUsage struct {
// EndedAt is the date and time when the server was deleted
EndedAt time.Time `json:"-"`
// Flavor is the display name of a flavor
Flavor string `json:"flavor"`
// Hours is the duration that the server exists in hours
Hours float64 `json:"hours"`
// InstanceID is the UUID of the instance
InstanceID string `json:"instance_id"`
// LocalGB is the sum of the root disk size of the server and the ephemeral disk size of it (in GiB)
LocalGB int `json:"local_gb"`
// MemoryMB is the memory size of the server (in MB)
MemoryMB int `json:"memory_mb"`
// Name is the name assigned to the server when it was created
Name string `json:"name"`
// StartedAt is the date and time when the server was started
StartedAt time.Time `json:"-"`
// State is the VM power state
State string `json:"state"`
// TenantID is the UUID of the tenant in a multi-tenancy cloud
TenantID string `json:"tenant_id"`
// Uptime is the uptime of the server in seconds
Uptime int `json:"uptime"`
// VCPUs is the number of virtual CPUs that the server uses
VCPUs int `json:"vcpus"`
}
// UnmarshalJSON sets *u to a copy of data.
func (u *ServerUsage) UnmarshalJSON(b []byte) error {
type tmp ServerUsage
var s struct {
tmp
EndedAt gophercloud.JSONRFC3339MilliNoZ `json:"ended_at"`
StartedAt gophercloud.JSONRFC3339MilliNoZ `json:"started_at"`
}
if err := json.Unmarshal(b, &s); err != nil {
return err
}
*u = ServerUsage(s.tmp)
u.EndedAt = time.Time(s.EndedAt)
u.StartedAt = time.Time(s.StartedAt)
return nil
}
// SingleTenantPage stores a single, only page of TenantUsage results from a
// SingleTenant call.
type SingleTenantPage struct {
pagination.LinkedPageBase
}
// IsEmpty determines whether or not a SingleTenantPage is empty.
func (r SingleTenantPage) IsEmpty() (bool, error) {
ks, err := ExtractSingleTenant(r)
return ks == nil, err
}
// NextPageURL uses the response's embedded link reference to navigate to the
// next page of results.
func (r SingleTenantPage) NextPageURL() (string, error) {
var s struct {
Links []gophercloud.Link `json:"tenant_usage_links"`
}
err := r.ExtractInto(&s)
if err != nil {
return "", err
}
return gophercloud.ExtractNextURL(s.Links)
}
// ExtractSingleTenant interprets a SingleTenantPage as a TenantUsage result.
func ExtractSingleTenant(page pagination.Page) (*TenantUsage, error) {
var s struct {
TenantUsage *TenantUsage `json:"tenant_usage"`
}
err := (page.(SingleTenantPage)).ExtractInto(&s)
return s.TenantUsage, err
}
// AllTenantsPage stores a single, only page of TenantUsage results from a
// AllTenants call.
type AllTenantsPage struct {
pagination.LinkedPageBase
}
// ExtractAllTenants interprets a AllTenantsPage as a TenantUsage result.
func ExtractAllTenants(page pagination.Page) ([]TenantUsage, error) {
var s struct {
TenantUsages []TenantUsage `json:"tenant_usages"`
}
err := (page.(AllTenantsPage)).ExtractInto(&s)
return s.TenantUsages, err
}
// IsEmpty determines whether or not an AllTenantsPage is empty.
func (r AllTenantsPage) IsEmpty() (bool, error) {
usages, err := ExtractAllTenants(r)
return len(usages) == 0, err
}
// NextPageURL uses the response's embedded link reference to navigate to the
// next page of results.
func (r AllTenantsPage) NextPageURL() (string, error) {
var s struct {
Links []gophercloud.Link `json:"tenant_usages_links"`
}
err := r.ExtractInto(&s)
if err != nil {
return "", err
}
return gophercloud.ExtractNextURL(s.Links)
}