Skip to content

Commit

Permalink
Ability to place a stack into maintenance mode zalando-stups#443
Browse files Browse the repository at this point in the history
Given a stack it will detect all asgs within that stack
negates the tag named 'maintenance' and do the same
on all instances currently belonging to that asg.

$ senza maintenance some-stack-name
Changing maintenance mode on Auto Scaling Group some-stack-name-version-AppServer-1R2KFL5HLI5NT..
Maintance mode set to False for some-stack-name-version-AppServer-1R2KFL5HLI5NT

$ senza maintenance some-stack-name
Changing maintenance mode on Auto Scaling Group some-stack-name-version-AppServer-1R2KFL5HLI5NT..
Maintance mode set to True for some-stack-name-version-AppServer-1R2KFL5HLI5NT

Signed-off-by: Ian Duffy <[email protected]>
  • Loading branch information
Ian Duffy committed Feb 1, 2017
1 parent c369a90 commit f14b1b7
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 0 deletions.
40 changes: 40 additions & 0 deletions senza/cli.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#!/usr/bin/env python3
import ast
import base64
import calendar
import collections
Expand Down Expand Up @@ -1389,6 +1390,45 @@ def get_auto_scaling_groups(stack_refs, region):
yield asg_name


@cli.command()
@click.argument('stack_name')
@click.argument('stack_version', required=False)
@region_option
def maintenance(stack_name, stack_version, region):
'''Negates the value of the tag named 'maintenance' across the given stack
asg and its instances.'''

stack_refs = get_stack_refs([stack_name, stack_version])
region = get_region(region)
check_credentials(region)

asg = BotoClientProxy('autoscaling', region)
ec2 = BotoClientProxy('ec2', region)

for asg_name in get_auto_scaling_groups(stack_refs, region):
with Action('Changing maintenance mode on Auto Scaling Group {}..'.format(asg_name)) as act:
result = asg.describe_auto_scaling_groups(AutoScalingGroupNames=[asg_name])
groups = result['AutoScalingGroups']
for group in groups:
result = [tag['Value'] for tag in group['Tags'] if tag['Key'] == 'maintenance']
result = 'false' if not result else not ast.literal_eval(result[0])
ec2.create_tags(
Resources=[instance['InstanceId'] for instance in group['Instances']],
Tags=[{
'Key': 'maintenance',
'Value': str(result)
}]
)
asg.create_or_update_tags(Tags=[{
'ResourceId': group['AutoScalingGroupName'],
'ResourceType': 'auto-scaling-group',
'Key': 'maintenance',
'Value': str(result),
'PropagateAtLaunch': True
}])
act.ok('\nMaintance mode set to {} for {}'.format(result, asg_name))


@cli.command()
@click.argument('stack_ref', nargs=-1)
@region_option
Expand Down
18 changes: 18 additions & 0 deletions tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -1501,6 +1501,24 @@ def test_AccountArguments(monkeypatch):
assert test.Domain == 'example.net'
assert test.TeamID == 'cli'

def test_maintenance(monkeypatch):
boto3 = MagicMock()
boto3.list_stacks.return_value = {'StackSummaries': [{'StackName': 'myapp-1',
'CreationTime': '2016-06-14'}]}
boto3.describe_stack_resources.return_value = {'StackResources':
[{'ResourceType': 'AWS::AutoScaling::AutoScalingGroup',
'PhysicalResourceId': 'myasg'}]}
instance = {'InstanceId': 'MyInstance'}
group = {'AutoScalingGroupName': 'myasg', 'Instances': [instance], 'Tags': []}
boto3.describe_auto_scaling_groups.return_value = {'AutoScalingGroups': [group]}

monkeypatch.setattr('boto3.client', MagicMock(return_value=boto3))

runner = CliRunner()
result = runner.invoke(cli, ['maintenance', 'myapp', '1', '--region=aa-fakeregion-1'],
catch_exceptions=False)

assert 'Changing maintenance mode on Auto Scaling Group' in result.output

def test_patch(monkeypatch):
boto3 = MagicMock()
Expand Down

0 comments on commit f14b1b7

Please sign in to comment.