cloudformation_test.go 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. package backend
  2. import (
  3. "fmt"
  4. "reflect"
  5. "testing"
  6. "github.com/docker/ecs-plugin/pkg/compose"
  7. "github.com/aws/aws-sdk-go/service/elbv2"
  8. "github.com/awslabs/goformation/v4/cloudformation"
  9. "github.com/awslabs/goformation/v4/cloudformation/ec2"
  10. "github.com/awslabs/goformation/v4/cloudformation/elasticloadbalancingv2"
  11. "github.com/awslabs/goformation/v4/cloudformation/iam"
  12. "github.com/compose-spec/compose-go/cli"
  13. "github.com/compose-spec/compose-go/loader"
  14. "github.com/compose-spec/compose-go/types"
  15. "gotest.tools/v3/assert"
  16. "gotest.tools/v3/golden"
  17. )
  18. func TestSimpleConvert(t *testing.T) {
  19. project := load(t, "testdata/input/simple-single-service.yaml")
  20. result := convertResultAsString(t, project, "TestCluster")
  21. expected := "simple/simple-cloudformation-conversion.golden"
  22. golden.Assert(t, result, expected)
  23. }
  24. func TestSimpleWithOverrides(t *testing.T) {
  25. project := load(t, "testdata/input/simple-single-service.yaml", "testdata/input/simple-single-service-with-overrides.yaml")
  26. result := convertResultAsString(t, project, "TestCluster")
  27. expected := "simple/simple-cloudformation-with-overrides-conversion.golden"
  28. golden.Assert(t, result, expected)
  29. }
  30. func TestRolePolicy(t *testing.T) {
  31. template := convertYaml(t, `
  32. version: "3"
  33. services:
  34. foo:
  35. image: hello_world
  36. x-aws-pull_credentials: "secret"
  37. `)
  38. role := template.Resources["FooTaskExecutionRole"].(*iam.Role)
  39. assert.Check(t, role != nil)
  40. assert.Check(t, role.ManagedPolicyArns[0] == ECSTaskExecutionPolicy)
  41. assert.Check(t, role.ManagedPolicyArns[1] == ECRReadOnlyPolicy)
  42. // We expect an extra policy has been created for x-aws-pull_credentials
  43. assert.Check(t, len(role.Policies) == 1)
  44. policy := role.Policies[0].PolicyDocument.(*PolicyDocument)
  45. expected := []string{"secretsmanager:GetSecretValue", "ssm:GetParameters", "kms:Decrypt"}
  46. assert.DeepEqual(t, expected, policy.Statement[0].Action)
  47. assert.DeepEqual(t, []string{"secret"}, policy.Statement[0].Resource)
  48. }
  49. func TestMapNetworksToSecurityGroups(t *testing.T) {
  50. template := convertYaml(t, `
  51. version: "3"
  52. services:
  53. test:
  54. image: hello_world
  55. networks:
  56. - front-tier
  57. - back-tier
  58. networks:
  59. front-tier:
  60. name: public
  61. back-tier:
  62. internal: true
  63. `)
  64. assert.Check(t, template.Resources["TestPublicNetwork"] != nil)
  65. assert.Check(t, template.Resources["TestBacktierNetwork"] != nil)
  66. assert.Check(t, template.Resources["TestBacktierNetworkIngress"] != nil)
  67. ingress := template.Resources["TestPublicNetworkIngress"].(*ec2.SecurityGroupIngress)
  68. assert.Check(t, ingress != nil)
  69. assert.Check(t, ingress.SourceSecurityGroupId == cloudformation.Ref("TestPublicNetwork"))
  70. }
  71. func TestLoadBalancerTypeApplication(t *testing.T) {
  72. template := convertYaml(t, `
  73. version: "3"
  74. services:
  75. test:
  76. image: nginx
  77. ports:
  78. - 80:80
  79. `)
  80. lb := template.Resources["TestLoadBalancer"].(*elasticloadbalancingv2.LoadBalancer)
  81. assert.Check(t, lb != nil)
  82. assert.Check(t, lb.Type == elbv2.LoadBalancerTypeEnumApplication)
  83. assert.Check(t, len(lb.SecurityGroups) > 0)
  84. }
  85. func TestLoadBalancerTypeNetwork(t *testing.T) {
  86. template := convertYaml(t, `
  87. version: "3"
  88. services:
  89. test:
  90. image: nginx
  91. ports:
  92. - 80:80
  93. - 88:88
  94. `)
  95. lb := template.Resources["TestLoadBalancer"].(*elasticloadbalancingv2.LoadBalancer)
  96. assert.Check(t, lb != nil)
  97. assert.Check(t, lb.Type == elbv2.LoadBalancerTypeEnumNetwork)
  98. }
  99. func TestResourcesHaveProjectTagSet(t *testing.T) {
  100. template := convertYaml(t, `
  101. version: "3"
  102. services:
  103. test:
  104. image: nginx
  105. ports:
  106. - 80:80
  107. - 88:88
  108. `)
  109. for _, r := range template.Resources {
  110. tags := reflect.Indirect(reflect.ValueOf(r)).FieldByName("Tags")
  111. if !tags.IsValid() {
  112. continue
  113. }
  114. for i := 0; i < tags.Len(); i++ {
  115. k := tags.Index(i).FieldByName("Key").String()
  116. v := tags.Index(i).FieldByName("Value").String()
  117. if k == compose.ProjectTag {
  118. assert.Equal(t, v, "Test")
  119. }
  120. }
  121. }
  122. }
  123. func convertResultAsString(t *testing.T, project *types.Project, clusterName string) string {
  124. client, err := NewBackend("", clusterName, "")
  125. assert.NilError(t, err)
  126. result, err := client.Convert(project)
  127. assert.NilError(t, err)
  128. resultAsJSON, err := result.JSON()
  129. assert.NilError(t, err)
  130. return fmt.Sprintf("%s\n", string(resultAsJSON))
  131. }
  132. func load(t *testing.T, paths ...string) *types.Project {
  133. options := cli.ProjectOptions{
  134. Name: t.Name(),
  135. ConfigPaths: paths,
  136. }
  137. project, err := cli.ProjectFromOptions(&options)
  138. assert.NilError(t, err)
  139. return project
  140. }
  141. func convertYaml(t *testing.T, yaml string) *cloudformation.Template {
  142. dict, err := loader.ParseYAML([]byte(yaml))
  143. assert.NilError(t, err)
  144. model, err := loader.Load(types.ConfigDetails{
  145. ConfigFiles: []types.ConfigFile{
  146. {Config: dict},
  147. },
  148. }, func(options *loader.Options) {
  149. options.Name = "Test"
  150. })
  151. assert.NilError(t, err)
  152. template, err := Backend{}.Convert(model)
  153. assert.NilError(t, err)
  154. return template
  155. }