def test_backend_dict_can_specify_additional_regions(): backend_dict = BackendDict(ExampleBackend, "ec2", additional_regions=["region1", "global"]) backend_dict.get("us-east-1").should.be.a(ExampleBackend) backend_dict.get("region1").should.be.a(ExampleBackend) backend_dict.get("global").should.be.a(ExampleBackend) # Unknown regions still do not exist backend_dict.get("us-east-3").should.equal(None)
def test_backend_dict_can_retrieve_for_specific_account(): backend_dict = BackendDict(ExampleBackend, "ec2") # Retrieve AccountSpecificBackend after checking it exists backend_dict.should.have.key("000000") backend = backend_dict.get("000000") backend.should.be.a(AccountSpecificBackend) # Retrieve AccountSpecificBackend by assuming it exists backend = backend_dict["012345"] backend.should.be.a(AccountSpecificBackend) backend.should.have.key("eu-north-1") regional_backend = backend["eu-north-1"] regional_backend.should.be.a(ExampleBackend) regional_backend.region_name.should.equal("eu-north-1") # We always return a fixed account_id for now, until we have proper multi-account support regional_backend.account_id.should.equal("123456789012")
endpoint_id, manifest_name, mss_package, origination, startover_window_seconds, time_delay_seconds, whitelist, ): try: origin_endpoint = self._origin_endpoints[endpoint_id] origin_endpoint.authorization = authorization origin_endpoint.cmaf_package = cmaf_package origin_endpoint.dash_package = dash_package origin_endpoint.description = description origin_endpoint.hls_package = hls_package origin_endpoint.manifest_name = manifest_name origin_endpoint.mss_package = mss_package origin_endpoint.origination = origination origin_endpoint.startover_window_seconds = startover_window_seconds origin_endpoint.time_delay_seconds = time_delay_seconds origin_endpoint.whitelist = whitelist return origin_endpoint except KeyError: error = "NotFoundException" raise ClientError( error, "origin endpoint with id={} not found".format(endpoint_id)) mediapackage_backends = BackendDict(MediaPackageBackend, "mediapackage")
query_id] if query_id in self.named_queries else None def list_data_catalogs(self): return [{ "CatalogName": dc.name, "Type": dc.type } for dc in self.data_catalogs.values()] def get_data_catalog(self, name): if name not in self.data_catalogs: return None dc = self.data_catalogs[name] return { "Name": dc.name, "Description": dc.description, "Type": dc.type, "Parameters": dc.parameters, } def create_data_catalog(self, name, catalog_type, description, parameters, tags): if name in self.data_catalogs: return None data_catalog = DataCatalog(self, name, catalog_type, description, parameters, tags) self.data_catalogs[name] = data_catalog return data_catalog athena_backends = BackendDict(AthenaBackend, "athena")
self.tagger.untag_resource_using_names(resource_arn, tag_keys) def update_broker( self, authentication_strategy, auto_minor_version_upgrade, broker_id, configuration, engine_version, host_instance_type, ldap_server_metadata, logs, maintenance_window_start_time, security_groups, ): broker = self.describe_broker(broker_id) broker.update( authentication_strategy=authentication_strategy, auto_minor_version_upgrade=auto_minor_version_upgrade, configuration=configuration, engine_version=engine_version, host_instance_type=host_instance_type, ldap_server_metadata=ldap_server_metadata, logs=logs, maintenance_window_start_time=maintenance_window_start_time, security_groups=security_groups, ) mq_backends = BackendDict(MQBackend, "mq")
service_region, zones, "codecommit") def create_repository(self, repository_name, repository_description): repository = self.repositories.get(repository_name) if repository: raise RepositoryNameExistsException(repository_name) self.repositories[repository_name] = CodeCommit( self.region, repository_description, repository_name) return self.repositories[repository_name].repository_metadata def get_repository(self, repository_name): repository = self.repositories.get(repository_name) if not repository: raise RepositoryDoesNotExistException(repository_name) return repository.repository_metadata def delete_repository(self, repository_name): repository = self.repositories.get(repository_name) if repository: self.repositories.pop(repository_name) return repository.repository_metadata.get("repositoryId") return None codecommit_backends = BackendDict(CodeCommitBackend, "codecommit")
def put_container_policy(self, container_name, policy): if container_name not in self._containers: raise ResourceNotFoundException() self._containers[container_name].policy = policy return {} def get_container_policy(self, container_name): if container_name not in self._containers: raise ResourceNotFoundException() policy = self._containers[container_name].policy if not policy: raise PolicyNotFoundException() return policy def put_metric_policy(self, container_name, metric_policy): if container_name not in self._containers: raise ResourceNotFoundException() self._containers[container_name].metric_policy = metric_policy return {} def get_metric_policy(self, container_name): if container_name not in self._containers: raise ResourceNotFoundException() metric_policy = self._containers[container_name].metric_policy if not metric_policy: raise PolicyNotFoundException() return metric_policy mediastore_backends = BackendDict(MediaStoreBackend, "mediastore")
stages = secret.versions[move_to_version_id]["version_stages"] if "AWSPREVIOUS" in stages: stages.remove("AWSPREVIOUS") return secret_id @staticmethod def get_resource_policy(secret_id): resource_policy = { "Version": "2012-10-17", "Statement": { "Effect": "Allow", "Principal": { "AWS": [ "arn:aws:iam::111122223333:root", "arn:aws:iam::444455556666:root", ] }, "Action": ["secretsmanager:GetSecretValue"], "Resource": "*", }, } return json.dumps({ "ARN": secret_id, "Name": secret_id, "ResourcePolicy": json.dumps(resource_policy), }) secretsmanager_backends = BackendDict(SecretsManagerBackend, "secretsmanager")
}, }, } def put_replication_configuration(self, replication_config): rules = replication_config["rules"] if len(rules) > 1: raise ValidationException("This feature is disabled") if len(rules) == 1: for dest in rules[0]["destinations"]: if (dest["region"] == self.region_name and dest["registryId"] == DEFAULT_REGISTRY_ID): raise InvalidParameterException( "Invalid parameter at 'replicationConfiguration' failed to satisfy constraint: " "'Replication destination cannot be the same as the source registry'" ) self.replication_config = replication_config return {"replicationConfiguration": replication_config} def describe_registry(self): return { "registryId": DEFAULT_REGISTRY_ID, "replicationConfiguration": self.replication_config, } ecr_backends = BackendDict(ECRBackend, "ecr")
self._objects[path] = new_object return new_object def delete_object(self, path): if path not in self._objects: error = "ObjectNotFoundException" raise ClientError(error, "Object with id={} not found".format(path)) del self._objects[path] return {} def get_object(self, path, object_range=None): """ The Range-parameter is not yet supported. """ objects_found = [item for item in self._objects.values() if item.path == path] if len(objects_found) == 0: error = "ObjectNotFoundException" raise ClientError(error, "Object with id={} not found".format(path)) return objects_found[0] def list_items(self, path, max_results=1000, next_token=None): """ The Path- and MaxResults-parameters are not yet supported. """ items = self._objects.values() response_items = [c.to_dict() for c in items] return response_items mediastoredata_backends = BackendDict(MediaStoreDataBackend, "mediastore-data")
dict(Record(long_value=50)), dict(Record(string_value="Beta st")), dict(Record(string_value="Toronto")), ], [ dict(Record(long_value=100)), dict(Record(string_value="Gamma av")), dict(Record(string_value="Seattle")), ], ], 3, ) def _validate_uuid(uuid): match = re.search(r"^[a-z0-9]{8}(-[a-z0-9]{4}){3}-[a-z0-9]{12}(:\d+)?$", uuid) if not match: raise ValidationException( "id must satisfy regex pattern: ^[a-z0-9]{8}(-[a-z0-9]{4}){3}-[a-z0-9]{12}(:\\d+)?$" ) # For unknown reasons I cannot use the service name "redshift-data" as I should # It seems boto3 is unable to get the list of available regions for "redshift-data" # See code here https://github.com/spulec/moto/blob/master/moto/core/utils.py#L407 # sess.get_available_regions("redshift-data") returns an empty list # Then I use the service redshift since they share the same regions # See https://docs.aws.amazon.com/general/latest/gr/redshift-service.html redshiftdata_backends = BackendDict(RedshiftDataAPIServiceBackend, "redshift")
): # process timeouts on all objects self._process_timeouts() domain = self._get_domain(domain_name) wfe = domain.get_workflow_execution( workflow_id, run_id=run_id, raise_if_closed=True ) wfe.terminate(child_policy=child_policy, details=details, reason=reason) def record_activity_task_heartbeat(self, task_token, details=None): # process timeouts on all objects self._process_timeouts() activity_task = self._find_activity_task_from_token(task_token) activity_task.reset_heartbeat_clock() if details: activity_task.details = details def signal_workflow_execution( self, domain_name, signal_name, workflow_id, workflow_input=None, run_id=None ): # process timeouts on all objects self._process_timeouts() domain = self._get_domain(domain_name) wfe = domain.get_workflow_execution( workflow_id, run_id=run_id, raise_if_closed=True ) wfe.signal(signal_name, workflow_input) swf_backends = BackendDict(SWFBackend, "swf")
key_id = self.get_key_id(key_id_or_arn) if key_id in self.keys: return self.tagger.list_tags_for_resource(key_id) raise JsonRESTError( "NotFoundException", "The request was rejected because the specified entity or resource could not be found.", ) def tag_resource(self, key_id_or_arn, tags): key_id = self.get_key_id(key_id_or_arn) if key_id in self.keys: self.tagger.tag_resource(key_id, tags) return {} raise JsonRESTError( "NotFoundException", "The request was rejected because the specified entity or resource could not be found.", ) def untag_resource(self, key_id_or_arn, tag_names): key_id = self.get_key_id(key_id_or_arn) if key_id in self.keys: self.tagger.untag_resource_using_names(key_id, tag_names) return {} raise JsonRESTError( "NotFoundException", "The request was rejected because the specified entity or resource could not be found.", ) kms_backends = BackendDict(KmsBackend, "kms")
if created_after: jobs = [job for job in jobs if job["createdAt"] >= created_after] if created_before: jobs = [job for job in jobs if job["createdAt"] <= created_before] if states: jobs = [job for job in jobs if job["state"] in states] if name: jobs = [job for job in jobs if job["name"] in name] sort_key = "id" return paginated_list(jobs, sort_key, max_results, next_token) def describe_job_run(self, job_id, virtual_cluster_id): if not re.match(r"[a-z,A-Z,0-9]{19}", job_id): raise ValidationException("Invalid job run short id") if job_id not in self.jobs.keys(): raise ResourceNotFoundException(f"Job run {job_id} doesn't exist.") if virtual_cluster_id != self.jobs[job_id].virtual_cluster_id: raise ResourceNotFoundException(f"Job run {job_id} doesn't exist.") return self.jobs[job_id].to_dict() emrcontainers_backends = BackendDict(EMRContainersBackend, "emr-containers")
def get_trace_summary(self, start_time, end_time, filter_expression, summaries): return self._segment_collection.summary(start_time, end_time, filter_expression, summaries) def get_trace_ids(self, trace_ids, next_token): traces, unprocessed_ids = self._segment_collection.get_trace_ids( trace_ids) result = {"Traces": [], "UnprocessedTraceIds": unprocessed_ids} for trace in traces: segments = [] for segment in trace["segments"]: segments.append({"Id": segment.id, "Document": segment.raw}) result["Traces"].append({ "Duration": int((trace["end_date"] - trace["start_date"]).total_seconds()), "Id": trace["trace_id"], "Segments": segments, }) return result xray_backends = BackendDict(XRayBackend, "xray")
message_attributes=entry.get("MessageAttributes", []), group_id=entry.get("MessageGroupId"), ) successful.append({"MessageId": message_id, "Id": entry["Id"]}) except Exception as e: if isinstance(e, InvalidParameterValue): failed.append({ "Id": entry["Id"], "Code": "InvalidParameter", "Message": f"Invalid parameter: {e.message}", "SenderFault": True, }) return successful, failed sns_backends = BackendDict(SNSBackend, "sns") DEFAULT_EFFECTIVE_DELIVERY_POLICY = { "defaultHealthyRetryPolicy": { "numNoDelayRetries": 0, "numMinDelayRetries": 0, "minDelayTarget": 20, "maxDelayTarget": 20, "numMaxDelayRetries": 0, "numRetries": 3, "backoffFunction": "linear", }, "sicklyRetryPolicy": None, "throttlePolicy": None, "guaranteed": False, }
"Width": 0.0703125, "Height": 0.0263671875, "Left": 0.4976806640625, "Top": 0.880859375, }, "Polygon": [ { "X": 0.4976806640625, "Y": 0.880859375 }, { "X": 0.5679931640625, "Y": 0.880859375 }, { "X": 0.5679931640625, "Y": 0.9072265625 }, { "X": 0.4976806640625, "Y": 0.9072265625 }, ], }, }, }, ] rekognition_backends = BackendDict(RekognitionBackend, "rekognition")
for attribute in saml_assertion_attributes: if (attribute["@Name"] == "https://aws.amazon.com/SAML/Attributes/RoleSessionName"): kwargs["role_session_name"] = attribute["saml|AttributeValue"][ "#text"] if (attribute["@Name"] == "https://aws.amazon.com/SAML/Attributes/SessionDuration"): kwargs["duration"] = int( attribute["saml|AttributeValue"]["#text"]) if "duration" not in kwargs: kwargs["duration"] = DEFAULT_STS_SESSION_DURATION kwargs["external_id"] = None kwargs["policy"] = None role = AssumedRole(**kwargs) self.assumed_roles.append(role) return role def get_caller_identity(self): # Logic resides in responses.py # Fake method here to make implementation coverage script aware that this method is implemented pass sts_backends: Mapping[str, STSBackend] = BackendDict(STSBackend, "sts", use_boto3_regions=False, additional_regions=["global"])
def get_application_settings(self, application_id): app = self.get_app(application_id) return app.get_settings() def list_tags_for_resource(self, resource_arn): tags = self.tagger.get_tag_dict_for_resource(resource_arn) return {"tags": tags} def tag_resource(self, resource_arn, tags): tags = TaggingService.convert_dict_to_tags_input(tags) self.tagger.tag_resource(resource_arn, tags) def untag_resource(self, resource_arn, tag_keys): self.tagger.untag_resource_using_names(resource_arn, tag_keys) return def put_event_stream(self, application_id, stream_arn, role_arn): app = self.get_app(application_id) return app.put_event_stream(stream_arn, role_arn) def get_event_stream(self, application_id): app = self.get_app(application_id) return app.get_event_stream() def delete_event_stream(self, application_id): app = self.get_app(application_id) return app.delete_event_stream() pinpoint_backends = BackendDict(PinpointBackend, "pinpoint")
raise InvalidParameterException( message=LAUNCH_TEMPLATE_WITH_DISK_SIZE_MSG if disk_size else LAUNCH_TEMPLATE_WITH_REMOTE_ACCESS_MSG) def _validate_fargate_profile_selectors(selectors): def raise_exception(message): raise InvalidParameterException( clusterName=None, nodegroupName=None, fargateProfileName=None, addonName=None, message=message, ) # At least one Selector must exist if not selectors: raise_exception(message=FARGATE_PROFILE_NEEDS_SELECTOR_MSG) for selector in selectors: # Every existing Selector must have a namespace if "namespace" not in selector: raise_exception(message=FARGATE_PROFILE_SELECTOR_NEEDS_NAMESPACE) # If a selector has labels, it can not have more than 5 if len(selector.get("labels", {})) > 5: raise_exception(message=FARGATE_PROFILE_TOO_MANY_LABELS) eks_backends = BackendDict(EKSBackend, "eks")
def delete_vault(self, vault_name): self.vaults.pop(vault_name) def initiate_job(self, vault_name, job_type, tier, archive_id): vault = self.get_vault(vault_name) job_id = vault.initiate_job(job_type, tier, archive_id) return job_id def describe_job(self, vault_name, archive_id): vault = self.get_vault(vault_name) return vault.describe_job(archive_id) def list_jobs(self, vault_name): vault = self.get_vault(vault_name) return vault.list_jobs() def get_job_output(self, vault_name, job_id): vault = self.get_vault(vault_name) if vault.job_ready(job_id): return vault.get_job_output(job_id) else: return None def upload_archive(self, vault_name, body, description): vault = self.get_vault(vault_name) return vault.create_archive(body, description) glacier_backends = BackendDict(GlacierBackend, "glacier")
api_name = "GET_HLS_STREAMING_SESSION_URL" url = self._get_streaming_url(stream_name, stream_arn, api_name) return url def get_dash_streaming_session_url( self, stream_name, stream_arn, playback_mode, display_fragment_timestamp, display_fragment_number, dash_fragment_selector, expires, max_manifest_fragment_results, ): # Ignore option paramters as the format of hls_url does't depends on them api_name = "GET_DASH_STREAMING_SESSION_URL" url = self._get_streaming_url(stream_name, stream_arn, api_name) return url def get_clip(self, stream_name, stream_arn, clip_fragment_selector): kinesisvideo_backends[self.region_name]._get_stream( stream_name, stream_arn) content_type = "video/mp4" # Fixed content_type as it depends on input stream payload = b"sample-mp4-video" return content_type, payload kinesisvideoarchivedmedia_backends = BackendDict( KinesisVideoArchivedMediaBackend, "kinesis-video-archived-media")
def remove_flow_vpc_interface(self, flow_arn, vpc_interface_name): if flow_arn in self._flows: flow = self._flows[flow_arn] flow.vpc_interfaces = [ vpc_interface for vpc_interface in self._flows[flow_arn].vpc_interfaces if vpc_interface["name"] != vpc_interface_name ] else: raise NotFoundException( message="flow with arn={} not found".format(flow_arn)) return flow_arn, vpc_interface_name def remove_flow_output(self, flow_arn, output_name): if flow_arn in self._flows: flow = self._flows[flow_arn] flow.outputs = [ output for output in self._flows[flow_arn].outputs if output["name"] != output_name ] else: raise NotFoundException( message="flow with arn={} not found".format(flow_arn)) return flow_arn, output_name # add methods from here mediaconnect_backends = BackendDict(MediaConnectBackend, "mediaconnect")
self._set_idempotency_token_arn(idempotency_token, cert.arn) self._certificates[cert.arn] = cert if tags: cert.tags.add(tags) return cert.arn def add_tags_to_certificate(self, arn, tags): # get_cert does arn check cert_bundle = self.get_certificate(arn) cert_bundle.tags.add(tags) def remove_tags_from_certificate(self, arn, tags): # get_cert does arn check cert_bundle = self.get_certificate(arn) cert_bundle.tags.remove(tags) def export_certificate(self, certificate_arn, passphrase): passphrase_bytes = base64.standard_b64decode(passphrase) cert_bundle = self.get_certificate(certificate_arn) certificate = cert_bundle.cert.decode() certificate_chain = cert_bundle.chain.decode() private_key = cert_bundle.serialize_pk(passphrase_bytes) return certificate, certificate_chain, private_key acm_backends = BackendDict(AWSCertificateManagerBackend, "ec2")
tags_to_remove): try: res = self._find_environment_by_arn(resource_arn) except KeyError: raise ResourceNotFoundException( "Resource not found for ARN '{}'.".format(resource_arn)) for key, value in tags_to_add.items(): res.tags[key] = value for key in tags_to_remove: del res.tags[key] def list_tags_for_resource(self, resource_arn): try: res = self._find_environment_by_arn(resource_arn) except KeyError: raise ResourceNotFoundException( "Resource not found for ARN '{}'.".format(resource_arn)) return res.tags def _find_environment_by_arn(self, arn): for app in self.applications.keys(): for env in self.applications[app].environments.values(): if env.environment_arn == arn: return env raise KeyError() eb_backends = BackendDict(EBBackend, "elasticbeanstalk")
context=self, ) self.tagging_service.tag_resource(access_point.access_point_id, tags) self.access_points[access_point.access_point_id] = access_point return access_point def describe_access_points(self, access_point_id): """ Pagination is not yet implemented """ if access_point_id: if access_point_id not in self.access_points: raise AccessPointNotFound(access_point_id) return [self.access_points[access_point_id]] return self.access_points.values() def delete_access_point(self, access_point_id): self.access_points.pop(access_point_id, None) def list_tags_for_resource(self, resource_id): return self.tagging_service.list_tags_for_resource(resource_id)["Tags"] def tag_resource(self, resource_id, tags): self.tagging_service.tag_resource(resource_id, tags) def untag_resource(self, resource_id, tag_keys): self.tagging_service.untag_resource_using_names(resource_id, tag_keys) efs_backends = BackendDict(EFSBackend, "efs")
tagged_resources += self._describe_tags_for_resource_type( resource_type) except ResourceNotFoundFaultError: pass return tagged_resources def delete_tags(self, resource_name, tag_keys): resource = self._get_resource_from_arn(resource_name) resource.delete_tags(tag_keys) def get_cluster_credentials(self, cluster_identifier, db_user, auto_create, duration_seconds): if duration_seconds < 900 or duration_seconds > 3600: raise InvalidParameterValueError( "Token duration must be between 900 and 3600 seconds") expiration = datetime.datetime.now() + datetime.timedelta( 0, duration_seconds) if cluster_identifier in self.clusters: user_prefix = "IAM:" if auto_create is False else "IAMA:" db_user = user_prefix + db_user return { "DbUser": db_user, "DbPassword": random_string(32), "Expiration": expiration, } else: raise ClusterNotFoundError(cluster_identifier) redshift_backends = BackendDict(RedshiftBackend, "redshift")
"ResourceShare {} could not be found.".format(arn)) resource.update(**kwargs) response = resource.describe() response.pop("featureSet") return dict(resourceShare=response) def delete_resource_share(self, arn): resource = next( (resource for resource in self.resource_shares if arn == resource.arn), None) if not resource: raise UnknownResourceException( "ResourceShare {} could not be found.".format(arn)) resource.delete() return dict(returnValue=True) def enable_sharing_with_aws_organization(self): if not self.organizations_backend.org: raise OperationNotPermittedException return dict(returnValue=True) ram_backends = BackendDict(ResourceAccessManagerBackend, "ram")
if "version" in payload and thing.thing_shadow.version != payload[ "version"]: raise ConflictException("Version conflict") new_shadow = FakeShadow.create_from_previous_version( thing.thing_shadow, payload) thing.thing_shadow = new_shadow return thing.thing_shadow def get_thing_shadow(self, thing_name): thing = iot_backends[self.region_name].describe_thing(thing_name) if thing.thing_shadow is None or thing.thing_shadow.deleted: raise ResourceNotFoundException() return thing.thing_shadow def delete_thing_shadow(self, thing_name): thing = iot_backends[self.region_name].describe_thing(thing_name) if thing.thing_shadow is None: raise ResourceNotFoundException() payload = None new_shadow = FakeShadow.create_from_previous_version( thing.thing_shadow, payload) thing.thing_shadow = new_shadow return thing.thing_shadow def publish(self, topic, payload): self.published_payloads.append((topic, payload)) iotdata_backends = BackendDict(IoTDataPlaneBackend, "iot")
return pipelines def get_pipeline(self, pipeline_id): return self.pipelines[pipeline_id] def delete_pipeline(self, pipeline_id): self.pipelines.pop(pipeline_id, None) def put_pipeline_definition(self, pipeline_id, pipeline_objects): pipeline = self.get_pipeline(pipeline_id) pipeline.set_pipeline_objects(pipeline_objects) def get_pipeline_definition(self, pipeline_id): pipeline = self.get_pipeline(pipeline_id) return pipeline.objects def describe_objects(self, object_ids, pipeline_id): pipeline = self.get_pipeline(pipeline_id) pipeline_objects = [ pipeline_object for pipeline_object in pipeline.objects if pipeline_object.object_id in object_ids ] return pipeline_objects def activate_pipeline(self, pipeline_id): pipeline = self.get_pipeline(pipeline_id) pipeline.activate() datapipeline_backends = BackendDict(DataPipelineBackend, "datapipeline")