Exemple #1
0
def execute_change_set(req_data):
    cs_arn = req_data.get('ChangeSetName')[0]
    stack_name = req_data.get('StackName')[0]
    cs_details = CHANGE_SETS.get(cs_arn)
    if not cs_details:
        return error_response('Change Set %s does not exist' % cs_arn, 404,
                              'ChangeSetNotFound')

    # convert to JSON (might have been YAML, and update_stack/create_stack seem to only work with JSON)
    template = template_deployer.template_to_json(
        cs_details.get('TemplateBody')[0])

    # update stack information
    cloudformation_service = aws_stack.connect_to_service('cloudformation')
    if stack_exists(stack_name):
        result = cloudformation_service.update_stack(StackName=stack_name,
                                                     TemplateBody=template)
    else:
        result = cloudformation_service.create_stack(StackName=stack_name,
                                                     TemplateBody=template)

    # now run the actual deployment
    template_deployer.deploy_template(template)

    response = make_response('ExecuteChangeSet')
    return response
def update_cloudformation(method, path, data, headers, response=None, return_forward_info=False):
    req_data = None
    if method == 'POST' and path == '/':
        req_data = urlparse.parse_qs(data)
        action = req_data.get('Action')[0]

    if return_forward_info:
        if req_data:
            if action == 'CreateChangeSet':
                return create_change_set(req_data)
            elif action == 'DescribeChangeSet':
                return describe_change_set(req_data)
            elif action == 'ExecuteChangeSet':
                return execute_change_set(req_data)
        return True

    if req_data:
        if action == 'DescribeStackResources':
            response_dict = xmltodict.parse(response.content)['DescribeStackResourcesResponse']
            resources = response_dict['DescribeStackResourcesResult']['StackResources']
            if not resources:
                # TODO: check if stack exists
                return error_response('Stack does not exist', code=404)
        if action == 'DescribeStackResource':
            if response.status_code >= 500:
                # fix an error in moto where it fails with 500 if the stack does not exist
                return error_response('Stack resource does not exist', code=404)
        elif action == 'CreateStack' or action == 'UpdateStack':
            if response.status_code in range(200, 300):
                # run the actual deployment
                template = template_deployer.template_to_json(req_data.get('TemplateBody')[0])
                template_deployer.deploy_template(template)
    def return_response(self, method, path, data, headers, response):
        req_data = None
        if method == 'POST' and path == '/':
            req_data = urlparse.parse_qs(to_str(data))
            action = req_data.get('Action')[0]

        if req_data:
            if action == 'DescribeStackResources':
                if response.status_code < 300:
                    response_dict = xmltodict.parse(response.content)['DescribeStackResourcesResponse']
                    resources = response_dict['DescribeStackResourcesResult']['StackResources']
                    if not resources:
                        # Check if stack exists
                        stack_name = req_data.get('StackName')[0]
                        cloudformation_client = aws_stack.connect_to_service('cloudformation')
                        try:
                            cloudformation_client.describe_stacks(StackName=stack_name)
                        except Exception:
                            return error_response('Stack with id %s does not exist' % stack_name, code=404)
            if action == 'DescribeStackResource':
                if response.status_code >= 500:
                    # fix an error in moto where it fails with 500 if the stack does not exist
                    return error_response('Stack resource does not exist', code=404)
            elif action == 'CreateStack' or action == 'UpdateStack':
                if response.status_code >= 400 and response.status_code < 500:
                    return response
                # run the actual deployment
                template = template_deployer.template_to_json(req_data.get('TemplateBody')[0])
                template_deployer.deploy_template(template, req_data.get('StackName')[0])
Exemple #4
0
    def return_response(self, method, path, data, headers, response):
        req_data = None
        if method == 'POST' and path == '/':
            req_data = urlparse.parse_qs(to_str(data))
            action = req_data.get('Action')[0]

        if req_data:
            if action == 'DescribeStackResources':
                if response.status_code < 300:
                    response_dict = xmltodict.parse(response.content)['DescribeStackResourcesResponse']
                    resources = response_dict['DescribeStackResourcesResult']['StackResources']
                    if not resources:
                        # Check if stack exists
                        stack_name = req_data.get('StackName')[0]
                        cloudformation_client = aws_stack.connect_to_service('cloudformation')
                        try:
                            cloudformation_client.describe_stacks(StackName=stack_name)
                        except Exception:
                            return error_response('Stack with id %s does not exist' % stack_name, code=404)
            if action == 'DescribeStackResource':
                if response.status_code >= 500:
                    # fix an error in moto where it fails with 500 if the stack does not exist
                    return error_response('Stack resource does not exist', code=404)
            if action == 'ListStackResources':
                response_dict = xmltodict.parse(response.content, force_list=('member'))['ListStackResourcesResponse']
                resources = response_dict['ListStackResourcesResult']['StackResourceSummaries']
                if resources:
                    sqs_client = aws_stack.connect_to_service('sqs')
                    content_str = content_str_original = to_str(response.content)
                    new_response = Response()
                    new_response.status_code = response.status_code
                    new_response.headers = response.headers
                    for resource in resources['member']:
                        if resource['ResourceType'] == 'AWS::SQS::Queue':
                            try:
                                queue_name = resource['PhysicalResourceId']
                                queue_url = sqs_client.get_queue_url(QueueName=queue_name)['QueueUrl']
                            except Exception:
                                stack_name = req_data.get('StackName')[0]
                                return error_response('Stack with id %s does not exist' % stack_name, code=404)
                            content_str = re.sub(resource['PhysicalResourceId'], queue_url, content_str)
                    new_response._content = content_str
                    if content_str_original != new_response._content:
                        # if changes have been made, return patched response
                        new_response.headers['content-length'] = len(new_response._content)
                        return new_response
            elif action in ('CreateStack', 'UpdateStack'):
                if response.status_code >= 400:
                    return response
                # run the actual deployment
                template = template_deployer.template_to_json(req_data.get('TemplateBody')[0])
                template_deployer.deploy_template(template, req_data.get('StackName')[0])
Exemple #5
0
def create_stack(req_data):
    stack_name = req_data.get('StackName')[0]
    if stack_exists(stack_name):
        message = 'The resource with the name requested already exists.'
        return error_response(message, error_type='AlreadyExists')
    # create stack
    cloudformation_service = aws_stack.connect_to_service('cloudformation')
    template = template_deployer.template_to_json(
        req_data.get('TemplateBody')[0])
    cloudformation_service.create_stack(StackName=stack_name,
                                        TemplateBody=template)
    # now run the actual deployment
    template_deployer.deploy_template(template, stack_name)
    return True
def update_cloudformation(method, path, data, headers, response=None, return_forward_info=False):
    req_data = None
    if method == 'POST' and path == '/':
        req_data = urlparse.parse_qs(data)
        action = req_data.get('Action')[0]

    if return_forward_info:
        if req_data:
            if action == 'CreateChangeSet':
                return create_change_set(req_data)
            elif action == 'DescribeChangeSet':
                return describe_change_set(req_data)
            elif action == 'ExecuteChangeSet':
                return execute_change_set(req_data)
        return True

    if req_data:
        if action == 'CreateStack' or action == 'UpdateStack':
            if response.status_code in range(200, 300):
                # run the actual deployment
                template = template_deployer.template_to_json(req_data.get('TemplateBody')[0])
                template_deployer.deploy_template(template)
def execute_change_set(req_data):
    cs_arn = req_data.get('ChangeSetName')[0]
    stack_name = req_data.get('StackName')[0]
    cs_details = CHANGE_SETS.get(cs_arn)
    if not cs_details:
        return error_response('Change Set %s does not exist' % cs_arn, 404, 'ChangeSetNotFound')

    # convert to JSON (might have been YAML, and update_stack/create_stack seem to only work with JSON)
    template = template_deployer.template_to_json(cs_details.get('TemplateBody')[0])

    # update stack information
    cloudformation_service = aws_stack.connect_to_service('cloudformation')
    if stack_exists(stack_name):
        cloudformation_service.update_stack(StackName=stack_name,
            TemplateBody=template)
    else:
        cloudformation_service.create_stack(StackName=stack_name,
            TemplateBody=template)

    # now run the actual deployment
    template_deployer.deploy_template(template, stack_name)

    response = make_response('ExecuteChangeSet')
    return response
Exemple #8
0
def update_cloudformation(method,
                          path,
                          data,
                          headers,
                          response=None,
                          return_forward_info=False):
    req_data = None
    if method == 'POST' and path == '/':
        req_data = urlparse.parse_qs(data)
        action = req_data.get('Action')[0]

    if return_forward_info:
        if req_data:
            if action == 'CreateChangeSet':
                return create_change_set(req_data)
            elif action == 'DescribeChangeSet':
                return describe_change_set(req_data)
            elif action == 'ExecuteChangeSet':
                return execute_change_set(req_data)
            elif action == 'UpdateStack' and req_data.get('TemplateURL'):
                # Temporary fix until the moto CF backend can handle TemplateURL (currently fails)
                url = re.sub(r'https?://s3\.amazonaws\.com',
                             aws_stack.get_local_service_url('s3'),
                             req_data.get('TemplateURL')[0])
                req_data['TemplateBody'] = requests.get(url).content
                modified_data = urlparse.urlencode(req_data, doseq=True)
                return Request(data=modified_data,
                               headers=headers,
                               method=method)
        return True

    if req_data:
        if action == 'DescribeStackResources':
            if response.status_code < 300:
                response_dict = xmltodict.parse(
                    response.content)['DescribeStackResourcesResponse']
                resources = response_dict['DescribeStackResourcesResult'][
                    'StackResources']
                if not resources:
                    # Check if stack exists
                    stack_name = req_data.get('StackName')[0]
                    cloudformation_client = aws_stack.connect_to_service(
                        'cloudformation')
                    try:
                        cloudformation_client.describe_stacks(
                            StackName=stack_name)
                    except Exception as e:
                        return error_response(
                            'Stack with id %s does not exist' % stack_name,
                            code=404)
        if action == 'DescribeStackResource':
            if response.status_code >= 500:
                # fix an error in moto where it fails with 500 if the stack does not exist
                return error_response('Stack resource does not exist',
                                      code=404)
        elif action == 'CreateStack' or action == 'UpdateStack':
            # run the actual deployment
            template = template_deployer.template_to_json(
                req_data.get('TemplateBody')[0])
            template_deployer.deploy_template(template,
                                              req_data.get('StackName')[0])
            if response.status_code >= 400:
                return make_response(action)