def update_credentials(credentials): request = credentials request['kms_key'] = custom_resource_utils.get_embedded_physical_id(CloudCanvas.get_setting('KmsKey')) request['method'] = 'PUT' client = boto3.client('lambda') response = client.invoke( FunctionName = custom_resource_utils.get_embedded_physical_id(CloudCanvas.get_setting(constants.JIRA_CREDENTIALS_LAMBDA)), Payload = json.dumps(request) ) return json.loads(response['Payload'].read().decode("utf-8"))
def get_question_table(): if not hasattr(get_question_table, 'question_table'): question_table_name = custom_resource_utils.get_embedded_physical_id(CloudCanvas.get_setting('Questions')) get_question_table.question_table = boto3.resource('dynamodb').Table(question_table_name) if get_question_table.question_table is None: raise RuntimeError('No Question Table') return get_question_table.question_table
def get_answer_aggregation_table(): if not hasattr(get_answer_aggregation_table, 'answer_aggregation_table'): answer_aggregation_table_name = custom_resource_utils.get_embedded_physical_id(CloudCanvas.get_setting('AnswerAggregations')) get_answer_aggregation_table.answer_aggregation_table = boto3.resource('dynamodb').Table(answer_aggregation_table_name) if get_answer_aggregation_table.answer_aggregation_table is None: raise RuntimeError('No AnswerAggregation Table') return get_answer_aggregation_table.answer_aggregation_table
def get_survey_table(): if not hasattr(get_survey_table, 'survey_table'): survey_table_name = custom_resource_utils.get_embedded_physical_id(CloudCanvas.get_setting('Surveys')) get_survey_table.survey_table = boto3.resource('dynamodb').Table(survey_table_name) if get_survey_table.survey_table is None: raise RuntimeError('No Survey Table') return get_survey_table.survey_table
def update_cognito_identity_providers(stack_manager, stack_arn, user_pool_id, updated_resources=None): """ This is called when a user pool is being updated, and identity pools need to be updated to match the new mappings from the template metadata. Identity pools will be affected as follows: - Identity pools will be linked to the user pool if they aren't already. - Identity pools that are already linked will be updated with the user pool's current client ids. - Identity pools that are linked but no longer part of the mapping will be unlinked from the user pool. """ if updated_resources is None: updated_resources = {} provider_to_update = user_pool.get_provider_name(user_pool_id) mappings = get_identity_mappings(stack_manager, stack_arn, updated_resources) for mapping in mappings: identity_pool_id = custom_resource_utils.get_embedded_physical_id(mapping['identity_pool_resource'].physical_id) if identity_pool_id: identity_pool = get_identity_client().describe_identity_pool(IdentityPoolId=identity_pool_id) is_linked = bool([provider for provider in identity_pool.get('CognitoIdentityProviders', []) if provider.get('ProviderName') == provider_to_update]) should_be_linked = bool([provider for provider in mapping['providers'] if provider.get('ProviderName') == provider_to_update]) # If is_linked, the link either needs to be updated or removed. # If should_be_linked, the link either needs to be created or updated. if is_linked or should_be_linked: # Create an update request based on the current pool description. update_request = {} for field in IDENTITY_POOL_FIELDS: if field in identity_pool: update_request[field] = identity_pool[field] # Replace the current list of providers. This handles linking, updating, and unlinking pools. update_request['CognitoIdentityProviders'] = mapping['providers'] # Update the pool. get_identity_client().update_identity_pool(**update_request)
def get_identity_pool(identity_pool_id): """Returns the identity pool if one was found, or None if the identity_pool_id is missing or invalid.""" if not identity_pool_id or identity_pool_id.find(':') < 0: # The ID is missing or invalid. return None return get_identity_client().describe_identity_pool( IdentityPoolId=custom_resource_utils.get_embedded_physical_id(identity_pool_id))
def __get_resource_name(context, deployment, resource_group, resource_name): description = __get_resource(context, deployment, resource_group, resource_name) phys_id = description.get('PhysicalResourceId', None) if (description['ResourceType'].startswith("Custom::")): return custom_resource_utils.get_embedded_physical_id(phys_id) return phys_id
def assert_linked(self, identity_pool_logical_id, expected_user_pools): actual_providers = {} identity_pool_id = self.get_physical_id(identity_pool_logical_id) identity_pool = self.get_identity_pool(identity_pool_id) for provider in identity_pool.get('CognitoIdentityProviders', []): providers = actual_providers.get(provider['ProviderName'], set()) providers.add(provider['ClientId']) actual_providers[provider['ProviderName']] = providers expected_providers = {} debug_messages = ['Identity pool {} has physical id {}'.format(identity_pool_logical_id, identity_pool_id)] for user_pool_logical_id, client_names in expected_user_pools.iteritems(): user_pool_id = custom_resource_utils.get_embedded_physical_id(self.get_physical_id(user_pool_logical_id)) debug_messages.append('User pool {} has physical id {}'.format(user_pool_logical_id, user_pool_id)) client_apps = self.aws_cognito_idp.list_user_pool_clients(UserPoolId=user_pool_id, MaxResults=60).get('UserPoolClients', []) for client_app in client_apps: debug_messages.append(' {}: {}'.format(client_app['ClientName'], client_app['ClientId'])) client_id_by_name = {client_app['ClientName']: client_app['ClientId'] for client_app in client_apps} providers = set() for client_name in client_names: self.assertIn(client_name, client_id_by_name, 'User pool {} should have a client named {}'.format(user_pool_logical_id, client_name)) providers.add(client_id_by_name[client_name]) expected_providers[unicode(self.get_provider_name(user_pool_id))] = providers if expected_providers != actual_providers: print "\n".join(debug_messages) self.assertEqual(expected_providers, actual_providers)
def create_launch_configuration(config): startup_script = INSTANCE_STARTUP_SCRIPT % { 'domain': CloudCanvas.get_setting('DomainName'), 'task_list': CloudCanvas.get_setting('TaskList'), 'div_task': CloudCanvas.get_setting('DivTask'), 'build_task': CloudCanvas.get_setting('BuildTask'), 'merge_task': CloudCanvas.get_setting('MergeTask'), 'log_db': custom_resource_utils.get_embedded_physical_id(CloudCanvas.get_setting('LogDB')), 's3': CloudCanvas.get_setting('S3Bucket') } try: params = { 'IamInstanceProfile': CloudCanvas.get_setting("InstanceProfile"), 'LaunchConfigurationName': config['launchConfigurationName'], 'ImageId': config['imageId'], 'InstanceType': config['instanceType'], 'SecurityGroups': [CloudCanvas.get_setting("EC2SecurityGroup")], 'InstanceMonitoring': {'Enabled': False}, 'AssociatePublicIpAddress': True, 'UserData': startup_script } if len(config['keyPair']): params['KeyName'] = config['keyPair'] __get_autoscaling_client().create_launch_configuration(**params) except ClientError as e: return e.response['Error']['Code'] return SUCCEED_STATUS
def __get_table(): global SPEECH_TABLE if SPEECH_TABLE == None: SPEECH_TABLE = boto3.resource('dynamodb').Table( custom_resource_utils.get_embedded_physical_id( CloudCanvas.get_setting("SpeechLibTable"))) return SPEECH_TABLE
def get_identity_pool(identity_pool_id): if not identity_pool_id or identity_pool_id.find(':') < 0: # The ID is missing or invalid. return None return get_identity_client().describe_identity_pool( IdentityPoolId=custom_resource_utils.get_embedded_physical_id( identity_pool_id))
def updateUserPoolEmailMessage(context, url, project_config_bucket_id): project_name_parts = project_config_bucket_id.split('-') project_name = project_name_parts[0] resource = context.config.project_resources[constant.PROJECT_RESOURCE_NAME_USER_POOL] stackid = resource['StackId'] region = resource_manager.util.get_region_from_arn(stackid) user_pool_id = custom_resource_utils.get_embedded_physical_id(resource['PhysicalResourceId']) client = context.aws.client('cognito-idp', region=region) email_invite_subject = "Your Amazon Lumberyard Cloud Gem Portal temporary password" email_invite_message = "Your Amazon Lumberyard Administrator has invited you to the project " + project_name + "'s <a href=" + url + ">Cloud Gem Portal</a>.<BR><BR>Username: {username} <BR>Temporary Password: {####} <BR><BR>Cloud Gem Portal URL: " + url try: client.update_user_pool( UserPoolId=user_pool_id, EmailVerificationMessage="You or your Amazon Lumberyard Administrator has reset your password for the <a href=" + url + ">Cloud Gem Portal</a> on your project '" + project_name + "'.<BR><BR>You will need this code to change your password when you login next.<BR>Code: {####} <BR><BR>Cloud Gem Portal URL: " + url, EmailVerificationSubject='Your Amazon Lumberyard Cloud Gem Portal verification code', AdminCreateUserConfig={ 'InviteMessageTemplate': { 'EmailMessage': email_invite_message, 'EmailSubject': email_invite_subject }, "AllowAdminCreateUserOnly": True }, AutoVerifiedAttributes=['email'] ) context.view._output_message("The Cloud Gem Portal URL has been written to the Cognito user email template successfully.") except ClientError: return
def create_Jira_tickets(prepared_reports): cw = CloudWatch() for report in prepared_reports: # Check whether the report is duplicated client = boto3.client('lambda') response = client.invoke( FunctionName=custom_resource_utils.get_embedded_physical_id( CloudCanvas.get_setting('DeduppingLambda')), Payload=json.dumps({'report': report})) issue_id = json.loads(response['Payload'].read().decode("utf-8")) attachments = report.get('attachment_id', None) identifier = report.get('universal_unique_identifier', None) report.pop('attachment_id') report.pop('universal_unique_identifier') # Create a new JIRA ticket if the report is not duplicated if not issue_id: issue_id = __create_jira_ticket(cw, report, attachments) update_occurance_count(issue_id) report['jira_status'] = issue_id additonal_report_Info.update_report_header({ 'universal_unique_identifier': identifier, 'jira_status': report.get('jira_status', None), 'bookmark': report.get('bookmark', None), 'report_status': report.get('report_status', None) }) return 'SUCCESS'
def __get_jira_integration_settings_table(): if not hasattr(__get_jira_integration_settings_table, 'jira_integration_settings'): __get_jira_integration_settings_table.jira_integration_settings = boto3.resource( 'dynamodb').Table( custom_resource_utils.get_embedded_physical_id( CloudCanvas.get_setting('JiraIntegrationSettings'))) return __get_jira_integration_settings_table.jira_integration_settings
def get_service_api_id(context): cgp_service_api_info = custom_resource_utils.get_embedded_physical_id( context.stack.get_physical_resource_id(context.config.project_stack_id, "ServiceApi")) return json.loads( cgp_service_api_info.replace( get_match_group(SERVICE_API_PREFIX_PATTERN, cgp_service_api_info), ""))['RestApiId']
def __get_jira_ticket_occurance_count_table(): if not hasattr(__get_jira_ticket_occurance_count_table, 'jira_ticket_occurance_count'): __get_jira_ticket_occurance_count_table.jira_ticket_occurance_count = boto3.resource( 'dynamodb').Table( custom_resource_utils.get_embedded_physical_id( CloudCanvas.get_setting('JiraTicketOccuranceCount'))) return __get_jira_ticket_occurance_count_table.jira_ticket_occurance_count
def get_user_pool(user_pool_id): """Returns the user pool if one was found, or None if the identity_pool_id is missing or invalid.""" if not user_pool_id or user_pool_id.find('_') < 0: # The ID is missing or invalid. return None return get_idp_client().describe_user_pool( UserPoolId=custom_resource_utils.get_embedded_physical_id( user_pool_id))
def get_message_table(): if not hasattr(get_message_table, 'message_table'): message_table_name = custom_resource_utils.get_embedded_physical_id( CloudCanvas.get_setting('MessageTable')) message_table = boto3.resource('dynamodb').Table(message_table_name) if message_table is None: raise RuntimeError('No Message Table') return message_table
def __010_get_anonymous_aws_credentials(self): self.context['identity_pool_id'] = custom_resource_utils.get_embedded_physical_id(self.get_stack_resource_physical_id(self.get_deployment_access_stack_arn(self.TEST_DEPLOYMENT_NAME), 'PlayerAccessIdentityPool')) identity_response = self.aws_cognito_identity.get_id(IdentityPoolId=self.context['identity_pool_id'], Logins={}) response = self.aws_cognito_identity.get_credentials_for_identity(IdentityId=identity_response['IdentityId'], Logins={}) self.context['anonymous_aws_credentials'] = { 'AccessKeyId': response['Credentials']['AccessKeyId'], 'SecretKey': response['Credentials']['SecretKey'], 'SessionToken': response['Credentials']['SessionToken'] }
def __get_credentials(): request = {'method': 'GET'} client = boto3.client('lambda') response = client.invoke( FunctionName=custom_resource_utils.get_embedded_physical_id( CloudCanvas.get_setting(constants.JIRA_CREDENTIALS_LAMBDA)), Payload=json.dumps(request)) return json.loads(response['Payload'].read().decode("utf-8"))
def create_portal_administrator(context): resource = context.config.project_resources[ constant.PROJECT_RESOURCE_NAME_USER_POOL] stackid = resource['StackId'] region = resource_manager.util.get_region_from_arn(stackid) user_pool_id = custom_resource_utils.get_embedded_physical_id( resource['PhysicalResourceId']) client = context.aws.client('cognito-idp', region=region) administrator_name = 'administrator' is_new_user = False password = None try: response = client.admin_get_user(UserPoolId=user_pool_id, Username=administrator_name) user_exists = True if 'UserStatus' in response and response[ 'UserStatus'] == 'FORCE_CHANGE_PASSWORD': is_new_user = True except ClientError: user_exists = False if not user_exists: # create the account if it does not random_str = ''.join( random.choice(string.ascii_uppercase + string.ascii_lowercase + string.digits) for _ in range(8)) password = ''.join((random.choice(string.ascii_uppercase), random.choice(string.ascii_lowercase), random.choice(string.digits), '@', random_str)) # shuffle password characters chars = list(password) random.shuffle(chars) password = ''.join(chars) try: response = client.admin_create_user(UserPoolId=user_pool_id, Username=administrator_name, TemporaryPassword=password) response = client.admin_add_user_to_group( UserPoolId=user_pool_id, Username=administrator_name, GroupName='administrator') is_new_user = True except ClientError as e: credentials = context.aws.load_credentials() access_key = credentials.get(constant.DEFAULT_SECTION_NAME, constant.ACCESS_KEY_OPTION) raise HandledError( "Failed to create the administrator account with username '{}' and password '{}'. Have your administrator verify the user account '{}' with access key '{}' has the policies ['cognito-idp:AdminCreateUser', 'cognito-idp:AdminAddUserToGroup']." .format(administrator_name, password, context.config.user_default_profile, access_key), e) return is_new_user, administrator_name, password
def _get_stack_resource_by_name(context, deployment_name, resource_group_name, resource_name): '''Returns the resource id of the staging table.''' if deployment_name is None: deployment_name = context.config.default_deployment stack_id = context.config.get_resource_group_stack_id(deployment_name , resource_group_name, optional=True) resource_obj = context.stack.get_physical_resource_id(stack_id, resource_name) resource_arn = custom_resource_utils.get_embedded_physical_id(resource_obj) show_manifest.found_stack(resource_arn) return resource_arn
def get_client_apps(user_pool_id): """Gets all client apps for a pool.""" response = get_idp_client().list_user_pool_clients(UserPoolId=user_pool_id, MaxResults=60) client_apps = response.get('UserPoolClients', []) while 'NextToken' in response: response = get_idp_client().list_user_pool_clients( UserPoolId=custom_resource_utils.get_embedded_physical_id( user_pool_id), MaxResults=60, NextToken=response['NextToken']) client_apps.extend(response.get('UserPoolClients', [])) return client_apps
def _get_channel_table(): if not hasattr(_get_channel_table, 'channel_table'): channel_table_name = custom_resource_utils.get_embedded_physical_id( CloudCanvas.get_setting('ChannelDataTable')) dynamoresource = boto3.resource('dynamodb') _get_channel_table.channel_table = dynamoresource.Table( channel_table_name) if _get_channel_table.channel_table is None: raise errors.PortalRequestError('No Channel Table') return _get_channel_table.channel_table
def get_data_from_custom_physical_resource_id(physical_resource_id): if physical_resource_id: embedded_physical_resource_id = custom_resource_utils.get_embedded_physical_id(physical_resource_id) i_data_marker = embedded_physical_resource_id.find(ID_DATA_MARKER) if i_data_marker == -1: id_data = {} else: try: id_data = json.loads(embedded_physical_resource_id[i_data_marker + len(ID_DATA_MARKER):]) except Exception as e: raise HandledError('Could not parse JSON data from physical resource id {}. {}'.format(physical_resource_id, e.message)) else: id_data = {} return id_data
def __get_player_accessible_arns(context, deployment_name, role, args=None): player_accessible_arns = set() deployment_access_stack_id = context.config.get_deployment_access_stack_id( deployment_name, True if args is not None and args.is_gui else False) player_role_id = context.stack.get_physical_resource_id( deployment_access_stack_id, role, optional=True) if player_role_id.startswith( "{"): # same check that happens in custom_resource info class player_role_id = custom_resource_utils.get_embedded_physical_id( player_role_id).split("/")[-1] if player_role_id is None: return {} iam = context.aws.client('iam') res = {} try: res = iam.list_role_policies(RoleName=player_role_id) except ClientError as e: if e.response["Error"]["Code"] in ["AccessDenied"]: return {} for policy_name in res.get('PolicyNames', []): res = iam.get_role_policy(RoleName=player_role_id, PolicyName=policy_name) policy_document = res.get('PolicyDocument', {}) statements = policy_document.get('Statement', []) if not isinstance(statements, type([])): # def list above hides list statements = [statements] for statement in statements: if statement.get('Effect', '') != 'Allow': continue resource_arns = statement.get('Resource', []) if not isinstance(resource_arns, type( [])): # def list above hides list resource_arns = [resource_arns] for resource_arn in resource_arns: player_accessible_arns.add( __trim_player_accessible_arn(resource_arn)) return player_accessible_arns
def __record_cognito_pools(context): pools = {"Project": {}} for resource_name, definition in context.config.project_resources.iteritems( ): if definition["ResourceType"] in [ "Custom::CognitoIdentityPool", "Custom::CognitoUserPool" ]: pools["Project"][resource_name] = { "PhysicalResourceId": custom_resource_utils.get_embedded_physical_id( definition['PhysicalResourceId']), "Type": definition["ResourceType"] } cognito_pools.write_to_project_file(context, pools)
def __upload_attachment(attachment, jira_issue): s3_client = boto3.client('s3', config=Config(signature_version='s3v4')) key = attachment.get('id', '') try: response = s3_client.get_object(Bucket = custom_resource_utils.get_embedded_physical_id(CloudCanvas.get_setting(constants.SANITIZED_BUCKET)), Key = key) except Exception as e: print "Unable to GET the sanitized attachment. Key==>", key return new_attachment = StringIO.StringIO() new_attachment.write(response['Body'].read()) attachment_object = get_jira_client().add_attachment( issue = jira_issue, attachment = new_attachment, filename = ('{}.{}').format(attachment.get('name', ''), attachment.get('extension', '')))
def get_data_from_custom_physical_resource_id(physical_resource_id): """Returns data extracted from a physical resource id with embedded JSON data.""" if physical_resource_id: embedded_physical_resource_id = custom_resource_utils.get_embedded_physical_id( physical_resource_id) i_data_marker = embedded_physical_resource_id.find(ID_DATA_MARKER) if i_data_marker == -1: id_data = {} else: try: id_data = json.loads( embedded_physical_resource_id[i_data_marker + len(ID_DATA_MARKER):]) except Exception as e: print( 'Could not parse JSON data from physical resource id {}. {}' .format(embedded_physical_resource_id, str(e))) id_data = {} else: id_data = {} return id_data
def update_cognito_identity_providers(stack_manager, stack_arn, user_pool_id, updated_resources={}): provider_to_update = user_pool.get_provider_name(user_pool_id) mappings = get_identity_mappings(stack_manager, stack_arn, updated_resources) for mapping in mappings: identity_pool_id = custom_resource_utils.get_embedded_physical_id( mapping['identity_pool_resource'].physical_id) if identity_pool_id: identity_pool = get_identity_client().describe_identity_pool( IdentityPoolId=identity_pool_id) is_linked = bool([ provider for provider in identity_pool.get( 'CognitoIdentityProviders', []) if provider.get('ProviderName') == provider_to_update ]) should_be_linked = bool([ provider for provider in mapping['providers'] if provider.get('ProviderName') == provider_to_update ]) # If is_linked, the link either needs to be updated or removed. # If should_be_linked, the link either needs to be created or updated. if is_linked or should_be_linked: # Create an update request based on the current pool description. update_request = {} for field in IDENTITY_POOL_FIELDS: if field in identity_pool: update_request[field] = identity_pool[field] # Replace the current list of providers. This handles linking, updating, and unlinking pools. update_request['CognitoIdentityProviders'] = mapping[ 'providers'] # Update the pool. get_identity_client().update_identity_pool(**update_request)