Пример #1
0
    def _put_attribute(self,
                       cluster_name,
                       name,
                       value=None,
                       target_id=None,
                       target_type=None):
        if target_id is None and target_type is None:
            for instance in self.container_instances[cluster_name].values():
                instance.attributes[name] = value
        elif target_type is None:
            # targetId is full container instance arn
            try:
                arn = target_id.rsplit('/', 1)[-1]
                self.container_instances[cluster_name][arn].attributes[
                    name] = value
            except KeyError:
                raise JsonRESTError('TargetNotFoundException',
                                    'Could not find {0}'.format(target_id))
        else:
            # targetId is container uuid, targetType must be container-instance
            try:
                if target_type != 'container-instance':
                    raise JsonRESTError('TargetNotFoundException',
                                        'Could not find {0}'.format(target_id))

                self.container_instances[cluster_name][target_id].attributes[
                    name] = value
            except KeyError:
                raise JsonRESTError('TargetNotFoundException',
                                    'Could not find {0}'.format(target_id))
Пример #2
0
    def _delete_attribute(
        self, cluster_name, name, value=None, target_id=None, target_type=None
    ):
        if target_id is None and target_type is None:
            for instance in self.container_instances[cluster_name].values():
                if name in instance.attributes and instance.attributes[name] == value:
                    del instance.attributes[name]
        elif target_type is None:
            # targetId is full container instance arn
            try:
                arn = target_id.rsplit("/", 1)[-1]
                instance = self.container_instances[cluster_name][arn]
                if name in instance.attributes and instance.attributes[name] == value:
                    del instance.attributes[name]
            except KeyError:
                raise JsonRESTError(
                    "TargetNotFoundException", "Could not find {0}".format(target_id)
                )
        else:
            # targetId is container uuid, targetType must be container-instance
            try:
                if target_type != "container-instance":
                    raise JsonRESTError(
                        "TargetNotFoundException",
                        "Could not find {0}".format(target_id),
                    )

                instance = self.container_instances[cluster_name][target_id]
                if name in instance.attributes and instance.attributes[name] == value:
                    del instance.attributes[name]
            except KeyError:
                raise JsonRESTError(
                    "TargetNotFoundException", "Could not find {0}".format(target_id)
                )
Пример #3
0
    def put_permission(self, event_bus_name, action, principal, statement_id):
        if not event_bus_name:
            event_bus_name = "default"

        event_bus = self.describe_event_bus(event_bus_name)

        if action is None or action != "events:PutEvents":
            raise JsonRESTError(
                "ValidationException",
                "Provided value in parameter 'action' is not supported.",
            )

        if principal is None or self.ACCOUNT_ID.match(principal) is None:
            raise JsonRESTError("InvalidParameterValue",
                                r"Principal must match ^(\d{1,12}|\*)$")

        if statement_id is None or self.STATEMENT_ID.match(
                statement_id) is None:
            raise JsonRESTError(
                "InvalidParameterValue",
                r"StatementId must match ^[a-zA-Z0-9-_]{1,64}$")

        event_bus._permissions[statement_id] = {
            "Action": action,
            "Principal": principal,
        }
Пример #4
0
    def delete_attributes(self, cluster_name, attributes=None):
        if cluster_name is None or cluster_name not in self.clusters:
            raise JsonRESTError('ClusterNotFoundException', 'Cluster not found', status=400)

        if attributes is None:
            raise JsonRESTError('InvalidParameterException', 'attributes value is required')

        for attr in attributes:
            self._delete_attribute(cluster_name, attr['name'], attr.get('value'), attr.get('targetId'), attr.get('targetType'))
Пример #5
0
    def put_events(self, events):
        num_events = len(events)

        if num_events < 1:
            raise JsonRESTError("ValidationError", "Need at least 1 event")
        elif num_events > 10:
            raise JsonRESTError("ValidationError", "Can only submit 10 events at once")

        # We dont really need to store the events yet
        return []
Пример #6
0
    def update_ttl(self, table_name, ttl_spec):
        table = self.tables.get(table_name)
        if table is None:
            raise JsonRESTError('ResourceNotFound', 'Table not found')

        if 'Enabled' not in ttl_spec or 'AttributeName' not in ttl_spec:
            raise JsonRESTError('InvalidParameterValue',
                                'TimeToLiveSpecification does not contain Enabled and AttributeName')

        if ttl_spec['Enabled']:
            table.ttl['TimeToLiveStatus'] = 'ENABLED'
        else:
            table.ttl['TimeToLiveStatus'] = 'DISABLED'
        table.ttl['AttributeName'] = ttl_spec['AttributeName']
Пример #7
0
    def remove_permission(self, event_bus_name, statement_id):
        if not event_bus_name:
            event_bus_name = "default"

        event_bus = self.describe_event_bus(event_bus_name)

        if not len(event_bus._permissions):
            raise JsonRESTError("ResourceNotFoundException",
                                "EventBus does not have a policy.")

        if not event_bus._permissions.pop(statement_id, None):
            raise JsonRESTError(
                "ResourceNotFoundException",
                "Statement with the provided id does not exist.",
            )
Пример #8
0
 def tag_resource(self, arn, tags):
     name = arn.split("/")[-1]
     if name in self.rules:
         self.tagger.tag_resource(self.rules[name].arn, tags)
         return {}
     raise JsonRESTError("ResourceNotFoundException",
                         "An entity that you specified does not exist.")
Пример #9
0
    def delete_event_bus(self, name):
        if name == "default":
            raise JsonRESTError(
                "ValidationException", "Cannot delete event bus default."
            )

        self.event_buses.pop(name, None)
Пример #10
0
    def describe_container_instances(self, cluster_str, list_container_instance_ids):
        cluster_name = cluster_str.split("/")[-1]
        if cluster_name not in self.clusters:
            raise Exception("{0} is not a cluster".format(cluster_name))
        if not list_container_instance_ids:
            raise JsonRESTError(
                "InvalidParameterException", "Container instance cannot be empty"
            )
        failures = []
        container_instance_objects = []
        for container_instance_id in list_container_instance_ids:
            container_instance_id = container_instance_id.split("/")[-1]
            container_instance = self.container_instances[cluster_name].get(
                container_instance_id, None
            )
            if container_instance is not None:
                container_instance_objects.append(container_instance)
            else:
                failures.append(
                    ContainerInstanceFailure(
                        "MISSING", container_instance_id, self.region_name
                    )
                )

        return container_instance_objects, failures
Пример #11
0
 def list_resource_tags(self, key_id):
     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.",
     )
Пример #12
0
 def list_tags_for_resource(self, arn):
     name = arn.split("/")[-1]
     if name in self.rules:
         return self.tagger.list_tags_for_resource(self.rules[name].arn)
     raise JsonRESTError(
         "ResourceNotFoundException", "An entity that you specified does not exist."
     )
Пример #13
0
    def update_time_to_live(self, table_name, ttl_spec):
        table = self.tables.get(table_name)
        if table is None:
            raise JsonRESTError("ResourceNotFound", "Table not found")

        if "Enabled" not in ttl_spec or "AttributeName" not in ttl_spec:
            raise JsonRESTError(
                "InvalidParameterValue",
                "TimeToLiveSpecification does not contain Enabled and AttributeName",
            )

        if ttl_spec["Enabled"]:
            table.ttl["TimeToLiveStatus"] = "ENABLED"
        else:
            table.ttl["TimeToLiveStatus"] = "DISABLED"
        table.ttl["AttributeName"] = ttl_spec["AttributeName"]
Пример #14
0
    def list_attributes(self,
                        target_type,
                        cluster_name=None,
                        attr_name=None,
                        attr_value=None,
                        max_results=None,
                        next_token=None):
        if target_type != 'container-instance':
            raise JsonRESTError('InvalidParameterException',
                                'targetType must be container-instance')

        filters = [lambda x: True]

        # item will be {0 cluster_name, 1 arn, 2 name, 3 value}
        if cluster_name is not None:
            filters.append(lambda item: item[0] == cluster_name)
        if attr_name:
            filters.append(lambda item: item[2] == attr_name)
        if attr_name:
            filters.append(lambda item: item[3] == attr_value)

        all_attrs = []
        for cluster_name, cobj in self.container_instances.items():
            for container_instance in cobj.values():
                for key, value in container_instance.attributes.items():
                    all_attrs.append(
                        (cluster_name,
                         container_instance.container_instance_arn, key,
                         value))

        return filter(lambda x: all(f(x) for f in filters), all_attrs)
Пример #15
0
 def untag_resource(self, key_id, tag_names):
     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.",
     )
Пример #16
0
 def _parse_resource_arn(resource_arn):
     match = re.match(
         "^arn:aws:ecs:(?P<region>[^:]+):(?P<account_id>[^:]+):(?P<service>[^:]+)/(?P<id>.*)$",
         resource_arn)
     if not match:
         raise JsonRESTError('InvalidParameterException',
                             'The ARN provided is invalid.')
     return match.groupdict()
Пример #17
0
 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.",
     )
Пример #18
0
    def put_permission(self, action, principal, statement_id):
        if action is None or action != "events:PutEvents":
            raise JsonRESTError("InvalidParameterValue",
                                "Action must be PutEvents")

        if principal is None or self.ACCOUNT_ID.match(principal) is None:
            raise JsonRESTError("InvalidParameterValue",
                                "Principal must match ^(\d{1,12}|\*)$")

        if statement_id is None or self.STATEMENT_ID.match(
                statement_id) is None:
            raise JsonRESTError(
                "InvalidParameterValue",
                "StatementId must match ^[a-zA-Z0-9-_]{1,64}$")

        self.permissions[statement_id] = {
            "action": action,
            "principal": principal
        }
Пример #19
0
    def put_permission(self, action, principal, statement_id):
        if action is None or action != 'PutEvents':
            raise JsonRESTError('InvalidParameterValue',
                                'Action must be PutEvents')

        if principal is None or self.ACCOUNT_ID.match(principal) is None:
            raise JsonRESTError('InvalidParameterValue',
                                'Principal must match ^(\d{1,12}|\*)$')

        if statement_id is None or self.STATEMENT_ID.match(
                statement_id) is None:
            raise JsonRESTError(
                'InvalidParameterValue',
                'StatementId must match ^[a-zA-Z0-9-_]{1,64}$')

        self.permissions[statement_id] = {
            'action': action,
            'principal': principal
        }
Пример #20
0
    def delete_attributes(self, cluster_name, attributes=None):
        if cluster_name is None or cluster_name not in self.clusters:
            raise JsonRESTError(
                "ClusterNotFoundException", "Cluster not found", status=400
            )

        if attributes is None:
            raise JsonRESTError(
                "InvalidParameterException", "attributes value is required"
            )

        for attr in attributes:
            self._delete_attribute(
                cluster_name,
                attr["name"],
                attr.get("value"),
                attr.get("targetId"),
                attr.get("targetType"),
            )
Пример #21
0
    def remove_targets(self, name, ids):
        rule = self.rules.get(name)

        if rule:
            rule.remove_targets(ids)
            return {"FailedEntries": [], "FailedEntryCount": 0}
        else:
            raise JsonRESTError(
                "ResourceNotFoundException",
                "An entity that you specified does not exist",
            )
Пример #22
0
 def extract_keys_for_schema(cls, item: Dict, key_schema: List[Dict]):
     result = {}
     for key in key_schema:
         attr_name = key["AttributeName"]
         if attr_name not in item:
             raise JsonRESTError(
                 error_type="ValidationException",
                 message="One of the required keys was not given a value",
             )
         result[attr_name] = item[attr_name]
     return result
Пример #23
0
    def create_event_bus(self, name, event_source_name=None):
        if name in self.event_buses:
            raise JsonRESTError(
                "ResourceAlreadyExistsException",
                "Event bus {} already exists.".format(name),
            )

        if not event_source_name and "/" in name:
            raise JsonRESTError("ValidationException",
                                "Event bus name must not contain '/'.")

        if event_source_name and event_source_name not in self.event_sources:
            raise JsonRESTError(
                "ResourceNotFoundException",
                "Event source {} does not exist.".format(event_source_name),
            )

        self.event_buses[name] = EventBus(self.region_name, name)

        return self.event_buses[name]
Пример #24
0
    def describe_event_bus(self, name):
        if not name:
            name = "default"

        event_bus = self.event_buses.get(name)

        if not event_bus:
            raise JsonRESTError("ResourceNotFoundException",
                                "Event bus {} does not exist.".format(name))

        return event_bus
Пример #25
0
    def put_events(self, events):
        num_events = len(events)

        if num_events < 1:
            raise JsonRESTError("ValidationError", "Need at least 1 event")
        elif num_events > 10:
            # the exact error text is longer, the Value list consists of all the put events
            raise ValidationException(
                "1 validation error detected: "
                "Value '[PutEventsRequestEntry]' at 'entries' failed to satisfy constraint: "
                "Member must have length less than or equal to 10")

        entries = []
        for event in events:
            if "Source" not in event:
                entries.append({
                    "ErrorCode":
                    "InvalidArgument",
                    "ErrorMessage":
                    "Parameter Source is not valid. Reason: Source is a required argument.",
                })
            elif "DetailType" not in event:
                entries.append({
                    "ErrorCode":
                    "InvalidArgument",
                    "ErrorMessage":
                    "Parameter DetailType is not valid. Reason: DetailType is a required argument.",
                })
            elif "Detail" not in event:
                entries.append({
                    "ErrorCode":
                    "InvalidArgument",
                    "ErrorMessage":
                    "Parameter Detail is not valid. Reason: Detail is a required argument.",
                })
            else:
                try:
                    json.loads(event["Detail"])
                except ValueError:  # json.JSONDecodeError exists since Python 3.5
                    entries.append({
                        "ErrorCode": "MalformedDetail",
                        "ErrorMessage": "Detail is malformed.",
                    })
                    continue

                entries.append({"EventId": str(uuid4())})

        # We dont really need to store the events yet
        return entries
Пример #26
0
    def list_tags_for_resource(self, resource_arn):
        """Currently only implemented for task definitions"""
        match = re.match(
            "^arn:aws:ecs:(?P<region>[^:]+):(?P<account_id>[^:]+):(?P<service>[^:]+)/(?P<id>.*)$",
            resource_arn)
        if not match:
            raise JsonRESTError('InvalidParameterException',
                                'The ARN provided is invalid.')

        service = match.group("service")
        if service == "task-definition":
            for task_definition in self.task_definitions.values():
                for revision in task_definition.values():
                    if revision.arn == resource_arn:
                        return revision.tags
            else:
                raise TaskDefinitionNotFoundException()
        raise NotImplementedError()
Пример #27
0
    def describe_ttl(self, table_name):
        table = self.tables.get(table_name)
        if table is None:
            raise JsonRESTError('ResourceNotFound', 'Table not found')

        return table.ttl
Пример #28
0
    def put_events(self, events):
        num_events = len(events)

        if num_events < 1:
            raise JsonRESTError("ValidationError", "Need at least 1 event")
        elif num_events > 10:
            # the exact error text is longer, the Value list consists of all the put events
            raise ValidationException(
                "1 validation error detected: "
                "Value '[PutEventsRequestEntry]' at 'entries' failed to satisfy constraint: "
                "Member must have length less than or equal to 10")

        entries = []
        for event in events:
            if "Source" not in event:
                entries.append({
                    "ErrorCode":
                    "InvalidArgument",
                    "ErrorMessage":
                    "Parameter Source is not valid. Reason: Source is a required argument.",
                })
            elif "DetailType" not in event:
                entries.append({
                    "ErrorCode":
                    "InvalidArgument",
                    "ErrorMessage":
                    "Parameter DetailType is not valid. Reason: DetailType is a required argument.",
                })
            elif "Detail" not in event:
                entries.append({
                    "ErrorCode":
                    "InvalidArgument",
                    "ErrorMessage":
                    "Parameter Detail is not valid. Reason: Detail is a required argument.",
                })
            else:
                try:
                    json.loads(event["Detail"])
                except ValueError:  # json.JSONDecodeError exists since Python 3.5
                    entries.append({
                        "ErrorCode": "MalformedDetail",
                        "ErrorMessage": "Detail is malformed.",
                    })
                    continue

                entries.append({"EventId": str(uuid4())})

                # add to correct archive
                # if 'EventBusName' is not espically set, it will stored in the default
                event_bus_name = event.get("EventBusName", "default")
                archives = [
                    archive for archive in self.archives.values()
                    if archive.event_bus_name == event_bus_name
                ]

                for archive in archives:
                    event_copy = copy.deepcopy(event)
                    event_copy.pop("EventBusName", None)

                    if archive.matches_pattern(event):
                        archive.events.append(event_copy)

        # We dont really need to store the events yet
        return entries
Пример #29
0
 def remove_permission(self, statement_id):
     try:
         del self.permissions[statement_id]
     except KeyError:
         raise JsonRESTError('ResourceNotFoundException',
                             'StatementId not found')
Пример #30
0
    def describe_time_to_live(self, table_name):
        table = self.tables.get(table_name)
        if table is None:
            raise JsonRESTError("ResourceNotFound", "Table not found")

        return table.ttl