forked from jhpyle/docassemble
-
Notifications
You must be signed in to change notification settings - Fork 0
/
da-cli
executable file
·156 lines (133 loc) · 5.78 KB
/
da-cli
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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
#!/usr/bin/env python
# Before running this script, make sure boto3 is installed:
# sudo apt-get install python-boto3
# or
# sudo pip install boto3
keyPair = 'ec2.pem'
serviceApp = 'app'
serviceBackend = 'backend'
targetGroupWeb = 'web'
targetGroupWebSocket = 'websocket'
targetGroupRedirect = 'http-redirect'
autoScalingGroup = 'docassembleAsg'
import boto3
import time
import sys
import copy
def available_instances():
instances = list()
statuses = ec2.describe_instance_status()
for status in statuses['InstanceStatuses']:
if status['InstanceStatus']['Status'] == 'ok' and status['SystemStatus']['Status'] == 'ok':
instances.append(status['InstanceId'])
return instances
def instances_for_service(service):
instances = list()
for taskarn in ecs.list_tasks(serviceName=service).get('taskArns', list()):
for item in ecs.describe_tasks(tasks=[taskarn]).get('tasks', list()):
for instance in ecs.describe_container_instances(containerInstances=[item['containerInstanceArn']]).get('containerInstances', list()):
instances.append(instance['ec2InstanceId'])
return instances
def get_target_groups():
result = dict()
for tg in elb.describe_target_groups().get('TargetGroups', list()):
result[tg['TargetGroupName']] = tg['TargetGroupArn']
return result
def get_registered_targets(targetgroup):
instances = list()
for target in elb.describe_target_health(TargetGroupArn=targetgroup).get('TargetHealthDescriptions', list()):
instances.append(target['Target']['Id'])
return instances
def get_service_status(servicename):
return ecs.describe_services(services=[servicename])['services'][0]
def update_desired_count(service, desired_count):
ecs.update_service(service=service, desiredCount=int(desired_count))
while True:
result = get_service_status(service)
if result['desiredCount'] != result['runningCount']:
time.sleep(2)
else:
break
def fix_registered_instances():
target_groups_arns = get_target_groups()
web_servers = get_registered_targets(target_groups_arns[targetGroupWeb])
web_sockets_servers = get_registered_targets(target_groups_arns[targetGroupWebSocket])
for server in web_servers:
if server not in web_sockets_servers:
elb.register_targets(TargetGroupArn=target_groups_arns[targetGroupWebSocket], Targets=[{'Id': server}])
http_servers = get_registered_targets(target_groups_arns[targetGroupRedirect])
for server in web_servers:
if server not in http_servers:
elb.register_targets(TargetGroupArn=target_groups_arns[targetGroupRedirect], Targets=[{'Id': server}])
def start_up(the_count=1):
the_count = int(the_count)
print "Creating EC2 instances"
update_ec2_instances(the_count + 1)
print "Updating backend count"
update_desired_count(serviceBackend, 1)
print "Updating app count"
update_desired_count(serviceApp, the_count)
print "Waiting for targets to be registered"
target_groups_arns = get_target_groups()
while True:
web_servers = get_registered_targets(target_groups_arns[targetGroupWeb])
if len(web_servers) >= the_count:
break
time.sleep(2)
print "Registering targets for target group " + str(targetGroupWebSocket)
fix_registered_instances()
def shut_down():
print "Updating app count"
update_desired_count(serviceApp, 0)
print "Updating backend count"
update_desired_count(serviceBackend, 0)
print "Terminating EC2 instances"
update_ec2_instances(0)
def connect_string(service):
for instance_id in instances_for_service(service):
print "ssh -i " + keyPair + " ec2-user@" + ec2.describe_instances(InstanceIds=[instance_id])['Reservations'][0]['Instances'][0]['PublicDnsName']
def update_ec2_instances(desired_count):
autoscale.set_desired_capacity(AutoScalingGroupName=autoScalingGroup, DesiredCapacity=int(desired_count))
while True:
result = autoscale.describe_auto_scaling_groups(AutoScalingGroupNames=[autoScalingGroup])['AutoScalingGroups'][0]
if result['DesiredCapacity'] != len(result['Instances']):
time.sleep(2)
else:
break
while True:
if len(available_instances()) < int(desired_count):
time.sleep(2)
else:
break
def shutdown_unused_ec2_instances():
all_instances = available_instances()
used_instances = list()
used_instances.extend(instances_for_service(serviceBackend))
used_instances.extend(instances_for_service(serviceApp))
for instance in all_instances:
if instance in used_instances:
continue
autoscale.terminate_instance_in_auto_scaling_group(InstanceId=instance, ShouldDecrementDesiredCapacity=True)
while True:
result = autoscale.describe_auto_scaling_groups(AutoScalingGroupNames=[autoScalingGroup])['AutoScalingGroups'][0]
if result['DesiredCapacity'] != len(result['Instances']):
time.sleep(2)
else:
break
dispatch = dict(shutdown_unused_ec2_instances=shutdown_unused_ec2_instances, update_ec2_instances=update_ec2_instances, connect_string=connect_string, shut_down=shut_down, start_up=start_up, fix_registered_instances=fix_registered_instances, update_desired_count=update_desired_count)
arguments = copy.deepcopy(sys.argv)
this_file = arguments.pop(0)
def error_message():
print "usage: " + str(this_file) + " <command>\nThe <command> can be one of: " + ', '.join(dispatch.keys())
if len(arguments) == 0:
error_message()
sys.exit(1)
command = arguments.pop(0)
if command not in dispatch:
error_message()
sys.exit(1)
ec2 = boto3.client('ec2')
ecs = boto3.client('ecs')
elb = boto3.client('elbv2')
autoscale = boto3.client('autoscaling')
dispatch[command](*arguments)