Completed
Push — master ( a30f7a...98e9e8 )
by Fabian
01:38 queued 34s
created

ecs_deploy.ecs()   A

Complexity

Conditions 1

Size

Total Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 1.125
Metric Value
cc 1
dl 0
loc 3
ccs 1
cts 2
cp 0.5
crap 1.125
rs 10
1 1
from __future__ import print_function, absolute_import
2 1
from time import sleep
3
4 1
import click
5 1
from datetime import datetime, timedelta
6
7 1
from ecs_deploy.ecs import DeployAction, ScaleAction, EcsClient
8
9
10 1
@click.group()
11
def ecs():
12
    pass
13
14
15 1
def get_client(access_key_id, secret_access_key, region, profile):
16 1
    return EcsClient(access_key_id, secret_access_key, region, profile)
17
18
19 1
@click.command()
20 1
@click.argument('cluster')
21 1
@click.argument('service')
22 1
@click.option('-t', '--tag', help='Changes the tag for ALL container images')
23 1
@click.option('-i', '--image', type=(str, str), multiple=True, help='Overwrites the image for a container')
24 1
@click.option('-c', '--command', type=(str, str), multiple=True, help='Overwrites the command in a container')
25 1
@click.option('--region', required=False, help='AWS region')
26 1
@click.option('--access-key-id', required=False, help='AWS access key id')
27 1
@click.option('--secret-access-key', required=False, help='AWS secret access yey')
28 1
@click.option('--profile', required=False, help='AWS configuration profile')
29 1
@click.option('--timeout', required=False, default=300, type=int, help='AWS configuration profile')
30
def deploy(cluster, service, tag, image, command, access_key_id, secret_access_key, region, profile, timeout):
31
    """
32
    Redeploy or modify a service.
33
34
    \b
35
    CLUSTER is the name of your cluster (e.g. 'my-custer') within ECS.
36
    SERVICE is the name of your service (e.g. 'my-app') within ECS.
37
38
    When not giving any other options, the task definition will not be changed. It will just be duplicated, so that
39
    all container images will be pulled and redeployed.
40
    """
41
42 1
    try:
43 1
        client = get_client(access_key_id, secret_access_key, region, profile)
44 1
        deployment = DeployAction(client, cluster, service)
45 1
        task_definition = deployment.get_current_task_definition(deployment.service)
46
47 1
        task_definition.set_images(tag, **{key: value for (key, value) in image})
48 1
        task_definition.set_commands(**{key: value for (key, value) in command})
49 1
        print_diff(task_definition)
50
51 1
        click.secho('Creating new task definition revision')
52 1
        new_task_definition = deployment.update_task_definition(task_definition)
53 1
        click.secho('Successfully created revision: %d' % new_task_definition.revision, fg='green')
54 1
        click.secho('Successfully deregistered revision: %d\n' % task_definition.revision, fg='green')
55 1
        click.secho('Updating service')
56 1
        deployment.deploy(new_task_definition)
57 1
        click.secho('Successfully changed task definition to: %s:%s\n' %
58
                    (new_task_definition.family, new_task_definition.revision), fg='green')
59
60 1
        wait_for_finish(deployment, timeout, 'Deploying task definition', 'Deployment successful', 'Deployment failed')
61
62 1
    except Exception as e:
63 1
        click.secho('%s\n' % str(e), fg='red', err=True)
64 1
        exit(1)
65
66
67 1
@click.command()
68 1
@click.argument('cluster')
69 1
@click.argument('service')
70 1
@click.argument('desired_count', type=int)
71 1
@click.option('--region', help='AWS region')
72 1
@click.option('--access-key-id', help='AWS access key id')
73 1
@click.option('--secret-access-key', help='AWS secret access yey')
74 1
@click.option('--profile', help='AWS configuration profile')
75 1
@click.option('--timeout', default=300, type=int, help='AWS configuration profile')
76
def scale(cluster, service, desired_count, access_key_id, secret_access_key, region, profile, timeout):
77
    """
78
    Scale a service up or down.
79
80
    \b
81
    CLUSTER is the name of your cluster (e.g. 'my-custer') within ECS.
82
    SERVICE is the name of your service (e.g. 'my-app') within ECS.
83
    DESIRED_COUNT is the number of tasks your service should run.
84
    """
85 1
    try:
86 1
        client = get_client(access_key_id, secret_access_key, region, profile)
87 1
        scaling = ScaleAction(client, cluster, service)
88 1
        click.secho('Updating service')
89 1
        scaling.scale(desired_count)
90 1
        click.secho('Successfully changed desired count to: %s\n' % desired_count, fg='green')
91 1
        wait_for_finish(scaling, timeout, 'Scaling service', 'Scaling successful', 'Scaling failed')
92
93 1
    except Exception as e:
94 1
        click.secho('%s\n' % str(e), fg='red', err=True)
95 1
        exit(1)
96
97
98 1
def wait_for_finish(action, timeout, title, success_message, failure_message):
99 1
    click.secho(title, nl=False)
100 1
    waiting = True
101 1
    waiting_timeout = datetime.now() + timedelta(seconds=timeout)
102 1
    while waiting and datetime.now() < waiting_timeout:
103 1
        sleep(1)
104 1
        click.secho('.', nl=False)
105 1
        service = action.get_service()
106 1
        waiting = not action.is_deployed(service) and not service.errors
107
108 1
    if waiting or service.errors:
109 1
        print_errors(service, waiting, failure_message)
110 1
        exit(1)
111
112 1
    click.secho('\n%s\n' % success_message, fg='green')
113 1
    exit(0)
114
115
116 1
def print_diff(task_definition):
117 1
    if task_definition.diff:
118 1
        click.secho('Updating task definition')
119 1
        for diff in task_definition.diff:
120 1
            click.secho(str(diff), fg='blue')
121 1
        click.secho('')
122
123
124 1
def print_errors(service, was_timeout=False, message=''):
125 1
    if was_timeout:
126 1
        click.secho('\n%s (timeout)\n' % message, fg='red', err=True)
127
    else:
128 1
        click.secho('\n%s\n' % message, fg='red', err=True)
129
130 1
    for timestamp in service.errors:
131 1
        click.secho('%s\n%s\n' % (timestamp, service.errors[timestamp]), fg='red', err=True)
132
133 1
    if service.older_errors:
134 1
        click.secho('Older errors', fg='yellow', err=True)
135 1
        for timestamp in service.older_errors:
136 1
            click.secho('%s\n%s\n' % (timestamp, service.older_errors[timestamp]), fg='yellow', err=True)
137
138
139 1
ecs.add_command(deploy)
140 1
ecs.add_command(scale)
141
142 1
if __name__ == '__main__':
143
    ecs()
144