def test_with_list_role_policies_access_denied_error(
         self, mock_delete_role, mock_delete_role_policy,
         mock_list_role_policies):
     id_data = {
         'AbstractRoleMappings': {
             self.logical_role_name: self.role_name
         }
     }
     role_utils.delete_access_control_role(id_data, self.logical_role_name)
     self.assertEquals(id_data, {'AbstractRoleMappings': {}})
     mock_list_role_policies.assert_called_once_with(
         RoleName=self.role_name)
     mock_delete_role.assert_called_once_with(RoleName=self.role_name)
 def test_with_delete_role_no_such_entity_error(self, mock_delete_role,
                                                mock_delete_role_policy,
                                                mock_list_role_policies):
     id_data = {
         'AbstractRoleMappings': {
             self.logical_role_name: self.role_name
         }
     }
     role_utils.delete_access_control_role(id_data, self.logical_role_name)
     self.assertEquals(id_data, {'AbstractRoleMappings': {}})
     mock_list_role_policies.assert_called_once_with(
         RoleName=self.role_name)
     mock_delete_role_policy.assert_any_call(RoleName=self.role_name,
                                             PolicyName=self.policy_name_1)
     mock_delete_role_policy.assert_any_call(RoleName=self.role_name,
                                             PolicyName=self.policy_name_2)
     mock_delete_role.assert_called_once_with(RoleName=self.role_name)
 def test_with_list_role_policies_other_error(self, mock_list_role_policies,
                                              mock_delete_role,
                                              mock_delete_role_policy):
     id_data = {
         'AbstractRoleMappings': {
             self.logical_role_name: self.role_name
         }
     }
     with self.assertRaisesRegexp(ClientError, self.unknown_error_code):
         role_utils.delete_access_control_role(id_data,
                                               self.logical_role_name)
     self.assertEquals(
         id_data,
         {'AbstractRoleMappings': {
             self.logical_role_name: self.role_name
         }})
     mock_list_role_policies.assert_called_once_with(
         RoleName=self.role_name)
Beispiel #4
0
def handler(event, context):

    props = properties.load(
        event, {
            'ConfigurationBucket':
            properties.String(),
            'ConfigurationKey':
            properties.String(),
            'FunctionName':
            properties.String(),
            'Settings':
            properties.Object(default={}, schema={'*': properties.String()}),
            'Runtime':
            properties.String()
        })

    request_type = event['RequestType']
    stack_arn = event['StackId']
    logical_role_name = props.FunctionName

    id_data = aws_utils.get_data_from_custom_physical_resource_id(
        event.get('PhysicalResourceId', None))

    if request_type == 'Delete':

        role_utils.delete_access_control_role(id_data, logical_role_name)

        response_data = {}

    else:

        if request_type == 'Create':

            project_service_lambda_arn = _get_project_service_lambda_arn(
                stack_arn)

            assume_role_service = 'lambda.amazonaws.com'
            role_arn = role_utils.create_access_control_role(
                id_data,
                stack_arn,
                logical_role_name,
                assume_role_service,
                default_policy=get_default_policy(project_service_lambda_arn))

        elif request_type == 'Update':

            role_arn = role_utils.get_access_control_role_arn(
                id_data, logical_role_name)

        else:
            raise RuntimeError(
                'Unexpected request type: {}'.format(request_type))

        _add_built_in_settings(props.Settings.__dict__, stack_arn)

        # Check if we have a folder just for this function, if not use the default
        input_key = _get_input_key(props)

        output_key = _inject_settings(props.Settings.__dict__, props.Runtime,
                                      props.ConfigurationBucket, input_key,
                                      props.FunctionName)

        response_data = {
            'ConfigurationBucket':
            props.ConfigurationBucket,
            'ConfigurationKey':
            output_key,
            'Runtime':
            props.Runtime,
            'Role':
            role_arn,
            'RoleName':
            role_utils.get_access_control_role_name(stack_arn,
                                                    logical_role_name)
        }

    physical_resource_id = aws_utils.construct_custom_physical_resource_id_with_data(
        stack_arn, event['LogicalResourceId'], id_data)

    custom_resource_response.succeed(event, context, response_data,
                                     physical_resource_id)
Beispiel #5
0
def handler(event, context):

    request_type = event['RequestType']
    logical_resource_id = event['LogicalResourceId']
    logical_role_name = logical_resource_id
    owning_stack_info = stack_info.get_stack_info(event['StackId'])
    rest_api_resource_name = owning_stack_info.stack_name + '-' + logical_resource_id
    id_data = aws_utils.get_data_from_custom_physical_resource_id(
        event.get('PhysicalResourceId', None))

    response_data = {}

    if request_type == 'Create':

        props = properties.load(event, PROPERTY_SCHEMA)
        role_arn = role_utils.create_access_control_role(
            id_data, owning_stack_info.stack_arn, logical_role_name,
            API_GATEWAY_SERVICE_NAME)
        swagger_content = get_configured_swagger_content(
            owning_stack_info, props, role_arn, rest_api_resource_name)
        rest_api_id = create_api_gateway(props, swagger_content)
        response_data['Url'] = get_api_url(rest_api_id,
                                           owning_stack_info.region)
        id_data['RestApiId'] = rest_api_id

    elif request_type == 'Update':

        rest_api_id = id_data.get('RestApiId', None)
        if not rest_api_id:
            raise RuntimeError(
                'No RestApiId found in id_data: {}'.format(id_data))

        props = properties.load(event, PROPERTY_SCHEMA)
        role_arn = role_utils.get_access_control_role_arn(
            id_data, logical_role_name)
        swagger_content = get_configured_swagger_content(
            owning_stack_info, props, role_arn, rest_api_resource_name)
        update_api_gateway(rest_api_id, props, swagger_content)
        response_data['Url'] = get_api_url(rest_api_id,
                                           owning_stack_info.region)

    elif request_type == 'Delete':

        if not id_data:

            # The will be no data in the id if Cloud Formation cancels a resource creation
            # (due to a failure in another resource) before it processes the resource create
            # response. Appearently Cloud Formation has an internal temporary id for the
            # resource and uses it for the delete request.
            #
            # Unfortunalty there isn't a good way to deal with this case. We don't have the
            # id data, so we can't clean up the things it identifies. At best we can allow the
            # stack cleanup to continue, leaving the rest API behind and role behind.

            print 'WARNING: No id_data provided on delete.'.format(id_data)

        else:

            rest_api_id = id_data.get('RestApiId', None)
            if not rest_api_id:
                raise RuntimeError(
                    'No RestApiId found in id_data: {}'.format(id_data))

            delete_api_gateway(rest_api_id)
            del id_data['RestApiId']

            role_utils.delete_access_control_role(id_data, logical_role_name)

    else:

        raise RuntimeError('Invalid RequestType: {}'.format(request_type))

    physical_resource_id = aws_utils.construct_custom_physical_resource_id_with_data(
        event['StackId'], logical_resource_id, id_data)

    custom_resource_response.succeed(event, context, response_data,
                                     physical_resource_id)