blob: 003abf3bc4076d05958e991122a07ca63fb4a011 [file] [log] [blame]
Jon Perritta065da12015-02-06 10:20:16 -07001package stackresources
2
3import (
4 "fmt"
5 "net/http"
6 "testing"
7 "time"
8
9 "github.com/rackspace/gophercloud"
10 th "github.com/rackspace/gophercloud/testhelper"
11 fake "github.com/rackspace/gophercloud/testhelper/client"
12)
13
Jon Perrittbba201b2015-02-08 21:12:38 -070014// FindExpected represents the expected object from a Find request.
Jon Perritta065da12015-02-06 10:20:16 -070015var FindExpected = []Resource{
16 Resource{
17 Name: "hello_world",
18 Links: []gophercloud.Link{
19 gophercloud.Link{
20 Href: "http://166.78.160.107:8004/v1/98606384f58d4ad0b3db7d0d779549ac/stacks/postman_stack/5f57cff9-93fc-424e-9f78-df0515e7f48b/resources/hello_world",
21 Rel: "self",
22 },
23 gophercloud.Link{
24 Href: "http://166.78.160.107:8004/v1/98606384f58d4ad0b3db7d0d779549ac/stacks/postman_stack/5f57cff9-93fc-424e-9f78-df0515e7f48b",
25 Rel: "stack",
26 },
27 },
28 LogicalID: "hello_world",
29 StatusReason: "state changed",
30 UpdatedTime: time.Date(2015, 2, 5, 21, 33, 11, 0, time.UTC),
31 RequiredBy: []interface{}{},
32 Status: "CREATE_IN_PROGRESS",
33 PhysicalID: "49181cd6-169a-4130-9455-31185bbfc5bf",
34 Type: "OS::Nova::Server",
35 },
36}
37
Jon Perrittbba201b2015-02-08 21:12:38 -070038// FindOutput represents the response body from a Find request.
Jon Perritta065da12015-02-06 10:20:16 -070039const FindOutput = `
40{
41 "resources": [
42 {
43 "resource_name": "hello_world",
44 "links": [
45 {
46 "href": "http://166.78.160.107:8004/v1/98606384f58d4ad0b3db7d0d779549ac/stacks/postman_stack/5f57cff9-93fc-424e-9f78-df0515e7f48b/resources/hello_world",
47 "rel": "self"
48 },
49 {
50 "href": "http://166.78.160.107:8004/v1/98606384f58d4ad0b3db7d0d779549ac/stacks/postman_stack/5f57cff9-93fc-424e-9f78-df0515e7f48b",
51 "rel": "stack"
52 }
53 ],
54 "logical_resource_id": "hello_world",
55 "resource_status_reason": "state changed",
56 "updated_time": "2015-02-05T21:33:11Z",
57 "required_by": [],
58 "resource_status": "CREATE_IN_PROGRESS",
59 "physical_resource_id": "49181cd6-169a-4130-9455-31185bbfc5bf",
60 "resource_type": "OS::Nova::Server"
61 }
62 ]
63}`
64
65// HandleFindSuccessfully creates an HTTP handler at `/stacks/hello_world/resources`
66// on the test handler mux that responds with a `Find` response.
67func HandleFindSuccessfully(t *testing.T, output string) {
68 th.Mux.HandleFunc("/stacks/hello_world/resources", func(w http.ResponseWriter, r *http.Request) {
69 th.TestMethod(t, r, "GET")
70 th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
71 th.TestHeader(t, r, "Accept", "application/json")
72
73 w.Header().Set("Content-Type", "application/json")
74 w.WriteHeader(http.StatusOK)
75 fmt.Fprintf(w, output)
76 })
77}
78
Jon Perrittbba201b2015-02-08 21:12:38 -070079// ListExpected represents the expected object from a List request.
Jon Perritta065da12015-02-06 10:20:16 -070080var ListExpected = []Resource{
81 Resource{
82 Name: "hello_world",
83 Links: []gophercloud.Link{
84 gophercloud.Link{
85 Href: "http://166.78.160.107:8004/v1/98606384f58d4ad0b3db7d0d779549ac/stacks/postman_stack/5f57cff9-93fc-424e-9f78-df0515e7f48b/resources/hello_world",
86 Rel: "self",
87 },
88 gophercloud.Link{
89 Href: "http://166.78.160.107:8004/v1/98606384f58d4ad0b3db7d0d779549ac/stacks/postman_stack/5f57cff9-93fc-424e-9f78-df0515e7f48b",
90 Rel: "stack",
91 },
92 },
93 LogicalID: "hello_world",
94 StatusReason: "state changed",
95 UpdatedTime: time.Date(2015, 2, 5, 21, 33, 11, 0, time.UTC),
96 RequiredBy: []interface{}{},
97 Status: "CREATE_IN_PROGRESS",
98 PhysicalID: "49181cd6-169a-4130-9455-31185bbfc5bf",
99 Type: "OS::Nova::Server",
100 },
101}
102
Jon Perrittbba201b2015-02-08 21:12:38 -0700103// ListOutput represents the response body from a List request.
Jon Perritta065da12015-02-06 10:20:16 -0700104const ListOutput = `{
105 "resources": [
106 {
107 "resource_name": "hello_world",
108 "links": [
109 {
110 "href": "http://166.78.160.107:8004/v1/98606384f58d4ad0b3db7d0d779549ac/stacks/postman_stack/5f57cff9-93fc-424e-9f78-df0515e7f48b/resources/hello_world",
111 "rel": "self"
112 },
113 {
114 "href": "http://166.78.160.107:8004/v1/98606384f58d4ad0b3db7d0d779549ac/stacks/postman_stack/5f57cff9-93fc-424e-9f78-df0515e7f48b",
115 "rel": "stack"
116 }
117 ],
118 "logical_resource_id": "hello_world",
119 "resource_status_reason": "state changed",
120 "updated_time": "2015-02-05T21:33:11Z",
121 "required_by": [],
122 "resource_status": "CREATE_IN_PROGRESS",
123 "physical_resource_id": "49181cd6-169a-4130-9455-31185bbfc5bf",
124 "resource_type": "OS::Nova::Server"
125 }
126]
127}`
128
129// HandleListSuccessfully creates an HTTP handler at `/stacks/hello_world/49181cd6-169a-4130-9455-31185bbfc5bf/resources`
130// on the test handler mux that responds with a `List` response.
131func HandleListSuccessfully(t *testing.T, output string) {
132 th.Mux.HandleFunc("/stacks/hello_world/49181cd6-169a-4130-9455-31185bbfc5bf/resources", func(w http.ResponseWriter, r *http.Request) {
133 th.TestMethod(t, r, "GET")
134 th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
135 th.TestHeader(t, r, "Accept", "application/json")
136
137 w.Header().Set("Content-Type", "application/json")
138 r.ParseForm()
139 marker := r.Form.Get("marker")
140 switch marker {
141 case "":
142 fmt.Fprintf(w, output)
143 default:
144 t.Fatalf("Unexpected marker: [%s]", marker)
145 }
146 })
147}
148
Jon Perrittbba201b2015-02-08 21:12:38 -0700149// GetExpected represents the expected object from a Get request.
Jon Perritta065da12015-02-06 10:20:16 -0700150var GetExpected = &Resource{
151 Name: "wordpress_instance",
152 Links: []gophercloud.Link{
153 gophercloud.Link{
154 Href: "http://166.78.160.107:8004/v1/98606384f58d4ad0b3db7d0d779549ac/stacks/teststack/0b1771bd-9336-4f2b-ae86-a80f971faf1e/resources/wordpress_instance",
155 Rel: "self",
156 },
157 gophercloud.Link{
158 Href: "http://166.78.160.107:8004/v1/98606384f58d4ad0b3db7d0d779549ac/stacks/teststack/0b1771bd-9336-4f2b-ae86-a80f971faf1e",
159 Rel: "stack",
160 },
161 },
162 LogicalID: "wordpress_instance",
163 StatusReason: "state changed",
164 UpdatedTime: time.Date(2014, 12, 10, 18, 34, 35, 0, time.UTC),
165 RequiredBy: []interface{}{},
166 Status: "CREATE_COMPLETE",
167 PhysicalID: "00e3a2fe-c65d-403c-9483-4db9930dd194",
168 Type: "OS::Nova::Server",
169}
170
Jon Perrittbba201b2015-02-08 21:12:38 -0700171// GetOutput represents the response body from a Get request.
Jon Perritta065da12015-02-06 10:20:16 -0700172const GetOutput = `
173{
174 "resource": {
175 "resource_name": "wordpress_instance",
176 "description": "",
177 "links": [
178 {
179 "href": "http://166.78.160.107:8004/v1/98606384f58d4ad0b3db7d0d779549ac/stacks/teststack/0b1771bd-9336-4f2b-ae86-a80f971faf1e/resources/wordpress_instance",
180 "rel": "self"
181 },
182 {
183 "href": "http://166.78.160.107:8004/v1/98606384f58d4ad0b3db7d0d779549ac/stacks/teststack/0b1771bd-9336-4f2b-ae86-a80f971faf1e",
184 "rel": "stack"
185 }
186 ],
187 "logical_resource_id": "wordpress_instance",
188 "resource_status": "CREATE_COMPLETE",
189 "updated_time": "2014-12-10T18:34:35Z",
190 "required_by": [],
191 "resource_status_reason": "state changed",
192 "physical_resource_id": "00e3a2fe-c65d-403c-9483-4db9930dd194",
193 "resource_type": "OS::Nova::Server"
194 }
195}`
196
197// HandleGetSuccessfully creates an HTTP handler at `/stacks/teststack/0b1771bd-9336-4f2b-ae86-a80f971faf1e/resources/wordpress_instance`
198// on the test handler mux that responds with a `Get` response.
199func HandleGetSuccessfully(t *testing.T, output string) {
200 th.Mux.HandleFunc("/stacks/teststack/0b1771bd-9336-4f2b-ae86-a80f971faf1e/resources/wordpress_instance", func(w http.ResponseWriter, r *http.Request) {
201 th.TestMethod(t, r, "GET")
202 th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
203 th.TestHeader(t, r, "Accept", "application/json")
204
205 w.Header().Set("Content-Type", "application/json")
206 w.WriteHeader(http.StatusOK)
207 fmt.Fprintf(w, output)
208 })
209}
210
Jon Perrittbba201b2015-02-08 21:12:38 -0700211// MetadataExpected represents the expected object from a Metadata request.
Jon Perritta065da12015-02-06 10:20:16 -0700212var MetadataExpected = map[string]string{
213 "number": "7",
214 "animal": "auk",
215}
216
Jon Perrittbba201b2015-02-08 21:12:38 -0700217// MetadataOutput represents the response body from a Metadata request.
Jon Perritta065da12015-02-06 10:20:16 -0700218const MetadataOutput = `
219{
220 "metadata": {
221 "number": "7",
222 "animal": "auk"
223 }
224}`
225
226// HandleMetadataSuccessfully creates an HTTP handler at `/stacks/teststack/0b1771bd-9336-4f2b-ae86-a80f971faf1e/resources/wordpress_instance/metadata`
227// on the test handler mux that responds with a `Metadata` response.
228func HandleMetadataSuccessfully(t *testing.T, output string) {
229 th.Mux.HandleFunc("/stacks/teststack/0b1771bd-9336-4f2b-ae86-a80f971faf1e/resources/wordpress_instance/metadata", func(w http.ResponseWriter, r *http.Request) {
230 th.TestMethod(t, r, "GET")
231 th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
232 th.TestHeader(t, r, "Accept", "application/json")
233
234 w.Header().Set("Content-Type", "application/json")
235 w.WriteHeader(http.StatusOK)
236 fmt.Fprintf(w, output)
237 })
238}
239
Jon Perrittbba201b2015-02-08 21:12:38 -0700240// ListTypesExpected represents the expected object from a ListTypes request.
Jon Perritta065da12015-02-06 10:20:16 -0700241var ListTypesExpected = []string{
242 "OS::Nova::Server",
243 "OS::Heat::RandomString",
244 "OS::Swift::Container",
245 "OS::Trove::Instance",
246 "OS::Nova::FloatingIPAssociation",
247 "OS::Cinder::VolumeAttachment",
248 "OS::Nova::FloatingIP",
249 "OS::Nova::KeyPair",
250}
251
Jon Perrittbba201b2015-02-08 21:12:38 -0700252// ListTypesOutput represents the response body from a ListTypes request.
Jon Perritta065da12015-02-06 10:20:16 -0700253const ListTypesOutput = `
254{
255 "resource_types": [
256 "OS::Nova::Server",
257 "OS::Heat::RandomString",
258 "OS::Swift::Container",
259 "OS::Trove::Instance",
260 "OS::Nova::FloatingIPAssociation",
261 "OS::Cinder::VolumeAttachment",
262 "OS::Nova::FloatingIP",
263 "OS::Nova::KeyPair"
264 ]
265}`
266
267// HandleListTypesSuccessfully creates an HTTP handler at `/resource_types`
268// on the test handler mux that responds with a `ListTypes` response.
269func HandleListTypesSuccessfully(t *testing.T, output string) {
270 th.Mux.HandleFunc("/resource_types", func(w http.ResponseWriter, r *http.Request) {
271 th.TestMethod(t, r, "GET")
272 th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
273 th.TestHeader(t, r, "Accept", "application/json")
274
275 w.Header().Set("Content-Type", "application/json")
276 w.WriteHeader(http.StatusOK)
277 fmt.Fprintf(w, output)
278 })
279}
Jon Perritt1d4aca02015-02-06 12:29:16 -0700280
Jon Perrittbba201b2015-02-08 21:12:38 -0700281// GetSchemaExpected represents the expected object from a Schema request.
Jon Perritt1d4aca02015-02-06 12:29:16 -0700282var GetSchemaExpected = &TypeSchema{
283 Attributes: map[string]interface{}{
284 "an_attribute": map[string]interface{}{
285 "description": "An attribute description .",
286 },
287 },
288 Properties: map[string]interface{}{
289 "a_property": map[string]interface{}{
290 "update_allowed": false,
291 "required": true,
292 "type": "string",
293 "description": "A resource description.",
294 },
295 },
296 ResourceType: "OS::Heat::AResourceName",
297}
298
Jon Perrittbba201b2015-02-08 21:12:38 -0700299// GetSchemaOutput represents the response body from a Schema request.
Jon Perritt1d4aca02015-02-06 12:29:16 -0700300const GetSchemaOutput = `
301{
302 "attributes": {
303 "an_attribute": {
304 "description": "An attribute description ."
305 }
306 },
307 "properties": {
308 "a_property": {
309 "update_allowed": false,
310 "required": true,
311 "type": "string",
312 "description": "A resource description."
313 }
314 },
315 "resource_type": "OS::Heat::AResourceName"
316}`
317
318// HandleGetSchemaSuccessfully creates an HTTP handler at `/resource_types/OS::Heat::AResourceName`
319// on the test handler mux that responds with a `Schema` response.
320func HandleGetSchemaSuccessfully(t *testing.T, output string) {
321 th.Mux.HandleFunc("/resource_types/OS::Heat::AResourceName", func(w http.ResponseWriter, r *http.Request) {
322 th.TestMethod(t, r, "GET")
323 th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
324 th.TestHeader(t, r, "Accept", "application/json")
325
326 w.Header().Set("Content-Type", "application/json")
327 w.WriteHeader(http.StatusOK)
328 fmt.Fprintf(w, output)
329 })
330}
331
Jon Perrittbba201b2015-02-08 21:12:38 -0700332// GetTemplateExpected represents the expected object from a Template request.
Jon Perrittb1e303a2015-02-06 22:15:44 -0700333var GetTemplateExpected = &TypeTemplate{
334 HeatTemplateFormatVersion: "2012-12-12",
335 Outputs: map[string]interface{}{
336 "private_key": map[string]interface{}{
337 "Description": "The private key if it has been saved.",
338 "Value": "{\"Fn::GetAtt\": [\"KeyPair\", \"private_key\"]}",
339 },
340 "public_key": map[string]interface{}{
341 "Description": "The public key.",
342 "Value": "{\"Fn::GetAtt\": [\"KeyPair\", \"public_key\"]}",
343 },
344 },
345 Parameters: map[string]interface{}{
346 "name": map[string]interface{}{
347 "Description": "The name of the key pair.",
348 "Type": "String",
349 },
350 "public_key": map[string]interface{}{
351 "Description": "The optional public key. This allows users to supply the public key from a pre-existing key pair. If not supplied, a new key pair will be generated.",
352 "Type": "String",
353 },
354 "save_private_key": map[string]interface{}{
355 "AllowedValues": []string{
356 "True",
357 "true",
358 "False",
359 "false",
360 },
361 "Default": false,
362 "Description": "True if the system should remember a generated private key; False otherwise.",
363 "Type": "String",
364 },
365 },
366 Resources: map[string]interface{}{
367 "KeyPair": map[string]interface{}{
368 "Properties": map[string]interface{}{
369 "name": map[string]interface{}{
370 "Ref": "name",
371 },
372 "public_key": map[string]interface{}{
373 "Ref": "public_key",
374 },
375 "save_private_key": map[string]interface{}{
376 "Ref": "save_private_key",
377 },
378 },
379 "Type": "OS::Nova::KeyPair",
380 },
381 },
382}
383
Jon Perrittbba201b2015-02-08 21:12:38 -0700384// GetTemplateOutput represents the response body from a Template request.
Jon Perritt1d4aca02015-02-06 12:29:16 -0700385const GetTemplateOutput = `
386{
Jon Perrittb1e303a2015-02-06 22:15:44 -0700387 "HeatTemplateFormatVersion": "2012-12-12",
Jon Perritt1d4aca02015-02-06 12:29:16 -0700388 "Outputs": {
Jon Perrittb1e303a2015-02-06 22:15:44 -0700389 "private_key": {
390 "Description": "The private key if it has been saved.",
391 "Value": "{\"Fn::GetAtt\": [\"KeyPair\", \"private_key\"]}"
Jon Perritt1d4aca02015-02-06 12:29:16 -0700392 },
Jon Perrittb1e303a2015-02-06 22:15:44 -0700393 "public_key": {
394 "Description": "The public key.",
395 "Value": "{\"Fn::GetAtt\": [\"KeyPair\", \"public_key\"]}"
Jon Perritt1d4aca02015-02-06 12:29:16 -0700396 }
397 },
Jon Perritt1d4aca02015-02-06 12:29:16 -0700398 "Parameters": {
Jon Perritt1d4aca02015-02-06 12:29:16 -0700399 "name": {
Jon Perrittb1e303a2015-02-06 22:15:44 -0700400 "Description": "The name of the key pair.",
401 "Type": "String"
Jon Perritt1d4aca02015-02-06 12:29:16 -0700402 },
Jon Perrittb1e303a2015-02-06 22:15:44 -0700403 "public_key": {
404 "Description": "The optional public key. This allows users to supply the public key from a pre-existing key pair. If not supplied, a new key pair will be generated.",
405 "Type": "String"
Jon Perritt1d4aca02015-02-06 12:29:16 -0700406 },
Jon Perrittb1e303a2015-02-06 22:15:44 -0700407 "save_private_key": {
Jon Perritt1d4aca02015-02-06 12:29:16 -0700408 "AllowedValues": [
Jon Perrittb1e303a2015-02-06 22:15:44 -0700409 "True",
410 "true",
411 "False",
412 "false"
413 ],
414 "Default": false,
415 "Description": "True if the system should remember a generated private key; False otherwise.",
416 "Type": "String"
Jon Perritt1d4aca02015-02-06 12:29:16 -0700417 }
418 },
419 "Resources": {
Jon Perrittb1e303a2015-02-06 22:15:44 -0700420 "KeyPair": {
Jon Perritt1d4aca02015-02-06 12:29:16 -0700421 "Properties": {
Jon Perritt1d4aca02015-02-06 12:29:16 -0700422 "name": {
423 "Ref": "name"
424 },
Jon Perrittb1e303a2015-02-06 22:15:44 -0700425 "public_key": {
426 "Ref": "public_key"
Jon Perritt1d4aca02015-02-06 12:29:16 -0700427 },
Jon Perrittb1e303a2015-02-06 22:15:44 -0700428 "save_private_key": {
429 "Ref": "save_private_key"
Jon Perritt1d4aca02015-02-06 12:29:16 -0700430 }
Jon Perrittb1e303a2015-02-06 22:15:44 -0700431 },
432 "Type": "OS::Nova::KeyPair"
Jon Perritt1d4aca02015-02-06 12:29:16 -0700433 }
434 }
435}`
Jon Perrittb1e303a2015-02-06 22:15:44 -0700436
437// HandleGetTemplateSuccessfully creates an HTTP handler at `/resource_types/OS::Heat::AResourceName/template`
438// on the test handler mux that responds with a `Template` response.
439func HandleGetTemplateSuccessfully(t *testing.T, output string) {
440 th.Mux.HandleFunc("/resource_types/OS::Heat::AResourceName/template", func(w http.ResponseWriter, r *http.Request) {
441 th.TestMethod(t, r, "GET")
442 th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
443 th.TestHeader(t, r, "Accept", "application/json")
444
445 w.Header().Set("Content-Type", "application/json")
446 w.WriteHeader(http.StatusOK)
447 fmt.Fprintf(w, output)
448 })
449}