Exemplo n.º 1
0
def test_get_payload_with_messages(url, service_match):
    slack = SlackNotification(url, service_match)

    messages = (
        ('foo', 'bar'),
        ('lorem', 'ipsum'),
    )

    payload = slack.get_payload('Foobar', messages, 'good')

    expected = {
        'username':
        '******',
        'attachments': [{
            'color':
            'good',
            'pretext':
            'Foobar',
            'fields': [{
                'short': True,
                'title': 'foo',
                'value': 'bar'
            }, {
                'short': True,
                'title': 'lorem',
                'value': 'ipsum'
            }],
        }],
    }

    assert payload == expected
Exemplo n.º 2
0
def test_notify_start_without_url(post_mock, url, service_match,
                                  task_definition):
    slack = SlackNotification(None, None)
    slack.notify_start('my-cluster', 'my-tag', task_definition, 'my-comment',
                       'my-user', 'my-service', 'my-rule')

    post_mock.assert_not_called()
Exemplo n.º 3
0
def test_notify_start_without_tag(post_mock, url, service_match,
                                  task_definition):
    post_mock.return_value = NotifyResponseSuccessfulMock()

    task_definition.set_images(webserver=u'new-image:my-tag',
                               application=u'app-image:another-tag')
    task_definition.set_environment((('webserver', 'foo', 'baz'), ))

    slack = SlackNotification(url, service_match)
    slack.notify_start('my-cluster', None, task_definition, 'my-comment',
                       'my-user', 'my-service', 'my-rule')

    payload = {
        'username':
        '******',
        'attachments': [{
            'pretext':
            'Deployment has started',
            'color':
            None,
            'fields': [{
                'title': 'Cluster',
                'value': 'my-cluster',
                'short': True
            }, {
                'title': 'Service',
                'value': 'my-service',
                'short': True
            }, {
                'title': 'Scheduled Task',
                'value': 'my-rule',
                'short': True
            }, {
                'title': 'User',
                'value': 'my-user',
                'short': True
            }, {
                'title': 'Comment',
                'value': 'my-comment',
                'short': True
            }, {
                'title': 'image',
                'value': 'new-image:my-tag',
                'short': True
            }, {
                'title': 'image',
                'value': 'app-image:another-tag',
                'short': True
            }, {
                'title': 'Environment',
                'value': '_sensitive (therefore hidden)_',
                'short': True
            }]
        }]
    }

    post_mock.assert_called_with(url, json=payload)
Exemplo n.º 4
0
def test_get_payload_without_messages(url, service_match):
    slack = SlackNotification(url, service_match)

    payload = slack.get_payload('Foobar', [], 'good')

    expected = {
        'username': '******',
        'attachments': [{
            'color': 'good',
            'pretext': 'Foobar',
            'fields': [],
        }],
    }

    assert payload == expected
Exemplo n.º 5
0
def test_notify_success(post_mock, url, service_match, task_definition):
    post_mock.return_value = NotifyResponseSuccessfulMock()

    slack = SlackNotification(url, service_match)
    slack.notify_failure('my-cluster', 'my-error', 'my-service', 'my-rule')

    payload = {
        'username':
        '******',
        'attachments': [{
            'pretext':
            'Deployment failed',
            'color':
            'danger',
            'fields': [
                {
                    'title': 'Cluster',
                    'value': 'my-cluster',
                    'short': True
                },
                {
                    'title': 'Service',
                    'value': 'my-service',
                    'short': True
                },
                {
                    'title': 'Scheduled Task',
                    'value': 'my-rule',
                    'short': True
                },
                {
                    'title': 'Duration',
                    'value': '0:00:00',
                    'short': True
                },
                {
                    'title': 'Error',
                    'value': 'my-error',
                    'short': True
                },
            ]
        }]
    }

    post_mock.assert_called_with(url, json=payload)
Exemplo n.º 6
0
def cron(cluster, task, rule, image, tag, command, env, role, region,
         access_key_id, secret_access_key, newrelic_apikey, newrelic_appid,
         newrelic_region, comment, user, profile, diff, deregister, rollback,
         slack_url, slack_service_match):
    """
    Update a scheduled task.

    \b
    CLUSTER is the name of your cluster (e.g. 'my-custer') within ECS.
    TASK is the name of your task definition (e.g. 'my-task') within ECS.
    RULE is the name of the rule to use the new task definition.
    """
    try:
        client = get_client(access_key_id, secret_access_key, region, profile)
        action = RunAction(client, cluster)

        td = action.get_task_definition(task)
        click.secho('Update task definition based on: %s\n' %
                    td.family_revision)

        td.set_images(tag, **{key: value for (key, value) in image})
        td.set_commands(**{key: value for (key, value) in command})
        td.set_environment(env)
        td.set_role_arn(role)

        slack = SlackNotification(
            getenv('SLACK_URL', slack_url),
            getenv('SLACK_SERVICE_MATCH', slack_service_match))
        slack.notify_start(cluster, tag, td, comment, user, rule=rule)

        if diff:
            print_diff(td)

        new_td = create_task_definition(action, td)

        client.update_rule(cluster=cluster, rule=rule, task_definition=new_td)
        click.secho('Updating scheduled task')
        click.secho('Successfully updated scheduled task %s\n' % rule,
                    fg='green')

        slack.notify_success(cluster, td.revision, rule=rule)

        record_deployment(tag, newrelic_apikey, newrelic_appid,
                          newrelic_region, comment, user)

        if deregister:
            deregister_task_definition(action, td)

    except EcsError as e:
        click.secho('%s\n' % str(e), fg='red', err=True)
        exit(1)
Exemplo n.º 7
0
def deploy(cluster,
           service,
           tag,
           image,
           command,
           env,
           secret,
           role,
           execution_role,
           task,
           region,
           access_key_id,
           secret_access_key,
           profile,
           timeout,
           newrelic_apikey,
           newrelic_appid,
           newrelic_region,
           comment,
           user,
           ignore_warnings,
           diff,
           deregister,
           rollback,
           exclusive_env,
           exclusive_secrets,
           sleep_time,
           slack_url,
           slack_service_match='.*'):
    """
    Redeploy or modify a service.

    \b
    CLUSTER is the name of your cluster (e.g. 'my-custer') within ECS.
    SERVICE is the name of your service (e.g. 'my-app') within ECS.

    When not giving any other options, the task definition will not be changed.
    It will just be duplicated, so that all container images will be pulled
    and redeployed.
    """

    try:
        client = get_client(access_key_id, secret_access_key, region, profile)
        deployment = DeployAction(client, cluster, service)

        td = get_task_definition(deployment, task)
        td.set_images(tag, **{key: value for (key, value) in image})
        td.set_commands(**{key: value for (key, value) in command})
        td.set_environment(env, exclusive_env)
        td.set_secrets(secret, exclusive_secrets)
        td.set_role_arn(role)
        td.set_execution_role_arn(execution_role)

        slack = SlackNotification(
            getenv('SLACK_URL', slack_url),
            getenv('SLACK_SERVICE_MATCH', slack_service_match))
        slack.notify_start(cluster, tag, td, comment, user, service=service)

        click.secho('Deploying based on task definition: %s\n' %
                    td.family_revision)

        if diff:
            print_diff(td)

        new_td = create_task_definition(deployment, td)

        try:
            deploy_task_definition(deployment=deployment,
                                   task_definition=new_td,
                                   title='Deploying new task definition',
                                   success_message='Deployment successful',
                                   failure_message='Deployment failed',
                                   timeout=timeout,
                                   deregister=deregister,
                                   previous_task_definition=td,
                                   ignore_warnings=ignore_warnings,
                                   sleep_time=sleep_time)

        except TaskPlacementError as e:
            slack.notify_failure(cluster, str(e), service=service)
            if rollback:
                click.secho('%s\n' % str(e), fg='red', err=True)
                rollback_task_definition(deployment,
                                         td,
                                         new_td,
                                         sleep_time=sleep_time)
                exit(1)
            else:
                raise

        record_deployment(tag, newrelic_apikey, newrelic_appid,
                          newrelic_region, comment, user)

        slack.notify_success(cluster, td.revision, service=service)

    except (EcsError, NewRelicException) as e:
        click.secho('%s\n' % str(e), fg='red', err=True)
        exit(1)
Exemplo n.º 8
0
def test_notify_failure_failed(post, url, service_match, task_definition):
    with raises(SlackException):
        post.return_value = NotifyResponseUnsuccessfulMock()
        slack = SlackNotification(url, service_match)
        slack.notify_failure('my-cluster', 'my-error', 'my-service', 'my-rule')
Exemplo n.º 9
0
def test_notify_failure_without_url(post_mock, url, service_match,
                                    task_definition):
    slack = SlackNotification(None, None)
    slack.notify_failure('my-cluster', 'my-error', 'my-service', 'my-rule')
    post_mock.assert_not_called()
Exemplo n.º 10
0
def cron(cluster, task, rule, image, tag, command, cpu, memory,
         memoryreservation, privileged, env, secret, ulimit, system_control,
         port, mount, log, role, execution_role, region, access_key_id,
         secret_access_key, newrelic_apikey, newrelic_appid, newrelic_region,
         comment, user, profile, diff, deregister, rollback, exclusive_env,
         exclusive_secrets, slack_url, slack_service_match, exclusive_ulimits,
         exclusive_system_controls, exclusive_ports, exclusive_mounts, volume):
    """
    Update a scheduled task.

    \b
    CLUSTER is the name of your cluster (e.g. 'my-custer') within ECS.
    TASK is the name of your task definition (e.g. 'my-task') within ECS.
    RULE is the name of the rule to use the new task definition.
    """
    try:
        client = get_client(access_key_id, secret_access_key, region, profile)
        action = RunAction(client, cluster)

        td = action.get_task_definition(task)
        click.secho('Update task definition based on: %s\n' %
                    td.family_revision)

        td.set_images(tag, **{key: value for (key, value) in image})
        td.set_commands(**{key: value for (key, value) in command})
        td.set_cpu(**{key: value for (key, value) in cpu})
        td.set_memory(**{key: value for (key, value) in memory})
        td.set_memoryreservation(
            **{key: value
               for (key, value) in memoryreservation})
        td.set_privileged(**{key: value for (key, value) in privileged})
        td.set_environment(env, exclusive_env)
        td.set_secrets(secret, exclusive_secrets)
        td.set_ulimits(ulimit, exclusive_ulimits)
        td.set_system_controls(system_control, exclusive_system_controls)
        td.set_port_mappings(port, exclusive_ports)
        td.set_mount_points(mount, exclusive_mounts)
        td.set_log_configurations(log)
        td.set_role_arn(role)
        td.set_execution_role_arn(execution_role)
        td.set_volumes(volume)

        slack = SlackNotification(
            getenv('SLACK_URL', slack_url),
            getenv('SLACK_SERVICE_MATCH', slack_service_match))
        slack.notify_start(cluster, tag, td, comment, user, rule=rule)

        if diff:
            print_diff(td)

        new_td = create_task_definition(action, td)

        client.update_rule(cluster=cluster, rule=rule, task_definition=new_td)
        click.secho('Updating scheduled task')
        click.secho('Successfully updated scheduled task %s\n' % rule,
                    fg='green')

        slack.notify_success(cluster, td.revision, rule=rule)

        record_deployment(tag, newrelic_apikey, newrelic_appid,
                          newrelic_region, comment, user)

        if deregister:
            deregister_task_definition(action, td)

    except EcsError as e:
        click.secho('%s\n' % str(e), fg='red', err=True)
        exit(1)
Exemplo n.º 11
0
def deploy(cluster,
           service,
           tag,
           image,
           command,
           health_check,
           cpu,
           memory,
           memoryreservation,
           privileged,
           essential,
           env,
           secret,
           ulimit,
           system_control,
           port,
           mount,
           log,
           role,
           execution_role,
           task,
           region,
           access_key_id,
           secret_access_key,
           profile,
           timeout,
           newrelic_apikey,
           newrelic_appid,
           newrelic_region,
           comment,
           user,
           ignore_warnings,
           diff,
           deregister,
           rollback,
           exclusive_env,
           exclusive_secrets,
           sleep_time,
           exclusive_ulimits,
           exclusive_system_controls,
           exclusive_ports,
           exclusive_mounts,
           volume,
           add_container,
           remove_container,
           slack_url,
           slack_service_match='.*'):
    """
    Redeploy or modify a service.

    \b
    CLUSTER is the name of your cluster (e.g. 'my-custer') within ECS.
    SERVICE is the name of your service (e.g. 'my-app') within ECS.

    When not giving any other options, the task definition will not be changed.
    It will just be duplicated, so that all container images will be pulled
    and redeployed.
    """

    try:
        client = get_client(access_key_id, secret_access_key, region, profile)
        deployment = DeployAction(client, cluster, service)

        td = get_task_definition(deployment, task)
        # If there is a new container, add it at frist.
        td.add_containers(add_container)
        td.remove_containers(remove_container)
        td.set_images(tag, **{key: value for (key, value) in image})
        td.set_commands(**{key: value for (key, value) in command})
        td.set_health_checks(**{key: vals for (key, *vals) in health_check})
        td.set_cpu(**{key: value for (key, value) in cpu})
        td.set_memory(**{key: value for (key, value) in memory})
        td.set_memoryreservation(
            **{key: value
               for (key, value) in memoryreservation})
        td.set_privileged(**{key: value for (key, value) in privileged})
        td.set_essential(**{key: value for (key, value) in essential})
        td.set_environment(env, exclusive_env)
        td.set_secrets(secret, exclusive_secrets)
        td.set_ulimits(ulimit, exclusive_ulimits)
        td.set_system_controls(system_control, exclusive_system_controls)
        td.set_port_mappings(port, exclusive_ports)
        td.set_mount_points(mount, exclusive_mounts)
        td.set_log_configurations(log)
        td.set_role_arn(role)
        td.set_execution_role_arn(execution_role)
        td.set_volumes(volume)

        slack = SlackNotification(
            getenv('SLACK_URL', slack_url),
            getenv('SLACK_SERVICE_MATCH', slack_service_match))
        slack.notify_start(cluster, tag, td, comment, user, service=service)

        click.secho('Deploying based on task definition: %s\n' %
                    td.family_revision)

        if diff:
            print_diff(td)

        new_td = create_task_definition(deployment, td)

        try:
            deploy_task_definition(deployment=deployment,
                                   task_definition=new_td,
                                   title='Deploying new task definition',
                                   success_message='Deployment successful',
                                   failure_message='Deployment failed',
                                   timeout=timeout,
                                   deregister=deregister,
                                   previous_task_definition=td,
                                   ignore_warnings=ignore_warnings,
                                   sleep_time=sleep_time)

        except TaskPlacementError as e:
            slack.notify_failure(cluster, str(e), service=service)
            if rollback:
                click.secho('%s\n' % str(e), fg='red', err=True)
                rollback_task_definition(deployment,
                                         td,
                                         new_td,
                                         sleep_time=sleep_time)
                exit(1)
            else:
                raise

        record_deployment(tag, newrelic_apikey, newrelic_appid,
                          newrelic_region, comment, user)

        slack.notify_success(cluster, td.revision, service=service)

    except (EcsError, NewRelicException) as e:
        click.secho('%s\n' % str(e), fg='red', err=True)
        exit(1)