Пример #1
0
def test_flatten():
    """Ensure flatten method can really flatten an array"""
    input_arr = [1, 2, [3, 4], [5, 6, 7]]
    output_arr = utils.flatten(input_arr)

    assert output_arr == range(1, 8)
Пример #2
0
def create_or_update_stack(aws_account, region, ebs_bucket_name):
    """Handle creating or updating the ebs-snapper stack, and waiting"""
    # check for stack, create it if necessary
    stack_name = 'ebs-snapper-{}'.format(aws_account)
    cf_client = boto3.client('cloudformation', region_name=region)

    template_url = "https://s3.amazonaws.com/{}/cloudformation.json".format(
        ebs_bucket_name)
    try:
        LOG.info('Creating stack from %s', template_url)
        # only required parameter
        DEFAULT_STACK_PARAMS.append({
            'ParameterKey': 'LambdaS3Bucket',
            'ParameterValue': ebs_bucket_name,
            'UsePreviousValue': False
        })
        response = cf_client.create_stack(StackName=stack_name,
                                          TemplateURL=template_url,
                                          Parameters=DEFAULT_STACK_PARAMS,
                                          Capabilities=[
                                              'CAPABILITY_IAM',
                                          ])
        LOG.debug(response)
        LOG.warn("Wait while the stack %s is created.", stack_name)
    except ClientError as e:
        if not e.response['Error']['Code'] == 'AlreadyExistsException':
            raise

        try:
            LOG.info('Stack exists, updating stack from %s', template_url)

            # we can't specify "UsePreviousValue" if template didn't have this
            # param before our update. We can only UsePreviousValue if param
            # is already present in previous version of this template.
            sn = stack_name
            sr = cf_client.describe_stacks(StackName=sn)
            es_stack = [
                x for x in sr.get('Stacks', []) if x['StackName'] == sn
            ]
            es_params = [x.get('Parameters', []) for x in es_stack]
            es_param_keys = [
                x['ParameterKey'] for x in utils.flatten(es_params)
            ]

            # else we will get the default template value for this param
            params = []
            for k in es_param_keys:
                params.append({'ParameterKey': k, 'UsePreviousValue': True})

            response = cf_client.update_stack(StackName=stack_name,
                                              TemplateURL=template_url,
                                              Parameters=params,
                                              Capabilities=[
                                                  'CAPABILITY_IAM',
                                              ])
            LOG.debug(response)
            LOG.warn("Waiting while the stack %s is being updated.",
                     stack_name)
        except ClientError as f:
            validation_error = f.response['Error']['Code'] == 'ValidationError'
            no_updates = f.response['Error'][
                'Message'] == 'No updates are to be performed.'
            if not validation_error and not no_updates:
                raise
            LOG.warn('No changes. Stack was not updated.')

    # wait for stack to settle to a completed status
    wait_for_completion(cf_client, stack_name)