blob: 13f5dd21fbe7654b8c9c1c2488e7e7ce51971f91 [file] [log] [blame]
Jon Perritt3711cd02014-12-22 22:20:15 -07001package stackresources
2
3import (
4 "time"
5
6 "github.com/mitchellh/mapstructure"
7 "github.com/rackspace/gophercloud"
8 "github.com/rackspace/gophercloud/pagination"
9)
10
Jon Perrittbba201b2015-02-08 21:12:38 -070011// Resource represents a stack resource.
Jon Perritt3711cd02014-12-22 22:20:15 -070012type Resource struct {
13 Links []gophercloud.Link `mapstructure:"links"`
14 LogicalID string `mapstructure:"logical_resource_id"`
15 Name string `mapstructure:"resource_name"`
16 PhysicalID string `mapstructure:"physical_resource_id"`
17 RequiredBy []interface{} `mapstructure:"required_by"`
18 Status string `mapstructure:"resource_status"`
19 StatusReason string `mapstructure:"resource_status_reason"`
20 Type string `mapstructure:"resource_type"`
21 UpdatedTime time.Time `mapstructure:"-"`
22}
23
Jon Perrittbba201b2015-02-08 21:12:38 -070024// FindResult represents the result of a Find operation.
Jon Perritt3711cd02014-12-22 22:20:15 -070025type FindResult struct {
26 gophercloud.Result
27}
28
Jon Perrittbba201b2015-02-08 21:12:38 -070029// Extract returns a slice of Resource objects and is called after a
30// Find operation.
Jon Perritt3711cd02014-12-22 22:20:15 -070031func (r FindResult) Extract() ([]Resource, error) {
32 if r.Err != nil {
33 return nil, r.Err
34 }
35
36 var res struct {
37 Res []Resource `mapstructure:"resources"`
38 }
39
40 if err := mapstructure.Decode(r.Body, &res); err != nil {
41 return nil, err
42 }
43
Jon Perritta065da12015-02-06 10:20:16 -070044 resources := r.Body.(map[string]interface{})["resources"].([]interface{})
Jon Perritt3711cd02014-12-22 22:20:15 -070045
Jon Perritta065da12015-02-06 10:20:16 -070046 for i, resourceRaw := range resources {
47 resource := resourceRaw.(map[string]interface{})
Jon Perritt3711cd02014-12-22 22:20:15 -070048 if date, ok := resource["updated_time"]; ok && date != nil {
49 t, err := time.Parse(time.RFC3339, date.(string))
50 if err != nil {
51 return nil, err
52 }
53 res.Res[i].UpdatedTime = t
54 }
55 }
56
57 return res.Res, nil
58}
59
60// ResourcePage abstracts the raw results of making a List() request against the API.
61// As OpenStack extensions may freely alter the response bodies of structures returned to the client, you may only safely access the
62// data provided through the ExtractResources call.
63type ResourcePage struct {
Jon Perrittc8717332015-02-08 20:14:29 -070064 pagination.MarkerPageBase
Jon Perritt3711cd02014-12-22 22:20:15 -070065}
66
67// IsEmpty returns true if a page contains no Server results.
Jon Perrittc8717332015-02-08 20:14:29 -070068func (r ResourcePage) IsEmpty() (bool, error) {
69 resources, err := ExtractResources(r)
Jon Perritt3711cd02014-12-22 22:20:15 -070070 if err != nil {
71 return true, err
72 }
73 return len(resources) == 0, nil
74}
75
Jon Perrittc8717332015-02-08 20:14:29 -070076// LastMarker returns the last container name in a ListResult.
77func (r ResourcePage) LastMarker() (string, error) {
78 resources, err := ExtractResources(r)
Jon Perritt3711cd02014-12-22 22:20:15 -070079 if err != nil {
80 return "", err
81 }
Jon Perrittc8717332015-02-08 20:14:29 -070082 if len(resources) == 0 {
83 return "", nil
84 }
85 return resources[len(resources)-1].PhysicalID, nil
Jon Perritt3711cd02014-12-22 22:20:15 -070086}
87
88// ExtractResources interprets the results of a single page from a List() call, producing a slice of Resource entities.
89func ExtractResources(page pagination.Page) ([]Resource, error) {
90 casted := page.(ResourcePage).Body
91
92 var response struct {
93 Resources []Resource `mapstructure:"resources"`
94 }
95 err := mapstructure.Decode(casted, &response)
Jon Perritta065da12015-02-06 10:20:16 -070096
97 resources := casted.(map[string]interface{})["resources"].([]interface{})
98
99 for i, resourceRaw := range resources {
100 resource := resourceRaw.(map[string]interface{})
101 if date, ok := resource["updated_time"]; ok && date != nil {
102 t, err := time.Parse(time.RFC3339, date.(string))
103 if err != nil {
104 return nil, err
105 }
106 response.Resources[i].UpdatedTime = t
107 }
108 }
109
Jon Perritt3711cd02014-12-22 22:20:15 -0700110 return response.Resources, err
111}
112
Jon Perrittbba201b2015-02-08 21:12:38 -0700113// GetResult represents the result of a Get operation.
Jon Perritt3711cd02014-12-22 22:20:15 -0700114type GetResult struct {
115 gophercloud.Result
116}
117
Jon Perrittbba201b2015-02-08 21:12:38 -0700118// Extract returns a pointer to a Resource object and is called after a
119// Get operation.
Jon Perritt3711cd02014-12-22 22:20:15 -0700120func (r GetResult) Extract() (*Resource, error) {
121 if r.Err != nil {
122 return nil, r.Err
123 }
124
125 var res struct {
126 Res *Resource `mapstructure:"resource"`
127 }
128
129 if err := mapstructure.Decode(r.Body, &res); err != nil {
130 return nil, err
131 }
132
133 resource := r.Body.(map[string]interface{})["resource"].(map[string]interface{})
134
135 if date, ok := resource["updated_time"]; ok && date != nil {
136 t, err := time.Parse(time.RFC3339, date.(string))
137 if err != nil {
138 return nil, err
139 }
140 res.Res.UpdatedTime = t
141 }
142
143 return res.Res, nil
144}
145
Jon Perrittbba201b2015-02-08 21:12:38 -0700146// MetadataResult represents the result of a Metadata operation.
Jon Perritt3711cd02014-12-22 22:20:15 -0700147type MetadataResult struct {
148 gophercloud.Result
149}
150
Jon Perrittbba201b2015-02-08 21:12:38 -0700151// Extract returns a map object and is called after a
152// Metadata operation.
Jon Perritt3711cd02014-12-22 22:20:15 -0700153func (r MetadataResult) Extract() (map[string]string, error) {
154 if r.Err != nil {
155 return nil, r.Err
156 }
157
158 var res struct {
159 Meta map[string]string `mapstructure:"metadata"`
160 }
161
162 if err := mapstructure.Decode(r.Body, &res); err != nil {
163 return nil, err
164 }
165
166 return res.Meta, nil
167}
Jon Perritta065da12015-02-06 10:20:16 -0700168
169// ResourceTypePage abstracts the raw results of making a ListTypes() request against the API.
170// As OpenStack extensions may freely alter the response bodies of structures returned to the client, you may only safely access the
171// data provided through the ExtractResourceTypes call.
172type ResourceTypePage struct {
173 pagination.SinglePageBase
174}
175
176// IsEmpty returns true if a ResourceTypePage contains no resource types.
177func (r ResourceTypePage) IsEmpty() (bool, error) {
178 rts, err := ExtractResourceTypes(r)
179 if err != nil {
180 return true, err
181 }
182 return len(rts) == 0, nil
183}
184
185// ExtractResourceTypes extracts and returns resource types.
186func ExtractResourceTypes(page pagination.Page) ([]string, error) {
187 var response struct {
188 ResourceTypes []string `mapstructure:"resource_types"`
189 }
190
191 err := mapstructure.Decode(page.(ResourceTypePage).Body, &response)
192 return response.ResourceTypes, err
193}
Jon Perritt1d4aca02015-02-06 12:29:16 -0700194
Jon Perrittbba201b2015-02-08 21:12:38 -0700195// TypeSchema represents a stack resource schema.
Jon Perritt1d4aca02015-02-06 12:29:16 -0700196type TypeSchema struct {
197 Attributes map[string]interface{} `mapstructure:"attributes"`
198 Properties map[string]interface{} `mapstrucutre:"properties"`
199 ResourceType string `mapstructure:"resource_type"`
200}
201
Jon Perrittbba201b2015-02-08 21:12:38 -0700202// SchemaResult represents the result of a Schema operation.
Jon Perritt1d4aca02015-02-06 12:29:16 -0700203type SchemaResult struct {
204 gophercloud.Result
205}
206
Jon Perrittbba201b2015-02-08 21:12:38 -0700207// Extract returns a pointer to a TypeSchema object and is called after a
208// Schema operation.
Jon Perritt1d4aca02015-02-06 12:29:16 -0700209func (r SchemaResult) Extract() (*TypeSchema, error) {
210 if r.Err != nil {
211 return nil, r.Err
212 }
213
214 var res TypeSchema
215
216 if err := mapstructure.Decode(r.Body, &res); err != nil {
217 return nil, err
218 }
219
220 return &res, nil
221}
Jon Perrittb1e303a2015-02-06 22:15:44 -0700222
Jon Perrittbba201b2015-02-08 21:12:38 -0700223// TypeTemplate represents a stack resource template.
Jon Perrittb1e303a2015-02-06 22:15:44 -0700224type TypeTemplate struct {
225 HeatTemplateFormatVersion string
226 Outputs map[string]interface{}
227 Parameters map[string]interface{}
228 Resources map[string]interface{}
229}
230
Jon Perrittbba201b2015-02-08 21:12:38 -0700231// TemplateResult represents the result of a Template operation.
Jon Perrittb1e303a2015-02-06 22:15:44 -0700232type TemplateResult struct {
233 gophercloud.Result
234}
235
Jon Perrittbba201b2015-02-08 21:12:38 -0700236// Extract returns a pointer to a TypeTemplate object and is called after a
237// Template operation.
Jon Perrittb1e303a2015-02-06 22:15:44 -0700238func (r TemplateResult) Extract() (*TypeTemplate, error) {
239 if r.Err != nil {
240 return nil, r.Err
241 }
242
243 var res TypeTemplate
244
245 if err := mapstructure.Decode(r.Body, &res); err != nil {
246 return nil, err
247 }
248
249 return &res, nil
250}