示例#1
0
 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.assertEqual(id_data, {'AbstractRoleMappings': {self.logical_role_name: self.role_name}})
     mock_list_role_policies.assert_called_once_with(RoleName=self.role_name)
示例#2
0
 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.assertEqual(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)
示例#3
0
 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.assertEqual(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)
示例#4
0
 def test_with_delete_role_policy_other_error(self, mock_list_role_policies, mock_delete_role_policy,
                                              mock_delete_role):
     print('=== {} {} {}'.format(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.assertEqual(id_data, {'AbstractRoleMappings': {self.logical_role_name: self.role_name}})
     mock_delete_role_policy.assert_any_call(RoleName=self.role_name, PolicyName=self.policy_name_1)
     mock_list_role_policies.assert_called_once_with(RoleName=self.role_name)
def handler(event, context):
    props = properties.load(event, PROPERTIES_SCHEMA)

    request_type = event['RequestType']
    stack_arn = event['StackId']
    logical_role_name = props.FunctionName
    stack_manager = stack_info.StackInfoManager()

    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:
        stack = stack_manager.get_stack_info(stack_arn)

        if request_type == 'Create':

            project_service_lambda_arn = _get_project_service_lambda_arn(stack)
            assume_role_service = 'lambda.amazonaws.com'
            role_arn = role_utils.create_access_control_role(
                stack_manager,
                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)
        # Check if we have a folder just for this function, if not use the default
        output_key = input_key = _get_input_key(props)
        if not props.IgnoreAppendingSettingsToZip:
            output_key = _inject_settings(props.Settings.__dict__,
                                          props.Runtime,
                                          props.ConfigurationBucket, input_key,
                                          props.FunctionName)

        cc_settings = copy.deepcopy(props.Settings.__dict__)
        # Remove "Services" from settings because they get injected into the python code package during _inject_settings
        # TODO: move handling of project-level service interfaces to the same code as cross-gem interfaces
        if "Services" in cc_settings:
            del cc_settings["Services"]

        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),
            'ComposedLambdaConfiguration': {
                'Code': {
                    'S3Bucket': props.ConfigurationBucket,
                    'S3Key': output_key
                },
                "Environment": {
                    "Variables": cc_settings
                },
                'Role': role_arn,
                'Runtime': props.Runtime
            },
            "CCSettings":
            cc_settings
        }

    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)
示例#6
0
def handler(event, context):
    """Entry point for the Custom::ServiceApi resource handler."""
    stack_id = event['StackId']
    request_type = event['RequestType']
    logical_resource_id = event['LogicalResourceId']
    logical_role_name = logical_resource_id
    stack_manager = stack_info.StackInfoManager()
    stack = stack_manager.get_stack_info(stack_id)

    rest_api_resource_name = stack.stack_name + '-' + logical_resource_id
    id_data = aws_utils.get_data_from_custom_physical_resource_id(
        event.get('PhysicalResourceId', None))

    response_data = {}
    project_tags = {
        constant.PROJECT_NAME_TAG: stack.project_stack.project_name,
        constant.STACK_ID_TAG: stack_id
    }

    if request_type == 'Create':

        props = properties.load(event, PROPERTY_SCHEMA)
        role_arn = role_utils.create_access_control_role(
            stack_manager, id_data, stack.stack_arn, logical_role_name,
            API_GATEWAY_SERVICE_NAME)
        swagger_content = get_configured_swagger_content(
            stack, props, role_arn, rest_api_resource_name)
        rest_api_id = create_api_gateway(rest_api_resource_name, props,
                                         swagger_content)
        service_url = get_service_url(rest_api_id, stack.region)

        register_service_interfaces(stack, service_url, swagger_content)
        update_api_gateway_tags(rest_api_id, event, project_tags)

        response_data['Url'] = service_url
        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(
            stack, props, role_arn, rest_api_resource_name)
        update_api_gateway(rest_api_id, props, swagger_content)
        service_url = get_service_url(rest_api_id, stack.region)
        register_service_interfaces(stack, service_url, swagger_content)

        update_api_gateway_tags(rest_api_id, event, project_tags)

        response_data['Url'] = service_url

    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. Apparently Cloud Formation has an internal temporary id for the
            # resource and uses it for the delete request.
            #
            # Unfortunately 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.')

        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)
            service_url = get_service_url(rest_api_id, stack.region)
            unregister_service_interfaces(stack, service_url)

            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)

    return custom_resource_response.success_response(response_data,
                                                     physical_resource_id)
def handler(event, context):

    props = properties.load(event, PROPERTIES_SCHEMA)

    request_type = event['RequestType']
    stack_arn = event['StackId']
    logical_role_name = props.FunctionName
    stack_manager = stack_info.StackInfoManager()

    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:

        stack = stack_manager.get_stack_info(stack_arn)

        if request_type == 'Create':

            project_service_lambda_arn = _get_project_service_lambda_arn(stack)
            assume_role_service = 'lambda.amazonaws.com'
            role_arn = role_utils.create_access_control_role(
                stack_manager,
                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)
        # give access to project level ServiceDirectory APIs
        # Other deployment-level APIs are handled in InterfaceDependeny resolver custom resource type
        permitted_arns = _add_services_settings(stack, props.Settings.__dict__, props.Services)
        _add_service_access_policy_to_role(role_arn, permitted_arns)
        # Check if we have a folder just for this function, if not use the default
        output_key = input_key = _get_input_key(props)
        if not props.IgnoreAppendingSettingsToZip:
            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),
            'ComposedLambdaConfiguration': {
                'Code': {
                    'S3Bucket': props.ConfigurationBucket,
                    'S3Key': output_key
                },
                'Role': role_arn,
                'Runtime': props.Runtime
            }
        }
        
    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)