def handler(event, context):
    if event['RequestType'] == 'Delete':
        return custom_resource_response.success_response({'Arn': ''}, '')
    props = properties.load(event, {
            'ConfigurationBucket': properties.String(),
            'ConfigurationKey': properties.String(),
            'LogicalPoolName': properties.String(),
            'RoleType': properties.String(default=""),
            'Path': properties.String(),
            'AssumeRolePolicyDocument': properties.Dictionary()
        })

    stack_manager = stack_info.StackInfoManager()
    stack = stack_manager.get_stack_info(event['StackId'])

    identity_client = identity_pool.get_identity_client()

    cognito_pool_info = aws_utils.get_cognito_pool_from_file(props.ConfigurationBucket,
        props.ConfigurationKey,
        props.LogicalPoolName,
        stack)

    arn = ''
    if cognito_pool_info:
        response = identity_client.get_identity_pool_roles(IdentityPoolId=cognito_pool_info['PhysicalResourceId'])
        arn = response.get("Roles", {}).get(props.RoleType, "")
    else:
        name = "{}{}Role".format(stack.stack_name, event['LogicalResourceId'])
        arn=create_role(name, props)

    return custom_resource_response.success_response({'Arn': arn}, arn)
Esempio n. 2
0
def handler(event, context):
    """Entry point for the Custom::ResourceGroupConfiguration resource handler."""

    props = properties.load(
        event, {
            'ConfigurationBucket': properties.String(),
            'ConfigurationKey': properties.String(),
            'ResourceGroupName': properties.String()
        })

    data = {
        'ConfigurationBucket':
        props.ConfigurationBucket,
        'ConfigurationKey':
        '{}/resource-group/{}'.format(props.ConfigurationKey,
                                      props.ResourceGroupName),
        'TemplateURL':
        'https://s3.amazonaws.com/{}/{}/resource-group/{}/{}'.format(
            props.ConfigurationBucket, props.ConfigurationKey,
            props.ResourceGroupName, constant.RESOURCE_GROUP_TEMPLATE_FILENAME)
    }

    physical_resource_id = 'CloudCanvas:LambdaConfiguration:{stack_name}:{resource_group_name}'.format(
        stack_name=aws_utils.get_stack_name_from_stack_arn(event['StackId']),
        resource_group_name=props.ResourceGroupName)

    return custom_resource_response.success_response(data,
                                                     physical_resource_id)
Esempio n. 3
0
    def test_with_empty_list(self):

        target = properties.ObjectOrListOfObject(
            schema={'prop': properties.String()})
        value = target('Test', [])

        self.assertEqual(len(value), 0)
Esempio n. 4
0
    def test_with_None_and_default(self):

        target = properties.Object(default={'prop': 'default'},
                                   schema={'prop': properties.String()})
        value = target('Test', None)

        self.assertEqual(value.prop, 'default')
Esempio n. 5
0
def handler(event, context):
    '''Entry point for the Custom::AccessControl resource handler.'''
    
    props = properties.load(event, {
        'ConfigurationBucket': properties.String(), # Currently not used
        'ConfigurationKey': properties.String()})   # Depend on unique upload id in key to force Cloud Formation to call handler

    # Validate RequestType
    request_type = event['RequestType']
    if request_type not in ['Create', 'Update', 'Delete']:
        raise RuntimeError('Unexpected request type: {}'.format(request_type))

    # Get stack_info for the AccessControl resource's stack.
    stack_arn = event['StackId']
    stack_manager = stack_info.StackInfoManager()
    stack = stack_manager.get_stack_info(stack_arn)

    # Physical ID is always the same.
    physical_resource_id = aws_utils.get_stack_name_from_stack_arn(stack_arn) + '-' + event['LogicalResourceId']

    # The AccessControl resource has no output values. 
    data = {}

    # Accumlate problems encountered so we can give a full report.
    problems = ProblemList()

    # Apply access control as determined by the Cloud Canvas stack type.
    if stack.stack_type == stack.STACK_TYPE_RESOURCE_GROUP:
        were_changes = _apply_resource_group_access_control(request_type, stack, problems)
    elif stack.stack_type == stack.STACK_TYPE_DEPLOYMENT_ACCESS:
        were_changes = _apply_deployment_access_control(request_type, stack, problems)
    elif stack.stack_type == stack.STACK_TYPE_PROJECT:
        were_changes = _apply_project_access_control(request_type, stack, problems)
    else:
        raise RuntimeError('The Custom::AccessControl resource can only be used in resource group, deployment access, or project stack templates.')

    # If there were any problems, provide an error message with all the details.
    if problems:
        raise RuntimeError('Found invalid AccessControl metadata:\n    {}'.format(problems))

    # If there were changes, wait a few seconds for them to propagate
    if were_changes:
        print 'Delaying {} seconds for change propagation'.format(PROPAGATION_DELAY_SECONDS)
        time.sleep(PROPAGATION_DELAY_SECONDS)
    
    # Successful execution.
    return custom_resource_response.success_response(data, physical_resource_id)
Esempio n. 6
0
    def test_with_None_and_default_object(self):

        target = properties.ObjectOrListOfObject(
            schema={'prop': properties.String()}, default={'prop': 'value'})
        value = target('Test', None)

        self.assertEqual(len(value), 1)
        self.assertEqual(value[0].prop, 'value')
Esempio n. 7
0
    def test_with_None_and_no_default(self):

        target = properties.String()

        with self.assertRaises(properties.ValidationError) as e:
            value = target('Test', None)

        self.assertIn('Test', e.exception.message)
Esempio n. 8
0
    def test_with_non_object(self):

        target = properties.Object(schema={'prop': properties.String()})

        with self.assertRaises(properties.ValidationError) as e:
            value = target('Test', 1234)

        self.assertIn('Test', e.exception.message)
Esempio n. 9
0
    def test_with_non_string(self):

        target = properties.String()

        with self.assertRaises(properties.ValidationError) as e:
            value = target('Test', 1234)

        self.assertIn('Test', e.exception.message)
def handler(event, context):
    """Entry point for the Custom::CognitoIdPoolSharedRole resource handler."""
    stack_id = event['StackId']

    if event['RequestType'] == 'Delete':
        return custom_resource_response.success_response({'Arn': ''}, '')

    props = properties.load(
        event, {
            'ConfigurationBucket': properties.String(),
            'ConfigurationKey': properties.String(),
            'LogicalPoolName': properties.String(),
            'RoleType': properties.String(default=""),
            'Path': properties.String(),
            'AssumeRolePolicyDocument': properties.Dictionary()
        })

    stack_manager = stack_info.StackInfoManager()
    stack = stack_manager.get_stack_info(stack_id)

    identity_client = identity_pool.get_identity_client()

    cognito_pool_info = aws_utils.get_cognito_pool_from_file(
        props.ConfigurationBucket, props.ConfigurationKey,
        props.LogicalPoolName, stack)

    arn = ''
    if cognito_pool_info:
        response = identity_client.get_identity_pool_roles(
            IdentityPoolId=cognito_pool_info['PhysicalResourceId'])
        arn = response.get("Roles", {}).get(props.RoleType, "")
    else:
        # Set up resource tags for all resources created
        tags = [{
            "Key": constant.PROJECT_NAME_TAG,
            "Value": stack.project_stack.project_name
        }, {
            "Key": constant.STACK_ID_TAG,
            "Value": stack_id
        }]

        name = "{}{}Role".format(stack.stack_name, event['LogicalResourceId'])
        arn = _create_role(name, props, tags)

    return custom_resource_response.success_response({'Arn': arn}, arn)
Esempio n. 11
0
    def test_with_object_list(self):

        target = properties.ObjectOrListOfObject(
            schema={'prop': properties.String()})
        value = target('Test', [{'prop': 'value1'}, {'prop': 'value2'}])

        self.assertEqual(len(value), 2)
        self.assertEqual(value[0].prop, 'value1')
        self.assertEqual(value[1].prop, 'value2')
Esempio n. 12
0
def handler(event, context):
    
    props = properties.load(event, {
        'ConfigurationBucket': properties.String(),
        'ConfigurationKey': properties.String(),
        'ResourceGroupName': properties.String()})

    data = {
        'ConfigurationBucket': props.ConfigurationBucket,
        'ConfigurationKey': '{}/resource-group/{}'.format(props.ConfigurationKey, props.ResourceGroupName),
        'TemplateURL': 'https://s3.amazonaws.com/{}/{}/resource-group/{}/resource-template.json'.format(props.ConfigurationBucket, props.ConfigurationKey, props.ResourceGroupName)
    }

    physical_resource_id = 'CloudCanvas:LambdaConfiguration:{stack_name}:{resource_group_name}'.format(
        stack_name=aws_utils.get_stack_name_from_stack_arn(event['StackId']),
        resource_group_name=props.ResourceGroupName)

    response.succeed(event, context, data, physical_resource_id)
Esempio n. 13
0
    def test_with_invalid_object_in_list(self):

        target = properties.ObjectOrListOfObject(
            schema={'prop': properties.String()})

        with self.assertRaises(properties.ValidationError) as e:
            value = target('Test', [{'prop': 1234}])

        self.assertIn('Test', e.exception.message)
Esempio n. 14
0
def load_reference_metadata_properties(event):
    # Strip the fields other than 'ReferenceMetadata' from event['ResourceProperties']
    reference_metadata = event.get('ResourceProperties',
                                   {}).get('ReferenceMetadata', {})
    event['ResourceProperties'] = {'ReferenceMetadata': reference_metadata}

    return properties.load(
        event, {
            'ReferenceMetadata':
            properties.Object(
                schema={
                    'Arn':
                    properties.String(),
                    'PhysicalId':
                    properties.String(),
                    'Permissions':
                    properties.Object(
                        schema={
                            'Action': properties.StringOrListOfString(),
                            'ResourceSuffix':
                            properties.StringOrListOfString()
                        })
                })
        })
Esempio n. 15
0
def handler(event, context):
    stack_arn = event['StackId']
    stack = stack_info.StackInfoManager().get_stack_info(stack_arn)
    props = properties.load(event, {'ReferenceName': properties.String()})

    request_type = event['RequestType']
    if request_type not in ['Create', 'Update', 'Delete']:
        raise RuntimeError('Unexpected request type: {}'.format(request_type))

    data = {}
    if request_type != 'Delete':
        data = {
            'PhysicalId': _get_reference_physical_id(stack,
                                                     props.ReferenceName)
        }

    physical_resource_id = aws_utils.construct_custom_physical_resource_id_with_data(
        stack_arn, event['LogicalResourceId'],
        {'ReferenceName': props.ReferenceName})

    return custom_resource_response.success_response(data,
                                                     physical_resource_id)
Esempio n. 16
0
    "2012-10-17",
    'Statement': [{
        'Sid':
        "WriteLogs",
        'Effect':
        "Allow",
        'Action':
        ["logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents"],
        'Resource':
        "arn:aws:logs:*:*:*"
    }]
}

_handler_schema = {
    'Function':
    properties.String(""),
    'PolicyStatement':
    properties.ObjectOrListOfObject(
        default=[],
        schema={
            'Sid': properties.String(""),
            'Action': properties.StringOrListOfString(),
            'Resource': properties.StringOrListOfString(default=[]),
            'Effect': properties.String()
        })
}

_schema = {
    'LambdaConfiguration':
    properties.Dictionary(default={}),
    'LambdaTimeout':
    }

    if project_service_lambda_arn:
        policy['Statement'].append({
            "Sid": "InvokeProjectServiceLambda",
            "Effect": "Allow",
            "Action": ["lambda:InvokeFunction"],
            "Resource": project_service_lambda_arn
        })

    return json.dumps(policy)


PROPERTIES_SCHEMA = {
    'ConfigurationBucket':
    properties.String(),
    'ConfigurationKey':
    properties.String(),
    'FunctionName':
    properties.String(),
    'Settings':
    properties.Object(default={}, schema={'*': properties.String()}),
    'Runtime':
    properties.String(),
    'Services':
    properties.ObjectOrListOfObject(default=[],
                                    schema={
                                        'InterfaceId':
                                        properties.String(),
                                        'Optional':
                                        properties.Boolean(default=False)
Esempio n. 18
0
from cgf_utils import patch
from cgf_utils import aws_utils
from botocore.exceptions import ClientError
from cgf_service_directory import ServiceDirectory

cfg = boto_config.Config(read_timeout=70, connect_timeout=70)
s3 = aws_utils.ClientWrapper(boto3.client('s3', config=cfg))
api_gateway = aws_utils.ClientWrapper(boto3.client('apigateway', config=cfg),
                                      do_not_log_args=['body'])

API_GATEWAY_SERVICE_NAME = 'apigateway.amazonaws.com'
STAGE_NAME = 'api'

PROPERTY_SCHEMA = {
    'ConfigurationBucket':
    properties.String(),
    'ConfigurationKey':
    properties.String(),
    'CacheClusterEnabled':
    properties.Boolean(default=False),
    'CacheClusterSize':
    properties.String(default='0.5'),
    'SwaggerSettings':
    properties.Dictionary(default={}),
    'MethodSettings':
    properties.Object(
        default={},
        schema={
            '*':
            properties.Object(
                default={},  # path, can be *
Esempio n. 19
0
def handler(event, context):
    """Entry point for the Custom::CognitoIdentityPool resource handler."""
    stack_id = event['StackId']

    props = properties.load(
        event,
        {
            'ConfigurationBucket':
            properties.String(),
            'ConfigurationKey':
            properties.String(
            ),  # this is only here to force the resource handler to execute on each update to the deployment
            'IdentityPoolName':
            properties.String(),
            'UseAuthSettingsObject':
            properties.String(),
            'AllowUnauthenticatedIdentities':
            properties.String(),
            'DeveloperProviderName':
            properties.String(default=''),
            'ShareMode':
            properties.String(
                default=''
            ),  # SHARED when the pool from the file should be used
            'Roles':
            properties.Object(default={}, schema={'*': properties.String()}),
            'RoleMappings':
            properties.Object(
                default={},
                schema={
                    'Cognito':
                    properties.Object(
                        default={},
                        schema={
                            'Type': properties.String(''),
                            'AmbiguousRoleResolution': properties.String('')
                        })
                })
        })

    # give the identity pool a unique name per stack
    stack_manager = stack_info.StackInfoManager()
    stack = stack_manager.get_stack_info(stack_id)

    # Set up resource tags for all resources created
    tags = {
        constant.PROJECT_NAME_TAG: stack.project_stack.project_name,
        constant.STACK_ID_TAG: stack_id
    }

    shared_pool = aws_utils.get_cognito_pool_from_file(
        props.ConfigurationBucket, props.ConfigurationKey,
        event['LogicalResourceId'], stack)

    identity_pool_name = stack.stack_name + props.IdentityPoolName
    identity_pool_name = identity_pool_name.replace('-', ' ')
    identity_client = identity_pool.get_identity_client()
    identity_pool_id = custom_resource_utils.get_embedded_physical_id(
        event.get('PhysicalResourceId'))
    found_pool = identity_pool.get_identity_pool(identity_pool_id)

    request_type = event['RequestType']
    if shared_pool and props.ShareMode == 'SHARED':
        data = {
            'IdentityPoolName': identity_pool_name,
            'IdentityPoolId': shared_pool['PhysicalResourceId']
        }
        return custom_resource_response.success_response(
            data, shared_pool['PhysicalResourceId'])

    if request_type == 'Delete':
        if found_pool is not None:
            identity_client.delete_identity_pool(
                IdentityPoolId=identity_pool_id)
        data = {}

    else:
        use_auth_settings_object = props.UseAuthSettingsObject.lower(
        ) == 'true'
        supported_login_providers = {}

        if use_auth_settings_object:
            # download the auth settings from s3
            player_access_key = 'player-access/' + constant.AUTH_SETTINGS_FILENAME
            auth_doc = json.loads(
                _load_doc_from_s3(props.ConfigurationBucket,
                                  player_access_key))

            # if the doc has entries add them to the supported_login_providers dictionary
            if len(auth_doc) > 0:
                for key, value in six.iteritems(auth_doc):
                    supported_login_providers[
                        value['provider_uri']] = value['app_id']

        cognito_identity_providers = identity_pool.get_cognito_identity_providers(
            stack_manager, stack_id, event['LogicalResourceId'])

        print('Identity Providers: {}'.format(cognito_identity_providers))
        allow_anonymous = props.AllowUnauthenticatedIdentities.lower(
        ) == 'true'
        # if the pool exists just update it, otherwise create a new one

        args = {
            'IdentityPoolName': identity_pool_name,
            'AllowUnauthenticatedIdentities': allow_anonymous,
            'SupportedLoginProviders': supported_login_providers,
            'CognitoIdentityProviders': cognito_identity_providers,
            'IdentityPoolTags': tags
        }

        if props.DeveloperProviderName:
            args['DeveloperProviderName'] = props.DeveloperProviderName

        if found_pool is not None:
            identity_client.update_identity_pool(
                IdentityPoolId=identity_pool_id, **args)
        else:
            response = identity_client.create_identity_pool(**args)
            identity_pool_id = response['IdentityPoolId']

        # update the roles for the pool
        role_mappings = {}
        if props.RoleMappings.Cognito.Type and len(
                cognito_identity_providers) > 0:
            print('Adding role mappings for Cognito {}'.format(
                props.RoleMappings.Cognito.__dict__))
            role_mappings['{}:{}'.format(
                cognito_identity_providers[0]['ProviderName'],
                cognito_identity_providers[0]
                ['ClientId'])] = props.RoleMappings.Cognito.__dict__

        print("Role Mappings: {}".format(role_mappings))
        identity_client.set_identity_pool_roles(
            IdentityPoolId=identity_pool_id,
            Roles=props.Roles.__dict__,
            RoleMappings=role_mappings)

        data = {
            'IdentityPoolName': identity_pool_name,
            'IdentityPoolId': identity_pool_id
        }

    physical_resource_id = identity_pool_id

    return custom_resource_response.success_response(data,
                                                     physical_resource_id)
_default_lambda_memory = 128

# Default custom resource lambda timeout in Seconds, can be between 3-900 as per Lambda spec
_default_lambda_timeout = 10  # Seconds

# Schema for _handler_properties_configuration
# Set these values to increase memory and timeout values for a given custom resource Lambda
# These are mostly Lambda configuration properties and should follow existing names and restrictions
_handler_properties_configuration = {
    'MemorySize': properties.Integer(default=_default_lambda_memory),  # MB: Must be a multiple of 64MB as per Lambda spec
    'Timeout': properties.Integer(default=_default_lambda_timeout),  # Seconds: Must be between 3-900 as per Lambda spec
}

# Schema for ArnHandler or FunctionHandlers for core resource types
_handler_schema = {
    'Function': properties.String(""),
    'HandlerFunctionConfiguration': properties.Object(default={}, schema=_handler_properties_configuration),
    'PolicyStatement': properties.ObjectOrListOfObject(default=[], schema={
        'Sid': properties.String(""),
        'Action': properties.StringOrListOfString(),
        'Resource': properties.StringOrListOfString(default=[]),
        'Effect': properties.String(),
        'Condition': properties.Dictionary(default={})
    })
}

# Schema for the CoreResourceTypes custom CloudFormation resources.
# Note: LambdaConfiguration and LambdaTimeout are globally applied to all custom resource Lambdas.  To change Memory and Timeout for a given Lambda
# use a HandlerFunctionConfiguration which overrides the global lambda configs
#
# Note: Need to define expected fields here to avoid "Property is not supported" failures during definition validation
def handler(event, context):

    props = properties.load(
        event,
        {
            'ConfigurationBucket':
            properties.String(),
            'ConfigurationKey':
            properties.String(
            ),  ##this is only here to force the resource handler to execute on each update to the deployment
            'IdentityPoolName':
            properties.String(),
            'UseAuthSettingsObject':
            properties.String(),
            'AllowUnauthenticatedIdentities':
            properties.String(),
            'DeveloperProviderName':
            properties.String(default=''),
            'Roles':
            properties.Object(default={}, schema={'*': properties.String()}),
            'RoleMappings':
            properties.Object(
                default={},
                schema={
                    'Cognito':
                    properties.Object(
                        default={},
                        schema={
                            'Type': properties.String(''),
                            'AmbiguousRoleResolution': properties.String('')
                        })
                })
        })

    #give the identity pool a unique name per stack
    stack_manager = stack_info.StackInfoManager()
    stack_name = aws_utils.get_stack_name_from_stack_arn(event['StackId'])
    identity_pool_name = stack_name + props.IdentityPoolName
    identity_pool_name = identity_pool_name.replace('-', ' ')
    identity_client = identity_pool.get_identity_client()
    identity_pool_id = custom_resource_utils.get_embedded_physical_id(
        event.get('PhysicalResourceId'))
    found_pool = identity_pool.get_identity_pool(identity_pool_id)

    request_type = event['RequestType']
    if request_type == 'Delete':
        if found_pool != None:
            identity_client.delete_identity_pool(
                IdentityPoolId=identity_pool_id)
        data = {}

    else:
        use_auth_settings_object = props.UseAuthSettingsObject.lower(
        ) == 'true'
        supported_login_providers = {}

        if use_auth_settings_object == True:
            #download the auth settings from s3
            player_access_key = 'player-access/' + constant.AUTH_SETTINGS_FILENAME
            auth_doc = json.loads(
                _load_doc_from_s3(props.ConfigurationBucket,
                                  player_access_key))

            #if the doc has entries add them to the supported_login_providers dictionary
            if len(auth_doc) > 0:
                for key, value in auth_doc.iteritems():
                    supported_login_providers[
                        value['provider_uri']] = value['app_id']

        cognito_identity_providers = identity_pool.get_cognito_identity_providers(
            stack_manager, event['StackId'], event['LogicalResourceId'])

        print 'Identity Providers: ', cognito_identity_providers
        allow_anonymous = props.AllowUnauthenticatedIdentities.lower(
        ) == 'true'
        #if the pool exists just update it, otherwise create a new one

        args = {
            'IdentityPoolName': identity_pool_name,
            'AllowUnauthenticatedIdentities': allow_anonymous,
            'SupportedLoginProviders': supported_login_providers,
            'CognitoIdentityProviders': cognito_identity_providers
        }

        if props.DeveloperProviderName:
            args['DeveloperProviderName'] = props.DeveloperProviderName

        if found_pool != None:
            identity_client.update_identity_pool(
                IdentityPoolId=identity_pool_id, **args)
        else:
            response = identity_client.create_identity_pool(**args)
            identity_pool_id = response['IdentityPoolId']

        #update the roles for the pool
        role_mappings = {}
        if props.RoleMappings.Cognito.Type and len(
                cognito_identity_providers) > 0:
            print 'Adding role mappings for cognito', props.RoleMappings.Cognito.__dict__
            role_mappings['{}:{}'.format(
                cognito_identity_providers[0]['ProviderName'],
                cognito_identity_providers[0]
                ['ClientId'])] = props.RoleMappings.Cognito.__dict__

        print "Role Mappings: ", role_mappings
        identity_client.set_identity_pool_roles(
            IdentityPoolId=identity_pool_id,
            Roles=props.Roles.__dict__,
            RoleMappings=role_mappings)

        data = {
            'IdentityPoolName': identity_pool_name,
            'IdentityPoolId': identity_pool_id
        }

    physical_resource_id = identity_pool_id

    return custom_resource_response.success_response(data,
                                                     physical_resource_id)
def handler(event, context):
    """Entry point for the Custom::CognitoUserPool resource handler."""
    stack_id = event['StackId']

    props = properties.load(
        event,
        {
            'ClientApps':
            properties.StringOrListOfString(),
            'ExplicitAuthFlows':
            properties.StringOrListOfString(default=[]),
            'RefreshTokenValidity':
            properties.String('30'),
            'ConfigurationKey':
            properties.String(
            ),  # this is only here to force the resource handler to execute on each update to the deployment
            'LambdaConfig':
            properties.Dictionary({}),
            'PoolName':
            properties.String(),
            'Groups':
            properties.ObjectOrListOfObject(
                default=[],
                schema={
                    'Name': properties.String(),
                    'Description': properties.String(''),
                    'Role': properties.String(),
                    'Precedence': properties.String('99')
                }),
            'AllowAdminCreateUserOnly':
            properties.String('')
        })

    # give the identity pool a unique name per stack
    stack_manager = stack_info.StackInfoManager()
    stack = stack_manager.get_stack_info(stack_id)

    stack_name = stack.stack_name
    pool_name = props.PoolName.replace('-', ' ')
    pool_name = stack_name + pool_name
    cognito_idp_client = user_pool.get_idp_client()
    pool_id = custom_resource_utils.get_embedded_physical_id(
        event.get('PhysicalResourceId'))
    found_pool = user_pool.get_user_pool(pool_id)

    # Set up tags for all resources created
    tags = {
        constant.PROJECT_NAME_TAG: stack.project_stack.project_name,
        constant.STACK_ID_TAG: stack_id
    }

    request_type = event['RequestType']

    if request_type == 'Delete':
        if found_pool is not None:
            cognito_idp_client.delete_user_pool(UserPoolId=pool_id)
        data = {}

    else:
        # if the pool exists just update it, otherwise create a new one

        mfa_config = 'OFF'  # MFA is currently unsupported by Lumberyard
        # Users are automatically prompted to verify these things.
        # At least one auto-verified thing (email or phone) is required to allow password recovery.
        auto_verified_attributes = ['email']

        client_app_data = {}
        lambda_config = props.LambdaConfig

        user_pool.validate_identity_metadata(stack_manager, stack_id,
                                             event['LogicalResourceId'],
                                             props.ClientApps)
        admin_create_user_config = __get_admin_create_user_config(
            props.AllowAdminCreateUserOnly)
        print(json.dumps(admin_create_user_config))

        if found_pool is not None:  # Update
            response = cognito_idp_client.update_user_pool(
                UserPoolId=pool_id,
                MfaConfiguration=mfa_config,
                AutoVerifiedAttributes=auto_verified_attributes,
                LambdaConfig=lambda_config,
                AdminCreateUserConfig=admin_create_user_config,
                UserPoolTags=tags)

            existing_client_apps = user_pool.get_client_apps(pool_id)
            client_app_data = update_client_apps(pool_id, props.ClientApps,
                                                 existing_client_apps, False,
                                                 props.ExplicitAuthFlows,
                                                 props.RefreshTokenValidity)

            response = cognito_idp_client.list_groups(UserPoolId=pool_id)

            found_groups = {}
            for actual_group in response['Groups']:
                group_name = actual_group['GroupName']
                for requested_group in props.Groups:
                    # does the group exist in the resource template
                    if group_name == requested_group.Name:
                        found_groups.update({group_name: True})
                        break

                # delete the group as it is no longer in the resource template
                if group_name not in found_groups:
                    cognito_idp_client.delete_group(
                        GroupName=actual_group['GroupName'],
                        UserPoolId=pool_id)

            print("Found groups=>{}".format(json.dumps(found_groups)))
            # iterate the groups defined in the user pool resource template
            for group in props.Groups:
                # update the group as it is currently a group in the user pool
                group_definition = __generate_group_definition(pool_id, group)
                print("Group '{}' is defined by {}".format(
                    group.Name, json.dumps(group_definition)))
                if group.Name in found_groups:
                    cognito_idp_client.update_group(**group_definition)
                else:
                    # group is a new group on the user pool
                    cognito_idp_client.create_group(**group_definition)

        else:  # Create
            response = cognito_idp_client.create_user_pool(
                PoolName=pool_name,
                MfaConfiguration=mfa_config,
                AutoVerifiedAttributes=auto_verified_attributes,
                LambdaConfig=lambda_config,
                AdminCreateUserConfig=admin_create_user_config,
                UserPoolTags=tags)
            pool_id = response['UserPool']['Id']
            print('User pool creation response: {}'.format(response))
            for group in props.Groups:
                group_definition = __generate_group_definition(pool_id, group)
                print("Group '{}' is defined by {}".format(
                    group.Name, json.dumps(group_definition)))
                cognito_idp_client.create_group(**group_definition)

            client_app_data = update_client_apps(pool_id, props.ClientApps, [],
                                                 False,
                                                 props.ExplicitAuthFlows,
                                                 props.RefreshTokenValidity)

        updated_resources = {
            stack_id: {
                event['LogicalResourceId']: {
                    'physical_id': pool_id,
                    'client_apps': {
                        client_app['ClientName']: {
                            'client_id': client_app['ClientId']
                        }
                        for client_app in client_app_data['Created'] +
                        client_app_data['Updated']
                    }
                }
            }
        }

        identity_pool.update_cognito_identity_providers(
            stack_manager, stack_id, pool_id, updated_resources)

        data = {
            'UserPoolName': pool_name,
            'UserPoolId': pool_id,
            'ClientApps': client_app_data,
        }

    physical_resource_id = pool_id

    return custom_resource_response.success_response(data,
                                                     physical_resource_id)
        ]
    }
    if project_service_lambda_arn:
        policy['Statement'].append({
            "Sid": "InvokeProjectServiceLambda",
            "Effect": "Allow",
            "Action": [
                "lambda:InvokeFunction"
            ],
            "Resource": project_service_lambda_arn
        })
    return json.dumps(policy)


PROPERTIES_SCHEMA = {
    'ConfigurationBucket': properties.String(),
    'ConfigurationKey': properties.String(),
    'FunctionName': properties.String(),
    'Settings': properties.Object( default={},
        schema={
            '*': properties.String()
        }
    ),
    'Runtime': properties.String(),
    'Services': properties.ObjectOrListOfObject( default=[],
        schema={
            'InterfaceId': properties.String(),
            'Optional': properties.Boolean(default = False)
        }
    ),
    'IgnoreAppendingSettingsToZip': properties.Boolean(default = False)
Esempio n. 24
0
from resource_manager_common import service_interface
from cgf_utils import role_utils
from cgf_utils import patch
from cgf_utils import aws_utils
from botocore.exceptions import ClientError
from cgf_service_directory import ServiceDirectory

cfg = botocore.config.Config(read_timeout=70, connect_timeout=70)
s3 = aws_utils.ClientWrapper(boto3.client('s3', config = cfg))
api_gateway = aws_utils.ClientWrapper(boto3.client('apigateway', config = cfg), do_not_log_args=['body'])

API_GATEWAY_SERVICE_NAME = 'apigateway.amazonaws.com'
STAGE_NAME = 'api'

PROPERTY_SCHEMA = {
    'ConfigurationBucket': properties.String(),
    'ConfigurationKey': properties.String(),
    'CacheClusterEnabled': properties.Boolean( default = False ),
    'CacheClusterSize': properties.String( default = '0.5' ),
    'SwaggerSettings': properties.Dictionary( default={} ),
    'MethodSettings': properties.Object( default={},
        schema={
            '*': properties.Object( default={}, # path, can be *
                schema={
                    '*': properties.Object( default={}, # method, can be *
                        schema={
                            'cacheDataEncrypted': properties.Boolean( default = False ),
                            'cacheTtlInSeconds': properties.Integer( default = 300 ),
                            'cachingEnabled': properties.Boolean( default = False ),
                            'dataTraceEnabled': properties.Boolean( default = False ),
                            'loggingLevel': properties.String( default='OFF' ),
Esempio n. 25
0
    def test_with_object_and_no_default(self):

        target = properties.Object(schema={'prop': properties.String()})
        value = target('Test', {'prop': 'value'})

        self.assertEqual(value.prop, 'value')
Esempio n. 26
0
    def test_with_string_and_no_default(self):

        target = properties.String()
        value = target('Test', 'value')

        self.assertEqual(value, 'value')
Esempio n. 27
0
    def test_with_None_and_default(self):

        target = properties.String(default='value')
        value = target('Test', None)

        self.assertEqual(value, 'value')