Example #1
0
 def delete_integration(
     self, context: RequestContext, rest_api_id: String, resource_id: String, http_method: String
 ) -> None:
     try:
         call_moto(context)
     except Exception as e:
         raise NotFoundException("Invalid Resource identifier specified") from e
Example #2
0
def test_call_with_sqs_creates_state_correctly():
    qname = f"queue-{short_uid()}"

    response = moto.call_moto(
        moto.create_aws_request_context("sqs", "CreateQueue",
                                        {"QueueName": qname}),
        include_response_metadata=True,
    )
    url = response["QueueUrl"]

    try:
        assert response["ResponseMetadata"]["HTTPStatusCode"] == 200
        assert response["QueueUrl"].endswith(f"/{qname}")

        response = moto.call_moto(
            moto.create_aws_request_context("sqs", "ListQueues"))
        assert url in response["QueueUrls"]
    finally:
        moto.call_moto(
            moto.create_aws_request_context("sqs", "DeleteQueue",
                                            {"QueueUrl": url}))

    response = moto.call_moto(
        moto.create_aws_request_context("sqs", "ListQueues"))
    assert url not in response.get("QueueUrls", [])
Example #3
0
def test_call_with_es_creates_state_correctly():
    domain_name = f"domain-{short_uid()}"
    response = moto.call_moto(
        moto.create_aws_request_context(
            "es",
            "CreateElasticsearchDomain",
            {
                "DomainName": domain_name,
                "ElasticsearchVersion": "7.10",
            },
        ),
        include_response_metadata=True,
    )

    try:
        assert response["ResponseMetadata"]["HTTPStatusCode"] == 200
        assert response["DomainStatus"]["DomainName"] == domain_name
        assert response["DomainStatus"]["ElasticsearchVersion"] == "7.10"
    finally:
        response = moto.call_moto(
            moto.create_aws_request_context("es", "DeleteElasticsearchDomain",
                                            {"DomainName": domain_name}),
            include_response_metadata=True,
        )
        assert response["ResponseMetadata"]["HTTPStatusCode"] == 200
Example #4
0
def test_call_include_response_metadata():
    ctx = moto.create_aws_request_context("sqs", "ListQueues")

    response = moto.call_moto(ctx)
    assert "ResponseMetadata" not in response

    response = moto.call_moto(ctx, include_response_metadata=True)
    assert "ResponseMetadata" in response
Example #5
0
 def disable_rule(
     self, context: RequestContext, name: RuleName, event_bus_name: EventBusNameOrArn = None
 ) -> None:
     rule_scheduled_jobs = EventsBackend.get().rule_scheduled_jobs
     job_id = rule_scheduled_jobs.get(name)
     if job_id:
         LOG.debug("Disabling Rule: {} | job_id: {}".format(name, job_id))
         JobScheduler.instance().disable_job(job_id=job_id)
     call_moto(context)
Example #6
0
    def put_metric_alarm(
        self,
        context: RequestContext,
        request: PutMetricAlarmInput,
    ) -> None:
        moto.call_moto(context)

        name = request.get("AlarmName")
        arn = aws_stack.cloudwatch_alarm_arn(name)
        self.tags.tag_resource(arn, request.get("Tags"))
Example #7
0
def test_call_sqs_invalid_call_raises_http_exception():
    with pytest.raises(ServiceException) as e:
        moto.call_moto(
            moto.create_aws_request_context(
                "sqs",
                "DeleteQueue",
                {
                    "QueueUrl": "http://0.0.0.0/nonexistingqueue",
                },
            ))
    e.match("The specified queue does not exist")
Example #8
0
    def delete_rest_api(self, context: RequestContext, rest_api_id: String) -> None:
        try:
            call_moto(context)
        except KeyError as e:
            # moto raises a key error if we're trying to delete an API that doesn't exist
            raise NotFoundException(
                f"Invalid API identifier specified {context.account_id}:{rest_api_id}"
            ) from e

        event_publisher.fire_event(
            event_publisher.EVENT_APIGW_DELETE_API,
            payload={"a": event_publisher.get_hash(rest_api_id)},
        )
Example #9
0
 def delete_rule(
     self,
     context: RequestContext,
     name: RuleName,
     event_bus_name: EventBusNameOrArn = None,
     force: Boolean = None,
 ) -> None:
     rule_scheduled_jobs = EventsBackend.get().rule_scheduled_jobs
     job_id = rule_scheduled_jobs.get(name)
     if job_id:
         LOG.debug("Removing scheduled Events: {} | job_id: {}".format(name, job_id))
         JobScheduler.instance().cancel_job(job_id=job_id)
     call_moto(context)
Example #10
0
def test_call_with_sqs_modifies_state_in_moto_backend():
    """Whitebox test to check that moto backends are populated correctly"""
    from moto.sqs.models import sqs_backends

    qname = f"queue-{short_uid()}"

    response = moto.call_moto(
        moto.create_aws_request_context("sqs", "CreateQueue",
                                        {"QueueName": qname}))
    url = response["QueueUrl"]
    assert qname in sqs_backends.get(config.AWS_REGION_US_EAST_1).queues
    moto.call_moto(
        moto.create_aws_request_context("sqs", "DeleteQueue",
                                        {"QueueUrl": url}))
    assert qname not in sqs_backends.get(config.AWS_REGION_US_EAST_1).queues
Example #11
0
def test_request_with_response_header_location_fields():
    # CreateHostedZoneResponse has a member "Location" that's located in the headers
    zone_name = f"zone-{short_uid()}.com"
    request = moto.create_aws_request_context("route53", "CreateHostedZone", {
        "Name": zone_name,
        "CallerReference": "test"
    })
    response = moto.call_moto(request, include_response_metadata=True)
    # assert response["Location"]  # FIXME: this is required according to the spec, but not returned by moto
    assert response["HostedZone"]["Id"]

    # clean up
    moto.call_moto(
        moto.create_aws_request_context("route53", "DeleteHostedZone",
                                        {"Id": response["HostedZone"]["Id"]}))
Example #12
0
    def create_connection(
        self,
        context: RequestContext,
        name: ConnectionName,
        authorization_type: ConnectionAuthorizationType,
        auth_parameters: CreateConnectionAuthRequestParameters,
        description: ConnectionDescription = None,
    ):
        errors = []

        if not CONNECTION_NAME_PATTERN.match(name):
            error = f"{name} at 'name' failed to satisfy: Member must satisfy regular expression pattern: [\\.\\-_A-Za-z0-9]+"
            errors.append(error)

        if len(name) > 64:
            error = f"{name} at 'name' failed to satisfy: Member must have length less than or equal to 64"
            errors.append(error)

        if authorization_type not in ["BASIC", "API_KEY", "OAUTH_CLIENT_CREDENTIALS"]:
            error = f"{authorization_type} at 'authorizationType' failed to satisfy: Member must satisfy enum value set: [BASIC, OAUTH_CLIENT_CREDENTIALS, API_KEY]"
            errors.append(error)

        if len(errors) > 0:
            error_description = "; ".join(errors)
            error_plural = "errors" if len(errors) > 1 else "error"
            errors_amount = len(errors)
            message = f"{errors_amount} validation {error_plural} detected: {error_description}"
            raise CommonServiceException(message=message, code="ValidationException")

        return call_moto(context)
Example #13
0
    def send_templated_email(
        self,
        context: RequestContext,
        source: Address,
        destination: Destination,
        template: TemplateName,
        template_data: TemplateData,
        reply_to_addresses: AddressList = None,
        return_path: Address = None,
        source_arn: AmazonResourceName = None,
        return_path_arn: AmazonResourceName = None,
        tags: MessageTagList = None,
        configuration_set_name: ConfigurationSetName = None,
        template_arn: AmazonResourceName = None,
    ) -> SendTemplatedEmailResponse:
        response = call_moto(context)

        save_for_retrospection(
            response["MessageId"],
            context.region,
            Source=source,
            Template=template,
            TemplateData=template_data,
            Destination=destination,
        )

        return response
Example #14
0
    def send_email(
        self,
        context: RequestContext,
        source: Address,
        destination: Destination,
        message: Message,
        reply_to_addresses: AddressList = None,
        return_path: Address = None,
        source_arn: AmazonResourceName = None,
        return_path_arn: AmazonResourceName = None,
        tags: MessageTagList = None,
        configuration_set_name: ConfigurationSetName = None,
    ) -> SendEmailResponse:
        response = call_moto(context)

        save_for_retrospection(
            response["MessageId"],
            context.region,
            Source=source,
            Destination=destination,
            Subject=message["Subject"].get("Data"),
            Body=message["Body"].get("Text", {}).get("Data"),
        )

        return response
Example #15
0
 def put_log_events(
     self,
     context: RequestContext,
     log_group_name: LogGroupName,
     log_stream_name: LogStreamName,
     log_events: InputLogEvents,
     sequence_token: SequenceToken = None,
 ) -> PutLogEventsResponse:
     logs_backend = logs_backends[aws_stack.get_region()]
     metric_filters = logs_backend.filters.metric_filters
     for metric_filter in metric_filters:
         pattern = metric_filter.get("filterPattern", "")
         transformations = metric_filter.get("metricTransformations", [])
         matches = get_pattern_matcher(pattern)
         for log_event in log_events:
             if matches(pattern, log_event):
                 for tf in transformations:
                     value = tf.get("metricValue") or "1"
                     if "$size" in value:
                         LOG.info(
                             "Expression not yet supported for log filter metricValue", value
                         )
                     value = float(value) if is_number(value) else 1
                     data = [{"MetricName": tf["metricName"], "Value": value}]
                     try:
                         self.cw_client.put_metric_data(
                             Namespace=tf["metricNamespace"], MetricData=data
                         )
                     except Exception as e:
                         LOG.info(
                             "Unable to put metric data for matching CloudWatch log events", e
                         )
     return call_moto(context)
Example #16
0
    def describe_availability_zones(
        self,
        context: RequestContext,
        describe_availability_zones_request: DescribeAvailabilityZonesRequest,
    ) -> DescribeAvailabilityZonesResult:
        backend = ec2_backends.get(context.region)

        availability_zones = []
        zone_names = describe_availability_zones_request.get("ZoneNames")
        if zone_names:
            for zone in zone_names:
                zone_detail = backend.get_zone_by_name(zone)
                if zone_detail:
                    availability_zones.append(
                        AvailabilityZone(
                            State="available",
                            Messages=[],
                            RegionName=zone_detail.region_name,
                            ZoneName=zone_detail.name,
                            ZoneId=zone_detail.zone_id,
                        ))

            return DescribeAvailabilityZonesResult(
                AvailabilityZones=availability_zones)

        return call_moto(context)
Example #17
0
 def create_rest_api(self, context: RequestContext, request: CreateRestApiRequest) -> RestApi:
     result = call_moto(context)
     event_publisher.fire_event(
         event_publisher.EVENT_APIGW_CREATE_API,
         payload={"a": event_publisher.get_hash(result["id"])},
     )
     return result
Example #18
0
    def get_api_keys(
        self,
        context: RequestContext,
        position: String = None,
        limit: NullableInteger = None,
        name_query: String = None,
        customer_id: String = None,
        include_values: NullableBoolean = None,
    ) -> ApiKeys:
        moto_response: ApiKeys = call_moto(context=context)
        item_list = PaginatedList(moto_response["items"])

        def token_generator(item):
            return item["id"]

        def filter_function(item):
            return item["name"].startswith(name_query)

        paginated_list, next_token = item_list.get_page(
            token_generator=token_generator,
            next_token=position,
            page_size=limit,
            filter_function=filter_function if name_query else None,
        )

        return ApiKeys(
            items=paginated_list, warnings=moto_response.get("warnings"), position=next_token
        )
Example #19
0
    def list_aliases(
        self,
        context: RequestContext,
        key_id: KeyIdType = None,
        limit: LimitType = None,
        marker: MarkerType = None,
    ) -> ListAliasesResponse:
        if key_id is None:
            return call_moto(context)

        response_aliases = PaginatedList()

        if kms_backends.get(context.region).keys.get(key_id) is None:
            raise NotFoundException(f"Unable to find key '{key_id}'")

        aliases_of_key = kms_backends.get(
            context.region).get_all_aliases().get(key_id) or []

        for alias_name in aliases_of_key:
            response_aliases.append(
                AliasListEntry(
                    AliasArn=kms_alias_arn(alias_name,
                                           region_name=context.region),
                    AliasName=alias_name,
                    TargetKeyId=key_id,
                ))

        page, nxt = response_aliases.get_page(lambda a: a["AliasName"],
                                              next_token=marker,
                                              page_size=limit)

        return ListAliasesResponse(Aliases=page,
                                   NextMarker=nxt,
                                   Truncated=nxt is not None)
Example #20
0
 def list_templates(self,
                    context: RequestContext,
                    next_token: NextToken = None,
                    max_items: MaxItems = None) -> ListTemplatesResponse:
     for template in ses_backend.list_templates():
         if isinstance(template["Timestamp"], (date, datetime)):
             template["Timestamp"] = timestamp_millis(template["Timestamp"])
     return call_moto(context)
Example #21
0
 def get_caller_identity(
         self, context: RequestContext) -> GetCallerIdentityResponse:
     result = call_moto(context)
     username = config.TEST_IAM_USER_NAME or "localstack"
     result["Arn"] = result["Arn"].replace("user/moto", f"user/{username}")
     if config.TEST_IAM_USER_ID:
         result["UserId"] = config.TEST_IAM_USER_ID
     return result
Example #22
0
def test_call_with_modified_request():
    from moto.sqs.models import sqs_backends

    qname1 = f"queue-{short_uid()}"
    qname2 = f"queue-{short_uid()}"

    context = moto.create_aws_request_context("sqs", "CreateQueue",
                                              {"QueueName": qname1})
    response = moto.call_moto_with_request(
        context, {"QueueName": qname2})  # overwrite old request

    url = response["QueueUrl"]
    assert qname2 in sqs_backends.get(config.AWS_REGION_US_EAST_1).queues
    assert qname1 not in sqs_backends.get(config.AWS_REGION_US_EAST_1).queues

    moto.call_moto(
        moto.create_aws_request_context("sqs", "DeleteQueue",
                                        {"QueueUrl": url}))
Example #23
0
 def label_parameter_version(
     self,
     context: RequestContext,
     name: PSParameterName,
     labels: ParameterLabelList,
     parameter_version: PSParameterVersion = None,
 ) -> LabelParameterVersionResult:
     SsmProvider._notify_event_subscribers(name, "LabelParameterVersion")
     return LabelParameterVersionResult(**call_moto(context))
Example #24
0
    def put_metric_alarm(
        self,
        context: RequestContext,
        request: PutMetricAlarmInput,
    ) -> None:

        # missing will be the default, when not set (but it will not explicitly be set)
        if not request.get("TreatMissingData", "missing") in [
                "breaching",
                "notBreaching",
                "ignore",
                "missing",
        ]:
            raise ValidationError(
                f"The value {request['TreatMissingData']} is not supported for TreatMissingData parameter. Supported values are [breaching, notBreaching, ignore, missing]."
            )
        # do some sanity checks:
        if request.get("Period"):
            # Valid values are 10, 30, and any multiple of 60.
            value = request.get("Period")
            if value not in (10, 30):
                if value % 60 != 0:
                    raise ValidationError(
                        "Period must be 10, 30 or a multiple of 60")
        if request.get("Statistic"):
            if not request.get("Statistic") in [
                    "SampleCount",
                    "Average",
                    "Sum",
                    "Minimum",
                    "Maximum",
            ]:
                raise ValidationError(
                    f"Value '{request.get('Statistic')}' at 'statistic' failed to satisfy constraint: Member must satisfy enum value set: [Maximum, SampleCount, Sum, Minimum, Average]"
                )

        moto.call_moto(context)

        name = request.get("AlarmName")
        arn = aws_stack.cloudwatch_alarm_arn(name)
        self.tags.tag_resource(arn, request.get("Tags"))
        self.alarm_scheduler.schedule_metric_alarm(arn)
Example #25
0
 def put_parameter(self, context: RequestContext,
                   request: PutParameterRequest) -> PutParameterResult:
     name = request["Name"]
     nname = SsmProvider._normalize_name(name)
     if name != nname:
         request.update({"Name": nname})
         moto_res = call_moto_with_request(context, request)
     else:
         moto_res = call_moto(context)
     SsmProvider._notify_event_subscribers(nname, "Create")
     return PutParameterResult(**moto_res)
Example #26
0
def test_call_multi_region_backends():
    from moto.sqs.models import sqs_backends

    qname_us = f"queue-us-{short_uid()}"
    qname_eu = f"queue-eu-{short_uid()}"

    moto.call_moto(
        moto.create_aws_request_context("sqs",
                                        "CreateQueue", {"QueueName": qname_us},
                                        region="us-east-1"))
    moto.call_moto(
        moto.create_aws_request_context("sqs",
                                        "CreateQueue", {"QueueName": qname_eu},
                                        region="eu-central-1"))

    assert qname_us in sqs_backends.get("us-east-1").queues
    assert qname_eu not in sqs_backends.get("us-east-1").queues

    assert qname_us not in sqs_backends.get("eu-central-1").queues
    assert qname_eu in sqs_backends.get("eu-central-1").queues

    del sqs_backends.get("us-east-1").queues[qname_us]
    del sqs_backends.get("eu-central-1").queues[qname_eu]
Example #27
0
 def put_rule(
     self,
     context: RequestContext,
     name: RuleName,
     schedule_expression: ScheduleExpression = None,
     event_pattern: EventPattern = None,
     state: RuleState = None,
     description: RuleDescription = None,
     role_arn: RoleArn = None,
     tags: TagList = None,
     event_bus_name: EventBusNameOrArn = None,
 ) -> PutRuleResponse:
     self.put_rule_job_scheduler(name, state, schedule_expression)
     return call_moto(context)
Example #28
0
    def request_certificate(
        self,
        context: RequestContext,
        request: RequestCertificateRequest,
    ) -> RequestCertificateResponse:
        response: RequestCertificateResponse = moto.call_moto(context)

        cert_arn = response["CertificateArn"]
        backend = acm_backends.get(context.region)
        cert = backend._certificates[cert_arn]
        if not hasattr(cert, "domain_validation_options"):
            cert.domain_validation_options = request.get(
                "DomainValidationOptions")

        return response
Example #29
0
 def revoke_security_group_egress(
     self,
     context: RequestContext,
     revoke_security_group_egress_request: RevokeSecurityGroupEgressRequest,
 ) -> RevokeSecurityGroupEgressResult:
     try:
         return call_moto(context)
     except Exception as e:
         if "specified rule does not exist" in str(e):
             backend = ec2_backends[context.region]
             group_id = revoke_security_group_egress_request["GroupId"]
             group = backend.get_security_group_by_name_or_id(group_id)
             if group and not group.egress_rules:
                 return RevokeSecurityGroupEgressResult(Return=True)
         raise
Example #30
0
def _call_moto(context: RequestContext, operation_name: str, parameters: ServiceRequest):
    """
    Not necessarily the pattern we want to follow in the future, but this makes possible to nest
    moto call and still be interface compatible.

    Ripped :call_moto_with_request: from moto.py but applicable to any operation (operation_name).
    """
    local_context = create_aws_request_context(
        service_name=context.service.service_name,
        action=operation_name,
        parameters=parameters,
        region=context.region,
    )

    local_context.request.headers.extend(context.request.headers)
    return call_moto(local_context)