Completed
Push — develop ( 576284...d9b846 )
by Fabian
01:43
created

ecs_deploy.get_client()   A

Complexity

Conditions 1

Size

Total Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1
Metric Value
cc 1
dl 0
loc 2
ccs 2
cts 2
cp 1
crap 1
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
    return True
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 1
@click.command()
67 1
@click.argument('cluster')
68 1
@click.argument('service')
69 1
@click.argument('desired_count', type=int)
70 1
@click.option('--region', help='AWS region')
71 1
@click.option('--access-key-id', help='AWS access key id')
72 1
@click.option('--secret-access-key', help='AWS secret access yey')
73 1
@click.option('--profile', help='AWS configuration profile')
74 1
@click.option('--timeout', default=300, type=int, help='AWS configuration profile')
75
def scale(cluster, service, desired_count, access_key_id, secret_access_key, region, profile, timeout):
76
    """
77
    Scale a service up or down.
78
79
    \b
80
    CLUSTER is the name of your cluster (e.g. 'my-custer') within ECS.
81
    SERVICE is the name of your service (e.g. 'my-app') within ECS.
82
    DESIRED_COUNT is the number of tasks your service should run.
83
    """
84 1
    try:
85 1
        client = get_client(access_key_id, secret_access_key, region, profile)
86 1
        scaling = ScaleAction(client, cluster, service)
87 1
        click.secho('Updating service')
88 1
        scaling.scale(desired_count)
89 1
        click.secho('Successfully changed desired count to: %s\n' % desired_count, fg='green')
90 1
        wait_for_finish(scaling, timeout, 'Scaling service', 'Scaling successful', 'Scaling failed')
91
92 1
    except Exception as e:
93 1
        click.secho('%s\n' % str(e), fg='red', err=True)
94 1
        exit(1)
95
96
97 1
def wait_for_finish(action, timeout, title, success_message, failure_message):
98 1
    click.secho(title, nl=False)
99 1
    waiting = True
100 1
    waiting_timeout = datetime.now() + timedelta(seconds=timeout)
101 1
    service = action.get_service()
102 1
    while waiting and datetime.now() < waiting_timeout:
103 1
        if action.is_deployed(service) or service.errors:
104 1
            waiting = False
105
        else:
106 1
            sleep(2)
107 1
            service = action.get_service()
108 1
            click.secho('.', nl=False)
109
110 1
    if waiting:
111 1
        print_errors(service.older_errors, '%s (timeout)!' % failure_message)
112 1
        exit(1)
113 1
    elif service.errors:
114 1
        print_errors(service.errors, failure_message)
115 1
        exit(1)
116
117 1
    click.secho('\n%s\n' % success_message, fg='green')
118 1
    exit(0)
119
120
121 1
def print_diff(task_definition):
122 1
    if task_definition.diff:
123 1
        click.secho('Updating task definition')
124 1
        for diff in task_definition.diff:
125 1
            click.secho(str(diff), fg='blue')
126 1
        click.secho('')
127
128
129 1
def print_errors(errors, title=''):
130 1
    click.secho('\n%s\n' % title, fg='red', err=True)
131 1
    if errors:
132 1
        for timestamp in errors:
133 1
            click.secho('%s\n' % errors[timestamp], fg='red', err=True)
134 1
        return True
135 1
    return False
136
137 1
ecs.add_command(deploy)
138 1
ecs.add_command(scale)
139
140 1
if __name__ == '__main__':
141
    ecs()
142