blob: 18a8de5eaea082997d5232d18df2f2cd4e9bcf2e [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
14var FindExpected = []Resource{
15 Resource{
16 Name: "hello_world",
17 Links: []gophercloud.Link{
18 gophercloud.Link{
19 Href: "http://166.78.160.107:8004/v1/98606384f58d4ad0b3db7d0d779549ac/stacks/postman_stack/5f57cff9-93fc-424e-9f78-df0515e7f48b/resources/hello_world",
20 Rel: "self",
21 },
22 gophercloud.Link{
23 Href: "http://166.78.160.107:8004/v1/98606384f58d4ad0b3db7d0d779549ac/stacks/postman_stack/5f57cff9-93fc-424e-9f78-df0515e7f48b",
24 Rel: "stack",
25 },
26 },
27 LogicalID: "hello_world",
28 StatusReason: "state changed",
29 UpdatedTime: time.Date(2015, 2, 5, 21, 33, 11, 0, time.UTC),
30 RequiredBy: []interface{}{},
31 Status: "CREATE_IN_PROGRESS",
32 PhysicalID: "49181cd6-169a-4130-9455-31185bbfc5bf",
33 Type: "OS::Nova::Server",
34 },
35}
36
37const FindOutput = `
38{
39 "resources": [
40 {
41 "resource_name": "hello_world",
42 "links": [
43 {
44 "href": "http://166.78.160.107:8004/v1/98606384f58d4ad0b3db7d0d779549ac/stacks/postman_stack/5f57cff9-93fc-424e-9f78-df0515e7f48b/resources/hello_world",
45 "rel": "self"
46 },
47 {
48 "href": "http://166.78.160.107:8004/v1/98606384f58d4ad0b3db7d0d779549ac/stacks/postman_stack/5f57cff9-93fc-424e-9f78-df0515e7f48b",
49 "rel": "stack"
50 }
51 ],
52 "logical_resource_id": "hello_world",
53 "resource_status_reason": "state changed",
54 "updated_time": "2015-02-05T21:33:11Z",
55 "required_by": [],
56 "resource_status": "CREATE_IN_PROGRESS",
57 "physical_resource_id": "49181cd6-169a-4130-9455-31185bbfc5bf",
58 "resource_type": "OS::Nova::Server"
59 }
60 ]
61}`
62
63// HandleFindSuccessfully creates an HTTP handler at `/stacks/hello_world/resources`
64// on the test handler mux that responds with a `Find` response.
65func HandleFindSuccessfully(t *testing.T, output string) {
66 th.Mux.HandleFunc("/stacks/hello_world/resources", func(w http.ResponseWriter, r *http.Request) {
67 th.TestMethod(t, r, "GET")
68 th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
69 th.TestHeader(t, r, "Accept", "application/json")
70
71 w.Header().Set("Content-Type", "application/json")
72 w.WriteHeader(http.StatusOK)
73 fmt.Fprintf(w, output)
74 })
75}
76
77var ListExpected = []Resource{
78 Resource{
79 Name: "hello_world",
80 Links: []gophercloud.Link{
81 gophercloud.Link{
82 Href: "http://166.78.160.107:8004/v1/98606384f58d4ad0b3db7d0d779549ac/stacks/postman_stack/5f57cff9-93fc-424e-9f78-df0515e7f48b/resources/hello_world",
83 Rel: "self",
84 },
85 gophercloud.Link{
86 Href: "http://166.78.160.107:8004/v1/98606384f58d4ad0b3db7d0d779549ac/stacks/postman_stack/5f57cff9-93fc-424e-9f78-df0515e7f48b",
87 Rel: "stack",
88 },
89 },
90 LogicalID: "hello_world",
91 StatusReason: "state changed",
92 UpdatedTime: time.Date(2015, 2, 5, 21, 33, 11, 0, time.UTC),
93 RequiredBy: []interface{}{},
94 Status: "CREATE_IN_PROGRESS",
95 PhysicalID: "49181cd6-169a-4130-9455-31185bbfc5bf",
96 Type: "OS::Nova::Server",
97 },
98}
99
100const ListOutput = `{
101 "resources": [
102 {
103 "resource_name": "hello_world",
104 "links": [
105 {
106 "href": "http://166.78.160.107:8004/v1/98606384f58d4ad0b3db7d0d779549ac/stacks/postman_stack/5f57cff9-93fc-424e-9f78-df0515e7f48b/resources/hello_world",
107 "rel": "self"
108 },
109 {
110 "href": "http://166.78.160.107:8004/v1/98606384f58d4ad0b3db7d0d779549ac/stacks/postman_stack/5f57cff9-93fc-424e-9f78-df0515e7f48b",
111 "rel": "stack"
112 }
113 ],
114 "logical_resource_id": "hello_world",
115 "resource_status_reason": "state changed",
116 "updated_time": "2015-02-05T21:33:11Z",
117 "required_by": [],
118 "resource_status": "CREATE_IN_PROGRESS",
119 "physical_resource_id": "49181cd6-169a-4130-9455-31185bbfc5bf",
120 "resource_type": "OS::Nova::Server"
121 }
122]
123}`
124
125// HandleListSuccessfully creates an HTTP handler at `/stacks/hello_world/49181cd6-169a-4130-9455-31185bbfc5bf/resources`
126// on the test handler mux that responds with a `List` response.
127func HandleListSuccessfully(t *testing.T, output string) {
128 th.Mux.HandleFunc("/stacks/hello_world/49181cd6-169a-4130-9455-31185bbfc5bf/resources", func(w http.ResponseWriter, r *http.Request) {
129 th.TestMethod(t, r, "GET")
130 th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
131 th.TestHeader(t, r, "Accept", "application/json")
132
133 w.Header().Set("Content-Type", "application/json")
134 r.ParseForm()
135 marker := r.Form.Get("marker")
136 switch marker {
137 case "":
138 fmt.Fprintf(w, output)
139 default:
140 t.Fatalf("Unexpected marker: [%s]", marker)
141 }
142 })
143}
144
145var GetExpected = &Resource{
146 Name: "wordpress_instance",
147 Links: []gophercloud.Link{
148 gophercloud.Link{
149 Href: "http://166.78.160.107:8004/v1/98606384f58d4ad0b3db7d0d779549ac/stacks/teststack/0b1771bd-9336-4f2b-ae86-a80f971faf1e/resources/wordpress_instance",
150 Rel: "self",
151 },
152 gophercloud.Link{
153 Href: "http://166.78.160.107:8004/v1/98606384f58d4ad0b3db7d0d779549ac/stacks/teststack/0b1771bd-9336-4f2b-ae86-a80f971faf1e",
154 Rel: "stack",
155 },
156 },
157 LogicalID: "wordpress_instance",
158 StatusReason: "state changed",
159 UpdatedTime: time.Date(2014, 12, 10, 18, 34, 35, 0, time.UTC),
160 RequiredBy: []interface{}{},
161 Status: "CREATE_COMPLETE",
162 PhysicalID: "00e3a2fe-c65d-403c-9483-4db9930dd194",
163 Type: "OS::Nova::Server",
164}
165
166const GetOutput = `
167{
168 "resource": {
169 "resource_name": "wordpress_instance",
170 "description": "",
171 "links": [
172 {
173 "href": "http://166.78.160.107:8004/v1/98606384f58d4ad0b3db7d0d779549ac/stacks/teststack/0b1771bd-9336-4f2b-ae86-a80f971faf1e/resources/wordpress_instance",
174 "rel": "self"
175 },
176 {
177 "href": "http://166.78.160.107:8004/v1/98606384f58d4ad0b3db7d0d779549ac/stacks/teststack/0b1771bd-9336-4f2b-ae86-a80f971faf1e",
178 "rel": "stack"
179 }
180 ],
181 "logical_resource_id": "wordpress_instance",
182 "resource_status": "CREATE_COMPLETE",
183 "updated_time": "2014-12-10T18:34:35Z",
184 "required_by": [],
185 "resource_status_reason": "state changed",
186 "physical_resource_id": "00e3a2fe-c65d-403c-9483-4db9930dd194",
187 "resource_type": "OS::Nova::Server"
188 }
189}`
190
191// HandleGetSuccessfully creates an HTTP handler at `/stacks/teststack/0b1771bd-9336-4f2b-ae86-a80f971faf1e/resources/wordpress_instance`
192// on the test handler mux that responds with a `Get` response.
193func HandleGetSuccessfully(t *testing.T, output string) {
194 th.Mux.HandleFunc("/stacks/teststack/0b1771bd-9336-4f2b-ae86-a80f971faf1e/resources/wordpress_instance", func(w http.ResponseWriter, r *http.Request) {
195 th.TestMethod(t, r, "GET")
196 th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
197 th.TestHeader(t, r, "Accept", "application/json")
198
199 w.Header().Set("Content-Type", "application/json")
200 w.WriteHeader(http.StatusOK)
201 fmt.Fprintf(w, output)
202 })
203}
204
205var MetadataExpected = map[string]string{
206 "number": "7",
207 "animal": "auk",
208}
209
210const MetadataOutput = `
211{
212 "metadata": {
213 "number": "7",
214 "animal": "auk"
215 }
216}`
217
218// HandleMetadataSuccessfully creates an HTTP handler at `/stacks/teststack/0b1771bd-9336-4f2b-ae86-a80f971faf1e/resources/wordpress_instance/metadata`
219// on the test handler mux that responds with a `Metadata` response.
220func HandleMetadataSuccessfully(t *testing.T, output string) {
221 th.Mux.HandleFunc("/stacks/teststack/0b1771bd-9336-4f2b-ae86-a80f971faf1e/resources/wordpress_instance/metadata", func(w http.ResponseWriter, r *http.Request) {
222 th.TestMethod(t, r, "GET")
223 th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
224 th.TestHeader(t, r, "Accept", "application/json")
225
226 w.Header().Set("Content-Type", "application/json")
227 w.WriteHeader(http.StatusOK)
228 fmt.Fprintf(w, output)
229 })
230}
231
232var ListTypesExpected = []string{
233 "OS::Nova::Server",
234 "OS::Heat::RandomString",
235 "OS::Swift::Container",
236 "OS::Trove::Instance",
237 "OS::Nova::FloatingIPAssociation",
238 "OS::Cinder::VolumeAttachment",
239 "OS::Nova::FloatingIP",
240 "OS::Nova::KeyPair",
241}
242
243const ListTypesOutput = `
244{
245 "resource_types": [
246 "OS::Nova::Server",
247 "OS::Heat::RandomString",
248 "OS::Swift::Container",
249 "OS::Trove::Instance",
250 "OS::Nova::FloatingIPAssociation",
251 "OS::Cinder::VolumeAttachment",
252 "OS::Nova::FloatingIP",
253 "OS::Nova::KeyPair"
254 ]
255}`
256
257// HandleListTypesSuccessfully creates an HTTP handler at `/resource_types`
258// on the test handler mux that responds with a `ListTypes` response.
259func HandleListTypesSuccessfully(t *testing.T, output string) {
260 th.Mux.HandleFunc("/resource_types", func(w http.ResponseWriter, r *http.Request) {
261 th.TestMethod(t, r, "GET")
262 th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
263 th.TestHeader(t, r, "Accept", "application/json")
264
265 w.Header().Set("Content-Type", "application/json")
266 w.WriteHeader(http.StatusOK)
267 fmt.Fprintf(w, output)
268 })
269}
Jon Perritt1d4aca02015-02-06 12:29:16 -0700270
271var GetSchemaExpected = &TypeSchema{
272 Attributes: map[string]interface{}{
273 "an_attribute": map[string]interface{}{
274 "description": "An attribute description .",
275 },
276 },
277 Properties: map[string]interface{}{
278 "a_property": map[string]interface{}{
279 "update_allowed": false,
280 "required": true,
281 "type": "string",
282 "description": "A resource description.",
283 },
284 },
285 ResourceType: "OS::Heat::AResourceName",
286}
287
288const GetSchemaOutput = `
289{
290 "attributes": {
291 "an_attribute": {
292 "description": "An attribute description ."
293 }
294 },
295 "properties": {
296 "a_property": {
297 "update_allowed": false,
298 "required": true,
299 "type": "string",
300 "description": "A resource description."
301 }
302 },
303 "resource_type": "OS::Heat::AResourceName"
304}`
305
306// HandleGetSchemaSuccessfully creates an HTTP handler at `/resource_types/OS::Heat::AResourceName`
307// on the test handler mux that responds with a `Schema` response.
308func HandleGetSchemaSuccessfully(t *testing.T, output string) {
309 th.Mux.HandleFunc("/resource_types/OS::Heat::AResourceName", func(w http.ResponseWriter, r *http.Request) {
310 th.TestMethod(t, r, "GET")
311 th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
312 th.TestHeader(t, r, "Accept", "application/json")
313
314 w.Header().Set("Content-Type", "application/json")
315 w.WriteHeader(http.StatusOK)
316 fmt.Fprintf(w, output)
317 })
318}
319
Jon Perrittb1e303a2015-02-06 22:15:44 -0700320var GetTemplateExpected = &TypeTemplate{
321 HeatTemplateFormatVersion: "2012-12-12",
322 Outputs: map[string]interface{}{
323 "private_key": map[string]interface{}{
324 "Description": "The private key if it has been saved.",
325 "Value": "{\"Fn::GetAtt\": [\"KeyPair\", \"private_key\"]}",
326 },
327 "public_key": map[string]interface{}{
328 "Description": "The public key.",
329 "Value": "{\"Fn::GetAtt\": [\"KeyPair\", \"public_key\"]}",
330 },
331 },
332 Parameters: map[string]interface{}{
333 "name": map[string]interface{}{
334 "Description": "The name of the key pair.",
335 "Type": "String",
336 },
337 "public_key": map[string]interface{}{
338 "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.",
339 "Type": "String",
340 },
341 "save_private_key": map[string]interface{}{
342 "AllowedValues": []string{
343 "True",
344 "true",
345 "False",
346 "false",
347 },
348 "Default": false,
349 "Description": "True if the system should remember a generated private key; False otherwise.",
350 "Type": "String",
351 },
352 },
353 Resources: map[string]interface{}{
354 "KeyPair": map[string]interface{}{
355 "Properties": map[string]interface{}{
356 "name": map[string]interface{}{
357 "Ref": "name",
358 },
359 "public_key": map[string]interface{}{
360 "Ref": "public_key",
361 },
362 "save_private_key": map[string]interface{}{
363 "Ref": "save_private_key",
364 },
365 },
366 "Type": "OS::Nova::KeyPair",
367 },
368 },
369}
370
Jon Perritt1d4aca02015-02-06 12:29:16 -0700371const GetTemplateOutput = `
372{
Jon Perrittb1e303a2015-02-06 22:15:44 -0700373 "HeatTemplateFormatVersion": "2012-12-12",
Jon Perritt1d4aca02015-02-06 12:29:16 -0700374 "Outputs": {
Jon Perrittb1e303a2015-02-06 22:15:44 -0700375 "private_key": {
376 "Description": "The private key if it has been saved.",
377 "Value": "{\"Fn::GetAtt\": [\"KeyPair\", \"private_key\"]}"
Jon Perritt1d4aca02015-02-06 12:29:16 -0700378 },
Jon Perrittb1e303a2015-02-06 22:15:44 -0700379 "public_key": {
380 "Description": "The public key.",
381 "Value": "{\"Fn::GetAtt\": [\"KeyPair\", \"public_key\"]}"
Jon Perritt1d4aca02015-02-06 12:29:16 -0700382 }
383 },
Jon Perritt1d4aca02015-02-06 12:29:16 -0700384 "Parameters": {
Jon Perritt1d4aca02015-02-06 12:29:16 -0700385 "name": {
Jon Perrittb1e303a2015-02-06 22:15:44 -0700386 "Description": "The name of the key pair.",
387 "Type": "String"
Jon Perritt1d4aca02015-02-06 12:29:16 -0700388 },
Jon Perrittb1e303a2015-02-06 22:15:44 -0700389 "public_key": {
390 "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.",
391 "Type": "String"
Jon Perritt1d4aca02015-02-06 12:29:16 -0700392 },
Jon Perrittb1e303a2015-02-06 22:15:44 -0700393 "save_private_key": {
Jon Perritt1d4aca02015-02-06 12:29:16 -0700394 "AllowedValues": [
Jon Perrittb1e303a2015-02-06 22:15:44 -0700395 "True",
396 "true",
397 "False",
398 "false"
399 ],
400 "Default": false,
401 "Description": "True if the system should remember a generated private key; False otherwise.",
402 "Type": "String"
Jon Perritt1d4aca02015-02-06 12:29:16 -0700403 }
404 },
405 "Resources": {
Jon Perrittb1e303a2015-02-06 22:15:44 -0700406 "KeyPair": {
Jon Perritt1d4aca02015-02-06 12:29:16 -0700407 "Properties": {
Jon Perritt1d4aca02015-02-06 12:29:16 -0700408 "name": {
409 "Ref": "name"
410 },
Jon Perrittb1e303a2015-02-06 22:15:44 -0700411 "public_key": {
412 "Ref": "public_key"
Jon Perritt1d4aca02015-02-06 12:29:16 -0700413 },
Jon Perrittb1e303a2015-02-06 22:15:44 -0700414 "save_private_key": {
415 "Ref": "save_private_key"
Jon Perritt1d4aca02015-02-06 12:29:16 -0700416 }
Jon Perrittb1e303a2015-02-06 22:15:44 -0700417 },
418 "Type": "OS::Nova::KeyPair"
Jon Perritt1d4aca02015-02-06 12:29:16 -0700419 }
420 }
421}`
Jon Perrittb1e303a2015-02-06 22:15:44 -0700422
423// HandleGetTemplateSuccessfully creates an HTTP handler at `/resource_types/OS::Heat::AResourceName/template`
424// on the test handler mux that responds with a `Template` response.
425func HandleGetTemplateSuccessfully(t *testing.T, output string) {
426 th.Mux.HandleFunc("/resource_types/OS::Heat::AResourceName/template", func(w http.ResponseWriter, r *http.Request) {
427 th.TestMethod(t, r, "GET")
428 th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
429 th.TestHeader(t, r, "Accept", "application/json")
430
431 w.Header().Set("Content-Type", "application/json")
432 w.WriteHeader(http.StatusOK)
433 fmt.Fprintf(w, output)
434 })
435}