Ejemplo n.º 1
0
def test_list_applications(monkeypatch):
    context = Context({'region': 'caprica', 'vpc': 'myvpc'})

    security_group = MagicMock()
    security_group.tags = {
        'Manifest':
        yaml.dump({
            'application_name': 'myapp',
            'team_name': 'MyTeam',
            'exposed_ports': [123]
        })
    }

    context.get_applications = lambda: [Application('myapp', security_group)]
    context_constructor = lambda x, y: context

    monkeypatch.setattr('aws_minion.cli.Context', context_constructor)

    runner = CliRunner()

    with runner.isolated_filesystem():
        context.write_config('config.yaml')

        result = runner.invoke(
            cli, ['-p', 'default', '--config-file', 'config.yaml', 'app'],
            catch_exceptions=False)

    lines = result.output.splitlines()
    assert lines[1].split() == ['myapp', 'MyTeam', '[123]']
Ejemplo n.º 2
0
def test_delete_application(monkeypatch):
    monkeypatch.setattr('boto.ec2.connect_to_region', MagicMock())
    monkeypatch.setattr('boto.iam.connect_to_region', MagicMock())

    context = Context({'region': 'caprica', 'vpc': 'myvpc'})
    security_group = MagicMock()
    security_group.tags = {
        'Manifest': yaml.dump({'application_name': 'myapp'})
    }
    context.get_application = lambda name: Application('myapp', security_group)
    context.get_security_group = lambda name: None

    context_constructor = lambda x, y: context

    monkeypatch.setattr('aws_minion.cli.Context', context_constructor)

    runner = CliRunner()

    with runner.isolated_filesystem():
        context.write_config('config.yaml')

        result = runner.invoke(cli, [
            '-p', 'default', '--config-file', 'config.yaml', 'app', 'delete',
            'myapp'
        ],
                               catch_exceptions=False)
Ejemplo n.º 3
0
def test_create_application(monkeypatch):
    monkeypatch.setattr('boto.ec2.connect_to_region', MagicMock())
    monkeypatch.setattr('boto.iam.connect_to_region', MagicMock())
    monkeypatch.setattr('time.sleep', lambda s: s)

    context = Context({'region': 'caprica', 'vpc': 'myvpc'})
    context.get_application = raise_application_not_found
    context_constructor = lambda x, y: context

    monkeypatch.setattr('aws_minion.cli.Context', context_constructor)

    runner = CliRunner()

    data = {
        'application_name': 'myapp',
        'team_name': 'MyTeam',
        'exposed_ports': [123]
    }

    with runner.isolated_filesystem():
        with open('myapp.yaml', 'w') as fd:
            yaml.dump(data, fd)

        context.write_config('config.yaml')

        result = runner.invoke(cli, [
            '-p', 'default', '--config-file', 'config.yaml', 'applications',
            'create', 'myapp.yaml'
        ],
                               catch_exceptions=False)

    assert 'Creating IAM role and instance profile.. OK' in result.output
Ejemplo n.º 4
0
def test_versions_create_https(monkeypatch):
    subnet = MagicMock()
    subnet.id = 'subnet-mysubnet'
    vpc_conn = MagicMock()
    vpc_conn.get_all_subnets = lambda x: [subnet]

    monkeypatch.setattr('boto.vpc.connect_to_region', vpc_conn)
    monkeypatch.setattr('boto.ec2.connect_to_region', MagicMock())
    monkeypatch.setattr('boto.route53.connect_to_region', MagicMock())
    monkeypatch.setattr('boto.ec2.autoscale.connect_to_region', MagicMock())
    monkeypatch.setattr('boto.ec2.elb.connect_to_region', MagicMock())
    monkeypatch.setattr('time.sleep', lambda s: s)
    monkeypatch.setattr('aws_minion.cli.map_subnets', lambda s, r: {'public': [subnet], 'shared': [], 'private': []})
    monkeypatch.setattr('aws_minion.cli.docker_image_exists', lambda i: True)

    security_group = MagicMock()
    security_group.tags = {'Manifest': json.dumps({'exposed_ports': [8080], 'team_name': 'MyTeam'})}

    security_groups = {'app-myapp': security_group, 'app-myapp-lb': MagicMock()}

    auto_scaling_group = MagicMock()
    auto_scaling_group.tags = [MagicMock(key='DockerImage', value='foo/bar:123')]
    auto_scaling_group.desired_capacity = 3

    app = Application('myapp', security_group)

    version = ApplicationVersion('myregion', 'myapp', '1.0', auto_scaling_group)
    version.weight = 120

    context = Context({'region': 'caprica', 'vpc': 'myvpc', 'loggly_auth_token': 'abc', 'domain': 'mydomain',
                       'ssl_certificate_arn': 'super secret'})
    context.get_versions = lambda: [version]
    context.get_application = lambda x: app
    context.get_security_group = lambda x: security_groups.get(x)
    context.get_vpc_config = lambda: {'nameservers': ['8.8.8.8'], 'cacerts': ['https://example.org/cacert.pem'],
                                      'registry': 'example.org',
                                      'registry_insecure': True}
    context_constructor = lambda x, y: context

    monkeypatch.setattr('aws_minion.cli.Context', context_constructor)

    runner = CliRunner()

    with runner.isolated_filesystem():
        context.write_config('config.yaml')
        result = runner.invoke(cli, ['-p', 'default', '--config-file', 'config.yaml', 'versions', 'create', 'myapp', '1.0',
                                     'mydocker:2.3', '-e', 'MY_ENV_VAR=123'],
                               catch_exceptions=False)

    assert 'ABORTED. Default health check time to wait for members to become active has been exceeded.' in result.output
Ejemplo n.º 5
0
def test_versions_delete(monkeypatch):

    instances = [MagicMock(state='TERMINATED', id='instance-1')]

    conn = MagicMock(get_only_instances=lambda instance_ids: instances)

    monkeypatch.setattr('boto.ec2.connect_to_region', MagicMock(return_value=conn))
    monkeypatch.setattr('boto.route53.connect_to_region', MagicMock())
    monkeypatch.setattr('boto.ec2.autoscale.connect_to_region', MagicMock())
    monkeypatch.setattr('boto.ec2.elb.connect_to_region', MagicMock())
    monkeypatch.setattr('time.sleep', lambda s: s)

    security_group = MagicMock()
    security_group.tags = {'Manifest': json.dumps({'exposed_ports': [8080], 'team_name': 'MyTeam'})}

    auto_scaling_group = MagicMock()
    auto_scaling_group.tags = [MagicMock(key='DockerImage', value='foo/bar:123')]
    auto_scaling_group.instances = [MagicMock(instance_id='instance-1')]

    app = Application('myapp', security_group)

    version = ApplicationVersion('myregion', 'myapp', '1.0', auto_scaling_group)
    version.weight = 120

    context = Context({'region': 'caprica', 'vpc': 'myvpc', 'domain': 'mydomain'})
    context.get_versions = lambda a, b=None: [version]
    context.get_application = lambda x: app
    context_constructor = lambda x, y: context

    monkeypatch.setattr('aws_minion.cli.Context', context_constructor)

    runner = CliRunner()

    with runner.isolated_filesystem():
        context.write_config('config.yaml')
        result = runner.invoke(cli, ['-p', 'default', '--config-file', 'config.yaml', 'versions', 'delete', 'myapp', '1.0'],
                               catch_exceptions=False)

    assert 'Deleting load balancer.. OK' in result.output
Ejemplo n.º 6
0
def test_get_instances(monkeypatch):
    conn = MagicMock(name='conn')
    instance = MagicMock(name='instance')
    instance.tags = {'Name': 'app-myapp-123'}
    instance.vpc_id = 'myvpc'
    instance.id = 'myid'
    conn.get_only_instances.return_value = [instance]
    monkeypatch.setattr('boto.ec2.connect_to_region',
                        MagicMock(name='connect_to_region', return_value=conn))

    ctx = Context({
        'region': 'someregion',
        'domain': 'apps.example.com',
        'vpc': 'myvpc'
    })
    instances = ctx.get_instances()
    assert len(instances) == 1

    instance = ctx.get_instance_by_id('myid')
    assert instance.tags == instances[0].tags

    assert ctx.get_instance_by_id('000') is None
Ejemplo n.º 7
0
def test_get_applications(monkeypatch):
    conn = MagicMock(name='conn')
    sg1 = MagicMock(name='invalid sg')
    sg2 = MagicMock(name='valid sg')
    sg2.name = 'app-myapp'
    sg2.tags = {'Manifest': 'a: b'}
    sg2.vpc_id = 'myvpc'
    sg3 = MagicMock(name='another invalid sg')
    sg3.name = 'app-myapp-db'
    sg3.vpc_id = 'myvpc'
    conn.get_all_security_groups.return_value = [sg1, sg2, sg3]
    monkeypatch.setattr('boto.ec2.connect_to_region',
                        MagicMock(name='connect_to_region', return_value=conn))
    ctx = Context({
        'region': 'someregion',
        'domain': 'apps.example.com',
        'vpc': 'myvpc'
    })
    apps = ctx.get_applications()
    assert len(apps) == 1

    app = ctx.get_application('myapp')
    assert app == apps[0]
Ejemplo n.º 8
0
def test_get_versions(monkeypatch):

    record = MagicMock()
    record.type = 'CNAME'
    record.identifier = 'app-myapp'
    record.weight = 100

    zone = MagicMock(name='zone')
    zone.get_records.return_value = [record]

    dns_conn = MagicMock(name='dns_conn')
    dns_conn.get_zone.return_value = zone

    group = MagicMock(name='auto scale group')
    group.name = 'app-myapp-1.0'

    autoscale = MagicMock(name='autoscale_conn')
    autoscale.get_all_groups.return_value = [group]

    monkeypatch.setattr('boto.ec2.autoscale.connect_to_region',
                        MagicMock(return_value=autoscale))
    monkeypatch.setattr('boto.route53.connect_to_region',
                        MagicMock(return_value=dns_conn))
    ctx = Context({'region': 'someregion', 'domain': 'apps.example.com'})
    versions = ctx.get_versions('myapp', '0.1')
    assert versions == []

    versions = ctx.get_versions('myapp', '1.0')
    assert len(versions) == 1
    assert versions[0].application_name == 'myapp'
    assert versions[0].version == '1.0'

    version = ctx.get_version('myapp', '1.0')
    assert version == versions[0]

    with pytest.raises(Exception):
        ctx.get_version('non-existing-app', '0.1')
Ejemplo n.º 9
0
def test_versions_list(monkeypatch):
    auto_scaling_group = MagicMock()
    auto_scaling_group.tags = [MagicMock(key='DockerImage', value='foo/bar:123')]
    auto_scaling_group.desired_capacity = 3

    version = ApplicationVersion('myregion', 'myapp', '1.0', auto_scaling_group)
    version.weight = 120

    context = Context({'region': 'caprica'})
    context.get_versions = lambda: [version]
    context.get_vpc_config = lambda: {}
    context_constructor = lambda x, y: context

    monkeypatch.setattr('aws_minion.cli.Context', context_constructor)

    runner = CliRunner()

    with runner.isolated_filesystem():
        context.write_config('config.yaml')
        result = runner.invoke(cli, ['-p', 'default', '--config-file', 'config.yaml', 'versions'], catch_exceptions=False)

    lines = result.output.splitlines()
    cols = lines[1].split()
    assert cols == ['myapp', '1.0', 'foo/bar:123', '(no', 'instances)', '3', '60.0']
Ejemplo n.º 10
0
def test_versions_traffic(monkeypatch):
    monkeypatch.setattr('boto.vpc.connect_to_region', MagicMock())
    monkeypatch.setattr('boto.ec2.connect_to_region', MagicMock())
    monkeypatch.setattr('boto.ec2.autoscale.connect_to_region', MagicMock())
    monkeypatch.setattr('boto.ec2.elb.connect_to_region', MagicMock())
    monkeypatch.setattr('time.sleep', lambda s: s)

    security_group = MagicMock()
    security_group.tags = {'Manifest': json.dumps({'exposed_ports': [8080], 'team_name': 'MyTeam'})}

    security_groups = {'app-myapp': security_group, 'app-myapp-lb': MagicMock()}

    auto_scaling_group = MagicMock()
    auto_scaling_group.tags = [MagicMock(key='DockerImage', value='foo/bar:123')]
    auto_scaling_group.desired_capacity = 3

    app = Application('myapp', security_group)

    # start creating mocking of the route53 record sets and Application Versions
    # this is a lot of dirty and nasty code. Please, somebody help this code.
    versions = [ApplicationVersion('myregion', 'myapp', '1.0', auto_scaling_group),
                ApplicationVersion('myregion', 'myapp', '2.0', auto_scaling_group),
                ApplicationVersion('myregion', 'myapp', '3.0', auto_scaling_group),
                ApplicationVersion('myregion', 'myapp', '4.0', auto_scaling_group),
                ]
    versions[0].weight = 60 * PERCENT_RESOLUTION
    versions[1].weight = 30 * PERCENT_RESOLUTION
    versions[2].weight = 10 * PERCENT_RESOLUTION
    versions[3].weight = 0

    r53conn = Mock(name='r53conn')
    rr = MagicMock()
    records = collections.OrderedDict((versions[i].dns_identifier,
                                       MagicMock(weight=versions[i].weight,
                                                 identifier=versions[i].dns_identifier
                                                 )) for i in (0, 1, 2, 3))

    rr.__iter__ = lambda x: iter(records.values())
    for r in rr:
        r.name = "myapp.example.org."
        r.type = "CNAME"

    def add_change(op, dns_name, rtype, ttl, identifier, weight):
        if op == 'CREATE':
            x = MagicMock(weight=weight, identifier=identifier)
            x.name = "myapp.example.org"
            x.type = "CNAME"
            records[identifier] = x
        return Mock(name='change')

    def add_change_record(op, record):
        if op == 'DELETE':
            records[record.identifier].weight = 0
        elif op == 'USPERT':
            assert records[record.identifier].weight == record.weight

    rr.add_change = add_change
    rr.add_change_record = add_change_record

    r53conn().get_zone().get_records.return_value = rr
    monkeypatch.setattr('boto.route53.connect_to_region', r53conn)

    context = Context({'region': 'caprica', 'vpc': 'myvpc', 'loggly_auth_token': 'abc', 'domain': 'example.org'})
    context.get_versions = lambda v=None: versions
    context.get_application = lambda x: app
    context.get_security_group = lambda x: security_groups.get(x)
    context_constructor = Mock(return_value=context)

    monkeypatch.setattr('aws_minion.cli.Context', context_constructor)

    runner = CliRunner()

    common_opts = ['-p', 'default', '--config-file', 'config.yaml', 'versions', 'traffic', 'myapp']

    def run(opts):
        return runner.invoke(cli, common_opts + opts, catch_exceptions=False)

    with runner.isolated_filesystem():
        context.write_config('config.yaml')

        run(['4.0', '100'])

        ri = iter(rr)
        assert next(ri).weight == 0
        assert next(ri).weight == 0
        assert next(ri).weight == 0
        assert next(ri).weight == 200

        run(['3.0', '10'])
        ri = iter(rr)
        assert next(ri).weight == 0
        assert next(ri).weight == 0
        assert next(ri).weight == 20
        assert next(ri).weight == 180

        run(['2.0', '0.5'])
        ri = iter(rr)
        assert next(ri).weight == 0
        assert next(ri).weight == 1
        assert next(ri).weight == 20
        assert next(ri).weight == 179

        run(['1.0', '1'])
        ri = iter(rr)
        assert next(ri).weight == 2
        assert next(ri).weight == 1
        assert next(ri).weight == 19
        assert next(ri).weight == 178

        run(['4.0', '95'])
        ri = iter(rr)
        assert next(ri).weight == 1
        assert next(ri).weight == 1
        assert next(ri).weight == 13
        assert next(ri).weight == 185

        run(['4.0', '100'])
        ri = iter(rr)
        assert next(ri).weight == 0
        assert next(ri).weight == 0
        assert next(ri).weight == 0
        assert next(ri).weight == 200

        run(['4.0', '10'])
        ri = iter(rr)
        assert next(ri).weight == 0
        assert next(ri).weight == 0
        assert next(ri).weight == 0
        assert next(ri).weight == 200

        run(['4.0', '0'])
        ri = iter(rr)
        assert next(ri).weight == 0
        assert next(ri).weight == 0
        assert next(ri).weight == 0
        assert next(ri).weight == 0
Ejemplo n.º 11
0
def test_create_application(monkeypatch):
    monkeypatch.setattr('boto.ec2.connect_to_region', MagicMock())
    monkeypatch.setattr('boto.iam.connect_to_region', MagicMock())
    monkeypatch.setattr('time.sleep', lambda s: s)
    mock_sgr = MagicMock()
    monkeypatch.setattr('aws_minion.cli.SecurityGroupRule', mock_sgr)

    context = Context({'region': 'caprica', 'vpc': 'myvpc'})
    context.get_application = raise_application_not_found
    context_constructor = lambda x, y: context

    monkeypatch.setattr('aws_minion.cli.Context', context_constructor)

    runner = CliRunner()

    data = {
        'application_name': 'myapp',
        'team_name': 'MyTeam',
        'exposed_ports': [123],
        'exposed_protocol': 'http'
    }

    mock_sgr.reset_mock()

    with runner.isolated_filesystem():
        with open('myapp.yaml', 'w') as fd:
            yaml.dump(data, fd)

        context.write_config('config.yaml')

        result = runner.invoke(cli, [
            '-p', 'default', '--config-file', 'config.yaml', 'applications',
            'create', 'myapp.yaml'
        ],
                               catch_exceptions=False)

    assert call('tcp', 80, 80, '0.0.0.0/0', None) in mock_sgr.call_args_list
    assert call('tcp', 443, 443, '0.0.0.0/0', None) in mock_sgr.call_args_list

    assert 'Creating IAM role and instance profile.. OK' in result.output

    data_tcp = {
        'application_name': 'myapp',
        'team_name': 'MyTeam',
        'exposed_ports': [123],
        'exposed_protocol': 'tcp'
    }

    mock_sgr.reset_mock()

    with runner.isolated_filesystem():
        with open('myapp.yaml', 'w') as fd:
            yaml.dump(data_tcp, fd)

        context.write_config('config.yaml')

        result = runner.invoke(cli, [
            '-p', 'default', '--config-file', 'config.yaml', 'applications',
            'create', 'myapp.yaml'
        ],
                               catch_exceptions=False)

    assert mock_sgr.call_args == call('tcp', 123, 123, None, 'app-myapp-lb')
    assert 'Creating IAM role and instance profile.. OK' in result.output
Ejemplo n.º 12
0
def test_get_application_not_found(monkeypatch):
    monkeypatch.setattr('boto.ec2.connect_to_region', MagicMock())

    ctx = Context({'region': 'someregion'})
    with pytest.raises(ApplicationNotFound):
        ctx.get_application('myapp-non-existing')