from typing import Any, Dict, List, Optional from moto.utilities.utils import filter_resources, get_partition from ..utils import describe_tag_filter, random_managed_prefix_list_id from .core import TaggedEC2Resource class ManagedPrefixList(TaggedEC2Resource): def __init__( self, backend: Any, region: str, address_family: Optional[str] = None, entry: Optional[List[Dict[str, str]]] = None, max_entries: Optional[str] = None, prefix_list_name: Optional[str] = None, tags: Optional[Dict[str, str]] = None, owner_id: Optional[str] = None, ): self.ec2_backend = backend self.address_family = address_family self.max_entries = max_entries self.id = random_managed_prefix_list_id() self.prefix_list_name = prefix_list_name self.state = "create-complete" self.state_message = "create complete" self.add_tags(tags or {}) self.version: Optional[int] = 1 self.entries = {self.version: entry} if entry else {} self.resource_owner_id = owner_id if owner_id else None self.prefix_list_arn = self.arn(region, self.owner_id) self.delete_counter = 1 def arn(self, region: str, owner_id: str) -> str: return ( f"arn:{get_partition(region)}:ec2:{region}:{owner_id}:prefix-list/{self.id}" ) @property def owner_id(self) -> str: return self.resource_owner_id or self.ec2_backend.account_id class ManagedPrefixListBackend: def __init__(self) -> None: self.managed_prefix_lists: Dict[str, ManagedPrefixList] = {} self.create_default_pls() def create_managed_prefix_list( self, address_family: Optional[str] = None, entry: Optional[List[Dict[str, str]]] = None, max_entries: Optional[str] = None, prefix_list_name: Optional[str] = None, tags: Optional[Dict[str, str]] = None, owner_id: Optional[str] = None, ) -> ManagedPrefixList: managed_prefix_list = ManagedPrefixList( self, address_family=address_family, entry=entry, max_entries=max_entries, prefix_list_name=prefix_list_name, region=self.region_name, # type: ignore[attr-defined] tags=tags, owner_id=owner_id, ) self.managed_prefix_lists[managed_prefix_list.id] = managed_prefix_list return managed_prefix_list def describe_managed_prefix_lists( self, prefix_list_ids: Optional[List[str]] = None, filters: Any = None ) -> List[ManagedPrefixList]: managed_prefix_lists = list(self.managed_prefix_lists.values()) attr_pairs = ( ("owner-id", "owner_id"), ("prefix-list-id", "id"), ("prefix-list-name", "prefix_list_name"), ) if prefix_list_ids: managed_prefix_lists = [ managed_prefix_list for managed_prefix_list in managed_prefix_lists if managed_prefix_list.id in prefix_list_ids ] result = managed_prefix_lists if filters: result = filter_resources(result, filters, attr_pairs) result = describe_tag_filter(filters, result) for item in result.copy(): if not item.delete_counter: self.managed_prefix_lists.pop(item.id, None) result.remove(item) if item.state == "delete-complete": item.delete_counter -= 1 return result def get_managed_prefix_list_entries( self, prefix_list_id: str ) -> Optional[ManagedPrefixList]: return self.managed_prefix_lists.get(prefix_list_id) def delete_managed_prefix_list(self, prefix_list_id: str) -> ManagedPrefixList: managed_prefix_list: ManagedPrefixList = self.managed_prefix_lists.get( prefix_list_id ) # type: ignore managed_prefix_list.state = "delete-complete" return managed_prefix_list def modify_managed_prefix_list( self, add_entry: List[Dict[str, str]], remove_entry: List[Dict[str, str]], prefix_list_id: Optional[str] = None, current_version: Optional[str] = None, prefix_list_name: Optional[str] = None, ) -> ManagedPrefixList: managed_pl: ManagedPrefixList = self.managed_prefix_lists.get(prefix_list_id) # type: ignore managed_pl.prefix_list_name = prefix_list_name if remove_entry or add_entry: latest_version = managed_pl.entries.get(managed_pl.version) # type: ignore[arg-type] entries = ( managed_pl.entries.get(current_version, latest_version).copy() # type: ignore if managed_pl.entries else [] ) for item in entries.copy(): if item.get("Cidr", "") in remove_entry: entries.remove(item) for item in add_entry: if item not in entries.copy(): entries.append(item) managed_pl.version += 1 # type: ignore[operator] managed_pl.entries[managed_pl.version] = entries managed_pl.state = "modify-complete" return managed_pl def _create_aws_managed_prefix_list( self, name: str, address_family: str, entries: List[Dict[str, str]] ) -> None: managed_prefix_list = self.create_managed_prefix_list( address_family=address_family, entry=entries, prefix_list_name=name, owner_id="aws", ) managed_prefix_list.version = None managed_prefix_list.max_entries = None self.managed_prefix_lists[managed_prefix_list.id] = managed_prefix_list def create_default_pls(self) -> None: # See https://docs.aws.amazon.com/vpc/latest/userguide/working-with-aws-managed-prefix-lists.html # S3 self._create_aws_managed_prefix_list( name=f"com.amazonaws.{self.region_name}.s3", # type: ignore[attr-defined] address_family="IPv4", entries=[ {"Cidr": "52.216.0.0/15", "Description": "default"}, {"Cidr": "3.5.0.0/19", "Description": "default"}, {"Cidr": "54.231.0.0/16", "Description": "default"}, ], ) # DynamoDB self._create_aws_managed_prefix_list( name=f"com.amazonaws.{self.region_name}.dynamodb", # type: ignore[attr-defined] address_family="IPv4", entries=[ {"Cidr": "3.218.182.0/24", "Description": "default"}, {"Cidr": "3.218.180.0/23", "Description": "default"}, {"Cidr": "52.94.0.0/22", "Description": "default"}, {"Cidr": "52.119.224.0/20", "Description": "default"}, ], ) # CloudFront self._create_aws_managed_prefix_list( name="com.amazonaws.global.cloudfront.origin-facing", address_family="IPv4", entries=[ {"Cidr": "13.124.199.0/24", "Description": "default"}, {"Cidr": "130.176.0.0/18", "Description": "default"}, {"Cidr": "15.158.0.0/16", "Description": "default"}, {"Cidr": "18.68.0.0/16", "Description": "default"}, {"Cidr": "204.246.166.0/24", "Description": "default"}, {"Cidr": "205.251.218.0/24", "Description": "default"}, {"Cidr": "3.172.0.0/18", "Description": "default"}, {"Cidr": "54.239.208.0/21", "Description": "default"}, {"Cidr": "64.252.64.0/18", "Description": "default"}, {"Cidr": "70.132.0.0/18", "Description": "default"}, ], ) # Ground Station self._create_aws_managed_prefix_list( name="com.amazonaws.global.groundstation", address_family="IPv4", entries=[{"Cidr": "3.2.16.0/20", "Description": "default"}], ) # VPC Lattice self._create_aws_managed_prefix_list( name=f"com.amazonaws.{self.region_name}.vpc-lattice", # type: ignore[attr-defined] address_family="IPv4", entries=[{"Cidr": "169.254.171.0/24", "Description": "default"}], ) # VPC Lattice ipv6 self._create_aws_managed_prefix_list( name=f"com.amazonaws.{self.region_name}.ipv6.vpc-lattice", # type: ignore[attr-defined] address_family="IPv6", entries=[{"Cidr": "fd00:ec2:80::/64", "Description": "default"}], )
Memory