blob: 132cf770a0fcdc3878528bf4da200c0cdc5a6dc9 [file] [log] [blame]
Jon Perrittb55847b2015-03-17 20:43:48 -06001package publicips
2
3import (
4 "fmt"
5 "reflect"
6 "time"
7
8 "github.com/mitchellh/mapstructure"
9 "github.com/rackspace/gophercloud"
10 "github.com/rackspace/gophercloud/pagination"
11)
12
13// PublicIP represents a public IP address.
14type PublicIP struct {
15 // The unique ID of the public IP.
16 ID string `mapstructure:"id"`
17 // The IPv4 address of the public IP.
18 PublicIPv4 string `mapstructure:"public_ip_v4"`
19 // The cloud server (node) of the public IP.
20 CloudServer struct {
21 // The cloud server ID.
22 ID string `mapstructure:"id"`
23 // The name of the server.
24 Name string `mapstructure:"name"`
25 // The cloud network for the cloud server.
26 CloudNetwork struct {
27 // The network ID.
28 ID string `mapstructure:"id"`
29 // The network name.
30 Name string `mapstructure:"name"`
31 // The network's private IPv4 address.
32 PrivateIPv4 string `mapstructure:"private_ip_v4"`
33 // The IP range for the network.
34 CIDR string `mapstructure:"cidr"`
35 // The datetime the network was created.
36 CreatedAt time.Time `mapstructure:"-"`
37 // The last datetime the network was updated.
38 UpdatedAt time.Time `mapstructure:"-"`
39 } `mapstructure:"cloud_network"`
40 // The datetime the server was created.
41 CreatedAt time.Time `mapstructure:"-"`
42 // The datetime the server was last updated.
43 UpdatedAt time.Time `mapstructure:"-"`
44 } `mapstructure:"cloud_server"`
45 // The status of the public IP.
46 Status string `mapstructure:"status"`
47 // The details of the status of the public IP.
48 StatusDetail string `mapstructure:"status_detail"`
49 // The time the public IP was created.
50 CreatedAt time.Time `mapstructure:"-"`
51 // The time the public IP was last updated.
52 UpdatedAt time.Time `mapstructure:"-"`
53}
54
55// PublicIPPage is the page returned by a pager when traversing over a
56// collection of PublicIPs.
57type PublicIPPage struct {
58 pagination.SinglePageBase
59}
60
61// IsEmpty returns true if a PublicIPPage contains no PublicIPs.
62func (r PublicIPPage) IsEmpty() (bool, error) {
63 n, err := ExtractPublicIPs(r)
64 if err != nil {
65 return true, err
66 }
67 return len(n) == 0, nil
68}
69
70// ExtractPublicIPs extracts and returns a slice of PublicIPs. It is used while iterating over
71// a publicips.List call.
72func ExtractPublicIPs(page pagination.Page) ([]PublicIP, error) {
73 var res []PublicIP
74 casted := page.(PublicIPPage).Body
75 err := mapstructure.Decode(casted, &res)
76
77 var rawNodesDetails []interface{}
78 switch casted.(type) {
79 case interface{}:
80 rawNodesDetails = casted.([]interface{})
81 default:
82 return res, fmt.Errorf("Unknown type: %v", reflect.TypeOf(casted))
83 }
84
85 for i := range rawNodesDetails {
86 thisNodeDetails := (rawNodesDetails[i]).(map[string]interface{})
87
88 if t, ok := thisNodeDetails["created"].(string); ok && t != "" {
89 creationTime, err := time.Parse(time.RFC3339, t)
90 if err != nil {
91 return res, err
92 }
93 res[i].CreatedAt = creationTime
94 }
95
96 if t, ok := thisNodeDetails["updated"].(string); ok && t != "" {
97 updatedTime, err := time.Parse(time.RFC3339, t)
98 if err != nil {
99 return res, err
100 }
101 res[i].UpdatedAt = updatedTime
102 }
103
104 if cs, ok := thisNodeDetails["cloud_server"].(map[string]interface{}); ok {
105 if t, ok := cs["created"].(string); ok && t != "" {
106 creationTime, err := time.Parse(time.RFC3339, t)
107 if err != nil {
108 return res, err
109 }
110 res[i].CloudServer.CreatedAt = creationTime
111 }
112 if t, ok := cs["updated"].(string); ok && t != "" {
113 updatedTime, err := time.Parse(time.RFC3339, t)
114 if err != nil {
115 return res, err
116 }
117 res[i].CloudServer.UpdatedAt = updatedTime
118 }
119 if cn, ok := cs["cloud_network"].(map[string]interface{}); ok {
120 if t, ok := cn["created"].(string); ok && t != "" {
121 creationTime, err := time.Parse(time.RFC3339, t)
122 if err != nil {
123 return res, err
124 }
125 res[i].CloudServer.CloudNetwork.CreatedAt = creationTime
126 }
127 if t, ok := cn["updated"].(string); ok && t != "" {
128 updatedTime, err := time.Parse(time.RFC3339, t)
129 if err != nil {
130 return res, err
131 }
132 res[i].CloudServer.CloudNetwork.UpdatedAt = updatedTime
133 }
134 }
135 }
136 }
137
138 return res, err
139}
140
141// PublicIPResult represents a result that can be extracted into a PublicIP.
142type PublicIPResult struct {
143 gophercloud.Result
144}
145
146// CreateResult represents the result of a Create operation.
147type CreateResult struct {
148 PublicIPResult
149}
150
151// GetResult represents the result of a Get operation.
152type GetResult struct {
153 PublicIPResult
154}
155
156// Extract is a function that extracts a PublicIP from a PublicIPResult.
157func (r PublicIPResult) Extract() (*PublicIP, error) {
158 if r.Err != nil {
159 return nil, r.Err
160 }
161 var res PublicIP
162 err := mapstructure.Decode(r.Body, &res)
163
164 b := r.Body.(map[string]interface{})
165
166 if date, ok := b["created"]; ok && date != nil {
167 t, err := time.Parse(time.RFC3339, date.(string))
168 if err != nil {
169 return nil, err
170 }
171 res.CreatedAt = t
172 }
173
174 if date, ok := b["updated"]; ok && date != nil {
175 t, err := time.Parse(time.RFC3339, date.(string))
176 if err != nil {
177 return nil, err
178 }
179 res.UpdatedAt = t
180 }
181
182 if cs, ok := b["cloud_server"].(map[string]interface{}); ok {
183 if t, ok := cs["created"].(string); ok && t != "" {
184 creationTime, err := time.Parse(time.RFC3339, t)
185 if err != nil {
186 return &res, err
187 }
188 res.CloudServer.CreatedAt = creationTime
189 }
190 if t, ok := cs["updated"].(string); ok && t != "" {
191 updatedTime, err := time.Parse(time.RFC3339, t)
192 if err != nil {
193 return &res, err
194 }
195 res.CloudServer.UpdatedAt = updatedTime
196 }
197 if cn, ok := cs["cloud_network"].(map[string]interface{}); ok {
198 if t, ok := cn["created"].(string); ok && t != "" {
199 creationTime, err := time.Parse(time.RFC3339, t)
200 if err != nil {
201 return &res, err
202 }
203 res.CloudServer.CloudNetwork.CreatedAt = creationTime
204 }
205 if t, ok := cn["updated"].(string); ok && t != "" {
206 updatedTime, err := time.Parse(time.RFC3339, t)
207 if err != nil {
208 return &res, err
209 }
210 res.CloudServer.CloudNetwork.UpdatedAt = updatedTime
211 }
212 }
213 }
214
215 return &res, err
216}
217
218// DeleteResult represents the result of a Delete operation.
219type DeleteResult struct {
220 gophercloud.ErrResult
221}