| 
									
										
										
										
											2021-11-17 15:06:35 -05:00
										 |  |  | """Unit tests for route53resolver endpoint-related APIs.""" | 
					
						
							|  |  |  | from datetime import datetime, timezone | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import boto3 | 
					
						
							|  |  |  | from botocore.exceptions import ClientError | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import pytest | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | from moto import mock_route53resolver | 
					
						
							|  |  |  | from moto import settings | 
					
						
							| 
									
										
										
										
											2022-08-13 09:49:43 +00:00
										 |  |  | from moto.core import DEFAULT_ACCOUNT_ID as ACCOUNT_ID | 
					
						
							| 
									
										
										
										
											2021-11-17 15:06:35 -05:00
										 |  |  | from moto.ec2 import mock_ec2 | 
					
						
							| 
									
										
										
										
											2022-09-28 09:35:12 +00:00
										 |  |  | from moto.moto_api._internal import mock_random | 
					
						
							| 
									
										
										
										
											2021-11-17 15:06:35 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | TEST_REGION = "us-east-1" if settings.TEST_SERVER_MODE else "us-west-2" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def create_security_group(ec2_client): | 
					
						
							|  |  |  |     """Return a security group ID.""" | 
					
						
							|  |  |  |     group_name = "RRUnitTests" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Does the security group already exist? | 
					
						
							|  |  |  |     groups = ec2_client.describe_security_groups( | 
					
						
							|  |  |  |         Filters=[{"Name": "group-name", "Values": [group_name]}] | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # If so, we're done.  Otherwise, create it. | 
					
						
							|  |  |  |     if groups["SecurityGroups"]: | 
					
						
							|  |  |  |         return groups["SecurityGroups"][0]["GroupId"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     response = ec2_client.create_security_group( | 
					
						
							| 
									
										
										
										
											2022-03-10 13:39:59 -01:00
										 |  |  |         Description="Security group used by unit tests", GroupName=group_name | 
					
						
							| 
									
										
										
										
											2021-11-17 15:06:35 -05:00
										 |  |  |     ) | 
					
						
							|  |  |  |     return response["GroupId"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def create_vpc(ec2_client): | 
					
						
							|  |  |  |     """Return the ID for a valid VPC.""" | 
					
						
							|  |  |  |     return ec2_client.create_vpc(CidrBlock="10.0.0.0/16")["Vpc"]["VpcId"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def create_subnets(ec2_client, vpc_id): | 
					
						
							|  |  |  |     """Returns the IDs for two valid subnets.""" | 
					
						
							|  |  |  |     subnet_ids = [] | 
					
						
							|  |  |  |     for cidr_block in ["10.0.1.0/24", "10.0.0.0/24"]: | 
					
						
							|  |  |  |         subnet_ids.append( | 
					
						
							|  |  |  |             ec2_client.create_subnet( | 
					
						
							| 
									
										
										
										
											2022-03-10 13:39:59 -01:00
										 |  |  |                 VpcId=vpc_id, CidrBlock=cidr_block, AvailabilityZone=f"{TEST_REGION}a" | 
					
						
							| 
									
										
										
										
											2021-11-17 15:06:35 -05:00
										 |  |  |             )["Subnet"]["SubnetId"] | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |     return subnet_ids | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def create_test_endpoint(client, ec2_client, name=None, tags=None): | 
					
						
							|  |  |  |     """Create an endpoint that can be used for testing purposes.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Can't be used for unit tests that need to know/test the arguments. | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     if not tags: | 
					
						
							|  |  |  |         tags = [] | 
					
						
							| 
									
										
										
										
											2022-09-28 09:35:12 +00:00
										 |  |  |     random_num = mock_random.get_random_hex(10) | 
					
						
							| 
									
										
										
										
											2021-11-17 15:06:35 -05:00
										 |  |  |     subnet_ids = create_subnets(ec2_client, create_vpc(ec2_client)) | 
					
						
							|  |  |  |     resolver_endpoint = client.create_resolver_endpoint( | 
					
						
							|  |  |  |         CreatorRequestId=random_num, | 
					
						
							|  |  |  |         Name=name if name else "X" + random_num, | 
					
						
							|  |  |  |         SecurityGroupIds=[create_security_group(ec2_client)], | 
					
						
							|  |  |  |         Direction="INBOUND", | 
					
						
							|  |  |  |         IpAddresses=[ | 
					
						
							|  |  |  |             {"SubnetId": subnet_ids[0], "Ip": "10.0.1.200"}, | 
					
						
							|  |  |  |             {"SubnetId": subnet_ids[1], "Ip": "10.0.0.20"}, | 
					
						
							|  |  |  |         ], | 
					
						
							|  |  |  |         Tags=tags, | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     return resolver_endpoint["ResolverEndpoint"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_route53resolver | 
					
						
							|  |  |  | def test_route53resolver_invalid_create_endpoint_args(): | 
					
						
							|  |  |  |     """Test invalid arguments to the create_resolver_endpoint API.""" | 
					
						
							|  |  |  |     client = boto3.client("route53resolver", region_name=TEST_REGION) | 
					
						
							| 
									
										
										
										
											2022-09-28 09:35:12 +00:00
										 |  |  |     random_num = mock_random.get_random_hex(10) | 
					
						
							| 
									
										
										
										
											2021-11-17 15:06:35 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # Verify ValidationException error messages are accumulated properly: | 
					
						
							|  |  |  |     #  - creator requestor ID that exceeds the allowed length of 255. | 
					
						
							|  |  |  |     #  - name that exceeds the allowed length of 64. | 
					
						
							|  |  |  |     #  - direction that's neither INBOUND or OUTBOUND. | 
					
						
							|  |  |  |     #  - more than 10 IP Address sets. | 
					
						
							|  |  |  |     #  - too many security group IDs. | 
					
						
							|  |  |  |     long_id = random_num * 25 + "123456" | 
					
						
							|  |  |  |     long_name = random_num * 6 + "abcde" | 
					
						
							| 
									
										
										
										
											2022-09-28 09:35:12 +00:00
										 |  |  |     too_many_security_groups = ["sg-" + mock_random.get_random_hex(63)] | 
					
						
							| 
									
										
										
										
											2021-11-17 15:06:35 -05:00
										 |  |  |     bad_direction = "foo" | 
					
						
							|  |  |  |     too_many_ip_addresses = [{"SubnetId": f"{x}", "Ip": f"{x}" * 7} for x in range(11)] | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as exc: | 
					
						
							|  |  |  |         client.create_resolver_endpoint( | 
					
						
							|  |  |  |             CreatorRequestId=long_id, | 
					
						
							|  |  |  |             Name=long_name, | 
					
						
							|  |  |  |             SecurityGroupIds=too_many_security_groups, | 
					
						
							|  |  |  |             Direction=bad_direction, | 
					
						
							|  |  |  |             IpAddresses=too_many_ip_addresses, | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |     err = exc.value.response["Error"] | 
					
						
							|  |  |  |     assert err["Code"] == "ValidationException" | 
					
						
							|  |  |  |     assert "5 validation errors detected" in err["Message"] | 
					
						
							|  |  |  |     assert ( | 
					
						
							|  |  |  |         f"Value '{long_id}' at 'creatorRequestId' failed to satisfy constraint: " | 
					
						
							|  |  |  |         f"Member must have length less than or equal to 255" | 
					
						
							|  |  |  |     ) in err["Message"] | 
					
						
							|  |  |  |     assert ( | 
					
						
							|  |  |  |         f"Value '{too_many_security_groups}' at 'securityGroupIds' failed to " | 
					
						
							|  |  |  |         f"satisfy constraint: Member must have length less than or equal to 64" | 
					
						
							|  |  |  |     ) in err["Message"] | 
					
						
							|  |  |  |     assert ( | 
					
						
							|  |  |  |         f"Value '{long_name}' at 'name' failed to satisfy constraint: " | 
					
						
							|  |  |  |         f"Member must have length less than or equal to 64" | 
					
						
							|  |  |  |     ) in err["Message"] | 
					
						
							|  |  |  |     assert ( | 
					
						
							|  |  |  |         f"Value '{bad_direction}' at 'direction' failed to satisfy constraint: " | 
					
						
							|  |  |  |         f"Member must satisfy enum value set: [INBOUND, OUTBOUND]" | 
					
						
							|  |  |  |     ) in err["Message"] | 
					
						
							|  |  |  |     assert ( | 
					
						
							|  |  |  |         f"Value '{too_many_ip_addresses}' at 'ipAddresses' failed to satisfy " | 
					
						
							|  |  |  |         f"constraint: Member must have length less than or equal to 10" | 
					
						
							|  |  |  |     ) in err["Message"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Some single ValidationException errors ... | 
					
						
							|  |  |  |     bad_chars_in_name = "0@*3" | 
					
						
							|  |  |  |     ok_group_ids = ["sg-" + random_num] | 
					
						
							|  |  |  |     ok_ip_addrs = [{"SubnetId": f"{x}", "Ip": f"{x}" * 7} for x in range(10)] | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as exc: | 
					
						
							|  |  |  |         client.create_resolver_endpoint( | 
					
						
							|  |  |  |             CreatorRequestId=random_num, | 
					
						
							|  |  |  |             Name=bad_chars_in_name, | 
					
						
							|  |  |  |             SecurityGroupIds=ok_group_ids, | 
					
						
							|  |  |  |             Direction="INBOUND", | 
					
						
							|  |  |  |             IpAddresses=ok_ip_addrs, | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |     err = exc.value.response["Error"] | 
					
						
							|  |  |  |     assert err["Code"] == "ValidationException" | 
					
						
							|  |  |  |     assert "1 validation error detected" in err["Message"] | 
					
						
							|  |  |  |     assert ( | 
					
						
							| 
									
										
										
										
											2022-03-10 13:39:59 -01:00
										 |  |  |         rf"Value '{bad_chars_in_name}' at 'name' failed to satisfy constraint: " | 
					
						
							|  |  |  |         rf"Member must satisfy regular expression pattern: " | 
					
						
							|  |  |  |         rf"^(?!^[0-9]+$)([a-zA-Z0-9-_' ']+)$" | 
					
						
							| 
									
										
										
										
											2021-11-17 15:06:35 -05:00
										 |  |  |     ) in err["Message"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     subnet_too_long = [{"SubnetId": "a" * 33, "Ip": "1.2.3.4"}] | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as exc: | 
					
						
							|  |  |  |         client.create_resolver_endpoint( | 
					
						
							|  |  |  |             CreatorRequestId=random_num, | 
					
						
							|  |  |  |             Name="X" + random_num, | 
					
						
							|  |  |  |             SecurityGroupIds=ok_group_ids, | 
					
						
							|  |  |  |             Direction="OUTBOUND", | 
					
						
							|  |  |  |             IpAddresses=subnet_too_long, | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |     err = exc.value.response["Error"] | 
					
						
							|  |  |  |     assert err["Code"] == "ValidationException" | 
					
						
							|  |  |  |     assert "1 validation error detected" in err["Message"] | 
					
						
							|  |  |  |     assert ( | 
					
						
							|  |  |  |         f"Value '{subnet_too_long}' at 'ipAddresses.subnetId' failed to " | 
					
						
							|  |  |  |         f"satisfy constraint: Member must have length less than or equal to 32" | 
					
						
							|  |  |  |     ) in err["Message"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ec2 | 
					
						
							|  |  |  | @mock_route53resolver | 
					
						
							|  |  |  | def test_route53resolver_bad_create_endpoint_subnets(): | 
					
						
							|  |  |  |     """Test bad subnet scenarios for create_resolver_endpoint API.""" | 
					
						
							|  |  |  |     client = boto3.client("route53resolver", region_name=TEST_REGION) | 
					
						
							|  |  |  |     ec2_client = boto3.client("ec2", region_name=TEST_REGION) | 
					
						
							| 
									
										
										
										
											2022-09-28 09:35:12 +00:00
										 |  |  |     random_num = mock_random.get_random_hex(10) | 
					
						
							| 
									
										
										
										
											2021-11-17 15:06:35 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # Need 2 IP addresses at the minimum. | 
					
						
							|  |  |  |     subnet_ids = create_subnets(ec2_client, create_vpc(ec2_client)) | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as exc: | 
					
						
							|  |  |  |         client.create_resolver_endpoint( | 
					
						
							|  |  |  |             CreatorRequestId=random_num, | 
					
						
							|  |  |  |             Name="X" + random_num, | 
					
						
							|  |  |  |             SecurityGroupIds=[f"sg-{random_num}"], | 
					
						
							|  |  |  |             Direction="INBOUND", | 
					
						
							|  |  |  |             IpAddresses=[{"SubnetId": subnet_ids[0], "Ip": "1.2.3.4"}], | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |     err = exc.value.response["Error"] | 
					
						
							|  |  |  |     assert err["Code"] == "InvalidRequestException" | 
					
						
							|  |  |  |     assert "Resolver endpoint needs to have at least 2 IP addresses" in err["Message"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Need an IP that's within in the subnet. | 
					
						
							|  |  |  |     bad_ip_addr = "1.2.3.4" | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as exc: | 
					
						
							|  |  |  |         client.create_resolver_endpoint( | 
					
						
							|  |  |  |             CreatorRequestId=random_num, | 
					
						
							|  |  |  |             Name="X" + random_num, | 
					
						
							|  |  |  |             SecurityGroupIds=[f"sg-{random_num}"], | 
					
						
							|  |  |  |             Direction="INBOUND", | 
					
						
							|  |  |  |             IpAddresses=[ | 
					
						
							|  |  |  |                 {"SubnetId": subnet_ids[0], "Ip": bad_ip_addr}, | 
					
						
							|  |  |  |                 {"SubnetId": subnet_ids[1], "Ip": bad_ip_addr}, | 
					
						
							|  |  |  |             ], | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |     err = exc.value.response["Error"] | 
					
						
							|  |  |  |     assert err["Code"] == "InvalidRequestException" | 
					
						
							|  |  |  |     assert ( | 
					
						
							|  |  |  |         f"IP address '{bad_ip_addr}' is either not in subnet " | 
					
						
							|  |  |  |         f"'{subnet_ids[0]}' CIDR range or is reserved" | 
					
						
							|  |  |  |     ) in err["Message"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Bad subnet ID. | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as exc: | 
					
						
							|  |  |  |         client.create_resolver_endpoint( | 
					
						
							|  |  |  |             CreatorRequestId=random_num, | 
					
						
							|  |  |  |             Name="X" + random_num, | 
					
						
							|  |  |  |             SecurityGroupIds=[f"sg-{random_num}"], | 
					
						
							|  |  |  |             Direction="INBOUND", | 
					
						
							|  |  |  |             IpAddresses=[ | 
					
						
							|  |  |  |                 {"SubnetId": "foo", "Ip": "1.2.3.4"}, | 
					
						
							|  |  |  |                 {"SubnetId": subnet_ids[1], "Ip": "1.2.3.4"}, | 
					
						
							|  |  |  |             ], | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |     err = exc.value.response["Error"] | 
					
						
							|  |  |  |     assert err["Code"] == "InvalidParameterException" | 
					
						
							|  |  |  |     assert "The subnet ID 'foo' does not exist" in err["Message"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Can't reuse a ip address in a subnet. | 
					
						
							|  |  |  |     subnet_ids = create_subnets(ec2_client, create_vpc(ec2_client)) | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as exc: | 
					
						
							|  |  |  |         client.create_resolver_endpoint( | 
					
						
							|  |  |  |             CreatorRequestId="B" + random_num, | 
					
						
							|  |  |  |             Name="B" + random_num, | 
					
						
							|  |  |  |             SecurityGroupIds=[create_security_group(ec2_client)], | 
					
						
							|  |  |  |             Direction="INBOUND", | 
					
						
							|  |  |  |             IpAddresses=[ | 
					
						
							|  |  |  |                 {"SubnetId": subnet_ids[0], "Ip": "10.0.1.200"}, | 
					
						
							|  |  |  |                 {"SubnetId": subnet_ids[0], "Ip": "10.0.1.200"}, | 
					
						
							|  |  |  |             ], | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |     err = exc.value.response["Error"] | 
					
						
							|  |  |  |     assert err["Code"] == "ResourceExistsException" | 
					
						
							|  |  |  |     assert ( | 
					
						
							|  |  |  |         f"The IP address '10.0.1.200' in subnet '{subnet_ids[0]}' is already in use" | 
					
						
							|  |  |  |     ) in err["Message"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ec2 | 
					
						
							|  |  |  | @mock_route53resolver | 
					
						
							|  |  |  | def test_route53resolver_bad_create_endpoint_security_groups(): | 
					
						
							|  |  |  |     """Test bad security group scenarios for create_resolver_endpoint API.""" | 
					
						
							|  |  |  |     client = boto3.client("route53resolver", region_name=TEST_REGION) | 
					
						
							|  |  |  |     ec2_client = boto3.client("ec2", region_name=TEST_REGION) | 
					
						
							| 
									
										
										
										
											2022-09-28 09:35:12 +00:00
										 |  |  |     random_num = mock_random.get_random_hex(10) | 
					
						
							| 
									
										
										
										
											2021-11-17 15:06:35 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     subnet_ids = create_subnets(ec2_client, create_vpc(ec2_client)) | 
					
						
							|  |  |  |     ip_addrs = [ | 
					
						
							|  |  |  |         {"SubnetId": subnet_ids[0], "Ip": "10.0.1.200"}, | 
					
						
							|  |  |  |         {"SubnetId": subnet_ids[1], "Ip": "10.0.0.20"}, | 
					
						
							|  |  |  |     ] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Subnet must begin with "sg-". | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as exc: | 
					
						
							|  |  |  |         client.create_resolver_endpoint( | 
					
						
							|  |  |  |             CreatorRequestId=random_num, | 
					
						
							|  |  |  |             Name="X" + random_num, | 
					
						
							|  |  |  |             SecurityGroupIds=["foo"], | 
					
						
							|  |  |  |             Direction="INBOUND", | 
					
						
							|  |  |  |             IpAddresses=ip_addrs, | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |     err = exc.value.response["Error"] | 
					
						
							|  |  |  |     assert err["Code"] == "InvalidParameterException" | 
					
						
							|  |  |  |     assert ( | 
					
						
							|  |  |  |         "Malformed security group ID: Invalid id: 'foo' (expecting 'sg-...')" | 
					
						
							|  |  |  |     ) in err["Message"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Non-existent security group id. | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as exc: | 
					
						
							|  |  |  |         client.create_resolver_endpoint( | 
					
						
							|  |  |  |             CreatorRequestId=random_num, | 
					
						
							|  |  |  |             Name="X" + random_num, | 
					
						
							|  |  |  |             SecurityGroupIds=["sg-abc"], | 
					
						
							|  |  |  |             Direction="INBOUND", | 
					
						
							|  |  |  |             IpAddresses=ip_addrs, | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |     err = exc.value.response["Error"] | 
					
						
							|  |  |  |     assert err["Code"] == "ResourceNotFoundException" | 
					
						
							|  |  |  |     assert "The security group 'sg-abc' does not exist" in err["Message"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Too many security group ids. | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as exc: | 
					
						
							|  |  |  |         client.create_resolver_endpoint( | 
					
						
							|  |  |  |             CreatorRequestId=random_num, | 
					
						
							|  |  |  |             Name="X" + random_num, | 
					
						
							|  |  |  |             SecurityGroupIds=["sg-abc"] * 11, | 
					
						
							|  |  |  |             Direction="INBOUND", | 
					
						
							|  |  |  |             IpAddresses=ip_addrs, | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |     err = exc.value.response["Error"] | 
					
						
							|  |  |  |     assert err["Code"] == "InvalidParameterException" | 
					
						
							|  |  |  |     assert "Maximum of 10 security groups are allowed" in err["Message"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ec2 | 
					
						
							|  |  |  | @mock_route53resolver | 
					
						
							|  |  |  | def test_route53resolver_create_resolver_endpoint():  # pylint: disable=too-many-locals | 
					
						
							|  |  |  |     """Test good create_resolver_endpoint API calls.""" | 
					
						
							|  |  |  |     client = boto3.client("route53resolver", region_name=TEST_REGION) | 
					
						
							|  |  |  |     ec2_client = boto3.client("ec2", region_name=TEST_REGION) | 
					
						
							| 
									
										
										
										
											2022-09-28 09:35:12 +00:00
										 |  |  |     random_num = mock_random.get_random_hex(10) | 
					
						
							| 
									
										
										
										
											2021-11-17 15:06:35 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     vpc_id = create_vpc(ec2_client) | 
					
						
							|  |  |  |     subnet_ids = create_subnets(ec2_client, vpc_id) | 
					
						
							|  |  |  |     ip_addrs = [ | 
					
						
							|  |  |  |         {"SubnetId": subnet_ids[0], "Ip": "10.0.1.200"}, | 
					
						
							|  |  |  |         {"SubnetId": subnet_ids[1], "Ip": "10.0.0.20"}, | 
					
						
							|  |  |  |     ] | 
					
						
							|  |  |  |     security_group_id = create_security_group(ec2_client) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     creator_request_id = random_num | 
					
						
							|  |  |  |     name = "X" + random_num | 
					
						
							|  |  |  |     response = client.create_resolver_endpoint( | 
					
						
							|  |  |  |         CreatorRequestId=creator_request_id, | 
					
						
							|  |  |  |         Name=name, | 
					
						
							|  |  |  |         SecurityGroupIds=[security_group_id], | 
					
						
							|  |  |  |         Direction="INBOUND", | 
					
						
							|  |  |  |         IpAddresses=ip_addrs, | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     endpoint = response["ResolverEndpoint"] | 
					
						
							|  |  |  |     id_value = endpoint["Id"] | 
					
						
							|  |  |  |     assert id_value.startswith("rslvr-in-") | 
					
						
							|  |  |  |     assert endpoint["CreatorRequestId"] == creator_request_id | 
					
						
							|  |  |  |     assert ( | 
					
						
							|  |  |  |         endpoint["Arn"] | 
					
						
							|  |  |  |         == f"arn:aws:route53resolver:{TEST_REGION}:{ACCOUNT_ID}:resolver-endpoint/{id_value}" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     assert endpoint["Name"] == name | 
					
						
							|  |  |  |     assert endpoint["SecurityGroupIds"] == [security_group_id] | 
					
						
							|  |  |  |     assert endpoint["Direction"] == "INBOUND" | 
					
						
							|  |  |  |     assert endpoint["IpAddressCount"] == 2 | 
					
						
							|  |  |  |     assert endpoint["HostVPCId"] == vpc_id | 
					
						
							|  |  |  |     assert endpoint["Status"] == "OPERATIONAL" | 
					
						
							| 
									
										
										
										
											2021-11-22 12:57:07 -05:00
										 |  |  |     assert "Successfully created Resolver Endpoint" in endpoint["StatusMessage"] | 
					
						
							| 
									
										
										
										
											2021-11-17 15:06:35 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     time_format = "%Y-%m-%dT%H:%M:%S.%f+00:00" | 
					
						
							|  |  |  |     now = datetime.now(timezone.utc).replace(tzinfo=None) | 
					
						
							|  |  |  |     creation_time = datetime.strptime(endpoint["CreationTime"], time_format) | 
					
						
							|  |  |  |     creation_time = creation_time.replace(tzinfo=None) | 
					
						
							|  |  |  |     assert creation_time <= now | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     modification_time = datetime.strptime(endpoint["ModificationTime"], time_format) | 
					
						
							|  |  |  |     modification_time = modification_time.replace(tzinfo=None) | 
					
						
							|  |  |  |     assert modification_time <= now | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ec2 | 
					
						
							|  |  |  | @mock_route53resolver | 
					
						
							|  |  |  | def test_route53resolver_other_create_resolver_endpoint_errors(): | 
					
						
							| 
									
										
										
										
											2021-11-22 12:57:07 -05:00
										 |  |  |     """Test other error scenarios for create_resolver_endpoint API calls.""" | 
					
						
							| 
									
										
										
										
											2021-11-17 15:06:35 -05:00
										 |  |  |     client = boto3.client("route53resolver", region_name=TEST_REGION) | 
					
						
							|  |  |  |     ec2_client = boto3.client("ec2", region_name=TEST_REGION) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Create a good endpoint that we can use to test. | 
					
						
							|  |  |  |     created_endpoint = create_test_endpoint(client, ec2_client) | 
					
						
							|  |  |  |     request_id = created_endpoint["CreatorRequestId"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Attempt to create another endpoint with the same creator request id. | 
					
						
							|  |  |  |     vpc_id = create_vpc(ec2_client) | 
					
						
							|  |  |  |     subnet_ids = create_subnets(ec2_client, vpc_id) | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as exc: | 
					
						
							|  |  |  |         client.create_resolver_endpoint( | 
					
						
							|  |  |  |             CreatorRequestId=created_endpoint["CreatorRequestId"], | 
					
						
							| 
									
										
										
										
											2022-09-28 09:35:12 +00:00
										 |  |  |             Name="X" + mock_random.get_random_hex(10), | 
					
						
							| 
									
										
										
										
											2021-11-17 15:06:35 -05:00
										 |  |  |             SecurityGroupIds=created_endpoint["SecurityGroupIds"], | 
					
						
							|  |  |  |             Direction="INBOUND", | 
					
						
							|  |  |  |             IpAddresses=[ | 
					
						
							|  |  |  |                 {"SubnetId": subnet_ids[0], "Ip": "10.0.1.200"}, | 
					
						
							|  |  |  |                 {"SubnetId": subnet_ids[1], "Ip": "10.0.0.20"}, | 
					
						
							|  |  |  |             ], | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |     err = exc.value.response["Error"] | 
					
						
							|  |  |  |     assert err["Code"] == "ResourceExistsException" | 
					
						
							|  |  |  |     assert ( | 
					
						
							|  |  |  |         f"Resolver endpoint with creator request ID '{request_id}' already exists" | 
					
						
							|  |  |  |     ) in err["Message"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Too many endpoints. | 
					
						
							| 
									
										
										
										
											2022-09-28 09:35:12 +00:00
										 |  |  |     random_num = mock_random.get_random_hex(10) | 
					
						
							| 
									
										
										
										
											2021-11-17 15:06:35 -05:00
										 |  |  |     for idx in range(4): | 
					
						
							|  |  |  |         create_test_endpoint(client, ec2_client, name=f"A{idx}-{random_num}") | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as exc: | 
					
						
							|  |  |  |         create_test_endpoint(client, ec2_client, name=f"A5-{random_num}") | 
					
						
							|  |  |  |     err = exc.value.response["Error"] | 
					
						
							|  |  |  |     assert err["Code"] == "LimitExceededException" | 
					
						
							|  |  |  |     assert f"Account '{ACCOUNT_ID}' has exceeded 'max-endpoints" in err["Message"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ec2 | 
					
						
							|  |  |  | @mock_route53resolver | 
					
						
							|  |  |  | def test_route53resolver_delete_resolver_endpoint(): | 
					
						
							|  |  |  |     """Test good delete_resolver_endpoint API calls.""" | 
					
						
							|  |  |  |     client = boto3.client("route53resolver", region_name=TEST_REGION) | 
					
						
							|  |  |  |     ec2_client = boto3.client("ec2", region_name=TEST_REGION) | 
					
						
							|  |  |  |     created_endpoint = create_test_endpoint(client, ec2_client) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Now delete the resolver endpoint and verify the response. | 
					
						
							|  |  |  |     response = client.delete_resolver_endpoint( | 
					
						
							|  |  |  |         ResolverEndpointId=created_endpoint["Id"] | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     endpoint = response["ResolverEndpoint"] | 
					
						
							|  |  |  |     assert endpoint["CreatorRequestId"] == created_endpoint["CreatorRequestId"] | 
					
						
							|  |  |  |     assert endpoint["Id"] == created_endpoint["Id"] | 
					
						
							|  |  |  |     assert endpoint["Arn"] == created_endpoint["Arn"] | 
					
						
							|  |  |  |     assert endpoint["Name"] == created_endpoint["Name"] | 
					
						
							|  |  |  |     assert endpoint["SecurityGroupIds"] == created_endpoint["SecurityGroupIds"] | 
					
						
							|  |  |  |     assert endpoint["Direction"] == created_endpoint["Direction"] | 
					
						
							|  |  |  |     assert endpoint["IpAddressCount"] == created_endpoint["IpAddressCount"] | 
					
						
							|  |  |  |     assert endpoint["HostVPCId"] == created_endpoint["HostVPCId"] | 
					
						
							|  |  |  |     assert endpoint["Status"] == "DELETING" | 
					
						
							|  |  |  |     assert "Deleting" in endpoint["StatusMessage"] | 
					
						
							|  |  |  |     assert endpoint["CreationTime"] == created_endpoint["CreationTime"] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-24 13:22:38 -05:00
										 |  |  |     # Verify there are no endpoints or no network interfaces. | 
					
						
							|  |  |  |     response = client.list_resolver_endpoints() | 
					
						
							|  |  |  |     assert len(response["ResolverEndpoints"]) == 0 | 
					
						
							|  |  |  |     result = ec2_client.describe_network_interfaces() | 
					
						
							|  |  |  |     assert len(result["NetworkInterfaces"]) == 0 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-17 15:06:35 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-23 05:00:50 -05:00
										 |  |  | @mock_ec2 | 
					
						
							| 
									
										
										
										
											2021-11-17 15:06:35 -05:00
										 |  |  | @mock_route53resolver | 
					
						
							|  |  |  | def test_route53resolver_bad_delete_resolver_endpoint(): | 
					
						
							|  |  |  |     """Test delete_resolver_endpoint API calls with a bad ID.""" | 
					
						
							|  |  |  |     client = boto3.client("route53resolver", region_name=TEST_REGION) | 
					
						
							| 
									
										
										
										
											2021-11-23 05:00:50 -05:00
										 |  |  |     ec2_client = boto3.client("ec2", region_name=TEST_REGION) | 
					
						
							| 
									
										
										
										
											2022-09-28 09:35:12 +00:00
										 |  |  |     random_num = mock_random.get_random_hex(10) | 
					
						
							| 
									
										
										
										
											2021-11-17 15:06:35 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # Use a resolver endpoint id that is too long. | 
					
						
							|  |  |  |     long_id = "0123456789" * 6 + "xxxxx" | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as exc: | 
					
						
							|  |  |  |         client.delete_resolver_endpoint(ResolverEndpointId=long_id) | 
					
						
							|  |  |  |     err = exc.value.response["Error"] | 
					
						
							|  |  |  |     assert err["Code"] == "ValidationException" | 
					
						
							|  |  |  |     assert "1 validation error detected" in err["Message"] | 
					
						
							|  |  |  |     assert ( | 
					
						
							|  |  |  |         f"Value '{long_id}' at 'resolverEndpointId' failed to satisfy " | 
					
						
							|  |  |  |         f"constraint: Member must have length less than or equal to 64" | 
					
						
							|  |  |  |     ) in err["Message"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Delete a non-existent resolver endpoint. | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as exc: | 
					
						
							|  |  |  |         client.delete_resolver_endpoint(ResolverEndpointId=random_num) | 
					
						
							|  |  |  |     err = exc.value.response["Error"] | 
					
						
							|  |  |  |     assert err["Code"] == "ResourceNotFoundException" | 
					
						
							|  |  |  |     assert f"Resolver endpoint with ID '{random_num}' does not exist" in err["Message"] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-23 05:00:50 -05:00
										 |  |  |     # Create an endpoint and a rule referencing that endpoint.  Verify the | 
					
						
							|  |  |  |     # endpoint can't be deleted due to that rule. | 
					
						
							|  |  |  |     endpoint = create_test_endpoint(client, ec2_client) | 
					
						
							|  |  |  |     resolver_rule = client.create_resolver_rule( | 
					
						
							|  |  |  |         CreatorRequestId=random_num, | 
					
						
							|  |  |  |         RuleType="FORWARD", | 
					
						
							|  |  |  |         DomainName=f"X{random_num}.com", | 
					
						
							|  |  |  |         ResolverEndpointId=endpoint["Id"], | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as exc: | 
					
						
							|  |  |  |         client.delete_resolver_endpoint(ResolverEndpointId=endpoint["Id"]) | 
					
						
							|  |  |  |     err = exc.value.response["Error"] | 
					
						
							|  |  |  |     assert err["Code"] == "InvalidRequestException" | 
					
						
							|  |  |  |     assert ( | 
					
						
							|  |  |  |         f"Cannot delete resolver endpoint unless its related resolver rules " | 
					
						
							|  |  |  |         f"are deleted.  The following rules still exist for this resolver " | 
					
						
							|  |  |  |         f"endpoint:  {resolver_rule['ResolverRule']['Id']}" | 
					
						
							|  |  |  |     ) in err["Message"] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-17 15:06:35 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | @mock_ec2 | 
					
						
							|  |  |  | @mock_route53resolver | 
					
						
							|  |  |  | def test_route53resolver_get_resolver_endpoint(): | 
					
						
							|  |  |  |     """Test good get_resolver_endpoint API calls.""" | 
					
						
							|  |  |  |     client = boto3.client("route53resolver", region_name=TEST_REGION) | 
					
						
							|  |  |  |     ec2_client = boto3.client("ec2", region_name=TEST_REGION) | 
					
						
							|  |  |  |     created_endpoint = create_test_endpoint(client, ec2_client) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Now get the resolver endpoint and verify the response. | 
					
						
							|  |  |  |     response = client.get_resolver_endpoint(ResolverEndpointId=created_endpoint["Id"]) | 
					
						
							|  |  |  |     endpoint = response["ResolverEndpoint"] | 
					
						
							|  |  |  |     assert endpoint["CreatorRequestId"] == created_endpoint["CreatorRequestId"] | 
					
						
							|  |  |  |     assert endpoint["Id"] == created_endpoint["Id"] | 
					
						
							|  |  |  |     assert endpoint["Arn"] == created_endpoint["Arn"] | 
					
						
							|  |  |  |     assert endpoint["Name"] == created_endpoint["Name"] | 
					
						
							|  |  |  |     assert endpoint["SecurityGroupIds"] == created_endpoint["SecurityGroupIds"] | 
					
						
							|  |  |  |     assert endpoint["Direction"] == created_endpoint["Direction"] | 
					
						
							|  |  |  |     assert endpoint["IpAddressCount"] == created_endpoint["IpAddressCount"] | 
					
						
							|  |  |  |     assert endpoint["HostVPCId"] == created_endpoint["HostVPCId"] | 
					
						
							|  |  |  |     assert endpoint["Status"] == created_endpoint["Status"] | 
					
						
							|  |  |  |     assert endpoint["StatusMessage"] == created_endpoint["StatusMessage"] | 
					
						
							|  |  |  |     assert endpoint["CreationTime"] == created_endpoint["CreationTime"] | 
					
						
							|  |  |  |     assert endpoint["ModificationTime"] == created_endpoint["ModificationTime"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_route53resolver | 
					
						
							|  |  |  | def test_route53resolver_bad_get_resolver_endpoint(): | 
					
						
							|  |  |  |     """Test get_resolver_endpoint API calls with a bad ID.""" | 
					
						
							|  |  |  |     client = boto3.client("route53resolver", region_name=TEST_REGION) | 
					
						
							| 
									
										
										
										
											2022-09-28 09:35:12 +00:00
										 |  |  |     random_num = mock_random.get_random_hex(10) | 
					
						
							| 
									
										
										
										
											2021-11-17 15:06:35 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # Use a resolver endpoint id that is too long. | 
					
						
							|  |  |  |     long_id = "0123456789" * 6 + "xxxxx" | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as exc: | 
					
						
							|  |  |  |         client.get_resolver_endpoint(ResolverEndpointId=long_id) | 
					
						
							|  |  |  |     err = exc.value.response["Error"] | 
					
						
							|  |  |  |     assert err["Code"] == "ValidationException" | 
					
						
							|  |  |  |     assert "1 validation error detected" in err["Message"] | 
					
						
							|  |  |  |     assert ( | 
					
						
							|  |  |  |         f"Value '{long_id}' at 'resolverEndpointId' failed to satisfy " | 
					
						
							|  |  |  |         f"constraint: Member must have length less than or equal to 64" | 
					
						
							|  |  |  |     ) in err["Message"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Delete a non-existent resolver endpoint. | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as exc: | 
					
						
							|  |  |  |         client.get_resolver_endpoint(ResolverEndpointId=random_num) | 
					
						
							|  |  |  |     err = exc.value.response["Error"] | 
					
						
							|  |  |  |     assert err["Code"] == "ResourceNotFoundException" | 
					
						
							|  |  |  |     assert f"Resolver endpoint with ID '{random_num}' does not exist" in err["Message"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ec2 | 
					
						
							|  |  |  | @mock_route53resolver | 
					
						
							|  |  |  | def test_route53resolver_update_resolver_endpoint(): | 
					
						
							|  |  |  |     """Test good update_resolver_endpoint API calls.""" | 
					
						
							|  |  |  |     client = boto3.client("route53resolver", region_name=TEST_REGION) | 
					
						
							|  |  |  |     ec2_client = boto3.client("ec2", region_name=TEST_REGION) | 
					
						
							|  |  |  |     created_endpoint = create_test_endpoint(client, ec2_client) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Now update the resolver endpoint name and verify the response. | 
					
						
							| 
									
										
										
										
											2022-09-28 09:35:12 +00:00
										 |  |  |     new_name = "NewName" + mock_random.get_random_hex(6) | 
					
						
							| 
									
										
										
										
											2021-11-17 15:06:35 -05:00
										 |  |  |     response = client.update_resolver_endpoint( | 
					
						
							| 
									
										
										
										
											2022-03-10 13:39:59 -01:00
										 |  |  |         ResolverEndpointId=created_endpoint["Id"], Name=new_name | 
					
						
							| 
									
										
										
										
											2021-11-17 15:06:35 -05:00
										 |  |  |     ) | 
					
						
							|  |  |  |     endpoint = response["ResolverEndpoint"] | 
					
						
							|  |  |  |     assert endpoint["CreatorRequestId"] == created_endpoint["CreatorRequestId"] | 
					
						
							|  |  |  |     assert endpoint["Id"] == created_endpoint["Id"] | 
					
						
							|  |  |  |     assert endpoint["Arn"] == created_endpoint["Arn"] | 
					
						
							|  |  |  |     assert endpoint["Name"] == new_name | 
					
						
							|  |  |  |     assert endpoint["SecurityGroupIds"] == created_endpoint["SecurityGroupIds"] | 
					
						
							|  |  |  |     assert endpoint["Direction"] == created_endpoint["Direction"] | 
					
						
							|  |  |  |     assert endpoint["IpAddressCount"] == created_endpoint["IpAddressCount"] | 
					
						
							|  |  |  |     assert endpoint["HostVPCId"] == created_endpoint["HostVPCId"] | 
					
						
							|  |  |  |     assert endpoint["Status"] == created_endpoint["Status"] | 
					
						
							|  |  |  |     assert endpoint["StatusMessage"] == created_endpoint["StatusMessage"] | 
					
						
							|  |  |  |     assert endpoint["CreationTime"] == created_endpoint["CreationTime"] | 
					
						
							|  |  |  |     assert endpoint["ModificationTime"] != created_endpoint["ModificationTime"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_route53resolver | 
					
						
							|  |  |  | def test_route53resolver_bad_update_resolver_endpoint(): | 
					
						
							|  |  |  |     """Test update_resolver_endpoint API calls with a bad ID.""" | 
					
						
							|  |  |  |     client = boto3.client("route53resolver", region_name=TEST_REGION) | 
					
						
							| 
									
										
										
										
											2022-09-28 09:35:12 +00:00
										 |  |  |     random_num = mock_random.get_random_hex(10) | 
					
						
							|  |  |  |     random_name = "Z" + mock_random.get_random_hex(10) | 
					
						
							| 
									
										
										
										
											2021-11-17 15:06:35 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # Use a resolver endpoint id that is too long. | 
					
						
							|  |  |  |     long_id = "0123456789" * 6 + "xxxxx" | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as exc: | 
					
						
							|  |  |  |         client.update_resolver_endpoint(ResolverEndpointId=long_id, Name=random_name) | 
					
						
							|  |  |  |     err = exc.value.response["Error"] | 
					
						
							|  |  |  |     assert err["Code"] == "ValidationException" | 
					
						
							|  |  |  |     assert "1 validation error detected" in err["Message"] | 
					
						
							|  |  |  |     assert ( | 
					
						
							|  |  |  |         f"Value '{long_id}' at 'resolverEndpointId' failed to satisfy " | 
					
						
							|  |  |  |         f"constraint: Member must have length less than or equal to 64" | 
					
						
							|  |  |  |     ) in err["Message"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Delete a non-existent resolver endpoint. | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as exc: | 
					
						
							|  |  |  |         client.update_resolver_endpoint(ResolverEndpointId=random_num, Name=random_name) | 
					
						
							|  |  |  |     err = exc.value.response["Error"] | 
					
						
							|  |  |  |     assert err["Code"] == "ResourceNotFoundException" | 
					
						
							|  |  |  |     assert f"Resolver endpoint with ID '{random_num}' does not exist" in err["Message"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ec2 | 
					
						
							|  |  |  | @mock_route53resolver | 
					
						
							|  |  |  | def test_route53resolver_list_resolver_endpoint_ip_addresses(): | 
					
						
							|  |  |  |     """Test good list_resolver_endpoint_ip_addresses API calls.""" | 
					
						
							|  |  |  |     client = boto3.client("route53resolver", region_name=TEST_REGION) | 
					
						
							|  |  |  |     ec2_client = boto3.client("ec2", region_name=TEST_REGION) | 
					
						
							| 
									
										
										
										
											2022-09-28 09:35:12 +00:00
										 |  |  |     random_num = mock_random.get_random_hex(10) | 
					
						
							| 
									
										
										
										
											2021-11-17 15:06:35 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     subnet_ids = create_subnets(ec2_client, create_vpc(ec2_client)) | 
					
						
							|  |  |  |     response = client.create_resolver_endpoint( | 
					
						
							|  |  |  |         CreatorRequestId="B" + random_num, | 
					
						
							|  |  |  |         Name="B" + random_num, | 
					
						
							|  |  |  |         SecurityGroupIds=[create_security_group(ec2_client)], | 
					
						
							|  |  |  |         Direction="INBOUND", | 
					
						
							|  |  |  |         IpAddresses=[ | 
					
						
							|  |  |  |             {"SubnetId": subnet_ids[0], "Ip": "10.0.1.200"}, | 
					
						
							|  |  |  |             {"SubnetId": subnet_ids[1], "Ip": "10.0.0.20"}, | 
					
						
							|  |  |  |             {"SubnetId": subnet_ids[0], "Ip": "10.0.1.201"}, | 
					
						
							|  |  |  |         ], | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     endpoint_id = response["ResolverEndpoint"]["Id"] | 
					
						
							|  |  |  |     response = client.list_resolver_endpoint_ip_addresses( | 
					
						
							|  |  |  |         ResolverEndpointId=endpoint_id | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     assert len(response["IpAddresses"]) == 3 | 
					
						
							|  |  |  |     assert response["MaxResults"] == 10 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Set max_results to return 1 address, use next_token to get remaining. | 
					
						
							|  |  |  |     response = client.list_resolver_endpoint_ip_addresses( | 
					
						
							|  |  |  |         ResolverEndpointId=endpoint_id, MaxResults=1 | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     ip_addresses = response["IpAddresses"] | 
					
						
							|  |  |  |     assert len(ip_addresses) == 1 | 
					
						
							|  |  |  |     assert response["MaxResults"] == 1 | 
					
						
							|  |  |  |     assert "NextToken" in response | 
					
						
							|  |  |  |     assert ip_addresses[0]["IpId"].startswith("rni-") | 
					
						
							|  |  |  |     assert ip_addresses[0]["SubnetId"] == subnet_ids[0] | 
					
						
							|  |  |  |     assert ip_addresses[0]["Ip"] == "10.0.1.200" | 
					
						
							|  |  |  |     assert ip_addresses[0]["Status"] == "ATTACHED" | 
					
						
							|  |  |  |     assert ip_addresses[0]["StatusMessage"] == "This IP address is operational." | 
					
						
							|  |  |  |     assert "CreationTime" in ip_addresses[0] | 
					
						
							|  |  |  |     assert "ModificationTime" in ip_addresses[0] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     response = client.list_resolver_endpoint_ip_addresses( | 
					
						
							|  |  |  |         ResolverEndpointId=endpoint_id, NextToken=response["NextToken"] | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     assert len(response["IpAddresses"]) == 2 | 
					
						
							|  |  |  |     assert response["MaxResults"] == 10 | 
					
						
							|  |  |  |     assert "NextToken" not in response | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ec2 | 
					
						
							|  |  |  | @mock_route53resolver | 
					
						
							|  |  |  | def test_route53resolver_bad_list_resolver_endpoint_ip_addresses(): | 
					
						
							|  |  |  |     """Test bad list_resolver_endpoint_ip_addresses API calls.""" | 
					
						
							|  |  |  |     client = boto3.client("route53resolver", region_name=TEST_REGION) | 
					
						
							|  |  |  |     ec2_client = boto3.client("ec2", region_name=TEST_REGION) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Bad endpoint id. | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as exc: | 
					
						
							|  |  |  |         client.list_resolver_endpoint_ip_addresses(ResolverEndpointId="foo") | 
					
						
							|  |  |  |     err = exc.value.response["Error"] | 
					
						
							|  |  |  |     assert err["Code"] == "ResourceNotFoundException" | 
					
						
							|  |  |  |     assert "Resolver endpoint with ID 'foo' does not exist" in err["Message"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Good endpoint id, but bad max_results. | 
					
						
							| 
									
										
										
										
											2022-09-28 09:35:12 +00:00
										 |  |  |     random_num = mock_random.get_random_hex(10) | 
					
						
							| 
									
										
										
										
											2021-11-17 15:06:35 -05:00
										 |  |  |     response = create_test_endpoint(client, ec2_client, name=f"A-{random_num}") | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as exc: | 
					
						
							|  |  |  |         client.list_resolver_endpoint_ip_addresses( | 
					
						
							|  |  |  |             ResolverEndpointId=response["Id"], MaxResults=250 | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |     err = exc.value.response["Error"] | 
					
						
							|  |  |  |     assert err["Code"] == "ValidationException" | 
					
						
							|  |  |  |     assert "1 validation error detected" in err["Message"] | 
					
						
							|  |  |  |     assert ( | 
					
						
							|  |  |  |         "Value '250' at 'maxResults' failed to satisfy constraint: Member " | 
					
						
							|  |  |  |         "must have length less than or equal to 100" | 
					
						
							|  |  |  |     ) in err["Message"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ec2 | 
					
						
							|  |  |  | @mock_route53resolver | 
					
						
							|  |  |  | def test_route53resolver_list_resolver_endpoints(): | 
					
						
							| 
									
										
										
										
											2021-11-22 12:57:07 -05:00
										 |  |  |     """Test good list_resolver_endpoints API calls.""" | 
					
						
							| 
									
										
										
										
											2021-11-17 15:06:35 -05:00
										 |  |  |     client = boto3.client("route53resolver", region_name=TEST_REGION) | 
					
						
							|  |  |  |     ec2_client = boto3.client("ec2", region_name=TEST_REGION) | 
					
						
							| 
									
										
										
										
											2022-09-28 09:35:12 +00:00
										 |  |  |     random_num = mock_random.get_random_hex(10) | 
					
						
							| 
									
										
										
										
											2021-11-17 15:06:35 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # List endpoints when there are none. | 
					
						
							|  |  |  |     response = client.list_resolver_endpoints() | 
					
						
							|  |  |  |     assert len(response["ResolverEndpoints"]) == 0 | 
					
						
							|  |  |  |     assert response["MaxResults"] == 10 | 
					
						
							|  |  |  |     assert "NextToken" not in response | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Create 5 endpoints, verify all 5 are listed when no filters, max_results. | 
					
						
							|  |  |  |     for idx in range(4): | 
					
						
							|  |  |  |         create_test_endpoint(client, ec2_client, name=f"A{idx}-{random_num}") | 
					
						
							|  |  |  |     response = client.list_resolver_endpoints() | 
					
						
							|  |  |  |     endpoints = response["ResolverEndpoints"] | 
					
						
							|  |  |  |     assert len(endpoints) == 4 | 
					
						
							|  |  |  |     assert response["MaxResults"] == 10 | 
					
						
							|  |  |  |     for idx in range(4): | 
					
						
							|  |  |  |         assert endpoints[idx]["Name"].startswith(f"A{idx}") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Set max_results to return 1 endpoint, use next_token to get remaining 3. | 
					
						
							|  |  |  |     response = client.list_resolver_endpoints(MaxResults=1) | 
					
						
							|  |  |  |     endpoints = response["ResolverEndpoints"] | 
					
						
							|  |  |  |     assert len(endpoints) == 1 | 
					
						
							|  |  |  |     assert response["MaxResults"] == 1 | 
					
						
							|  |  |  |     assert "NextToken" in response | 
					
						
							|  |  |  |     assert endpoints[0]["Name"].startswith("A0") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     response = client.list_resolver_endpoints(NextToken=response["NextToken"]) | 
					
						
							|  |  |  |     endpoints = response["ResolverEndpoints"] | 
					
						
							|  |  |  |     assert len(endpoints) == 3 | 
					
						
							|  |  |  |     assert response["MaxResults"] == 10 | 
					
						
							|  |  |  |     assert "NextToken" not in response | 
					
						
							|  |  |  |     for idx, endpoint in enumerate(endpoints): | 
					
						
							|  |  |  |         assert endpoint["Name"].startswith(f"A{idx + 1}") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-19 08:57:54 -05:00
										 |  |  | @mock_ec2 | 
					
						
							|  |  |  | @mock_route53resolver | 
					
						
							|  |  |  | def test_route53resolver_list_resolver_endpoints_filters(): | 
					
						
							| 
									
										
										
										
											2021-11-22 12:57:07 -05:00
										 |  |  |     """Test good list_resolver_endpoints API calls that use filters.""" | 
					
						
							| 
									
										
										
										
											2021-11-19 08:57:54 -05:00
										 |  |  |     client = boto3.client("route53resolver", region_name=TEST_REGION) | 
					
						
							|  |  |  |     ec2_client = boto3.client("ec2", region_name=TEST_REGION) | 
					
						
							| 
									
										
										
										
											2022-09-28 09:35:12 +00:00
										 |  |  |     random_num = mock_random.get_random_hex(10) | 
					
						
							| 
									
										
										
										
											2021-11-19 08:57:54 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # Create some endpoints for testing purposes | 
					
						
							|  |  |  |     security_group_id = create_security_group(ec2_client) | 
					
						
							|  |  |  |     vpc_id = create_vpc(ec2_client) | 
					
						
							|  |  |  |     subnet_ids = create_subnets(ec2_client, vpc_id) | 
					
						
							|  |  |  |     ip0_values = ["10.0.1.201", "10.0.1.202", "10.0.1.203", "10.0.1.204"] | 
					
						
							|  |  |  |     ip1_values = ["10.0.0.21", "10.0.0.22", "10.0.0.23", "10.0.0.24"] | 
					
						
							|  |  |  |     endpoints = [] | 
					
						
							|  |  |  |     for idx in range(1, 5): | 
					
						
							|  |  |  |         ip_addrs = [ | 
					
						
							|  |  |  |             {"SubnetId": subnet_ids[0], "Ip": "10.0.1.200"}, | 
					
						
							|  |  |  |             {"SubnetId": subnet_ids[1], "Ip": "10.0.0.20"}, | 
					
						
							|  |  |  |             {"SubnetId": subnet_ids[0], "Ip": ip0_values[idx - 1]}, | 
					
						
							|  |  |  |             {"SubnetId": subnet_ids[1], "Ip": ip1_values[idx - 1]}, | 
					
						
							|  |  |  |         ] | 
					
						
							|  |  |  |         response = client.create_resolver_endpoint( | 
					
						
							|  |  |  |             CreatorRequestId=f"F{idx}-{random_num}", | 
					
						
							|  |  |  |             Name=f"F{idx}-{random_num}", | 
					
						
							|  |  |  |             SecurityGroupIds=[security_group_id], | 
					
						
							|  |  |  |             Direction="INBOUND" if idx % 2 else "OUTBOUND", | 
					
						
							|  |  |  |             IpAddresses=ip_addrs, | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         endpoints.append(response["ResolverEndpoint"]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Try all the valid filter names, including some of the old style names. | 
					
						
							|  |  |  |     response = client.list_resolver_endpoints( | 
					
						
							|  |  |  |         Filters=[{"Name": "CreatorRequestId", "Values": [f"F3-{random_num}"]}] | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     assert len(response["ResolverEndpoints"]) == 1 | 
					
						
							|  |  |  |     assert response["ResolverEndpoints"][0]["CreatorRequestId"] == f"F3-{random_num}" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     response = client.list_resolver_endpoints( | 
					
						
							|  |  |  |         Filters=[ | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 "Name": "CREATOR_REQUEST_ID", | 
					
						
							|  |  |  |                 "Values": [f"F2-{random_num}", f"F4-{random_num}"], | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         ] | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     assert len(response["ResolverEndpoints"]) == 2 | 
					
						
							|  |  |  |     assert response["ResolverEndpoints"][0]["CreatorRequestId"] == f"F2-{random_num}" | 
					
						
							|  |  |  |     assert response["ResolverEndpoints"][1]["CreatorRequestId"] == f"F4-{random_num}" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     response = client.list_resolver_endpoints( | 
					
						
							|  |  |  |         Filters=[{"Name": "Direction", "Values": ["INBOUND"]}] | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     assert len(response["ResolverEndpoints"]) == 2 | 
					
						
							|  |  |  |     assert response["ResolverEndpoints"][0]["CreatorRequestId"] == f"F1-{random_num}" | 
					
						
							|  |  |  |     assert response["ResolverEndpoints"][1]["CreatorRequestId"] == f"F3-{random_num}" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     response = client.list_resolver_endpoints( | 
					
						
							|  |  |  |         Filters=[{"Name": "HostVPCId", "Values": [vpc_id]}] | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     assert len(response["ResolverEndpoints"]) == 4 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     response = client.list_resolver_endpoints( | 
					
						
							|  |  |  |         Filters=[{"Name": "IpAddressCount", "Values": ["4"]}] | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     assert len(response["ResolverEndpoints"]) == 4 | 
					
						
							| 
									
										
										
										
											2021-11-22 12:57:07 -05:00
										 |  |  |     response = client.list_resolver_endpoints( | 
					
						
							|  |  |  |         Filters=[{"Name": "IpAddressCount", "Values": ["0", "7"]}] | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     assert len(response["ResolverEndpoints"]) == 0 | 
					
						
							| 
									
										
										
										
											2021-11-19 08:57:54 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     response = client.list_resolver_endpoints( | 
					
						
							|  |  |  |         Filters=[{"Name": "Name", "Values": [f"F1-{random_num}"]}] | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     assert len(response["ResolverEndpoints"]) == 1 | 
					
						
							|  |  |  |     assert response["ResolverEndpoints"][0]["Name"] == f"F1-{random_num}" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     response = client.list_resolver_endpoints( | 
					
						
							|  |  |  |         Filters=[ | 
					
						
							|  |  |  |             {"Name": "HOST_VPC_ID", "Values": [vpc_id]}, | 
					
						
							|  |  |  |             {"Name": "DIRECTION", "Values": ["INBOUND"]}, | 
					
						
							|  |  |  |             {"Name": "NAME", "Values": [f"F3-{random_num}"]}, | 
					
						
							|  |  |  |         ] | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     assert len(response["ResolverEndpoints"]) == 1 | 
					
						
							|  |  |  |     assert response["ResolverEndpoints"][0]["Name"] == f"F3-{random_num}" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     response = client.list_resolver_endpoints( | 
					
						
							|  |  |  |         Filters=[{"Name": "SecurityGroupIds", "Values": [security_group_id]}] | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     assert len(response["ResolverEndpoints"]) == 4 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     response = client.list_resolver_endpoints( | 
					
						
							|  |  |  |         Filters=[{"Name": "Status", "Values": ["OPERATIONAL"]}] | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     assert len(response["ResolverEndpoints"]) == 4 | 
					
						
							|  |  |  |     response = client.list_resolver_endpoints( | 
					
						
							|  |  |  |         Filters=[{"Name": "Status", "Values": ["CREATING"]}] | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     assert len(response["ResolverEndpoints"]) == 0 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_route53resolver | 
					
						
							|  |  |  | def test_route53resolver_bad_list_resolver_endpoints_filters(): | 
					
						
							| 
									
										
										
										
											2021-11-22 12:57:07 -05:00
										 |  |  |     """Test bad list_resolver_endpoints API calls that use filters.""" | 
					
						
							| 
									
										
										
										
											2021-11-19 08:57:54 -05:00
										 |  |  |     client = boto3.client("route53resolver", region_name=TEST_REGION) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # botocore barfs on an empty "Values": | 
					
						
							|  |  |  |     # TypeError: list_resolver_endpoints() only accepts keyword arguments. | 
					
						
							|  |  |  |     # client.list_resolver_endpoints([{"Name": "Direction", "Values": []}]) | 
					
						
							|  |  |  |     # client.list_resolver_endpoints([{"Values": []}]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as exc: | 
					
						
							|  |  |  |         client.list_resolver_endpoints(Filters=[{"Name": "foo", "Values": ["bar"]}]) | 
					
						
							|  |  |  |     err = exc.value.response["Error"] | 
					
						
							|  |  |  |     assert err["Code"] == "InvalidParameterException" | 
					
						
							|  |  |  |     assert "The filter 'foo' is invalid" in err["Message"] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-22 12:57:07 -05:00
										 |  |  |     with pytest.raises(ClientError) as exc: | 
					
						
							|  |  |  |         client.list_resolver_endpoints( | 
					
						
							|  |  |  |             Filters=[{"Name": "HostVpcId", "Values": ["bar"]}] | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |     err = exc.value.response["Error"] | 
					
						
							|  |  |  |     assert err["Code"] == "InvalidParameterException" | 
					
						
							|  |  |  |     assert "The filter 'HostVpcId' is invalid" in err["Message"] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-19 08:57:54 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-17 15:06:35 -05:00
										 |  |  | @mock_ec2 | 
					
						
							|  |  |  | @mock_route53resolver | 
					
						
							|  |  |  | def test_route53resolver_bad_list_resolver_endpoints(): | 
					
						
							|  |  |  |     """Test bad list_resolver_endpoints API calls.""" | 
					
						
							|  |  |  |     client = boto3.client("route53resolver", region_name=TEST_REGION) | 
					
						
							|  |  |  |     ec2_client = boto3.client("ec2", region_name=TEST_REGION) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Bad max_results. | 
					
						
							| 
									
										
										
										
											2022-09-28 09:35:12 +00:00
										 |  |  |     random_num = mock_random.get_random_hex(10) | 
					
						
							| 
									
										
										
										
											2021-11-17 15:06:35 -05:00
										 |  |  |     create_test_endpoint(client, ec2_client, name=f"A-{random_num}") | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as exc: | 
					
						
							|  |  |  |         client.list_resolver_endpoints(MaxResults=250) | 
					
						
							|  |  |  |     err = exc.value.response["Error"] | 
					
						
							|  |  |  |     assert err["Code"] == "ValidationException" | 
					
						
							|  |  |  |     assert "1 validation error detected" in err["Message"] | 
					
						
							|  |  |  |     assert ( | 
					
						
							|  |  |  |         "Value '250' at 'maxResults' failed to satisfy constraint: Member " | 
					
						
							|  |  |  |         "must have length less than or equal to 100" | 
					
						
							|  |  |  |     ) in err["Message"] | 
					
						
							| 
									
										
										
										
											2022-06-25 21:39:58 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ec2 | 
					
						
							|  |  |  | @mock_route53resolver | 
					
						
							|  |  |  | def test_associate_resolver_endpoint_ip_address(): | 
					
						
							|  |  |  |     client = boto3.client("route53resolver", region_name=TEST_REGION) | 
					
						
							|  |  |  |     ec2_client = boto3.client("ec2", region_name=TEST_REGION) | 
					
						
							|  |  |  |     # create subnet | 
					
						
							|  |  |  |     vpc_id = create_vpc(ec2_client) | 
					
						
							|  |  |  |     subnet = ec2_client.create_subnet( | 
					
						
							|  |  |  |         VpcId=vpc_id, CidrBlock="10.0.2.0/24", AvailabilityZone=f"{TEST_REGION}a" | 
					
						
							|  |  |  |     )["Subnet"] | 
					
						
							|  |  |  |     # create resolver | 
					
						
							| 
									
										
										
										
											2022-09-28 09:35:12 +00:00
										 |  |  |     random_num = mock_random.get_random_hex(10) | 
					
						
							| 
									
										
										
										
											2022-06-25 21:39:58 +00:00
										 |  |  |     resolver = create_test_endpoint(client, ec2_client, name=f"A-{random_num}") | 
					
						
							|  |  |  |     resolver.should.have.key("IpAddressCount").equals(2) | 
					
						
							|  |  |  |     # associate | 
					
						
							|  |  |  |     resp = client.associate_resolver_endpoint_ip_address( | 
					
						
							|  |  |  |         IpAddress={"Ip": "10.0.2.126", "SubnetId": subnet["SubnetId"]}, | 
					
						
							|  |  |  |         ResolverEndpointId=resolver["Id"], | 
					
						
							|  |  |  |     )["ResolverEndpoint"] | 
					
						
							|  |  |  |     resp.should.have.key("Id").equals(resolver["Id"]) | 
					
						
							|  |  |  |     resp.should.have.key("IpAddressCount").equals(3) | 
					
						
							|  |  |  |     resp.should.have.key("SecurityGroupIds").should.have.length_of(1) | 
					
						
							|  |  |  |     # verify ENI was created | 
					
						
							|  |  |  |     enis = ec2_client.describe_network_interfaces()["NetworkInterfaces"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ip_addresses = [eni["PrivateIpAddress"] for eni in enis] | 
					
						
							|  |  |  |     ip_addresses.should.contain("10.0.2.126") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_route53resolver | 
					
						
							|  |  |  | def test_associate_resolver_endpoint_ip_address__invalid_resolver(): | 
					
						
							|  |  |  |     client = boto3.client("route53resolver", region_name=TEST_REGION) | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as exc: | 
					
						
							|  |  |  |         client.associate_resolver_endpoint_ip_address( | 
					
						
							|  |  |  |             IpAddress={"Ip": "notapplicable"}, ResolverEndpointId="unknown" | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |     err = exc.value.response["Error"] | 
					
						
							|  |  |  |     err["Code"].should.equal("ResourceNotFoundException") | 
					
						
							|  |  |  |     err["Message"].should.equal("Resolver endpoint with ID 'unknown' does not exist") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ec2 | 
					
						
							|  |  |  | @mock_route53resolver | 
					
						
							|  |  |  | def test_disassociate_resolver_endpoint_ip_address__using_ip(): | 
					
						
							|  |  |  |     client = boto3.client("route53resolver", region_name=TEST_REGION) | 
					
						
							|  |  |  |     ec2_client = boto3.client("ec2", region_name=TEST_REGION) | 
					
						
							|  |  |  |     # create subnet | 
					
						
							|  |  |  |     vpc_id = create_vpc(ec2_client) | 
					
						
							|  |  |  |     subnet_id = ec2_client.create_subnet( | 
					
						
							|  |  |  |         VpcId=vpc_id, CidrBlock="10.0.2.0/24", AvailabilityZone=f"{TEST_REGION}a" | 
					
						
							|  |  |  |     )["Subnet"]["SubnetId"] | 
					
						
							|  |  |  |     # create resolver | 
					
						
							| 
									
										
										
										
											2022-09-28 09:35:12 +00:00
										 |  |  |     random_num = mock_random.get_random_hex(10) | 
					
						
							| 
									
										
										
										
											2022-06-25 21:39:58 +00:00
										 |  |  |     resolver = create_test_endpoint(client, ec2_client, name=f"A-{random_num}") | 
					
						
							|  |  |  |     # associate | 
					
						
							|  |  |  |     client.associate_resolver_endpoint_ip_address( | 
					
						
							|  |  |  |         IpAddress={"Ip": "10.0.2.126", "SubnetId": subnet_id}, | 
					
						
							|  |  |  |         ResolverEndpointId=resolver["Id"], | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     enis_before = ec2_client.describe_network_interfaces()["NetworkInterfaces"] | 
					
						
							|  |  |  |     # disassociate | 
					
						
							|  |  |  |     client.disassociate_resolver_endpoint_ip_address( | 
					
						
							|  |  |  |         ResolverEndpointId=resolver["Id"], | 
					
						
							|  |  |  |         IpAddress={"SubnetId": subnet_id, "Ip": "10.0.2.126"}, | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     # One ENI was deleted | 
					
						
							|  |  |  |     enis_after = ec2_client.describe_network_interfaces()["NetworkInterfaces"] | 
					
						
							|  |  |  |     (len(enis_after) + 1).should.equal(len(enis_before)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ec2 | 
					
						
							|  |  |  | @mock_route53resolver | 
					
						
							|  |  |  | def test_disassociate_resolver_endpoint_ip_address__using_ipid_and_subnet(): | 
					
						
							|  |  |  |     client = boto3.client("route53resolver", region_name=TEST_REGION) | 
					
						
							|  |  |  |     ec2_client = boto3.client("ec2", region_name=TEST_REGION) | 
					
						
							|  |  |  |     # create subnet | 
					
						
							|  |  |  |     vpc_id = create_vpc(ec2_client) | 
					
						
							|  |  |  |     subnet_id = ec2_client.create_subnet( | 
					
						
							|  |  |  |         VpcId=vpc_id, CidrBlock="10.0.2.0/24", AvailabilityZone=f"{TEST_REGION}a" | 
					
						
							|  |  |  |     )["Subnet"]["SubnetId"] | 
					
						
							|  |  |  |     # create resolver | 
					
						
							| 
									
										
										
										
											2022-09-28 09:35:12 +00:00
										 |  |  |     random_num = mock_random.get_random_hex(10) | 
					
						
							| 
									
										
										
										
											2022-06-25 21:39:58 +00:00
										 |  |  |     resolver = create_test_endpoint(client, ec2_client, name=f"A-{random_num}") | 
					
						
							|  |  |  |     # associate | 
					
						
							|  |  |  |     client.associate_resolver_endpoint_ip_address( | 
					
						
							|  |  |  |         IpAddress={"Ip": "10.0.2.126", "SubnetId": subnet_id}, | 
					
						
							|  |  |  |         ResolverEndpointId=resolver["Id"], | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ip_addresses = client.list_resolver_endpoint_ip_addresses( | 
					
						
							|  |  |  |         ResolverEndpointId=resolver["Id"] | 
					
						
							|  |  |  |     )["IpAddresses"] | 
					
						
							|  |  |  |     ip_id = [ip["IpId"] for ip in ip_addresses if ip["Ip"] == "10.0.2.126"][0] | 
					
						
							|  |  |  |     # disassociate | 
					
						
							|  |  |  |     resp = client.disassociate_resolver_endpoint_ip_address( | 
					
						
							|  |  |  |         ResolverEndpointId=resolver["Id"], | 
					
						
							|  |  |  |         IpAddress={"SubnetId": subnet_id, "IpId": ip_id}, | 
					
						
							|  |  |  |     )["ResolverEndpoint"] | 
					
						
							|  |  |  |     resp.should.have.key("IpAddressCount").equals(2) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ec2 | 
					
						
							|  |  |  | @mock_route53resolver | 
					
						
							|  |  |  | def test_disassociate_resolver_endpoint_ip_address__using_subnet_alone(): | 
					
						
							|  |  |  |     client = boto3.client("route53resolver", region_name=TEST_REGION) | 
					
						
							|  |  |  |     ec2_client = boto3.client("ec2", region_name=TEST_REGION) | 
					
						
							|  |  |  |     # create subnet | 
					
						
							|  |  |  |     vpc_id = create_vpc(ec2_client) | 
					
						
							|  |  |  |     subnet_id = ec2_client.create_subnet( | 
					
						
							|  |  |  |         VpcId=vpc_id, CidrBlock="10.0.2.0/24", AvailabilityZone=f"{TEST_REGION}a" | 
					
						
							|  |  |  |     )["Subnet"]["SubnetId"] | 
					
						
							|  |  |  |     # create resolver | 
					
						
							| 
									
										
										
										
											2022-09-28 09:35:12 +00:00
										 |  |  |     random_num = mock_random.get_random_hex(10) | 
					
						
							| 
									
										
										
										
											2022-06-25 21:39:58 +00:00
										 |  |  |     resolver = create_test_endpoint(client, ec2_client, name=f"A-{random_num}") | 
					
						
							|  |  |  |     # associate | 
					
						
							|  |  |  |     client.associate_resolver_endpoint_ip_address( | 
					
						
							|  |  |  |         IpAddress={"Ip": "10.0.2.126", "SubnetId": subnet_id}, | 
					
						
							|  |  |  |         ResolverEndpointId=resolver["Id"], | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     # disassociate without specifying IP | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as exc: | 
					
						
							|  |  |  |         client.disassociate_resolver_endpoint_ip_address( | 
					
						
							|  |  |  |             ResolverEndpointId=resolver["Id"], IpAddress={"SubnetId": subnet_id} | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |     err = exc.value.response["Error"] | 
					
						
							|  |  |  |     err["Code"].should.equal("InvalidRequestException") | 
					
						
							|  |  |  |     err["Message"].should.equal( | 
					
						
							|  |  |  |         "[RSLVR-00503] Need to specify either the IP ID or both subnet and IP address in order to remove IP address." | 
					
						
							|  |  |  |     ) |