up.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. package backend
  2. import (
  3. "context"
  4. "fmt"
  5. "os"
  6. "os/signal"
  7. "syscall"
  8. "github.com/compose-spec/compose-go/cli"
  9. "github.com/compose-spec/compose-go/types"
  10. "github.com/docker/ecs-plugin/pkg/compose"
  11. )
  12. func (b *Backend) Up(ctx context.Context, options *cli.ProjectOptions) error {
  13. project, err := cli.ProjectFromOptions(options)
  14. if err != nil {
  15. return err
  16. }
  17. err = b.api.CheckRequirements(ctx, b.Region)
  18. if err != nil {
  19. return err
  20. }
  21. cluster, err := b.GetCluster(ctx, project)
  22. if err != nil {
  23. return err
  24. }
  25. template, err := b.Convert(project)
  26. if err != nil {
  27. return err
  28. }
  29. vpc, err := b.GetVPC(ctx, project)
  30. if err != nil {
  31. return err
  32. }
  33. subNets, err := b.api.GetSubNets(ctx, vpc)
  34. if err != nil {
  35. return err
  36. }
  37. if len(subNets) < 2 {
  38. return fmt.Errorf("VPC %s should have at least 2 associated subnets in different availability zones", vpc)
  39. }
  40. lb, err := b.GetLoadBalancer(ctx, project)
  41. if err != nil {
  42. return err
  43. }
  44. parameters := map[string]string{
  45. ParameterClusterName: cluster,
  46. ParameterVPCId: vpc,
  47. ParameterSubnet1Id: subNets[0],
  48. ParameterSubnet2Id: subNets[1],
  49. ParameterLoadBalancerARN: lb,
  50. }
  51. update, err := b.api.StackExists(ctx, project.Name)
  52. if err != nil {
  53. return err
  54. }
  55. operation := compose.StackCreate
  56. if update {
  57. operation = compose.StackUpdate
  58. changeset, err := b.api.CreateChangeSet(ctx, project.Name, template, parameters)
  59. if err != nil {
  60. return err
  61. }
  62. err = b.api.UpdateStack(ctx, changeset)
  63. if err != nil {
  64. return err
  65. }
  66. } else {
  67. err = b.api.CreateStack(ctx, project.Name, template, parameters)
  68. if err != nil {
  69. return err
  70. }
  71. }
  72. signalChan := make(chan os.Signal, 1)
  73. signal.Notify(signalChan, syscall.SIGINT, syscall.SIGTERM)
  74. go func() {
  75. <-signalChan
  76. fmt.Println("user interrupted deployment. Deleting stack...")
  77. b.Down(ctx, options)
  78. }()
  79. err = b.WaitStackCompletion(ctx, project.Name, operation)
  80. return err
  81. }
  82. func (b Backend) GetVPC(ctx context.Context, project *types.Project) (string, error) {
  83. //check compose file for custom VPC selected
  84. if vpc, ok := project.Extensions[compose.ExtensionVPC]; ok {
  85. vpcID := vpc.(string)
  86. ok, err := b.api.VpcExists(ctx, vpcID)
  87. if err != nil {
  88. return "", err
  89. }
  90. if !ok {
  91. return "", fmt.Errorf("VPC does not exist: %s", vpc)
  92. }
  93. return vpcID, nil
  94. }
  95. defaultVPC, err := b.api.GetDefaultVPC(ctx)
  96. if err != nil {
  97. return "", err
  98. }
  99. return defaultVPC, nil
  100. }
  101. func (b Backend) GetLoadBalancer(ctx context.Context, project *types.Project) (string, error) {
  102. //check compose file for custom VPC selected
  103. if ext, ok := project.Extensions[compose.ExtensionLB]; ok {
  104. lb := ext.(string)
  105. ok, err := b.api.LoadBalancerExists(ctx, lb)
  106. if err != nil {
  107. return "", err
  108. }
  109. if !ok {
  110. return "", fmt.Errorf("load balancer does not exist: %s", lb)
  111. }
  112. return lb, nil
  113. }
  114. return "", nil
  115. }
  116. func (b Backend) GetCluster(ctx context.Context, project *types.Project) (string, error) {
  117. //check compose file for custom VPC selected
  118. if ext, ok := project.Extensions[compose.ExtensionCluster]; ok {
  119. cluster := ext.(string)
  120. ok, err := b.api.ClusterExists(ctx, cluster)
  121. if err != nil {
  122. return "", err
  123. }
  124. if !ok {
  125. return "", fmt.Errorf("cluster does not exist: %s", cluster)
  126. }
  127. return cluster, nil
  128. }
  129. return "", nil
  130. }