sdk.go 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. package amazon
  2. import (
  3. "context"
  4. "fmt"
  5. "github.com/aws/aws-sdk-go/aws"
  6. "github.com/aws/aws-sdk-go/aws/session"
  7. "github.com/aws/aws-sdk-go/service/cloudformation"
  8. "github.com/aws/aws-sdk-go/service/cloudformation/cloudformationiface"
  9. "github.com/aws/aws-sdk-go/service/cloudwatchlogs"
  10. "github.com/aws/aws-sdk-go/service/cloudwatchlogs/cloudwatchlogsiface"
  11. "github.com/aws/aws-sdk-go/service/ec2"
  12. "github.com/aws/aws-sdk-go/service/ec2/ec2iface"
  13. "github.com/aws/aws-sdk-go/service/ecs"
  14. "github.com/aws/aws-sdk-go/service/ecs/ecsiface"
  15. "github.com/aws/aws-sdk-go/service/elbv2"
  16. "github.com/aws/aws-sdk-go/service/elbv2/elbv2iface"
  17. "github.com/aws/aws-sdk-go/service/iam"
  18. "github.com/aws/aws-sdk-go/service/iam/iamiface"
  19. "github.com/aws/aws-sdk-go/service/secretsmanager"
  20. "github.com/aws/aws-sdk-go/service/secretsmanager/secretsmanageriface"
  21. cf "github.com/awslabs/goformation/v4/cloudformation"
  22. "github.com/sirupsen/logrus"
  23. )
  24. type sdk struct {
  25. sess *session.Session
  26. ECS ecsiface.ECSAPI
  27. EC2 ec2iface.EC2API
  28. ELB elbv2iface.ELBV2API
  29. CW cloudwatchlogsiface.CloudWatchLogsAPI
  30. IAM iamiface.IAMAPI
  31. CF cloudformationiface.CloudFormationAPI
  32. SM secretsmanageriface.SecretsManagerAPI
  33. }
  34. func NewAPI(sess *session.Session) API {
  35. return sdk{
  36. ECS: ecs.New(sess),
  37. EC2: ec2.New(sess),
  38. ELB: elbv2.New(sess),
  39. CW: cloudwatchlogs.New(sess),
  40. IAM: iam.New(sess),
  41. CF: cloudformation.New(sess),
  42. SM: secretsmanager.New(sess),
  43. }
  44. }
  45. func (s sdk) ClusterExists(ctx context.Context, name string) (bool, error) {
  46. logrus.Debug("Check if cluster was already created: ", name)
  47. clusters, err := s.ECS.DescribeClustersWithContext(aws.Context(ctx), &ecs.DescribeClustersInput{
  48. Clusters: []*string{aws.String(name)},
  49. })
  50. if err != nil {
  51. return false, err
  52. }
  53. return len(clusters.Clusters) > 0, nil
  54. }
  55. func (s sdk) CreateCluster(ctx context.Context, name string) (string, error) {
  56. logrus.Debug("Create cluster ", name)
  57. response, err := s.ECS.CreateClusterWithContext(aws.Context(ctx), &ecs.CreateClusterInput{ClusterName: aws.String(name)})
  58. if err != nil {
  59. return "", err
  60. }
  61. return *response.Cluster.Status, nil
  62. }
  63. func (s sdk) DeleteCluster(ctx context.Context, name string) error {
  64. logrus.Debug("Delete cluster ", name)
  65. response, err := s.ECS.DeleteClusterWithContext(aws.Context(ctx), &ecs.DeleteClusterInput{Cluster: aws.String(name)})
  66. if err != nil {
  67. return err
  68. }
  69. if *response.Cluster.Status == "INACTIVE" {
  70. return nil
  71. }
  72. return fmt.Errorf("Failed to delete cluster, status: %s" + *response.Cluster.Status)
  73. }
  74. func (s sdk) VpcExists(ctx context.Context, vpcID string) (bool, error) {
  75. logrus.Debug("Check if VPC exists: ", vpcID)
  76. _, err := s.EC2.DescribeVpcsWithContext(aws.Context(ctx), &ec2.DescribeVpcsInput{VpcIds: []*string{&vpcID}})
  77. return err == nil, err
  78. }
  79. func (s sdk) GetDefaultVPC(ctx context.Context) (string, error) {
  80. logrus.Debug("Retrieve default VPC")
  81. vpcs, err := s.EC2.DescribeVpcsWithContext(aws.Context(ctx), &ec2.DescribeVpcsInput{
  82. Filters: []*ec2.Filter{
  83. {
  84. Name: aws.String("isDefault"),
  85. Values: []*string{aws.String("true")},
  86. },
  87. },
  88. })
  89. if err != nil {
  90. return "", err
  91. }
  92. if len(vpcs.Vpcs) == 0 {
  93. return "", fmt.Errorf("account has not default VPC")
  94. }
  95. return *vpcs.Vpcs[0].VpcId, nil
  96. }
  97. func (s sdk) GetSubNets(ctx context.Context, vpcID string) ([]string, error) {
  98. logrus.Debug("Retrieve SubNets")
  99. subnets, err := s.EC2.DescribeSubnetsWithContext(aws.Context(ctx), &ec2.DescribeSubnetsInput{
  100. DryRun: nil,
  101. Filters: []*ec2.Filter{
  102. {
  103. Name: aws.String("vpc-id"),
  104. Values: []*string{aws.String(vpcID)},
  105. },
  106. {
  107. Name: aws.String("default-for-az"),
  108. Values: []*string{aws.String("true")},
  109. },
  110. },
  111. })
  112. if err != nil {
  113. return nil, err
  114. }
  115. ids := []string{}
  116. for _, subnet := range subnets.Subnets {
  117. ids = append(ids, *subnet.SubnetId)
  118. }
  119. return ids, nil
  120. }
  121. func (s sdk) ListRolesForPolicy(ctx context.Context, policy string) ([]string, error) {
  122. entities, err := s.IAM.ListEntitiesForPolicyWithContext(aws.Context(ctx), &iam.ListEntitiesForPolicyInput{
  123. EntityFilter: aws.String("Role"),
  124. PolicyArn: aws.String(policy),
  125. })
  126. if err != nil {
  127. return nil, err
  128. }
  129. roles := []string{}
  130. for _, e := range entities.PolicyRoles {
  131. roles = append(roles, *e.RoleName)
  132. }
  133. return roles, nil
  134. }
  135. func (s sdk) GetRoleArn(ctx context.Context, name string) (string, error) {
  136. role, err := s.IAM.GetRoleWithContext(aws.Context(ctx), &iam.GetRoleInput{
  137. RoleName: aws.String(name),
  138. })
  139. if err != nil {
  140. return "", err
  141. }
  142. return *role.Role.Arn, nil
  143. }
  144. func (s sdk) StackExists(ctx context.Context, name string) (bool, error) {
  145. stacks, err := s.CF.DescribeStacksWithContext(aws.Context(ctx), &cloudformation.DescribeStacksInput{
  146. StackName: aws.String(name),
  147. })
  148. if err != nil {
  149. // FIXME doesn't work as expected
  150. return false, nil
  151. }
  152. return len(stacks.Stacks) > 0, nil
  153. }
  154. func (s sdk) CreateStack(ctx context.Context, name string, template *cf.Template) error {
  155. logrus.Debug("Create CloudFormation stack")
  156. json, err := template.JSON()
  157. if err != nil {
  158. return err
  159. }
  160. _, err = s.CF.CreateStackWithContext(aws.Context(ctx), &cloudformation.CreateStackInput{
  161. OnFailure: aws.String("DELETE"),
  162. StackName: aws.String(name),
  163. TemplateBody: aws.String(string(json)),
  164. TimeoutInMinutes: aws.Int64(10),
  165. })
  166. return err
  167. }
  168. func (s sdk) DescribeStackEvents(ctx context.Context, name string) error {
  169. // Fixme implement Paginator on Events and return as a chan(events)
  170. _, err := s.CF.DescribeStackEventsWithContext(aws.Context(ctx), &cloudformation.DescribeStackEventsInput{
  171. StackName: aws.String(name),
  172. })
  173. return err
  174. }
  175. func (s sdk) DeleteStack(ctx context.Context, name string) error {
  176. logrus.Debug("Delete CloudFormation stack")
  177. _, err := s.CF.DeleteStackWithContext(aws.Context(ctx), &cloudformation.DeleteStackInput{
  178. StackName: aws.String(name),
  179. })
  180. return err
  181. }
  182. func (s sdk) CreateSecret(ctx context.Context, name string, content string) (string, error) {
  183. logrus.Debug("Create secret " + name)
  184. return "test", nil
  185. }
  186. func (s sdk) InspectSecret(ctx context.Context, name string) error {
  187. fmt.Printf("... done. \n")
  188. return nil
  189. }
  190. func (s sdk) ListSecrets(ctx context.Context) error {
  191. fmt.Printf("... done. \n")
  192. return nil
  193. }
  194. func (s sdk) DeleteSecret(ctx context.Context, name string) error {
  195. fmt.Printf("... done. \n")
  196. return nil
  197. }