You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

654 lines
22 KiB

  1. package cloudformation_test
  2. import (
  3. "testing"
  4. "time"
  5. . "gopkg.in/check.v1"
  6. "github.com/goamz/goamz/aws"
  7. cf "github.com/goamz/goamz/cloudformation"
  8. "github.com/goamz/goamz/testutil"
  9. )
  10. func Test(t *testing.T) {
  11. TestingT(t)
  12. }
  13. var _ = Suite(&S{})
  14. type S struct {
  15. cf *cf.CloudFormation
  16. }
  17. var testServer = testutil.NewHTTPServer()
  18. var mockTest bool
  19. func (s *S) SetUpSuite(c *C) {
  20. testServer.Start()
  21. auth := aws.Auth{AccessKey: "abc", SecretKey: "123"}
  22. s.cf = cf.New(auth, aws.Region{CloudFormationEndpoint: testServer.URL})
  23. }
  24. func (s *S) TearDownTest(c *C) {
  25. testServer.Flush()
  26. }
  27. func (s *S) TestCancelUpdateStack(c *C) {
  28. testServer.Response(200, nil, CancelUpdateStackResponse)
  29. resp, err := s.cf.CancelUpdateStack("foo")
  30. c.Assert(err, IsNil)
  31. values := testServer.WaitRequest().PostForm
  32. // Post request test
  33. c.Assert(values.Get("Version"), Equals, "2010-05-15")
  34. c.Assert(values.Get("Action"), Equals, "CancelUpdateStack")
  35. c.Assert(values.Get("StackName"), Equals, "foo")
  36. // Response test
  37. c.Assert(resp.RequestId, Equals, "4af14eec-350e-11e4-b260-EXAMPLE")
  38. }
  39. func (s *S) TestCreateStack(c *C) {
  40. testServer.Response(200, nil, CreateStackResponse)
  41. stackParams := &cf.CreateStackParams{
  42. NotificationARNs: []string{"arn:aws:sns:us-east-1:1234567890:my-topic"},
  43. Parameters: []cf.Parameter{
  44. {
  45. ParameterKey: "AvailabilityZone",
  46. ParameterValue: "us-east-1a",
  47. },
  48. },
  49. StackName: "MyStack",
  50. TemplateBody: "[Template Document]",
  51. }
  52. resp, err := s.cf.CreateStack(stackParams)
  53. c.Assert(err, IsNil)
  54. values := testServer.WaitRequest().PostForm
  55. // Post request test
  56. c.Assert(values.Get("Version"), Equals, "2010-05-15")
  57. c.Assert(values.Get("Action"), Equals, "CreateStack")
  58. c.Assert(values.Get("StackName"), Equals, "MyStack")
  59. c.Assert(values.Get("NotificationARNs.member.1"), Equals, "arn:aws:sns:us-east-1:1234567890:my-topic")
  60. c.Assert(values.Get("TemplateBody"), Equals, "[Template Document]")
  61. c.Assert(values.Get("Parameters.member.1.ParameterKey"), Equals, "AvailabilityZone")
  62. c.Assert(values.Get("Parameters.member.1.ParameterValue"), Equals, "us-east-1a")
  63. // Response test
  64. c.Assert(resp.RequestId, Equals, "4af14eec-350e-11e4-b260-EXAMPLE")
  65. c.Assert(resp.StackId, Equals, "arn:aws:cloudformation:us-east-1:123456789:stack/MyStack/aaf549a0-a413-11df-adb3-5081b3858e83")
  66. }
  67. func (s *S) TestCreateStackWithInvalidParams(c *C) {
  68. testServer.Response(400, nil, CreateStackWithInvalidParamsResponse)
  69. //testServer.Response(200, nil, DeleteAutoScalingGroupResponse)
  70. cfTemplate := `
  71. {
  72. "AWSTemplateFormatVersion" : "2010-09-09",
  73. "Description" : "Sample template",
  74. "Parameters" : {
  75. "KeyName" : {
  76. "Description" : "key pair",
  77. "Type" : "String"
  78. }
  79. },
  80. "Resources" : {
  81. "Ec2Instance" : {
  82. "Type" : "AWS::EC2::Instance",
  83. "Properties" : {
  84. "KeyName" : { "Ref" : "KeyName" },
  85. "ImageId" : "ami-7f418316",
  86. "UserData" : { "Fn::Base64" : "80" }
  87. }
  88. }
  89. },
  90. "Outputs" : {
  91. "InstanceId" : {
  92. "Description" : "InstanceId of the newly created EC2 instance",
  93. "Value" : { "Ref" : "Ec2Instance" }
  94. }
  95. }`
  96. stackParams := &cf.CreateStackParams{
  97. Capabilities: []string{"CAPABILITY_IAM"},
  98. DisableRollback: true,
  99. NotificationARNs: []string{
  100. "arn:aws:sns:us-east-1:1234567890:my-topic",
  101. "arn:aws:sns:us-east-1:1234567890:my-topic2",
  102. },
  103. OnFailure: "ROLLBACK",
  104. Parameters: []cf.Parameter{
  105. {
  106. ParameterKey: "AvailabilityZone",
  107. ParameterValue: "us-east-1a",
  108. },
  109. },
  110. StackName: "MyStack",
  111. StackPolicyBody: "{PolicyBody}",
  112. StackPolicyURL: "http://stack-policy-url",
  113. Tags: []cf.Tag{
  114. {
  115. Key: "TagKey",
  116. Value: "TagValue",
  117. },
  118. },
  119. TemplateBody: cfTemplate,
  120. TemplateURL: "http://url",
  121. TimeoutInMinutes: 20,
  122. }
  123. resp, err := s.cf.CreateStack(stackParams)
  124. c.Assert(err, NotNil)
  125. c.Assert(resp, IsNil)
  126. values := testServer.WaitRequest().PostForm
  127. // Post request test
  128. c.Assert(values.Get("Version"), Equals, "2010-05-15")
  129. c.Assert(values.Get("Action"), Equals, "CreateStack")
  130. c.Assert(values.Get("StackName"), Equals, "MyStack")
  131. c.Assert(values.Get("NotificationARNs.member.1"), Equals, "arn:aws:sns:us-east-1:1234567890:my-topic")
  132. c.Assert(values.Get("NotificationARNs.member.2"), Equals, "arn:aws:sns:us-east-1:1234567890:my-topic2")
  133. c.Assert(values.Get("Capabilities.member.1"), Equals, "CAPABILITY_IAM")
  134. c.Assert(values.Get("TemplateBody"), Equals, cfTemplate)
  135. c.Assert(values.Get("TemplateURL"), Equals, "http://url")
  136. c.Assert(values.Get("StackPolicyBody"), Equals, "{PolicyBody}")
  137. c.Assert(values.Get("StackPolicyURL"), Equals, "http://stack-policy-url")
  138. c.Assert(values.Get("OnFailure"), Equals, "ROLLBACK")
  139. c.Assert(values.Get("DisableRollback"), Equals, "true")
  140. c.Assert(values.Get("Tags.member.1.Key"), Equals, "TagKey")
  141. c.Assert(values.Get("Tags.member.1.Value"), Equals, "TagValue")
  142. c.Assert(values.Get("Parameters.member.1.ParameterKey"), Equals, "AvailabilityZone")
  143. c.Assert(values.Get("Parameters.member.1.ParameterValue"), Equals, "us-east-1a")
  144. c.Assert(values.Get("TimeoutInMinutes"), Equals, "20")
  145. // Response test
  146. c.Assert(err.(*cf.Error).RequestId, Equals, "70a76d42-9665-11e2-9fdf-211deEXAMPLE")
  147. c.Assert(err.(*cf.Error).Message, Equals, "Either Template URL or Template Body must be specified.")
  148. c.Assert(err.(*cf.Error).Type, Equals, "Sender")
  149. c.Assert(err.(*cf.Error).Code, Equals, "ValidationError")
  150. c.Assert(err.(*cf.Error).StatusCode, Equals, 400)
  151. }
  152. func (s *S) TestDeleteStack(c *C) {
  153. testServer.Response(200, nil, DeleteStackResponse)
  154. resp, err := s.cf.DeleteStack("foo")
  155. c.Assert(err, IsNil)
  156. values := testServer.WaitRequest().PostForm
  157. // Post request test
  158. c.Assert(values.Get("Version"), Equals, "2010-05-15")
  159. c.Assert(values.Get("Action"), Equals, "DeleteStack")
  160. c.Assert(values.Get("StackName"), Equals, "foo")
  161. // Response test
  162. c.Assert(resp.RequestId, Equals, "4af14eec-350e-11e4-b260-EXAMPLE")
  163. }
  164. func (s *S) TestDescribeStackEvents(c *C) {
  165. testServer.Response(200, nil, DescribeStackEventsResponse)
  166. resp, err := s.cf.DescribeStackEvents("MyStack", "")
  167. c.Assert(err, IsNil)
  168. values := testServer.WaitRequest().PostForm
  169. // Post request test
  170. t1, _ := time.Parse(time.RFC3339, "2010-07-27T22:26:28Z")
  171. t2, _ := time.Parse(time.RFC3339, "2010-07-27T22:27:28Z")
  172. t3, _ := time.Parse(time.RFC3339, "2010-07-27T22:28:28Z")
  173. c.Assert(values.Get("Version"), Equals, "2010-05-15")
  174. c.Assert(values.Get("Action"), Equals, "DescribeStackEvents")
  175. c.Assert(values.Get("StackName"), Equals, "MyStack")
  176. c.Assert(values.Get("NextToken"), Equals, "")
  177. // Response test
  178. expected := &cf.DescribeStackEventsResponse{
  179. StackEvents: []cf.StackEvent{
  180. {
  181. EventId: "Event-1-Id",
  182. StackId: "arn:aws:cloudformation:us-east-1:123456789:stack/MyStack/aaf549a0-a413-11df-adb3-5081b3858e83",
  183. StackName: "MyStack",
  184. LogicalResourceId: "MyStack",
  185. PhysicalResourceId: "MyStack_One",
  186. ResourceType: "AWS::CloudFormation::Stack",
  187. Timestamp: t1,
  188. ResourceStatus: "CREATE_IN_PROGRESS",
  189. ResourceStatusReason: "User initiated",
  190. },
  191. {
  192. EventId: "Event-2-Id",
  193. StackId: "arn:aws:cloudformation:us-east-1:123456789:stack/MyStack/aaf549a0-a413-11df-adb3-5081b3858e83",
  194. StackName: "MyStack",
  195. LogicalResourceId: "MyDBInstance",
  196. PhysicalResourceId: "MyStack_DB1",
  197. ResourceType: "AWS::SecurityGroup",
  198. Timestamp: t2,
  199. ResourceStatus: "CREATE_IN_PROGRESS",
  200. ResourceProperties: "{\"GroupDescription\":...}",
  201. },
  202. {
  203. EventId: "Event-3-Id",
  204. StackId: "arn:aws:cloudformation:us-east-1:123456789:stack/MyStack/aaf549a0-a413-11df-adb3-5081b3858e83",
  205. StackName: "MyStack",
  206. LogicalResourceId: "MySG1",
  207. PhysicalResourceId: "MyStack_SG1",
  208. ResourceType: "AWS::SecurityGroup",
  209. Timestamp: t3,
  210. ResourceStatus: "CREATE_COMPLETE",
  211. },
  212. },
  213. NextToken: "",
  214. RequestId: "4af14eec-350e-11e4-b260-EXAMPLE",
  215. }
  216. c.Assert(resp, DeepEquals, expected)
  217. }
  218. func (s *S) TestDescribeStackResource(c *C) {
  219. testServer.Response(200, nil, DescribeStackResourceResponse)
  220. resp, err := s.cf.DescribeStackResource("MyStack", "MyDBInstance")
  221. c.Assert(err, IsNil)
  222. values := testServer.WaitRequest().PostForm
  223. // Post request test
  224. c.Assert(values.Get("Version"), Equals, "2010-05-15")
  225. c.Assert(values.Get("Action"), Equals, "DescribeStackResource")
  226. c.Assert(values.Get("StackName"), Equals, "MyStack")
  227. c.Assert(values.Get("LogicalResourceId"), Equals, "MyDBInstance")
  228. t, _ := time.Parse(time.RFC3339, "2011-07-07T22:27:28Z")
  229. // Response test
  230. expected := &cf.DescribeStackResourceResponse{
  231. StackResourceDetail: cf.StackResourceDetail{
  232. StackId: "arn:aws:cloudformation:us-east-1:123456789:stack/MyStack/aaf549a0-a413-11df-adb3-5081b3858e83",
  233. StackName: "MyStack",
  234. LogicalResourceId: "MyDBInstance",
  235. PhysicalResourceId: "MyStack_DB1",
  236. ResourceType: "AWS::RDS::DBInstance",
  237. LastUpdatedTimestamp: t,
  238. ResourceStatus: "CREATE_COMPLETE",
  239. },
  240. RequestId: "4af14eec-350e-11e4-b260-EXAMPLE",
  241. }
  242. c.Assert(resp, DeepEquals, expected)
  243. }
  244. func (s *S) TestDescribeStackResources(c *C) {
  245. testServer.Response(200, nil, DescribeStackResourcesResponse)
  246. resp, err := s.cf.DescribeStackResources("MyStack", "", "")
  247. c.Assert(err, IsNil)
  248. values := testServer.WaitRequest().PostForm
  249. // Post request test
  250. t1, _ := time.Parse(time.RFC3339, "2010-07-27T22:27:28Z")
  251. t2, _ := time.Parse(time.RFC3339, "2010-07-27T22:28:28Z")
  252. c.Assert(values.Get("Version"), Equals, "2010-05-15")
  253. c.Assert(values.Get("Action"), Equals, "DescribeStackResources")
  254. c.Assert(values.Get("StackName"), Equals, "MyStack")
  255. c.Assert(values.Get("PhysicalResourceId"), Equals, "")
  256. c.Assert(values.Get("LogicalResourceId"), Equals, "")
  257. // Response test
  258. expected := &cf.DescribeStackResourcesResponse{
  259. StackResources: []cf.StackResource{
  260. {
  261. StackId: "arn:aws:cloudformation:us-east-1:123456789:stack/MyStack/aaf549a0-a413-11df-adb3-5081b3858e83",
  262. StackName: "MyStack",
  263. LogicalResourceId: "MyDBInstance",
  264. PhysicalResourceId: "MyStack_DB1",
  265. ResourceType: "AWS::DBInstance",
  266. Timestamp: t1,
  267. ResourceStatus: "CREATE_COMPLETE",
  268. },
  269. {
  270. StackId: "arn:aws:cloudformation:us-east-1:123456789:stack/MyStack/aaf549a0-a413-11df-adb3-5081b3858e83",
  271. StackName: "MyStack",
  272. LogicalResourceId: "MyAutoScalingGroup",
  273. PhysicalResourceId: "MyStack_ASG1",
  274. ResourceType: "AWS::AutoScalingGroup",
  275. Timestamp: t2,
  276. ResourceStatus: "CREATE_IN_PROGRESS",
  277. },
  278. },
  279. RequestId: "4af14eec-350e-11e4-b260-EXAMPLE",
  280. }
  281. c.Assert(resp, DeepEquals, expected)
  282. }
  283. func (s *S) TestDescribeStacks(c *C) {
  284. testServer.Response(200, nil, DescribeStacksResponse)
  285. resp, err := s.cf.DescribeStacks("MyStack", "")
  286. c.Assert(err, IsNil)
  287. values := testServer.WaitRequest().PostForm
  288. // Post request test
  289. t, _ := time.Parse(time.RFC3339, "2010-07-27T22:28:28Z")
  290. c.Assert(values.Get("Version"), Equals, "2010-05-15")
  291. c.Assert(values.Get("Action"), Equals, "DescribeStacks")
  292. c.Assert(values.Get("StackName"), Equals, "MyStack")
  293. c.Assert(values.Get("NextToken"), Equals, "")
  294. // Response test
  295. expected := &cf.DescribeStacksResponse{
  296. Stacks: []cf.Stack{
  297. {
  298. StackId: "arn:aws:cloudformation:us-east-1:123456789:stack/MyStack/aaf549a0-a413-11df-adb3-5081b3858e83",
  299. StackName: "MyStack",
  300. Description: "My Description",
  301. Capabilities: []string{"CAPABILITY_IAM"},
  302. NotificationARNs: []string{"arn:aws:sns:region-name:account-name:topic-name"},
  303. Parameters: []cf.Parameter{
  304. {
  305. ParameterKey: "MyKey",
  306. ParameterValue: "MyValue",
  307. },
  308. },
  309. Tags: []cf.Tag{
  310. {
  311. Key: "MyTagKey",
  312. Value: "MyTagValue",
  313. },
  314. },
  315. CreationTime: t,
  316. StackStatus: "CREATE_COMPLETE",
  317. DisableRollback: false,
  318. Outputs: []cf.Output{
  319. {
  320. Description: "ServerUrl",
  321. OutputKey: "StartPage",
  322. OutputValue: "http://my-load-balancer.amazonaws.com:80/index.html",
  323. },
  324. },
  325. },
  326. },
  327. NextToken: "",
  328. RequestId: "4af14eec-350e-11e4-b260-EXAMPLE",
  329. }
  330. c.Assert(resp, DeepEquals, expected)
  331. }
  332. func (s *S) TestEstimateTemplateCost(c *C) {
  333. testServer.Response(200, nil, EstimateTemplateCostResponse)
  334. resp, err := s.cf.EstimateTemplateCost(nil, "", "https://s3.amazonaws.com/cloudformation-samples-us-east-1/Drupal_Simple.template")
  335. c.Assert(err, IsNil)
  336. values := testServer.WaitRequest().PostForm
  337. // Post request test
  338. c.Assert(values.Get("Version"), Equals, "2010-05-15")
  339. c.Assert(values.Get("Action"), Equals, "EstimateTemplateCost")
  340. c.Assert(values.Get("TemplateBody"), Equals, "")
  341. c.Assert(values.Get("TemplateURL"), Equals, "https://s3.amazonaws.com/cloudformation-samples-us-east-1/Drupal_Simple.template")
  342. // Response test
  343. c.Assert(resp.Url, Equals, "http://calculator.s3.amazonaws.com/calc5.html?key=cf-2e351785-e821-450c-9d58-625e1e1ebfb6")
  344. c.Assert(resp.RequestId, Equals, "4af14eec-350e-11e4-b260-EXAMPLE")
  345. }
  346. func (s *S) TestGetStackPolicy(c *C) {
  347. testServer.Response(200, nil, GetStackPolicyResponse)
  348. resp, err := s.cf.GetStackPolicy("MyStack")
  349. c.Assert(err, IsNil)
  350. values := testServer.WaitRequest().PostForm
  351. // Post request test
  352. c.Assert(values.Get("Version"), Equals, "2010-05-15")
  353. c.Assert(values.Get("Action"), Equals, "GetStackPolicy")
  354. c.Assert(values.Get("StackName"), Equals, "MyStack")
  355. // Response test
  356. policy := `{
  357. "Statement" : [
  358. {
  359. "Effect" : "Deny",
  360. "Action" : "Update:*",
  361. "Principal" : "*",
  362. "Resource" : "LogicalResourceId/ProductionDatabase"
  363. },
  364. {
  365. "Effect" : "Allow",
  366. "Action" : "Update:*",
  367. "Principal" : "*",
  368. "Resource" : "*"
  369. }
  370. ]
  371. }`
  372. c.Assert(resp.StackPolicyBody, Equals, policy)
  373. c.Assert(resp.RequestId, Equals, "4af14eec-350e-11e4-b260-EXAMPLE")
  374. }
  375. func (s *S) TestGetTemplate(c *C) {
  376. testServer.Response(200, nil, GetTemplateResponse)
  377. resp, err := s.cf.GetTemplate("MyStack")
  378. c.Assert(err, IsNil)
  379. values := testServer.WaitRequest().PostForm
  380. // Post request test
  381. c.Assert(values.Get("Version"), Equals, "2010-05-15")
  382. c.Assert(values.Get("Action"), Equals, "GetTemplate")
  383. c.Assert(values.Get("StackName"), Equals, "MyStack")
  384. // Response test
  385. templateBody := `{
  386. "AWSTemplateFormatVersion" : "2010-09-09",
  387. "Description" : "Simple example",
  388. "Resources" : {
  389. "MySQS" : {
  390. "Type" : "AWS::SQS::Queue",
  391. "Properties" : {
  392. }
  393. }
  394. }
  395. }`
  396. c.Assert(resp.TemplateBody, Equals, templateBody)
  397. c.Assert(resp.RequestId, Equals, "4af14eec-350e-11e4-b260-EXAMPLE")
  398. }
  399. func (s *S) TestListStackResources(c *C) {
  400. testServer.Response(200, nil, ListStackResourcesResponse)
  401. resp, err := s.cf.ListStackResources("MyStack", "4dad1-32131da-d-31")
  402. c.Assert(err, IsNil)
  403. values := testServer.WaitRequest().PostForm
  404. // Post request test
  405. c.Assert(values.Get("Version"), Equals, "2010-05-15")
  406. c.Assert(values.Get("Action"), Equals, "ListStackResources")
  407. c.Assert(values.Get("StackName"), Equals, "MyStack")
  408. c.Assert(values.Get("NextToken"), Equals, "4dad1-32131da-d-31")
  409. // Response test
  410. t1, _ := time.Parse(time.RFC3339, "2011-06-21T20:15:58Z")
  411. t2, _ := time.Parse(time.RFC3339, "2011-06-21T20:25:57Z")
  412. t3, _ := time.Parse(time.RFC3339, "2011-06-21T20:26:12Z")
  413. t4, _ := time.Parse(time.RFC3339, "2011-06-21T20:28:48Z")
  414. t5, _ := time.Parse(time.RFC3339, "2011-06-21T20:29:06Z")
  415. t6, _ := time.Parse(time.RFC3339, "2011-06-21T20:29:23Z")
  416. expected := &cf.ListStackResourcesResponse{
  417. StackResourceSummaries: []cf.StackResourceSummary{
  418. {
  419. LogicalResourceId: "DBSecurityGroup",
  420. PhysicalResourceId: "gmarcteststack-dbsecuritygroup-1s5m0ez5lkk6w",
  421. ResourceType: "AWS::RDS::DBSecurityGroup",
  422. LastUpdatedTimestamp: t1,
  423. ResourceStatus: "CREATE_COMPLETE",
  424. },
  425. {
  426. LogicalResourceId: "SampleDB",
  427. PhysicalResourceId: "MyStack-sampledb-ycwhk1v830lx",
  428. ResourceType: "AWS::RDS::DBInstance",
  429. LastUpdatedTimestamp: t2,
  430. ResourceStatus: "CREATE_COMPLETE",
  431. },
  432. {
  433. LogicalResourceId: "SampleApplication",
  434. PhysicalResourceId: "MyStack-SampleApplication-1MKNASYR3RBQL",
  435. ResourceType: "AWS::ElasticBeanstalk::Application",
  436. LastUpdatedTimestamp: t3,
  437. ResourceStatus: "CREATE_COMPLETE",
  438. },
  439. {
  440. LogicalResourceId: "SampleEnvironment",
  441. PhysicalResourceId: "myst-Samp-1AGU6ERZX6M3Q",
  442. ResourceType: "AWS::ElasticBeanstalk::Environment",
  443. LastUpdatedTimestamp: t4,
  444. ResourceStatus: "CREATE_COMPLETE",
  445. },
  446. {
  447. LogicalResourceId: "AlarmTopic",
  448. PhysicalResourceId: "arn:aws:sns:us-east-1:803981987763:MyStack-AlarmTopic-SW4IQELG7RPJ",
  449. ResourceType: "AWS::SNS::Topic",
  450. LastUpdatedTimestamp: t5,
  451. ResourceStatus: "CREATE_COMPLETE",
  452. },
  453. {
  454. LogicalResourceId: "CPUAlarmHigh",
  455. PhysicalResourceId: "MyStack-CPUAlarmHigh-POBWQPDJA81F",
  456. ResourceType: "AWS::CloudWatch::Alarm",
  457. LastUpdatedTimestamp: t6,
  458. ResourceStatus: "CREATE_COMPLETE",
  459. },
  460. },
  461. NextToken: "",
  462. RequestId: "2d06e36c-ac1d-11e0-a958-f9382b6eb86b",
  463. }
  464. c.Assert(resp, DeepEquals, expected)
  465. }
  466. func (s *S) TestListStacks(c *C) {
  467. testServer.Response(200, nil, ListStacksResponse)
  468. resp, err := s.cf.ListStacks([]string{"CREATE_IN_PROGRESS", "DELETE_COMPLETE"}, "4dad1-32131da-d-31")
  469. c.Assert(err, IsNil)
  470. values := testServer.WaitRequest().PostForm
  471. // Post request test
  472. c.Assert(values.Get("Version"), Equals, "2010-05-15")
  473. c.Assert(values.Get("Action"), Equals, "ListStacks")
  474. c.Assert(values.Get("StackStatusFilter.member.1"), Equals, "CREATE_IN_PROGRESS")
  475. c.Assert(values.Get("StackStatusFilter.member.2"), Equals, "DELETE_COMPLETE")
  476. c.Assert(values.Get("NextToken"), Equals, "4dad1-32131da-d-31")
  477. // Response test
  478. c1, _ := time.Parse(time.RFC3339, "2011-05-23T15:47:44Z")
  479. c2, _ := time.Parse(time.RFC3339, "2011-03-05T19:57:58Z")
  480. d2, _ := time.Parse(time.RFC3339, "2011-03-10T16:20:51Z")
  481. expected := &cf.ListStacksResponse{
  482. StackSummaries: []cf.StackSummary{
  483. {
  484. StackId: "arn:aws:cloudformation:us-east-1:1234567:stack/TestCreate1/aaaaa",
  485. StackName: "vpc1",
  486. StackStatus: "CREATE_IN_PROGRESS",
  487. CreationTime: c1,
  488. TemplateDescription: "Creates one EC2 instance and a load balancer.",
  489. },
  490. {
  491. StackId: "arn:aws:cloudformation:us-east-1:1234567:stack/TestDelete2/bbbbb",
  492. StackName: "WP1",
  493. StackStatus: "DELETE_COMPLETE",
  494. CreationTime: c2,
  495. DeletionTime: d2,
  496. TemplateDescription: "A simple basic Cloudformation Template.",
  497. },
  498. },
  499. NextToken: "",
  500. RequestId: "2d06e36c-ac1d-11e0-a958-f9382b6eb86b",
  501. }
  502. c.Assert(resp, DeepEquals, expected)
  503. }
  504. func (s *S) TestSetStackPolicy(c *C) {
  505. testServer.Response(200, nil, SetStackPolicyResponse)
  506. resp, err := s.cf.SetStackPolicy("MyStack", "[Stack Policy Document]", "")
  507. c.Assert(err, IsNil)
  508. values := testServer.WaitRequest().PostForm
  509. // Post request test
  510. c.Assert(values.Get("Version"), Equals, "2010-05-15")
  511. c.Assert(values.Get("Action"), Equals, "SetStackPolicy")
  512. c.Assert(values.Get("StackName"), Equals, "MyStack")
  513. c.Assert(values.Get("StackPolicyBody"), Equals, "[Stack Policy Document]")
  514. c.Assert(values.Get("StackPolicyUrl"), Equals, "")
  515. // Response test
  516. c.Assert(resp.RequestId, Equals, "4af14eec-350e-11e4-b260-EXAMPLE")
  517. }
  518. func (s *S) TestUpdateStack(c *C) {
  519. testServer.Response(200, nil, UpdateStackResponse)
  520. stackParams := &cf.UpdateStackParams{
  521. Capabilities: []string{"CAPABILITY_IAM"},
  522. NotificationARNs: []string{"arn:aws:sns:us-east-1:1234567890:my-topic"},
  523. StackPolicyBody: "{PolicyBody}",
  524. StackPolicyDuringUpdateBody: "{PolicyDuringUpdateBody}",
  525. Parameters: []cf.Parameter{
  526. {
  527. ParameterKey: "AvailabilityZone",
  528. ParameterValue: "us-east-1a",
  529. },
  530. },
  531. UsePreviousTemplate: true,
  532. StackName: "MyStack",
  533. TemplateBody: "[Template Document]",
  534. }
  535. resp, err := s.cf.UpdateStack(stackParams)
  536. c.Assert(err, IsNil)
  537. values := testServer.WaitRequest().PostForm
  538. // Post request test
  539. c.Assert(values.Get("Version"), Equals, "2010-05-15")
  540. c.Assert(values.Get("Action"), Equals, "UpdateStack")
  541. c.Assert(values.Get("StackName"), Equals, "MyStack")
  542. c.Assert(values.Get("NotificationARNs.member.1"), Equals, "arn:aws:sns:us-east-1:1234567890:my-topic")
  543. c.Assert(values.Get("TemplateBody"), Equals, "[Template Document]")
  544. c.Assert(values.Get("Parameters.member.1.ParameterKey"), Equals, "AvailabilityZone")
  545. c.Assert(values.Get("Parameters.member.1.ParameterValue"), Equals, "us-east-1a")
  546. c.Assert(values.Get("Capabilities.member.1"), Equals, "CAPABILITY_IAM")
  547. c.Assert(values.Get("StackPolicyBody"), Equals, "{PolicyBody}")
  548. c.Assert(values.Get("StackPolicyDuringUpdateBody"), Equals, "{PolicyDuringUpdateBody}")
  549. c.Assert(values.Get("UsePreviousTemplate"), Equals, "true")
  550. // Response test
  551. c.Assert(resp.RequestId, Equals, "4af14eec-350e-11e4-b260-EXAMPLE")
  552. c.Assert(resp.StackId, Equals, "arn:aws:cloudformation:us-east-1:123456789:stack/MyStack/aaf549a0-a413-11df-adb3-5081b3858e83")
  553. }
  554. func (s *S) TestValidateTemplate(c *C) {
  555. testServer.Response(200, nil, ValidateTemplateResponse)
  556. resp, err := s.cf.ValidateTemplate("", "http://myTemplateRepository/TemplateOne.template")
  557. c.Assert(err, IsNil)
  558. values := testServer.WaitRequest().PostForm
  559. // Post request test
  560. c.Assert(values.Get("Version"), Equals, "2010-05-15")
  561. c.Assert(values.Get("Action"), Equals, "ValidateTemplate")
  562. c.Assert(values.Get("TemplateURL"), Equals, "http://myTemplateRepository/TemplateOne.template")
  563. c.Assert(values.Get("TemplateBody"), Equals, "")
  564. // Response test
  565. expected := &cf.ValidateTemplateResponse{
  566. Description: "Test",
  567. Capabilities: []string{"CAPABILITY_IAM"},
  568. Parameters: []cf.TemplateParameter{
  569. {
  570. NoEcho: false,
  571. ParameterKey: "InstanceType",
  572. Description: "Type of instance to launch",
  573. DefaultValue: "m1.small",
  574. },
  575. {
  576. NoEcho: false,
  577. ParameterKey: "WebServerPort",
  578. Description: "The TCP port for the Web Server",
  579. DefaultValue: "8888",
  580. },
  581. {
  582. NoEcho: false,
  583. ParameterKey: "KeyName",
  584. Description: "Name of an existing EC2 KeyPair to enable SSH access into the server",
  585. },
  586. },
  587. RequestId: "0be7b6e8-e4a0-11e0-a5bd-9f8d5a7dbc91",
  588. }
  589. c.Assert(resp, DeepEquals, expected)
  590. }