def add_permission(self, queue_name, actions, account_ids, label): queue = self.get_queue(queue_name) if actions is None or len(actions) == 0: raise RESTError("InvalidParameterValue", "Need at least one Action") if account_ids is None or len(account_ids) == 0: raise RESTError("InvalidParameterValue", "Need at least one Account ID") if not all([item in Queue.ALLOWED_PERMISSIONS for item in actions]): raise RESTError("InvalidParameterValue", "Invalid permissions") queue.permissions[label] = (account_ids, actions)
def set_ip_address_type(self, arn, ip_type): if ip_type not in ('internal', 'dualstack'): raise RESTError('InvalidParameterValue', 'IpAddressType must be either internal | dualstack') balancer = self.load_balancers.get(arn) if balancer is None: raise LoadBalancerNotFoundError() if ip_type == 'dualstack' and balancer.scheme == 'internal': raise RESTError('InvalidConfigurationRequest', 'Internal load balancers cannot be dualstack') balancer.stack = ip_type
def describe_policy(self, **kwargs): if re.compile(utils.SCP_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 RESTError("InvalidInputException", "You specified an invalid value.") return policy.describe()
def tag_queue(self, queue_name, tags): queue = self.get_queue(queue_name) if not len(tags): raise RESTError('MissingParameter', 'The request must contain the parameter Tags.') if len(tags) > 50: raise RESTError( 'InvalidParameterValue', 'Too many tags added for queue {}.'.format(queue_name)) queue.tags.update(tags)
def set_alarm_state(self, alarm_name, reason, reason_data, state_value): try: if reason_data is not None: json.loads(reason_data) except ValueError: raise RESTError('InvalidFormat', 'StateReasonData is invalid JSON') if alarm_name not in self.alarms: raise RESTError('ResourceNotFound', 'Alarm {0} not found'.format(alarm_name), status=404) if state_value not in ('OK', 'ALARM', 'INSUFFICIENT_DATA'): raise RESTError('InvalidParameterValue', 'StateValue is not one of OK | ALARM | INSUFFICIENT_DATA') self.alarms[alarm_name].update_state(reason, reason_data, state_value)
def delete_policy(self, **kwargs): for idx, policy in enumerate(self.policies): if policy.id == kwargs["PolicyId"]: if self.list_targets_for_policy(PolicyId=policy.id)["Targets"]: raise RESTError( "PolicyInUseException", "The policy is attached to one or more entities. You must detach it from all roots, OUs, and accounts before performing this operation.", ) del self.policies[idx] return raise RESTError( "PolicyNotFoundException", "We can't find a policy with the PolicyId that you specified.", )
def tag_queue(self, queue_name, tags): queue = self.get_queue(queue_name) if not len(tags): raise RESTError("MissingParameter", "The request must contain the parameter Tags.") if len(tags) > 50: raise RESTError( "InvalidParameterValue", "Too many tags added for queue {}.".format(queue_name), ) queue.tags.update(tags)
def remove_permission(self, queue_name, label): queue = self.get_queue(queue_name) if label not in queue.permissions: raise RESTError('InvalidParameterValue', 'Permission doesnt exist for the given label') del queue.permissions[label]
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
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
def describe_organization(self): if not self.org: raise RESTError( "AWSOrganizationsNotInUseException", "Your account is not a member of an organization.", ) return self.org.describe()
def create_endpoint( self, endpoint_name, endpoint_config_name, tags, ): try: endpoint_config = self.describe_endpoint_config( endpoint_config_name) except KeyError: message = "Could not find endpoint_config '{}'.".format( FakeEndpointConfig.arn_formatter(endpoint_config_name, self.region_name)) raise RESTError( error_type="ValidationException", message=message, template="error_json", ) endpoint = FakeEndpoint( region_name=self.region_name, endpoint_name=endpoint_name, endpoint_config_name=endpoint_config_name, production_variants=endpoint_config["ProductionVariants"], data_capture_config=endpoint_config["DataCaptureConfig"], tags=tags, ) self.endpoints[endpoint_name] = endpoint return endpoint
def get_organizational_unit_by_id(self, ou_id): ou = next((ou for ou in self.ou if ou.id == ou_id), None) if ou is None: raise RESTError( 'OrganizationalUnitNotFoundException', "You specified an organizational unit that doesn't exist.") return ou
def validate_parent_id(self, parent_id): try: self.get_organizational_unit_by_id(parent_id) except RESTError: raise RESTError('ParentNotFoundException', "You specified parent that doesn't exist.") return parent_id
def attach_policy(self, **kwargs): policy = self.get_policy_by_id(kwargs["PolicyId"]) if re.compile(utils.ROOT_ID_REGEX).match( kwargs["TargetId"]) or re.compile(utils.OU_ID_REGEX).match( kwargs["TargetId"]): ou = next((ou for ou in self.ou if ou.id == kwargs["TargetId"]), None) if ou is not None: if policy not in ou.attached_policies: ou.attached_policies.append(policy) policy.attachments.append(ou) else: raise RESTError( "OrganizationalUnitNotFoundException", "You specified an organizational unit that doesn't exist.", ) elif re.compile(utils.ACCOUNT_ID_REGEX).match(kwargs["TargetId"]): account = next( (a for a in self.accounts if a.id == kwargs["TargetId"]), None) if account is not None: if policy not in account.attached_policies: account.attached_policies.append(policy) policy.attachments.append(account) else: raise AccountNotFoundException else: raise InvalidInputException("You specified an invalid value.")
def detach_policy(self, **kwargs): policy = self.get_policy_by_id(kwargs["PolicyId"]) root_id_regex = utils.ROOT_ID_REGEX ou_id_regex = utils.OU_ID_REGEX account_id_regex = utils.ACCOUNT_ID_REGEX target_id = kwargs["TargetId"] if re.match(root_id_regex, target_id) or re.match( ou_id_regex, target_id): ou = next((ou for ou in self.ou if ou.id == target_id), None) if ou is not None: if policy in ou.attached_policies: ou.attached_policies.remove(policy) policy.attachments.remove(ou) else: raise RESTError( "OrganizationalUnitNotFoundException", "You specified an organizational unit that doesn't exist.", ) elif re.match(account_id_regex, target_id): account = next( (account for account in self.accounts if account.id == target_id), None, ) if account is not None: if policy in account.attached_policies: account.attached_policies.remove(policy) policy.attachments.remove(account) else: raise AccountNotFoundException else: raise InvalidInputException("You specified an invalid value.")
def create_event_source_mapping(self, spec): required = ["EventSourceArn", "FunctionName"] for param in required: if not spec.get(param): raise RESTError("InvalidParameterValueException", "Missing {}".format(param)) # Validate function name func = self._lambdas.get_function_by_name_or_arn( spec.get("FunctionName", "")) if not func: raise RESTError("ResourceNotFoundException", "Invalid FunctionName") # Validate queue for queue in sqs_backends[self.region_name].queues.values(): if queue.queue_arn == spec["EventSourceArn"]: if queue.lambda_event_source_mappings.get("func.function_arn"): # TODO: Correct exception? raise RESTError("ResourceConflictException", "The resource already exists.") if queue.fifo_queue: raise RESTError( "InvalidParameterValueException", "{} is FIFO".format(queue.queue_arn), ) else: spec.update({"FunctionArn": func.function_arn}) esm = EventSourceMapping(spec) self._event_source_mappings[esm.uuid] = esm # Set backend function on queue queue.lambda_event_source_mappings[esm.function_arn] = esm return esm for stream in json.loads(dynamodbstreams_backends[ self.region_name].list_streams())["Streams"]: if stream["StreamArn"] == spec["EventSourceArn"]: spec.update({"FunctionArn": func.function_arn}) esm = EventSourceMapping(spec) self._event_source_mappings[esm.uuid] = esm table_name = stream["TableName"] table = dynamodb_backends2[self.region_name].get_table( table_name) table.lambda_event_source_mappings[esm.function_arn] = esm return esm raise RESTError("ResourceNotFoundException", "Invalid EventSourceArn")
def get_command_by_id(self, id): command = next( (command for command in self._commands if command.command_id == id), None) if command is None: raise RESTError('InvalidCommandId', 'Invalid command id.') return command
def delete_organization(self, **kwargs): if [account for account in self.accounts if account.name != "master"]: raise RESTError( "OrganizationNotEmptyException", "To delete an organization you must first remove all member accounts (except the master).", ) self._reset() return {}
def list_targets_for_policy(self, **kwargs): if re.compile(utils.SCP_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 RESTError("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)
def list_targets_for_policy(self, **kwargs): if re.compile(utils.SCP_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 RESTError('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)
def get_account_by_id(self, account_id): account = next( (account for account in self.accounts if account.id == account_id), None) if account is None: raise RESTError('AccountNotFoundException', "You specified an account that doesn't exist.") return account
def validate_volume_size_in_gb(self, volume_size_in_gb): if not validators.is_integer_between(volume_size_in_gb, mn=5, optional=True): message = "Invalid range for parameter VolumeSizeInGB, value: {}, valid range: 5-inf" raise RESTError( error_type="ValidationException", message=message, template="error_json", )
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
def publish_layer_version(self, spec): required = ["LayerName", "Content"] for param in required: if not spec.get(param): raise RESTError("InvalidParameterValueException", "Missing {}".format(param)) layer_version = LayerVersion(spec, self.region_name) self._layers.put_layer_version(layer_version) return layer_version
def set_ip_address_type(self, arn, ip_type): if ip_type not in ("internal", "dualstack"): raise RESTError( "InvalidParameterValue", "IpAddressType must be either internal | dualstack", ) balancer = self.load_balancers.get(arn) if balancer is None: raise LoadBalancerNotFoundError() if ip_type == "dualstack" and balancer.scheme == "internal": raise RESTError( "InvalidConfigurationRequest", "Internal load balancers cannot be dualstack", ) balancer.stack = ip_type
def get_notebook_instance(self, notebook_instance_name): try: return self.notebook_instances[notebook_instance_name] except KeyError: message = "RecordNotFound" raise RESTError( error_type="ValidationException", message=message, template="error_json", )
def _validate_unique_notebook_instance_name(self, notebook_instance_name): if notebook_instance_name in self.notebook_instances: duplicate_arn = self.notebook_instances[notebook_instance_name].arn message = "Cannot create a duplicate Notebook Instance ({})".format( duplicate_arn) raise RESTError( error_type="ValidationException", message=message, template="error_json", )
def set_alarm_state(self, alarm_name, reason, reason_data, state_value): try: if reason_data is not None: json.loads(reason_data) except ValueError: raise RESTError("InvalidFormat", "StateReasonData is invalid JSON") if alarm_name not in self.alarms: raise RESTError( "ResourceNotFound", "Alarm {0} not found".format(alarm_name), status=404 ) if state_value not in ("OK", "ALARM", "INSUFFICIENT_DATA"): raise RESTError( "InvalidParameterValue", "StateValue is not one of OK | ALARM | INSUFFICIENT_DATA", ) self.alarms[alarm_name].update_state(reason, reason_data, state_value)
def delete_alarms(self, alarm_names): for alarm_name in alarm_names: if alarm_name not in self.alarms: raise RESTError( "ResourceNotFound", "Alarm {0} not found".format(alarm_name), status=404, ) for alarm_name in alarm_names: self.alarms.pop(alarm_name, None)