Completed
Push — develop ( fee1b3...576284 )
by Fabian
01:35
created

ecs_deploy.wait_for_finish()   B

Complexity

Conditions 6

Size

Total Lines 22

Duplication

Lines 0
Ratio 0 %

Code Coverage

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