Beispiel #1
0
 def get_training_job_by_arn(self, arn):
     training_jobs = [
         training_job
         for training_job in self.training_jobs.values()
         if training_job.training_job_arn == arn
     ]
     if len(training_jobs) == 0:
         message = "RecordNotFound"
         raise RESTError(
             error_type="ValidationException",
             message=message,
             template="error_json",
         )
     return training_jobs[0]
Beispiel #2
0
 def get_endpoint_by_arn(self, arn):
     endpoints = [
         endpoint
         for endpoint in self.endpoints.values()
         if endpoint.endpoint_arn == arn
     ]
     if len(endpoints) == 0:
         message = "RecordNotFound"
         raise RESTError(
             error_type="ValidationException",
             message=message,
             template="error_json",
         )
     return endpoints[0]
Beispiel #3
0
    def create_target_group(self, name, **kwargs):
        if len(name) > 32:
            raise InvalidTargetGroupNameError(
                "Target group name '{}' cannot be longer than '32' characters".
                format(name))
        if not re.match(r"^[a-zA-Z0-9\-]+$", name):
            raise InvalidTargetGroupNameError(
                "Target group name '{}' can only contain characters that are alphanumeric characters or hyphens(-)"
                .format(name))

        # undocumented validation
        if not re.match(r"(?!.*--)(?!^-)(?!.*-$)^[A-Za-z0-9-]+$", name):
            raise InvalidTargetGroupNameError(
                "1 validation error detected: Value '%s' at 'targetGroup.targetGroupArn.targetGroupName' failed to satisfy constraint: Member must satisfy regular expression pattern: (?!.*--)(?!^-)(?!.*-$)^[A-Za-z0-9-]+$"
                % name)

        if name.startswith("-") or name.endswith("-"):
            raise InvalidTargetGroupNameError(
                "Target group name '%s' cannot begin or end with '-'" % name)
        for target_group in self.target_groups.values():
            if target_group.name == name:
                raise DuplicateTargetGroupName()

        valid_protocols = ["HTTPS", "HTTP", "TCP"]
        if (kwargs.get("healthcheck_protocol")
                and kwargs["healthcheck_protocol"] not in valid_protocols):
            raise InvalidConditionValueError(
                "Value {} at 'healthCheckProtocol' failed to satisfy constraint: "
                "Member must satisfy enum value set: {}".format(
                    kwargs["healthcheck_protocol"], valid_protocols))
        if kwargs.get(
                "protocol") and kwargs["protocol"] not in valid_protocols:
            raise InvalidConditionValueError(
                "Value {} at 'protocol' failed to satisfy constraint: "
                "Member must satisfy enum value set: {}".format(
                    kwargs["protocol"], valid_protocols))

        if (kwargs.get("matcher") and FakeTargetGroup.HTTP_CODE_REGEX.match(
                kwargs["matcher"]["HttpCode"]) is None):
            raise RESTError(
                "InvalidParameterValue",
                "HttpCode must be like 200 | 200-399 | 200,201 ...",
            )

        arn = make_arn_for_target_group(account_id=1,
                                        name=name,
                                        region_name=self.region_name)
        target_group = FakeTargetGroup(name, arn, **kwargs)
        self.target_groups[target_group.arn] = target_group
        return target_group
Beispiel #4
0
 def validate_instance_type(self, instance_type):
     VALID_INSTANCE_TYPES = [
         "ml.p2.xlarge",
         "ml.m5.4xlarge",
         "ml.m4.16xlarge",
         "ml.t3.xlarge",
         "ml.p3.16xlarge",
         "ml.t2.xlarge",
         "ml.p2.16xlarge",
         "ml.c4.2xlarge",
         "ml.c5.2xlarge",
         "ml.c4.4xlarge",
         "ml.c5d.2xlarge",
         "ml.c5.4xlarge",
         "ml.c5d.4xlarge",
         "ml.c4.8xlarge",
         "ml.c5d.xlarge",
         "ml.c5.9xlarge",
         "ml.c5.xlarge",
         "ml.c5d.9xlarge",
         "ml.c4.xlarge",
         "ml.t2.2xlarge",
         "ml.c5d.18xlarge",
         "ml.t3.2xlarge",
         "ml.t3.medium",
         "ml.t2.medium",
         "ml.c5.18xlarge",
         "ml.p3.2xlarge",
         "ml.m5.xlarge",
         "ml.m4.10xlarge",
         "ml.t2.large",
         "ml.m5.12xlarge",
         "ml.m4.xlarge",
         "ml.t3.large",
         "ml.m5.24xlarge",
         "ml.m4.2xlarge",
         "ml.p2.8xlarge",
         "ml.m5.2xlarge",
         "ml.p3.8xlarge",
         "ml.m4.4xlarge",
     ]
     if not validators.is_one_of(instance_type, VALID_INSTANCE_TYPES):
         message = "Value '{}' at 'instanceType' failed to satisfy constraint: Member must satisfy enum value set: {}".format(
             instance_type, VALID_INSTANCE_TYPES
         )
         raise RESTError(
             error_type="ValidationException",
             message=message,
             template="error_json",
         )
Beispiel #5
0
    def untag_queue(self, queue_name, tag_keys):
        queue = self.get_queue(queue_name)

        if not len(tag_keys):
            raise RESTError(
                "InvalidParameterValue",
                "Tag keys must be between 1 and 128 characters in length.",
            )

        for key in tag_keys:
            try:
                del queue.tags[key]
            except KeyError:
                pass
Beispiel #6
0
    def create_function(self, spec):
        function_name = spec.get("FunctionName", None)
        if function_name is None:
            raise RESTError("InvalidParameterValueException",
                            "Missing FunctionName")

        fn = LambdaFunction(spec, self.region_name, version="$LATEST")

        self._lambdas.put_function(fn)

        if spec.get("Publish"):
            ver = self.publish_function(function_name)
            fn.version = ver.version
        return fn
Beispiel #7
0
    def set_security_groups(self, arn, sec_groups):
        balancer = self.load_balancers.get(arn)
        if balancer is None:
            raise LoadBalancerNotFoundError()

        # Check all security groups exist
        for sec_group_id in sec_groups:
            if self.ec2_backend.get_security_group_from_id(
                    sec_group_id) is None:
                raise RESTError(
                    'InvalidSecurityGroup',
                    'Security group {0} does not exist'.format(sec_group_id))

        balancer.security_groups = sec_groups
Beispiel #8
0
 def get_notebook_instance_by_arn(self, arn):
     instances = [
         notebook_instance
         for notebook_instance in self.notebook_instances.values()
         if notebook_instance.arn == arn
     ]
     if len(instances) == 0:
         message = "RecordNotFound"
         raise RESTError(
             error_type="ValidationException",
             message=message,
             template="error_json",
         )
     return instances[0]
Beispiel #9
0
    def get_invocation(self, instance_id, plugin_name):
        invocation = next(
            (
                invocation
                for invocation in self.invocations
                if invocation["InstanceId"] == instance_id
            ),
            None,
        )

        if invocation is None:
            raise RESTError(
                "InvocationDoesNotExist",
                "An error occurred (InvocationDoesNotExist) when calling the GetCommandInvocation operation",
            )

        if plugin_name is not None and invocation["PluginName"] != plugin_name:
            raise RESTError(
                "InvocationDoesNotExist",
                "An error occurred (InvocationDoesNotExist) when calling the GetCommandInvocation operation",
            )

        return invocation
Beispiel #10
0
    def create_function(self, spec):
        function_name = spec.get('FunctionName', None)
        if function_name is None:
            raise RESTError('InvalidParameterValueException',
                            'Missing FunctionName')

        fn = LambdaFunction(spec, self.region_name, version='$LATEST')

        self._lambdas.put_function(fn)

        if spec.get('Publish'):
            ver = self.publish_function(function_name)
            fn.version = ver.version
        return fn
Beispiel #11
0
 def list_metrics(self, next_token, namespace, metric_name, dimensions):
     if next_token:
         if next_token not in self.paged_metric_data:
             raise RESTError("PaginationException",
                             "Request parameter NextToken is invalid")
         else:
             metrics = self.paged_metric_data[next_token]
             del self.paged_metric_data[
                 next_token]  # Cant reuse same token twice
             return self._get_paginated(metrics)
     else:
         metrics = self.get_filtered_metrics(metric_name, namespace,
                                             dimensions)
         return self._get_paginated(metrics)
Beispiel #12
0
    def create_role(self, role_name, assume_role_policy_document, path,
                    permissions_boundary):
        role_id = random_resource_id()
        if permissions_boundary and not self.policy_arn_regex.match(
                permissions_boundary):
            raise RESTError(
                'InvalidParameterValue',
                'Value ({}) for parameter PermissionsBoundary is invalid.'.
                format(permissions_boundary))

        role = Role(role_id, role_name, assume_role_policy_document, path,
                    permissions_boundary)
        self.roles[role_id] = role
        return role
Beispiel #13
0
 def get_account_by_attr(self, attr, value):
     account = next(
         (
             account
             for account in self.accounts
             if hasattr(account, attr) and getattr(account, attr) == value
         ),
         None,
     )
     if account is None:
         raise RESTError(
             "AccountNotFoundException",
             "You specified an account that doesn't exist.",
         )
     return account
Beispiel #14
0
 def list_policies_for_target(self, **kwargs):
     if re.compile(utils.OU_ID_REGEX).match(kwargs["TargetId"]):
         obj = next((ou for ou in self.ou if ou.id == kwargs["TargetId"]),
                    None)
         if obj is None:
             raise RESTError(
                 "OrganizationalUnitNotFoundException",
                 "You specified an organizational unit that doesn't exist.",
             )
     elif re.compile(utils.ACCOUNT_ID_REGEX).match(kwargs["TargetId"]):
         obj = next(
             (a for a in self.accounts if a.id == kwargs["TargetId"]), None)
         if obj is None:
             raise RESTError(
                 "AccountNotFoundException",
                 "You specified an account that doesn't exist.",
             )
     else:
         raise RESTError("InvalidInputException",
                         "You specified an invalid value.")
     return dict(Policies=[
         p.describe()["Policy"]["PolicySummary"]
         for p in obj.attached_policies
     ])
Beispiel #15
0
 def list_children(self, **kwargs):
     parent_id = self.validate_parent_id(kwargs["ParentId"])
     if kwargs["ChildType"] == "ACCOUNT":
         obj_list = self.accounts
     elif kwargs["ChildType"] == "ORGANIZATIONAL_UNIT":
         obj_list = self.ou
     else:
         raise RESTError("InvalidInputException", "You specified an invalid value.")
     return dict(
         Children=[
             {"Id": obj.id, "Type": kwargs["ChildType"]}
             for obj in obj_list
             if obj.parent_id == parent_id
         ]
     )
Beispiel #16
0
    def _setup_dlq(self, policy):
        if Queue._is_empty_redrive_policy(policy):
            self.redrive_policy = None
            self.dead_letter_queue = None
            return

        if isinstance(policy, str):
            try:
                self.redrive_policy = json.loads(policy)
            except ValueError:
                raise RESTError(
                    "InvalidParameterValue",
                    "Redrive policy is not a dict or valid json",
                )
        elif isinstance(policy, dict):
            self.redrive_policy = policy
        else:
            raise RESTError(
                "InvalidParameterValue", "Redrive policy is not a dict or valid json"
            )

        if "deadLetterTargetArn" not in self.redrive_policy:
            raise RESTError(
                "InvalidParameterValue",
                "Redrive policy does not contain deadLetterTargetArn",
            )
        if "maxReceiveCount" not in self.redrive_policy:
            raise RESTError(
                "InvalidParameterValue",
                "Redrive policy does not contain maxReceiveCount",
            )

        # 'maxReceiveCount' is stored as int
        self.redrive_policy["maxReceiveCount"] = int(
            self.redrive_policy["maxReceiveCount"]
        )

        for queue in sqs_backends[self.region].queues.values():
            if queue.queue_arn == self.redrive_policy["deadLetterTargetArn"]:
                self.dead_letter_queue = queue

                if self.fifo_queue and not queue.fifo_queue:
                    raise RESTError(
                        "InvalidParameterCombination",
                        "Fifo queues cannot use non fifo dead letter queues",
                    )
                break
        else:
            raise RESTError(
                "AWS.SimpleQueueService.NonExistentQueue",
                "Could not find DLQ for {0}".format(
                    self.redrive_policy["deadLetterTargetArn"]
                ),
            )
Beispiel #17
0
 def list_targets_for_policy(self, **kwargs):
     if re.compile(utils.POLICY_ID_REGEX).match(kwargs["PolicyId"]):
         policy = next(
             (p for p in self.policies if p.id == kwargs["PolicyId"]), None
         )
         if policy is None:
             raise RESTError(
                 "PolicyNotFoundException",
                 "You specified a policy that doesn't exist.",
             )
     else:
         raise InvalidInputException("You specified an invalid value.")
     objects = [
         {"TargetId": obj.id, "Arn": obj.arn, "Name": obj.name, "Type": obj.type}
         for obj in policy.attachments
     ]
     return dict(Targets=objects)
Beispiel #18
0
    def get_tag_values(self, pagination_token, key):

        if pagination_token:
            if pagination_token not in self._pages:
                raise RESTError(
                    "PaginationTokenExpiredException", "Token does not exist"
                )

            generator = self._pages[pagination_token]["gen"]
            left_over = self._pages[pagination_token]["misc"]
        else:
            generator = self._get_tag_values_generator(key)
            left_over = None

        result = []
        current_tags = 0
        if left_over:
            result.append(left_over)
            current_tags += 1

        try:
            while True:
                # Generator format: ['value', 'value', 'value', ...]
                next_item = next(generator)

                if current_tags + 1 >= 128:
                    break

                current_tags += 1

                result.append(next_item)

        except StopIteration:
            # Finished generator before invalidating page limiting constraints
            return None, result

        # Didn't hit StopIteration so there's stuff left in generator
        new_token = str(uuid.uuid4())
        self._pages[new_token] = {"gen": generator, "misc": next_item}

        # Token used up, might as well bin now, if you call it again your an idiot
        if pagination_token:
            del self._pages[pagination_token]

        return new_token, result
Beispiel #19
0
    def modify_target_group(
        self,
        arn,
        health_check_proto=None,
        health_check_port=None,
        health_check_path=None,
        health_check_interval=None,
        health_check_timeout=None,
        healthy_threshold_count=None,
        unhealthy_threshold_count=None,
        http_codes=None,
    ):
        target_group = self.target_groups.get(arn)
        if target_group is None:
            raise TargetGroupNotFoundError()

        if (
            http_codes is not None
            and FakeTargetGroup.HTTP_CODE_REGEX.match(http_codes) is None
        ):
            raise RESTError(
                "InvalidParameterValue",
                "HttpCode must be like 200 | 200-399 | 200,201 ...",
            )

        if http_codes is not None:
            target_group.matcher["HttpCode"] = http_codes
        if health_check_interval is not None:
            target_group.healthcheck_interval_seconds = health_check_interval
        if health_check_path is not None:
            target_group.healthcheck_path = health_check_path
        if health_check_port is not None:
            target_group.healthcheck_port = health_check_port
        if health_check_proto is not None:
            target_group.healthcheck_protocol = health_check_proto
        if health_check_timeout is not None:
            target_group.healthcheck_timeout_seconds = health_check_timeout
        if healthy_threshold_count is not None:
            target_group.healthy_threshold_count = healthy_threshold_count
        if unhealthy_threshold_count is not None:
            target_group.unhealthy_threshold_count = unhealthy_threshold_count

        return target_group
Beispiel #20
0
    def list_policies_for_target(self, **kwargs):
        _filter = kwargs["Filter"]

        if re.match(utils.ROOT_ID_REGEX, kwargs["TargetId"]):
            obj = next((ou for ou in self.ou if ou.id == kwargs["TargetId"]),
                       None)
            if obj is None:
                raise TargetNotFoundException
        elif re.compile(utils.OU_ID_REGEX).match(kwargs["TargetId"]):
            obj = next((ou for ou in self.ou if ou.id == kwargs["TargetId"]),
                       None)
            if obj is None:
                raise RESTError(
                    "OrganizationalUnitNotFoundException",
                    "You specified an organizational unit that doesn't exist.",
                )
        elif re.compile(utils.ACCOUNT_ID_REGEX).match(kwargs["TargetId"]):
            obj = next(
                (a for a in self.accounts if a.id == kwargs["TargetId"]), None)
            if obj is None:
                raise AccountNotFoundException
        else:
            raise InvalidInputException("You specified an invalid value.")

        if not FakePolicy.supported_policy_type(_filter):
            raise InvalidInputException("You specified an invalid value.")

        if _filter not in [
                "AISERVICES_OPT_OUT_POLICY", "SERVICE_CONTROL_POLICY"
        ]:
            raise NotImplementedError(
                "The {0} policy type has not been implemented".format(_filter))

        return dict(Policies=[
            p.describe()["Policy"]["PolicySummary"]
            for p in obj.attached_policies if p.type == _filter
        ])
Beispiel #21
0
    def _setup_dlq(self, policy):

        if isinstance(policy, six.text_type):
            try:
                self.redrive_policy = json.loads(policy)
            except ValueError:
                raise RESTError('InvalidParameterValue',
                                'Redrive policy is not a dict or valid json')
        elif isinstance(policy, dict):
            self.redrive_policy = policy
        else:
            raise RESTError('InvalidParameterValue',
                            'Redrive policy is not a dict or valid json')

        if 'deadLetterTargetArn' not in self.redrive_policy:
            raise RESTError(
                'InvalidParameterValue',
                'Redrive policy does not contain deadLetterTargetArn')
        if 'maxReceiveCount' not in self.redrive_policy:
            raise RESTError('InvalidParameterValue',
                            'Redrive policy does not contain maxReceiveCount')

        # 'maxReceiveCount' is stored as int
        self.redrive_policy['maxReceiveCount'] = int(
            self.redrive_policy['maxReceiveCount'])

        for queue in sqs_backends[self.region].queues.values():
            if queue.queue_arn == self.redrive_policy['deadLetterTargetArn']:
                self.dead_letter_queue = queue

                if self.fifo_queue and not queue.fifo_queue:
                    raise RESTError(
                        'InvalidParameterCombination',
                        'Fifo queues cannot use non fifo dead letter queues')
                break
        else:
            raise RESTError(
                'AWS.SimpleQueueService.NonExistentQueue',
                'Could not find DLQ for {0}'.format(
                    self.redrive_policy['deadLetterTargetArn']))
Beispiel #22
0
 def describe_organization(self):
     if not self.org:
         raise RESTError(
             'AWSOrganizationsNotInUseException',
             "Your account is not a member of an organization.")
     return self.org.describe()
Beispiel #23
0
    def get_resources(self,
                      pagination_token=None,
                      resources_per_page=50,
                      tags_per_page=100,
                      tag_filters=None,
                      resource_type_filters=None):
        # Simple range checning
        if 100 >= tags_per_page >= 500:
            raise RESTError('InvalidParameterException',
                            'TagsPerPage must be between 100 and 500')
        if 1 >= resources_per_page >= 50:
            raise RESTError('InvalidParameterException',
                            'ResourcesPerPage must be between 1 and 50')

        # If we have a token, go and find the respective generator, or error
        if pagination_token:
            if pagination_token not in self._pages:
                raise RESTError('PaginationTokenExpiredException',
                                'Token does not exist')

            generator = self._pages[pagination_token]['gen']
            left_over = self._pages[pagination_token]['misc']
        else:
            generator = self._get_resources_generator(
                tag_filters=tag_filters,
                resource_type_filters=resource_type_filters)
            left_over = None

        result = []
        current_tags = 0
        current_resources = 0
        if left_over:
            result.append(left_over)
            current_resources += 1
            current_tags += len(left_over['Tags'])

        try:
            while True:
                # Generator format: [{'ResourceARN': str, 'Tags': [{'Key': str, 'Value': str]}, ...]
                next_item = six.next(generator)
                resource_tags = len(next_item['Tags'])

                if current_resources >= resources_per_page:
                    break
                if current_tags + resource_tags >= tags_per_page:
                    break

                current_resources += 1
                current_tags += resource_tags

                result.append(next_item)

        except StopIteration:
            # Finished generator before invalidating page limiting constraints
            return None, result

        # Didn't hit StopIteration so there's stuff left in generator
        new_token = str(uuid.uuid4())
        self._pages[new_token] = {'gen': generator, 'misc': next_item}

        # Token used up, might as well bin now, if you call it again your an idiot
        if pagination_token:
            del self._pages[pagination_token]

        return new_token, result
Beispiel #24
0
    def modify_listener(self,
                        arn,
                        port=None,
                        protocol=None,
                        ssl_policy=None,
                        certificates=None,
                        default_actions=None):
        default_actions = [FakeAction(action) for action in default_actions]
        for load_balancer in self.load_balancers.values():
            if arn in load_balancer.listeners:
                break
        else:
            raise ListenerNotFoundError()

        listener = load_balancer.listeners[arn]

        if port is not None:
            for listener_arn, current_listener in load_balancer.listeners.items(
            ):
                if listener_arn == arn:
                    continue
                if listener.port == port:
                    raise DuplicateListenerError()

            listener.port = port

        if protocol is not None:
            if protocol not in ('HTTP', 'HTTPS', 'TCP'):
                raise RESTError(
                    'UnsupportedProtocol',
                    'Protocol {0} is not supported'.format(protocol))

            # HTTPS checks
            if protocol == 'HTTPS':
                # HTTPS

                # Might already be HTTPS so may not provide certs
                if certificates is None and listener.protocol != 'HTTPS':
                    raise RESTError('InvalidConfigurationRequest',
                                    'Certificates must be provided for HTTPS')

                # Check certificates exist
                if certificates is not None:
                    default_cert = None
                    all_certs = set()  # for SNI
                    for cert in certificates:
                        if cert['is_default'] == 'true':
                            default_cert = cert['certificate_arn']
                        try:
                            self.acm_backend.get_certificate(
                                cert['certificate_arn'])
                        except Exception:
                            raise RESTError(
                                'CertificateNotFound',
                                'Certificate {0} not found'.format(
                                    cert['certificate_arn']))

                        all_certs.add(cert['certificate_arn'])

                    if default_cert is None:
                        raise RESTError('InvalidConfigurationRequest',
                                        'No default certificate')

                    listener.certificate = default_cert
                    listener.certificates = list(all_certs)

            listener.protocol = protocol

        if ssl_policy is not None:
            # Its already validated in responses.py
            listener.ssl_policy = ssl_policy

        if default_actions is not None and default_actions != []:
            # Is currently not validated
            listener.default_actions = default_actions

        return listener