-
-
Notifications
You must be signed in to change notification settings - Fork 3
/
aws.go
137 lines (125 loc) · 4.71 KB
/
aws.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
package cloud
import (
"errors"
"fmt"
"strings"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/autoscaling"
"github.com/aws/aws-sdk-go/service/autoscaling/autoscalingiface"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/aws/aws-sdk-go/service/ec2/ec2iface"
)
var (
ErrCannotIncreaseDesiredCountAboveMax = errors.New("cannot increase ASG desired size above max ASG size")
)
// GetServices returns an instance of a EC2 client with a session as well as
// an instance of an Autoscaling client with a session
func GetServices(awsRegion string) (ec2iface.EC2API, autoscalingiface.AutoScalingAPI, error) {
awsSession, err := session.NewSession(&aws.Config{Region: aws.String(awsRegion)})
if err != nil {
return nil, nil, err
}
return ec2.New(awsSession), autoscaling.New(awsSession), nil
}
func DescribeAutoScalingGroupsByNames(svc autoscalingiface.AutoScalingAPI, names []string) ([]*autoscaling.Group, error) {
input := &autoscaling.DescribeAutoScalingGroupsInput{
AutoScalingGroupNames: aws.StringSlice(names),
MaxRecords: aws.Int64(100),
}
result, err := svc.DescribeAutoScalingGroups(input)
if err != nil {
return nil, err
}
return result.AutoScalingGroups, nil
}
func filterAutoScalingGroupsByTag(autoScalingGroups []*autoscaling.Group, filter func([]*autoscaling.TagDescription) bool) (ret []*autoscaling.Group) {
for _, autoScalingGroup := range autoScalingGroups {
if filter(autoScalingGroup.Tags) {
ret = append(ret, autoScalingGroup)
}
}
return
}
// DescribeEnabledAutoScalingGroupsByTags Gets AutoScalingGroups that match the given tags
func DescribeEnabledAutoScalingGroupsByTags(svc autoscalingiface.AutoScalingAPI, autodiscoveryTags string) ([]*autoscaling.Group, error) {
input := &autoscaling.DescribeAutoScalingGroupsInput{}
var result []*autoscaling.Group
err := svc.DescribeAutoScalingGroupsPages(input, func(page *autoscaling.DescribeAutoScalingGroupsOutput, lastPage bool) bool {
tagFilter := func(tagDescriptions []*autoscaling.TagDescription) bool {
var matches []bool
for _, tag := range strings.Split(autodiscoveryTags, ",") {
kv := strings.Split(tag, "=")
match := false
for _, tagDescription := range tagDescriptions {
if aws.StringValue(tagDescription.Key) == kv[0] && aws.StringValue(tagDescription.Value) == kv[1] {
match = true
break
}
}
matches = append(matches, match)
}
for _, match := range matches {
if !match {
return false
}
}
return true
}
result = append(result, filterAutoScalingGroupsByTag(page.AutoScalingGroups, tagFilter)...)
return !lastPage
})
if err != nil {
return nil, err
}
return result, nil
}
func DescribeLaunchTemplateByID(svc ec2iface.EC2API, id string) (*ec2.LaunchTemplate, error) {
input := &ec2.DescribeLaunchTemplatesInput{
LaunchTemplateIds: []*string{
aws.String(id),
},
}
return DescribeLaunchTemplate(svc, input)
}
func DescribeLaunchTemplateByName(svc ec2iface.EC2API, name string) (*ec2.LaunchTemplate, error) {
input := &ec2.DescribeLaunchTemplatesInput{
LaunchTemplateNames: []*string{
aws.String(name),
},
}
return DescribeLaunchTemplate(svc, input)
}
func DescribeLaunchTemplate(svc ec2iface.EC2API, input *ec2.DescribeLaunchTemplatesInput) (*ec2.LaunchTemplate, error) {
templatesOutput, err := svc.DescribeLaunchTemplates(input)
descriptiveMsg := fmt.Sprintf("%v / %v", aws.StringValueSlice(input.LaunchTemplateIds), aws.StringValueSlice(input.LaunchTemplateNames))
if err != nil {
return nil, fmt.Errorf("unable to get description for Launch Templates %s: %v", descriptiveMsg, err)
}
if len(templatesOutput.LaunchTemplates) < 1 {
return nil, nil
}
return templatesOutput.LaunchTemplates[0], nil
}
func SetAutoScalingGroupDesiredCount(svc autoscalingiface.AutoScalingAPI, asg *autoscaling.Group, count int64) error {
if count > aws.Int64Value(asg.MaxSize) {
return ErrCannotIncreaseDesiredCountAboveMax
}
desiredInput := &autoscaling.SetDesiredCapacityInput{
AutoScalingGroupName: asg.AutoScalingGroupName,
DesiredCapacity: aws.Int64(count),
HonorCooldown: aws.Bool(true),
}
_, err := svc.SetDesiredCapacity(desiredInput)
if err != nil {
return fmt.Errorf("unable to increase ASG %s desired count to %d: %v", aws.StringValue(asg.AutoScalingGroupName), count, err)
}
return nil
}
func TerminateEc2Instance(svc autoscalingiface.AutoScalingAPI, instance *autoscaling.Instance, shouldDecrementDesiredCapacity bool) error {
_, err := svc.TerminateInstanceInAutoScalingGroup(&autoscaling.TerminateInstanceInAutoScalingGroupInput{
InstanceId: instance.InstanceId,
ShouldDecrementDesiredCapacity: aws.Bool(shouldDecrementDesiredCapacity),
})
return err
}