def test_get_records(self, kinesis_client, kinesis_create_stream, wait_for_stream_ready): stream_name = "test-%s" % short_uid() kinesis_create_stream(StreamName=stream_name, ShardCount=1) wait_for_stream_ready(stream_name) kinesis_client.put_records( StreamName=stream_name, Records=[{ "Data": "SGVsbG8gd29ybGQ=", "PartitionKey": "1" }], ) # get records with JSON encoding iterator = self._get_shard_iterator(stream_name, kinesis_client) response = kinesis_client.get_records(ShardIterator=iterator) json_records = response.get("Records") assert 1 == len(json_records) assert "Data" in json_records[0] # get records with CBOR encoding iterator = self._get_shard_iterator(stream_name, kinesis_client) url = config.get_edge_url() headers = aws_stack.mock_aws_request_headers("kinesis") headers["Content-Type"] = constants.APPLICATION_AMZ_CBOR_1_1 headers["X-Amz-Target"] = "Kinesis_20131202.GetRecords" data = cbor2.dumps({"ShardIterator": iterator}) result = requests.post(url, data, headers=headers) assert 200 == result.status_code result = cbor2.loads(result.content) attrs = ("Data", "EncryptionType", "PartitionKey", "SequenceNumber") assert select_attributes(json_records[0], attrs) == select_attributes( result["Records"][0], attrs)
def create_stack_instances(req_params): state = CloudFormationRegion.get() set_name = req_params.get('StackSetName') stack_set = [ sset for sset in state.stack_sets.values() if sset.stack_set_name == set_name ] if not stack_set: return not_found_error('Stack set named "%s" does not exist' % set_name) stack_set = stack_set[0] op_id = req_params.get('OperationId') or short_uid() sset_meta = stack_set.metadata accounts = extract_url_encoded_param_list(req_params, 'Accounts.member.%s') accounts = accounts or extract_url_encoded_param_list( req_params, 'DeploymentTargets.Accounts.member.%s') regions = extract_url_encoded_param_list(req_params, 'Regions.member.%s') stacks_to_await = [] for account in accounts: for region in regions: # deploy new stack LOG.debug('Deploying instance for stack set "%s" in region "%s"' % (set_name, region)) cf_client = aws_stack.connect_to_service('cloudformation', region_name=region) kwargs = select_attributes(sset_meta, 'TemplateBody') or select_attributes( sset_meta, 'TemplateURL') stack_name = 'sset-%s-%s' % (set_name, account) result = cf_client.create_stack(StackName=stack_name, **kwargs) stacks_to_await.append((stack_name, region)) # store stack instance instance = { 'StackSetId': sset_meta['StackSetId'], 'OperationId': op_id, 'Account': account, 'Region': region, 'StackId': result['StackId'], 'Status': 'CURRENT', 'StackInstanceStatus': { 'DetailedStatus': 'SUCCEEDED' } } instance = StackInstance(instance) stack_set.stack_instances.append(instance) # wait for completion of stack for stack in stacks_to_await: aws_stack.await_stack_completion(stack[0], region_name=stack[1]) # record operation operation = { 'OperationId': op_id, 'StackSetId': stack_set.metadata['StackSetId'], 'Action': 'CREATE', 'Status': 'SUCCEEDED' } stack_set.operations[op_id] = operation result = {'OperationId': op_id} return result
def create_stack_instances(req_params): state = CloudFormationRegion.get() set_name = req_params.get("StackSetName") stack_set = [ sset for sset in state.stack_sets.values() if sset.stack_set_name == set_name ] if not stack_set: return not_found_error('Stack set named "%s" does not exist' % set_name) stack_set = stack_set[0] op_id = req_params.get("OperationId") or short_uid() sset_meta = stack_set.metadata accounts = extract_url_encoded_param_list(req_params, "Accounts.member.%s") accounts = accounts or extract_url_encoded_param_list( req_params, "DeploymentTargets.Accounts.member.%s") regions = extract_url_encoded_param_list(req_params, "Regions.member.%s") stacks_to_await = [] for account in accounts: for region in regions: # deploy new stack LOG.debug('Deploying instance for stack set "%s" in region "%s"', set_name, region) cf_client = aws_stack.connect_to_service("cloudformation", region_name=region) kwargs = select_attributes(sset_meta, "TemplateBody") or select_attributes( sset_meta, "TemplateURL") stack_name = "sset-%s-%s" % (set_name, account) result = cf_client.create_stack(StackName=stack_name, **kwargs) stacks_to_await.append((stack_name, region)) # store stack instance instance = { "StackSetId": sset_meta["StackSetId"], "OperationId": op_id, "Account": account, "Region": region, "StackId": result["StackId"], "Status": "CURRENT", "StackInstanceStatus": { "DetailedStatus": "SUCCEEDED" }, } instance = StackInstance(instance) stack_set.stack_instances.append(instance) # wait for completion of stack for stack in stacks_to_await: aws_stack.await_stack_completion(stack[0], region_name=stack[1]) # record operation operation = { "OperationId": op_id, "StackSetId": stack_set.metadata["StackSetId"], "Action": "CREATE", "Status": "SUCCEEDED", } stack_set.operations[op_id] = operation result = {"OperationId": op_id} return result
def test_base_path_mapping(self): client = aws_stack.connect_to_service('apigateway') response = client.create_rest_api(name='my_api', description='this is my api') rest_api_id = response['id'] # CREATE domain_name = 'domain1.example.com' base_path = '/foo' result = client.create_base_path_mapping( domainName=domain_name, basePath=base_path, restApiId=rest_api_id, stage='dev') self.assertEqual(result['ResponseMetadata']['HTTPStatusCode'], 200) # LIST result = client.get_base_path_mappings(domainName=domain_name) self.assertEqual(result['ResponseMetadata']['HTTPStatusCode'], 200) expected = {'basePath': base_path, 'restApiId': rest_api_id, 'stage': 'dev'} self.assertEqual(result['items'], [expected]) # GET result = client.get_base_path_mapping(domainName=domain_name, basePath=base_path) self.assertEqual(result['ResponseMetadata']['HTTPStatusCode'], 200) self.assertEqual(select_attributes(result, ['basePath', 'restApiId', 'stage']), expected) # UPDATE result = client.update_base_path_mapping(domainName=domain_name, basePath=base_path, patchOperations=[]) # DELETE client.delete_base_path_mapping(domainName=domain_name, basePath=base_path) with self.assertRaises(Exception): client.get_base_path_mapping(domainName=domain_name, basePath=base_path) with self.assertRaises(Exception): client.delete_base_path_mapping(domainName=domain_name, basePath=base_path)
def _create_params(params, **kwargs): attributes = [ "AccessPolicies", "AdvancedOptions", "CognitoOptions", "DomainName", "EBSOptions", "ElasticsearchClusterConfig", "ElasticsearchVersion", "EncryptionAtRestOptions", "LogPublishingOptions", "NodeToNodeEncryptionOptions", "SnapshotOptions", "VPCOptions", ] result = select_attributes(params, attributes) result = remove_none_values(result) cluster_config = result.get("ElasticsearchClusterConfig") if isinstance(cluster_config, dict): # set defaults required for boto3 calls cluster_config.setdefault("DedicatedMasterType", "m3.medium.elasticsearch") cluster_config.setdefault("WarmType", "ultrawarm1.medium.elasticsearch") return result
def test_request_validator(self): client = aws_stack.connect_to_service('apigateway') response = client.create_rest_api(name='my_api', description='this is my api') rest_api_id = response['id'] name = 'validator123' result = client.create_request_validator(restApiId=rest_api_id, name=name) self.assertEqual(result['ResponseMetadata']['HTTPStatusCode'], 200) validator_id = result['id'] result = client.get_request_validators(restApiId=rest_api_id) self.assertEqual(result['ResponseMetadata']['HTTPStatusCode'], 200) self.assertEqual(result['items'], [{'id': validator_id, 'name': name}]) result = client.get_request_validator(restApiId=rest_api_id, requestValidatorId=validator_id) self.assertEqual(result['ResponseMetadata']['HTTPStatusCode'], 200) self.assertEqual(select_attributes(result, ['id', 'name']), { 'id': validator_id, 'name': name }) result = client.update_request_validator( restApiId=rest_api_id, requestValidatorId=validator_id, patchOperations=[]) client.delete_request_validator(restApiId=rest_api_id, requestValidatorId=validator_id) with self.assertRaises(Exception): client.get_request_validator(restApiId=rest_api_id, requestValidatorId=validator_id) with self.assertRaises(Exception): client.delete_request_validator(restApiId=rest_api_id, requestValidatorId=validator_id) # clean up client.delete_rest_api(restApiId=rest_api_id)
def list_stacks(req_params): state = CloudFormationRegion.get() stack_status_filters = _get_status_filter_members(req_params) stacks = [ s.describe_details() for s in state.stacks.values() if not stack_status_filters or s.status in stack_status_filters ] attrs = [ "StackId", "StackName", "TemplateDescription", "CreationTime", "LastUpdatedTime", "DeletionTime", "StackStatus", "StackStatusReason", "ParentId", "RootId", "DriftInformation", ] stacks = [select_attributes(stack, attrs) for stack in stacks] result = {"StackSummaries": stacks} return result
def list_global_tables(data): result = [ select_attributes(tab, ['GlobalTableName', 'ReplicationGroup']) for tab in GLOBAL_TABLES.values() ] result = {'GlobalTables': result} return result
def list_global_tables(data): result = [ select_attributes(tab, ["GlobalTableName", "ReplicationGroup"]) for tab in DynamoDBRegion.GLOBAL_TABLES.values() ] result = {"GlobalTables": result} return result
def _create_params(params, **kwargs): attributes = [ "Name", "Description", "KmsKeyId", "SecretString", "Tags" ] result = select_attributes(params, attributes) gen_secret = params.get("GenerateSecretString") if gen_secret: excl_lower = gen_secret.get("ExcludeLowercase") excl_upper = gen_secret.get("ExcludeUppercase") excl_chars = gen_secret.get("ExcludeCharacters") or "" excl_numbers = gen_secret.get("ExcludeNumbers") excl_punct = gen_secret.get("ExcludePunctuation") incl_spaces = gen_secret.get("IncludeSpace") length = gen_secret.get("PasswordLength") or 32 req_each = gen_secret.get("RequireEachIncludedType") secret_value = cls.generate_secret_value( length=length, excl_lower=excl_lower, excl_upper=excl_upper, excl_punct=excl_punct, incl_spaces=incl_spaces, excl_chars=excl_chars, excl_numbers=excl_numbers, req_each=req_each, ) template = gen_secret.get("SecretStringTemplate") if template: gen_key = gen_secret.get("GenerateStringKey") or "secret" template = json.loads(template) template[gen_key] = secret_value secret_value = json.dumps(template) result["SecretString"] = secret_value return result
def param_change_batch(params, **kwargs): attr_names = [ "Name", "Type", "SetIdentifier", "Weight", "Region", "GeoLocation", "Failover", "MultiValueAnswer", "TTL", "ResourceRecords", "AliasTarget", "HealthCheckId", ] attrs = select_attributes(params, attr_names) alias_target = attrs.get("AliasTarget", {}) alias_target["EvaluateTargetHealth"] = alias_target.get( "EvaluateTargetHealth", False) return { "Comment": params.get("Comment", ""), "Changes": [{ "Action": "CREATE", "ResourceRecordSet": attrs }], }
def list_stacks(req_params): state = CloudFormationRegion.get() filter = req_params.get('StackStatusFilter') stacks = [s.describe_details() for s in state.stacks.values() if filter in [None, s.status]] attrs = ['StackId', 'StackName', 'TemplateDescription', 'CreationTime', 'LastUpdatedTime', 'DeletionTime', 'StackStatus', 'StackStatusReason', 'ParentId', 'RootId', 'DriftInformation'] stacks = [select_attributes(stack, attrs) for stack in stacks] result = {'StackSummaries': {'member': stacks}} return result
def describe_details(self): attrs = ['StackId', 'StackName', 'Description', 'Parameters', 'StackStatusReason', 'StackStatus', 'Capabilities', 'Outputs', 'Tags', 'ParentId', 'RootId', 'RoleARN', 'CreationTime', 'DeletionTime', 'LastUpdatedTime', 'ChangeSetId'] result = select_attributes(self.metadata, attrs) for attr in ['Capabilities']: result[attr] = {'member': result.get(attr, [])} result['Outputs'] = {'member': self.outputs} result['Parameters'] = {'member': self.stack_parameters()} return result
def generate_data_key_pair_without_plaintext( self, context: RequestContext, generate_data_key_pair_without_plaintext_request: GenerateDataKeyPairWithoutPlaintextRequest, ) -> GenerateDataKeyPairWithoutPlaintextResponse: result = _generate_data_key_pair( generate_data_key_pair_without_plaintext_request) result = select_attributes( result, ["PrivateKeyCiphertextBlob", "PublicKey", "KeyId", "KeyPairSpec"]) return GenerateDataKeyPairResponse(**result)
def test_get_records(self): client = aws_stack.create_external_boto_client("kinesis") stream_name = "test-%s" % short_uid() client.create_stream(StreamName=stream_name, ShardCount=1) sleep(1.5) client.put_records( StreamName=stream_name, Records=[{ "Data": "SGVsbG8gd29ybGQ=", "PartitionKey": "1" }], ) # get records with JSON encoding iterator = self._get_shard_iterator(stream_name) response = client.get_records(ShardIterator=iterator) json_records = response.get("Records") self.assertEqual(1, len(json_records)) self.assertIn("Data", json_records[0]) # get records with CBOR encoding iterator = self._get_shard_iterator(stream_name) url = config.get_edge_url() headers = aws_stack.mock_aws_request_headers("kinesis") headers["Content-Type"] = constants.APPLICATION_AMZ_CBOR_1_1 headers["X-Amz-Target"] = "Kinesis_20131202.GetRecords" data = cbor2.dumps({"ShardIterator": iterator}) result = requests.post(url, data, headers=headers) self.assertEqual(200, result.status_code) result = cbor2.loads(result.content) attrs = ("Data", "EncryptionType", "PartitionKey", "SequenceNumber") self.assertEqual( select_attributes(json_records[0], attrs), select_attributes(result["Records"][0], attrs), ) # clean up client.delete_stream(StreamName=stream_name)
def param_change_batch(params, **kwargs): attr_names = ['Name', 'Type', 'SetIdentifier', 'Weight', 'Region', 'GeoLocation', 'Failover', 'MultiValueAnswer', 'TTL', 'ResourceRecords', 'AliasTarget', 'HealthCheckId'] attrs = select_attributes(params, attr_names) alias_target = attrs.get('AliasTarget', {}) alias_target['EvaluateTargetHealth'] = alias_target.get('EvaluateTargetHealth', False) return { 'Comment': params.get('Comment', ''), 'Changes': [{ 'Action': 'CREATE', 'ResourceRecordSet': attrs }] }
def generate_data_key_pair( self, context: RequestContext, generate_data_key_pair_request: GenerateDataKeyPairRequest, ) -> GenerateDataKeyPairResponse: result = _generate_data_key_pair(generate_data_key_pair_request) attrs = [ "PrivateKeyCiphertextBlob", "PrivateKeyPlaintext", "PublicKey", "KeyId", "KeyPairSpec", ] result = select_attributes(result, attrs) return GenerateDataKeyPairResponse(**result)
def handle_get_public_key(data, response): key_pairs = _get_key_pairs() result = key_pairs.get(data.get("KeyId", "")) if not result: return 404 attrs = [ "KeyId", "PublicKey", "KeySpec", "KeyUsage", "EncryptionAlgorithms", "SigningAlgorithms", ] result = select_attributes(result, attrs) set_response_content(response, result) response.status_code = 200 return response
def get_public_key( self, context: RequestContext, key_id: KeyIdType, grant_tokens: GrantTokenList = None) -> GetPublicKeyResponse: region_details = KMSBackend.get() result = region_details.key_pairs.get(key_id) if not result: raise NotFoundException() attrs = [ "KeyId", "PublicKey", "KeySpec", "KeyUsage", "EncryptionAlgorithms", "SigningAlgorithms", ] result = select_attributes(result, attrs) return GetPublicKeyResponse(**result)
def _create_params(params, *args, **kwargs): result = select_attributes( params, [ "CertificateAuthorityArn", "DomainName", "DomainValidationOptions", "SubjectAlternativeNames", "Tags", "ValidationMethod", ], ) logging_pref = params.get( "CertificateTransparencyLoggingPreference") if logging_pref: result["Options"] = { "CertificateTransparencyLoggingPreference": logging_pref } return result
def get_params(resource_props, stack_name, resources, resource_id): stage_name = resource_props.get("StageName", "default") resources[resource_id]["Properties"]["StageName"] = stage_name result = keys_to_lower(resource_props) param_names = [ "restApiId", "deploymentId", "description", "cacheClusterEnabled", "cacheClusterSize", "variables", "documentationVersion", "canarySettings", "tracingEnabled", "tags", ] result = select_attributes(result, param_names) result["tags"] = {t["key"]: t["value"] for t in result.get("tags", [])} result["stageName"] = stage_name return result
def get_params(params, **kwargs): result = keys_to_lower(params) param_names = [ "restApiId", "stageName", "deploymentId", "description", "cacheClusterEnabled", "cacheClusterSize", "variables", "documentationVersion", "canarySettings", "tracingEnabled", "tags", ] result = select_attributes(result, param_names) result["tags"] = { t["key"]: t["value"] for t in result.get("tags", []) } return result
def update_resource(self, new_resource, stack_name, resources): props = new_resource["Properties"] client = aws_stack.connect_to_service("lambda") config_keys = [ "Description", "Environment", "FunctionName", "Handler", "ImageConfig", "Layers", "MemorySize", "Role", "Runtime", "Timeout", "TracingConfig", "VpcConfig", ] update_config_props = select_attributes(props, config_keys) update_config_props = self.resolve_refs_recursively( stack_name, update_config_props, resources) if "Timeout" in update_config_props: update_config_props["Timeout"] = int( update_config_props["Timeout"]) if "Code" in props: code = props["Code"] or {} if not code.get("ZipFile"): LOG.debug('Updating code for Lambda "%s" from location: %s' % (props["FunctionName"], code)) code = LambdaFunction.get_lambda_code_param(props, _include_arch=True) client.update_function_code(FunctionName=props["FunctionName"], **code) if "Environment" in update_config_props: environment_variables = update_config_props["Environment"].get( "Variables", {}) update_config_props["Environment"]["Variables"] = { k: str(v) for k, v in environment_variables.items() } return client.update_function_configuration(**update_config_props)
def list_stacks(req_params): state = CloudFormationRegion.get() stack_status_filters = _get_status_filter_members(req_params) stack_list = list(state.stacks.values()) if stack_status_filters: stacks = [ s.describe_details() for s in stack_list if s.status in stack_status_filters ] else: stacks = [s.describe_details() for s in stack_list] attrs = [ 'StackId', 'StackName', 'TemplateDescription', 'CreationTime', 'LastUpdatedTime', 'DeletionTime', 'StackStatus', 'StackStatusReason', 'ParentId', 'RootId', 'DriftInformation' ] stacks = [select_attributes(stack, attrs) for stack in stacks] result = {'StackSummaries': {'member': stacks}} return result
def describe_details(self): attrs = [ "StackId", "StackName", "Description", "StackStatusReason", "StackStatus", "Capabilities", "ParentId", "RootId", "RoleARN", "CreationTime", "DeletionTime", "LastUpdatedTime", "ChangeSetId", ] result = select_attributes(self.metadata, attrs) result["Tags"] = self.tags result["Outputs"] = self.outputs_list() result["Parameters"] = self.stack_parameters() for attr in ["Capabilities", "Outputs", "Parameters", "Tags"]: result.setdefault(attr, []) return result
def _create_params(params, *args, **kwargs): result = select_attributes( params, [ "CertificateAuthorityArn", "DomainName", "DomainValidationOptions", "SubjectAlternativeNames", "Tags", "ValidationMethod", ], ) # adjust domain validation options valid_opts = result.get("DomainValidationOptions") if valid_opts: def _convert(opt): res = select_attributes(opt, ["DomainName", "ValidationDomain"]) res.setdefault("ValidationDomain", res["DomainName"]) return res result["DomainValidationOptions"] = [ _convert(opt) for opt in valid_opts ] # adjust logging preferences logging_pref = result.get( "CertificateTransparencyLoggingPreference") if logging_pref: result["Options"] = { "CertificateTransparencyLoggingPreference": logging_pref } return result
def _convert(opt): res = select_attributes(opt, ["DomainName", "ValidationDomain"]) res.setdefault("ValidationDomain", res["DomainName"]) return res
def select_parameters(*param_names): return lambda params, **kwargs: select_attributes(params, param_names)