Example #1
0
def test_create(monkeypatch, popen, version, parameters, region,
                disable_rollback, dry_run, tags):
    mock_named_tempfile = MagicMock()
    mock_tempfile = MagicMock()
    mock_tempfile.name = 'filename'
    mock_named_tempfile.__enter__.return_value = mock_tempfile
    mock_named_tempfile.return_value = mock_named_tempfile
    monkeypatch.setattr('tempfile.NamedTemporaryFile', mock_named_tempfile)
    lizzy_version_tag = 'LizzyVersion={}'.format(VERSION)

    region = region or 'region'
    senza = Senza(region)
    senza.logger = MagicMock()
    senza.create('yaml: yaml', version, parameters, disable_rollback, dry_run,
                 tags)

    mock_named_tempfile.assert_called_with()
    mock_tempfile.write.assert_called_with(b'yaml: yaml')

    expected_disabled_rollback = ['--disable-rollback'
                                  ] if disable_rollback else []
    expected_dry_run = ['--dry-run'] if dry_run else []

    cli_tags = ['-t', lizzy_version_tag]
    for tag in tags:
        cli_tags.extend(['-t', tag])

    popen.assert_called_with(
        ['senza', 'create', '--region', region, '--force'] +
        expected_disabled_rollback + expected_dry_run +
        ['--stacktrace-visible'] + cli_tags + ['filename', version] +
        parameters,
        stdout=-1,
        stderr=-2)
    assert not senza.logger.error.called
Example #2
0
def test_create_error(monkeypatch, popen):
    mock_named_tempfile = MagicMock()
    mock_tempfile = MagicMock()
    mock_tempfile.name = 'filename'
    mock_named_tempfile.__enter__.return_value = mock_tempfile
    mock_named_tempfile.return_value = mock_named_tempfile
    monkeypatch.setattr('tempfile.NamedTemporaryFile', mock_named_tempfile)

    senza = Senza('region')
    senza.logger = MagicMock()
    popen.returncode = 1

    with pytest.raises(ExecutionError):
        senza.create('yaml: yaml', '10', ['param1', 'param2'], False, False, {})
Example #3
0
def test_create_error(monkeypatch, popen):
    mock_named_tempfile = MagicMock()
    mock_tempfile = MagicMock()
    mock_tempfile.name = 'filename'
    mock_named_tempfile.__enter__.return_value = mock_tempfile
    mock_named_tempfile.return_value = mock_named_tempfile
    monkeypatch.setattr('tempfile.NamedTemporaryFile', mock_named_tempfile)

    senza = Senza('region')
    senza.logger = MagicMock()
    popen.returncode = 1

    with pytest.raises(ExecutionError):
        senza.create('yaml: yaml', '10', ['param1', 'param2'], False, False,
                     {})
Example #4
0
def test_create(monkeypatch, popen, version, parameters, region, disable_rollback, dry_run, tags):
    mock_named_tempfile = MagicMock()
    mock_tempfile = MagicMock()
    mock_tempfile.name = 'filename'
    mock_named_tempfile.__enter__.return_value = mock_tempfile
    mock_named_tempfile.return_value = mock_named_tempfile
    monkeypatch.setattr('tempfile.NamedTemporaryFile', mock_named_tempfile)
    lizzy_version_tag = 'LizzyVersion={}'.format(VERSION)

    region = region or 'region'
    senza = Senza(region)
    senza.logger = MagicMock()
    senza.create('yaml: yaml', version, parameters, disable_rollback,
                 dry_run, tags)

    mock_named_tempfile.assert_called_with()
    mock_tempfile.write.assert_called_with(b'yaml: yaml')

    expected_disabled_rollback = ['--disable-rollback'] if disable_rollback else []
    expected_dry_run = ['--dry-run'] if dry_run else []

    cli_tags = ['-t', lizzy_version_tag]
    for tag in tags:
        cli_tags.extend(['-t', tag])

    popen.assert_called_with(['senza', 'create',
                              '--region', region,
                              '--force']
                             + expected_disabled_rollback
                             + expected_dry_run
                             + ['--stacktrace-visible']
                             + cli_tags
                             + ['filename', version]
                             + parameters,
                             stdout=-1,
                             stderr=-2)
    assert not senza.logger.error.called
Example #5
0
def create_stack(new_stack: dict) -> dict:
    """
    POST /stacks/

    :param new_stack: New stack
    """

    keep_stacks = new_stack['keep_stacks']  # type: int
    new_traffic = new_stack['new_traffic']  # type: int
    stack_version = new_stack['stack_version']  # type: str
    senza_yaml = new_stack['senza_yaml']  # type: str
    parameters = new_stack.get('parameters', [])
    disable_rollback = new_stack.get('disable_rollback', False)
    region = new_stack.get('region', config.region)  # type: Optional[str]
    dry_run = new_stack.get('dry_run', False)
    tags = new_stack.get('tags', [])
    running_time = MeasureRunningTime('create_stack.success')

    sentry_client.capture_breadcrumb(
        data={
            'keep_stacks': keep_stacks,
            'new_traffic': new_traffic,
            'stack_version': stack_version,
            'disable_rollback': disable_rollback,
        })

    try:
        senza_definition = yaml.load(senza_yaml)
    except yaml.YAMLError as exception:
        metrics.count('create_stack.invalid_senza_file')
        return connexion.problem(400,
                                 'Invalid senza yaml',
                                 exception.message,
                                 headers=_make_headers())

    try:
        stack_name = senza_definition['SenzaInfo']['StackName']
    except KeyError as exception:
        logger.error("Couldn't get stack name from definition.",
                     extra={'senza_yaml': repr(senza_yaml)})
        missing_property = str(exception)
        problem = connexion.problem(
            400,
            'Invalid senza yaml',
            "Missing property in senza yaml: {}".format(missing_property),
            headers=_make_headers())
        metrics.count('create_stack.missing_stack_name_prop')
        return problem

    # Create the Stack
    logger.info("Creating stack %s...", stack_name)

    senza = Senza(region)
    tags = [
        'LizzyKeepStacks={}'.format(keep_stacks),
        'LizzyTargetTraffic={}'.format(new_traffic), *tags
    ]

    output = senza.create(senza_yaml, stack_version, parameters,
                          disable_rollback, dry_run, tags)

    logger.info("Stack created.",
                extra={
                    'stack_name': stack_name,
                    'stack_version': stack_version,
                    'parameters': parameters
                })
    stack_dict = (Stack.get(stack_name, stack_version, region=region)
                  if not dry_run else {
                      'stack_name': stack_name,
                      'creation_time': '',
                      'description': '',
                      'status': 'DRY-RUN',
                      'version': stack_version
                  })

    running_time.finish()
    metrics.count('create_stack.region.{}'.format(region))

    return stack_dict, 201, _make_headers(output=output)
Example #6
0
File: api.py Project: zalando/lizzy
def create_stack(new_stack: dict) -> dict:
    """
    POST /stacks/

    :param new_stack: New stack
    """

    keep_stacks = new_stack['keep_stacks']  # type: int
    new_traffic = new_stack['new_traffic']  # type: int
    stack_version = new_stack['stack_version']  # type: str
    senza_yaml = new_stack['senza_yaml']  # type: str
    parameters = new_stack.get('parameters', [])
    disable_rollback = new_stack.get('disable_rollback', False)
    region = new_stack.get('region', config.region)  # type: Optional[str]
    dry_run = new_stack.get('dry_run', False)
    tags = new_stack.get('tags', [])
    running_time = MeasureRunningTime('create_stack.success')

    sentry_client.capture_breadcrumb(data={
        'keep_stacks': keep_stacks,
        'new_traffic': new_traffic,
        'stack_version': stack_version,
        'disable_rollback': disable_rollback,
    })

    try:
        senza_definition = yaml.load(senza_yaml)
    except yaml.YAMLError as exception:
        metrics.count('create_stack.invalid_senza_file')
        return connexion.problem(400,
                                 'Invalid senza yaml',
                                 exception.message,
                                 headers=_make_headers())

    try:
        stack_name = senza_definition['SenzaInfo']['StackName']
    except KeyError as exception:
        logger.error("Couldn't get stack name from definition.",
                     extra={'senza_yaml': repr(senza_yaml)})
        missing_property = str(exception)
        problem = connexion.problem(400,
                                    'Invalid senza yaml',
                                    "Missing property in senza yaml: {}".format(
                                        missing_property),
                                    headers=_make_headers())
        metrics.count('create_stack.missing_stack_name_prop')
        return problem

    # Create the Stack
    logger.info("Creating stack %s...", stack_name)

    senza = Senza(region)
    tags = ['LizzyKeepStacks={}'.format(keep_stacks),
            'LizzyTargetTraffic={}'.format(new_traffic),
            *tags]

    output = senza.create(senza_yaml, stack_version, parameters, disable_rollback,
                          dry_run, tags)

    logger.info("Stack created.", extra={'stack_name': stack_name,
                                         'stack_version': stack_version,
                                         'parameters': parameters})
    stack_dict = (Stack.get(stack_name, stack_version, region=region)
                  if not dry_run
                  else {'stack_name': stack_name,
                        'creation_time': '',
                        'description': '',
                        'status': 'DRY-RUN',
                        'version': stack_version})

    running_time.finish()
    metrics.count('create_stack.region.{}'.format(region))

    return stack_dict, 201, _make_headers(output=output)