Prep Release 3.1.14 (#5242)

This commit is contained in:
Bert Blommers 2022-06-19 13:43:57 +00:00 committed by GitHub
parent 48186924ae
commit d03891e805
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 497 additions and 292 deletions

View File

@ -1,6 +1,51 @@
Moto Changelog
==============
3.1.14
-----
Docker Digest for 3.1.14: <autopopulateddigest>
New Methods:
* Greengrass:
* create_function_definition()
* create_resource_definition()
* create_function_definition_version()
* create_resource_definition_version()
* create_subscription_definition()
* create_subscription_definition_version()
* delete_function_definition()
* delete_resource_definition()
* delete_subscription_definition()
* get_function_definition()
* get_function_definition_version()
* get_resource_definition()
* get_resource_definition_version()
* get_subscription_definition()
* get_subscription_definition_version()
* list_function_definitions()
* list_function_definition_versions()
* list_resource_definitions()
* list_resource_definition_versions()
* list_subscription_definitions()
* list_subscription_definition_versions()
* update_function_definition()
* update_resource_definition()
* update_subscription_definition()
* EKS:
* list_tags_for_resources()
* tag_resource()
* untag_resource()
* Route53:
* associate_vpc()
* disassociate_vpc_from_hosted_zone()
* update_health_check()
* update_hosted_zone_comment()
Miscellaneous:
* APIGateway:put_integration() now supports the requestParameters-parameter
* EC2:create_route() now validates whether a route already exists
3.1.13
-----
Docker Digest for 3.1.13: _sha256:d7f6c779c79f03b686747ae26b52bdca26fd81a50c6a41a8a6cba50c96982abf_

View File

@ -2114,7 +2114,7 @@
## eks
<details>
<summary>35% implemented</summary>
<summary>44% implemented</summary>
- [ ] associate_encryption_config
- [ ] associate_identity_provider_config
@ -2140,11 +2140,11 @@
- [X] list_fargate_profiles
- [ ] list_identity_provider_configs
- [X] list_nodegroups
- [ ] list_tags_for_resource
- [X] list_tags_for_resource
- [ ] list_updates
- [ ] register_cluster
- [ ] tag_resource
- [ ] untag_resource
- [X] tag_resource
- [X] untag_resource
- [ ] update_addon
- [ ] update_cluster_config
- [ ] update_cluster_version
@ -2867,7 +2867,7 @@
## greengrass
<details>
<summary>17% implemented</summary>
<summary>43% implemented</summary>
- [ ] associate_role_to_group
- [ ] associate_service_role_to_account
@ -2878,26 +2878,26 @@
- [ ] create_deployment
- [X] create_device_definition
- [X] create_device_definition_version
- [ ] create_function_definition
- [ ] create_function_definition_version
- [X] create_function_definition
- [X] create_function_definition_version
- [ ] create_group
- [ ] create_group_certificate_authority
- [ ] create_group_version
- [ ] create_logger_definition
- [ ] create_logger_definition_version
- [ ] create_resource_definition
- [ ] create_resource_definition_version
- [X] create_resource_definition
- [X] create_resource_definition_version
- [ ] create_software_update_job
- [ ] create_subscription_definition
- [ ] create_subscription_definition_version
- [X] create_subscription_definition
- [X] create_subscription_definition_version
- [ ] delete_connector_definition
- [X] delete_core_definition
- [X] delete_device_definition
- [ ] delete_function_definition
- [X] delete_function_definition
- [ ] delete_group
- [ ] delete_logger_definition
- [ ] delete_resource_definition
- [ ] delete_subscription_definition
- [X] delete_resource_definition
- [X] delete_subscription_definition
- [ ] disassociate_role_from_group
- [ ] disassociate_service_role_from_account
- [ ] get_associated_role
@ -2910,19 +2910,19 @@
- [ ] get_deployment_status
- [X] get_device_definition
- [X] get_device_definition_version
- [ ] get_function_definition
- [ ] get_function_definition_version
- [X] get_function_definition
- [X] get_function_definition_version
- [ ] get_group
- [ ] get_group_certificate_authority
- [ ] get_group_certificate_configuration
- [ ] get_group_version
- [ ] get_logger_definition
- [ ] get_logger_definition_version
- [ ] get_resource_definition
- [ ] get_resource_definition_version
- [X] get_resource_definition
- [X] get_resource_definition_version
- [ ] get_service_role_for_account
- [ ] get_subscription_definition
- [ ] get_subscription_definition_version
- [X] get_subscription_definition
- [X] get_subscription_definition_version
- [ ] get_thing_runtime_configuration
- [ ] list_bulk_deployment_detailed_reports
- [ ] list_bulk_deployments
@ -2933,17 +2933,17 @@
- [ ] list_deployments
- [X] list_device_definition_versions
- [X] list_device_definitions
- [ ] list_function_definition_versions
- [ ] list_function_definitions
- [X] list_function_definition_versions
- [X] list_function_definitions
- [ ] list_group_certificate_authorities
- [ ] list_group_versions
- [ ] list_groups
- [ ] list_logger_definition_versions
- [ ] list_logger_definitions
- [ ] list_resource_definition_versions
- [ ] list_resource_definitions
- [ ] list_subscription_definition_versions
- [ ] list_subscription_definitions
- [X] list_resource_definition_versions
- [X] list_resource_definitions
- [X] list_subscription_definition_versions
- [X] list_subscription_definitions
- [ ] list_tags_for_resource
- [ ] reset_deployments
- [ ] start_bulk_deployment
@ -2954,19 +2954,20 @@
- [ ] update_connector_definition
- [X] update_core_definition
- [X] update_device_definition
- [ ] update_function_definition
- [X] update_function_definition
- [ ] update_group
- [ ] update_group_certificate_configuration
- [ ] update_logger_definition
- [ ] update_resource_definition
- [ ] update_subscription_definition
- [X] update_resource_definition
- [X] update_subscription_definition
- [ ] update_thing_runtime_configuration
</details>
## guardduty
<details>
<summary>18% implemented</summary>
<summary>17% implemented</summary>
- [ ] accept_administrator_invitation
- [ ] accept_invitation
- [ ] archive_findings
- [X] create_detector
@ -2987,9 +2988,11 @@
- [ ] describe_organization_configuration
- [ ] describe_publishing_destination
- [ ] disable_organization_admin_account
- [ ] disassociate_from_administrator_account
- [ ] disassociate_from_master_account
- [ ] disassociate_members
- [X] enable_organization_admin_account
- [ ] get_administrator_account
- [X] get_detector
- [X] get_filter
- [ ] get_findings
@ -2999,6 +3002,7 @@
- [ ] get_master_account
- [ ] get_member_detectors
- [ ] get_members
- [ ] get_remaining_free_trial_days
- [ ] get_threat_intel_set
- [ ] get_usage_statistics
- [ ] invite_members
@ -4733,10 +4737,10 @@
## route53
<details>
<summary>34% implemented</summary>
<summary>40% implemented</summary>
- [ ] activate_key_signing_key
- [ ] associate_vpc_with_hosted_zone
- [X] associate_vpc_with_hosted_zone
- [ ] change_cidr_collection
- [X] change_resource_record_sets
- [X] change_tags_for_resource
@ -4761,7 +4765,7 @@
- [ ] delete_traffic_policy_instance
- [ ] delete_vpc_association_authorization
- [ ] disable_hosted_zone_dnssec
- [ ] disassociate_vpc_from_hosted_zone
- [X] disassociate_vpc_from_hosted_zone
- [ ] enable_hosted_zone_dnssec
- [ ] get_account_limit
- [ ] get_change
@ -4801,8 +4805,8 @@
- [ ] list_traffic_policy_versions
- [ ] list_vpc_association_authorizations
- [ ] test_dns_answer
- [ ] update_health_check
- [ ] update_hosted_zone_comment
- [X] update_health_check
- [X] update_hosted_zone_comment
- [ ] update_traffic_policy_comment
- [ ] update_traffic_policy_instance
</details>
@ -5998,6 +6002,7 @@
- compute-optimizer
- connect
- connect-contact-lens
- connectcampaigns
- connectparticipant
- cur
- customer-profiles
@ -6110,6 +6115,7 @@
- qldb-session
- rbin
- rds-data
- redshiftserverless
- resiliencehub
- robomaker
- route53-recovery-cluster

View File

@ -12,6 +12,8 @@
cognito-idp
===========
.. autoclass:: moto.cognitoidp.models.CognitoIdpBackend
|start-h3| Example usage |end-h3|
.. sourcecode:: python
@ -145,10 +147,3 @@ cognito-idp
- [ ] verify_user_attribute
|start-h3| Stable Cognito User Pool Id |end-h3|
In some cases, you need to have reproducible IDs for the user pool.
For example, a single initialization before the start of integration tests.
This behavior can be enabled by passing the environment variable: MOTO_COGNITO_IDP_USER_POOL_ID_STRATEGY=HASH.

View File

@ -50,10 +50,22 @@ eks
- [ ] list_identity_provider_configs
- [X] list_nodegroups
- [X] list_tags_for_resource
This function currently will list tags on an EKS cluster only. It does not list tags from a managed node group
- [ ] list_updates
- [ ] register_cluster
- [X] tag_resource
This function currently will tag an EKS cluster only. It does not tag a managed node group
- [X] untag_resource
This function currently will remove tags on an EKS cluster only. It does not remove tags from a managed node group
- [ ] update_addon
- [ ] update_cluster_config
- [ ] update_cluster_version

View File

@ -34,26 +34,26 @@ greengrass
- [ ] create_deployment
- [X] create_device_definition
- [X] create_device_definition_version
- [ ] create_function_definition
- [ ] create_function_definition_version
- [X] create_function_definition
- [X] create_function_definition_version
- [ ] create_group
- [ ] create_group_certificate_authority
- [ ] create_group_version
- [ ] create_logger_definition
- [ ] create_logger_definition_version
- [ ] create_resource_definition
- [ ] create_resource_definition_version
- [X] create_resource_definition
- [X] create_resource_definition_version
- [ ] create_software_update_job
- [ ] create_subscription_definition
- [ ] create_subscription_definition_version
- [X] create_subscription_definition
- [X] create_subscription_definition_version
- [ ] delete_connector_definition
- [X] delete_core_definition
- [X] delete_device_definition
- [ ] delete_function_definition
- [X] delete_function_definition
- [ ] delete_group
- [ ] delete_logger_definition
- [ ] delete_resource_definition
- [ ] delete_subscription_definition
- [X] delete_resource_definition
- [X] delete_subscription_definition
- [ ] disassociate_role_from_group
- [ ] disassociate_service_role_from_account
- [ ] get_associated_role
@ -66,19 +66,19 @@ greengrass
- [ ] get_deployment_status
- [X] get_device_definition
- [X] get_device_definition_version
- [ ] get_function_definition
- [ ] get_function_definition_version
- [X] get_function_definition
- [X] get_function_definition_version
- [ ] get_group
- [ ] get_group_certificate_authority
- [ ] get_group_certificate_configuration
- [ ] get_group_version
- [ ] get_logger_definition
- [ ] get_logger_definition_version
- [ ] get_resource_definition
- [ ] get_resource_definition_version
- [X] get_resource_definition
- [X] get_resource_definition_version
- [ ] get_service_role_for_account
- [ ] get_subscription_definition
- [ ] get_subscription_definition_version
- [X] get_subscription_definition
- [X] get_subscription_definition_version
- [ ] get_thing_runtime_configuration
- [ ] list_bulk_deployment_detailed_reports
- [ ] list_bulk_deployments
@ -89,17 +89,17 @@ greengrass
- [ ] list_deployments
- [X] list_device_definition_versions
- [X] list_device_definitions
- [ ] list_function_definition_versions
- [ ] list_function_definitions
- [X] list_function_definition_versions
- [X] list_function_definitions
- [ ] list_group_certificate_authorities
- [ ] list_group_versions
- [ ] list_groups
- [ ] list_logger_definition_versions
- [ ] list_logger_definitions
- [ ] list_resource_definition_versions
- [ ] list_resource_definitions
- [ ] list_subscription_definition_versions
- [ ] list_subscription_definitions
- [X] list_resource_definition_versions
- [X] list_resource_definitions
- [X] list_subscription_definition_versions
- [X] list_subscription_definitions
- [ ] list_tags_for_resource
- [ ] reset_deployments
- [ ] start_bulk_deployment
@ -110,11 +110,11 @@ greengrass
- [ ] update_connector_definition
- [X] update_core_definition
- [X] update_device_definition
- [ ] update_function_definition
- [X] update_function_definition
- [ ] update_group
- [ ] update_group_certificate_configuration
- [ ] update_logger_definition
- [ ] update_resource_definition
- [ ] update_subscription_definition
- [X] update_resource_definition
- [X] update_subscription_definition
- [ ] update_thing_runtime_configuration

View File

@ -25,6 +25,7 @@ guardduty
|start-h3| Implemented features for this service |end-h3|
- [ ] accept_administrator_invitation
- [ ] accept_invitation
- [ ] archive_findings
- [X] create_detector
@ -45,9 +46,11 @@ guardduty
- [ ] describe_organization_configuration
- [ ] describe_publishing_destination
- [ ] disable_organization_admin_account
- [ ] disassociate_from_administrator_account
- [ ] disassociate_from_master_account
- [ ] disassociate_members
- [X] enable_organization_admin_account
- [ ] get_administrator_account
- [X] get_detector
- [X] get_filter
- [ ] get_findings
@ -57,6 +60,7 @@ guardduty
- [ ] get_master_account
- [ ] get_member_detectors
- [ ] get_members
- [ ] get_remaining_free_trial_days
- [ ] get_threat_intel_set
- [ ] get_usage_statistics
- [ ] invite_members

View File

@ -26,7 +26,7 @@ route53
|start-h3| Implemented features for this service |end-h3|
- [ ] activate_key_signing_key
- [ ] associate_vpc_with_hosted_zone
- [X] associate_vpc_with_hosted_zone
- [ ] change_cidr_collection
- [X] change_resource_record_sets
- [X] change_tags_for_resource
@ -55,7 +55,7 @@ route53
- [ ] delete_traffic_policy_instance
- [ ] delete_vpc_association_authorization
- [ ] disable_hosted_zone_dnssec
- [ ] disassociate_vpc_from_hosted_zone
- [X] disassociate_vpc_from_hosted_zone
- [ ] enable_hosted_zone_dnssec
- [ ] get_account_limit
- [ ] get_change
@ -111,8 +111,8 @@ route53
- [ ] list_traffic_policy_versions
- [ ] list_vpc_association_authorizations
- [ ] test_dns_answer
- [ ] update_health_check
- [ ] update_hosted_zone_comment
- [X] update_health_check
- [X] update_hosted_zone_comment
- [ ] update_traffic_policy_comment
- [ ] update_traffic_policy_instance

View File

@ -6,3 +6,4 @@ readthedocs-sphinx-search==0.1.1
docker
openapi_spec_validator
PyYAML>=5.1
python-jose[cryptography]>=3.1.0,<4.0.0

View File

@ -831,6 +831,13 @@ class CognitoResourceServer(BaseModel):
class CognitoIdpBackend(BaseBackend):
"""
In some cases, you need to have reproducible IDs for the user pool.
For example, a single initialization before the start of integration tests.
This behavior can be enabled by passing the environment variable: MOTO_COGNITO_IDP_USER_POOL_ID_STRATEGY=HASH.
"""
def __init__(self, region_name, account_id):
super().__init__(region_name, account_id)
self.user_pools = OrderedDict()

View File

@ -470,14 +470,14 @@ class Route53Backend(BaseBackend):
# check if hosted zone exists
self.get_hosted_zone(zone_id)
def associate_vpc(self, zone_id, vpcid, vpcregion):
def associate_vpc_with_hosted_zone(self, zone_id, vpcid, vpcregion):
zone = self.get_hosted_zone(zone_id)
if not zone.private_zone:
raise PublicZoneVPCAssociation()
zone.add_vpc(vpcid, vpcregion)
return zone
def disassociate_vpc(self, zone_id, vpcid):
def disassociate_vpc_from_hosted_zone(self, zone_id, vpcid):
zone = self.get_hosted_zone(zone_id)
if len(zone.vpcs) <= 1:
raise LastVPCAssociation()

View File

@ -151,7 +151,7 @@ class Route53(BaseResponse):
vpcid = vpc.get("VPCId", None)
vpcregion = vpc.get("VPCRegion", None)
route53_backend.associate_vpc(zoneid, vpcid, vpcregion)
route53_backend.associate_vpc_with_hosted_zone(zoneid, vpcid, vpcregion)
template = Template(ASSOCIATE_VPC_RESPONSE)
return 200, headers, template.render(comment=comment)
@ -169,7 +169,7 @@ class Route53(BaseResponse):
vpc = elements.get("DisassociateVPCFromHostedZoneRequest", {}).get("VPC", {})
vpcid = vpc.get("VPCId", None)
route53_backend.disassociate_vpc(zoneid, vpcid)
route53_backend.disassociate_vpc_from_hosted_zone(zoneid, vpcid)
template = Template(DISASSOCIATE_VPC_RESPONSE)
return 200, headers, template.render(comment=comment)

View File

@ -261,7 +261,7 @@ def write_implementation_coverage_to_docs(coverage):
file.write(" ...\n")
file.write("\n\n")
file.write(".. sourcecode:: python\n\n")
file.write(" @mock_all\n")
file.write(" @mock_all()\n")
file.write(" def test_all_supported_services_at_the_same_time():\n")
file.write(" ...\n")
file.write("\n")

View File

@ -161,6 +161,20 @@ def test_get_unknown_hosted_zone():
err["Message"].should.equal("No hosted zone found with ID: unknown")
@mock_route53
def test_update_hosted_zone_comment():
conn = boto3.client("route53", region_name="us-east-1")
response = conn.create_hosted_zone(
Name="testdns.aws.com.", CallerReference=str(hash("foo"))
)
zone_id = response["HostedZone"]["Id"].split("/")[-1]
conn.update_hosted_zone_comment(Id=zone_id, Comment="yolo")
resp = conn.get_hosted_zone(Id=zone_id)["HostedZone"]
resp["Config"].should.have.key("Comment").equals("yolo")
@mock_route53
def test_list_resource_record_set_unknown_zone():
conn = boto3.client("route53", region_name="us-east-1")
@ -188,90 +202,6 @@ def test_list_resource_record_set_unknown_type():
err["Message"].should.equal("Bad Request")
@mock_route53
def test_create_health_check():
conn = boto3.client("route53", region_name="us-east-1")
check = conn.create_health_check(
CallerReference="?",
HealthCheckConfig={
"IPAddress": "10.0.0.25",
"Port": 80,
"Type": "HTTP",
"ResourcePath": "/",
"FullyQualifiedDomainName": "example.com",
"SearchString": "a good response",
"RequestInterval": 10,
"FailureThreshold": 2,
},
)["HealthCheck"]
check.should.have.key("Id").match("[a-z0-9-]+")
check.should.have.key("CallerReference")
check.should.have.key("HealthCheckConfig")
check["HealthCheckConfig"].should.have.key("IPAddress").equal("10.0.0.25")
check["HealthCheckConfig"].should.have.key("Port").equal(80)
check["HealthCheckConfig"].should.have.key("Type").equal("HTTP")
check["HealthCheckConfig"].should.have.key("ResourcePath").equal("/")
check["HealthCheckConfig"].should.have.key("FullyQualifiedDomainName").equal(
"example.com"
)
check["HealthCheckConfig"].should.have.key("SearchString").equal("a good response")
check["HealthCheckConfig"].should.have.key("RequestInterval").equal(10)
check["HealthCheckConfig"].should.have.key("FailureThreshold").equal(2)
check.should.have.key("HealthCheckVersion").equal(1)
@mock_route53
def test_list_health_checks():
conn = boto3.client("route53", region_name="us-east-1")
conn.list_health_checks()["HealthChecks"].should.have.length_of(0)
check = conn.create_health_check(
CallerReference="?",
HealthCheckConfig={
"IPAddress": "10.0.0.25",
"Port": 80,
"Type": "HTTP",
"ResourcePath": "/",
"FullyQualifiedDomainName": "example.com",
"SearchString": "a good response",
"RequestInterval": 10,
"FailureThreshold": 2,
},
)["HealthCheck"]
checks = conn.list_health_checks()["HealthChecks"]
checks.should.have.length_of(1)
checks.should.contain(check)
@mock_route53
def test_delete_health_checks():
conn = boto3.client("route53", region_name="us-east-1")
conn.list_health_checks()["HealthChecks"].should.have.length_of(0)
check = conn.create_health_check(
CallerReference="?",
HealthCheckConfig={
"IPAddress": "10.0.0.25",
"Port": 80,
"Type": "HTTP",
"ResourcePath": "/",
"FullyQualifiedDomainName": "example.com",
"SearchString": "a good response",
"RequestInterval": 10,
"FailureThreshold": 2,
},
)["HealthCheck"]
conn.delete_health_check(HealthCheckId=check["Id"])
checks = conn.list_health_checks()["HealthChecks"]
checks.should.have.length_of(0)
@mock_route53
def test_use_health_check_in_resource_record_set():
conn = boto3.client("route53", region_name="us-east-1")
@ -457,70 +387,6 @@ def test_deleting_latency_route():
cnames[1]["Region"].should.equal("us-west-1")
@mock_ec2
@mock_route53
def test_hosted_zone_private_zone_preserved():
# Create mock VPC so we can get a VPC ID
region = "us-east-1"
ec2c = boto3.client("ec2", region_name=region)
vpc_id = ec2c.create_vpc(CidrBlock="10.1.0.0/16").get("Vpc").get("VpcId")
# Create hosted_zone as a Private VPC Hosted Zone
conn = boto3.client("route53", region_name=region)
new_zone = conn.create_hosted_zone(
Name="testdns.aws.com.",
CallerReference=str(hash("foo")),
HostedZoneConfig=dict(PrivateZone=True, Comment="Test"),
VPC={"VPCRegion": region, "VPCId": vpc_id},
)
zone_id = new_zone["HostedZone"]["Id"].split("/")[-1]
hosted_zone = conn.get_hosted_zone(Id=zone_id)
hosted_zone["HostedZone"]["Config"]["PrivateZone"].should.equal(True)
hosted_zone.should.have.key("VPCs")
hosted_zone["VPCs"].should.have.length_of(1)
hosted_zone["VPCs"][0].should.have.key("VPCId")
hosted_zone["VPCs"][0].should.have.key("VPCRegion")
hosted_zone["VPCs"][0]["VPCId"].should_not.equal(None)
hosted_zone["VPCs"][0]["VPCRegion"].should_not.equal(None)
hosted_zone["VPCs"][0]["VPCId"].should.be.equal(vpc_id)
hosted_zone["VPCs"][0]["VPCRegion"].should.be.equal(region)
hosted_zones = conn.list_hosted_zones()
hosted_zones["HostedZones"][0]["Config"]["PrivateZone"].should.equal(True)
hosted_zones = conn.list_hosted_zones_by_name(DNSName="testdns.aws.com.")
hosted_zones["HostedZones"].should.have.length_of(1)
hosted_zones["HostedZones"][0]["Config"]["PrivateZone"].should.equal(True)
# create_hosted_zone statements with PrivateZone=True,
# but without a _valid_ vpc-id should NOT fail.
zone2_name = "testdns2.aws.com."
no_vpc_zone = conn.create_hosted_zone(
Name=zone2_name,
CallerReference=str(hash("foo")),
HostedZoneConfig=dict(PrivateZone=True, Comment="Test without VPC"),
)
zone_id = no_vpc_zone["HostedZone"]["Id"].split("/")[-1]
hosted_zone = conn.get_hosted_zone(Id=zone_id)
hosted_zone["HostedZone"]["Config"]["PrivateZone"].should.equal(True)
hosted_zone.should.have.key("VPCs")
hosted_zone["VPCs"].should.have.length_of(0)
hosted_zones = conn.list_hosted_zones()
hosted_zones["HostedZones"].should.have.length_of(2)
hosted_zones["HostedZones"][0]["Config"]["PrivateZone"].should.equal(True)
hosted_zones["HostedZones"][1]["Config"]["PrivateZone"].should.equal(True)
hosted_zones = conn.list_hosted_zones_by_name(DNSName=zone2_name)
hosted_zones["HostedZones"].should.have.length_of(1)
hosted_zones["HostedZones"][0]["Config"]["PrivateZone"].should.equal(True)
hosted_zones["HostedZones"][0]["Name"].should.equal(zone2_name)
return
@mock_route53
def test_list_or_change_tags_for_resource_request():
conn = boto3.client("route53", region_name="us-east-1")
@ -737,69 +603,6 @@ def test_list_hosted_zones_by_dns_name():
zones["HostedZones"][3]["Name"].should.equal("test.a.org.")
@mock_ec2
@mock_route53
def test_list_hosted_zones_by_vpc():
# Create mock VPC so we can get a VPC ID
ec2c = boto3.client("ec2", region_name="us-east-1")
vpc_id = ec2c.create_vpc(CidrBlock="10.1.0.0/16").get("Vpc").get("VpcId")
region = "us-east-1"
conn = boto3.client("route53", region_name=region)
zone_b = conn.create_hosted_zone(
Name="test.b.com.",
CallerReference=str(hash("foo")),
HostedZoneConfig=dict(PrivateZone=True, Comment="test com"),
VPC={"VPCRegion": region, "VPCId": vpc_id},
)
zone_id = zone_b["HostedZone"]["Id"].split("/")[2]
response = conn.list_hosted_zones_by_vpc(VPCId=vpc_id, VPCRegion=region)
response.should.have.key("ResponseMetadata")
response.should.have.key("HostedZoneSummaries")
response["HostedZoneSummaries"].should.have.length_of(1)
response["HostedZoneSummaries"][0].should.have.key("HostedZoneId")
retured_zone = response["HostedZoneSummaries"][0]
retured_zone["HostedZoneId"].should.equal(zone_id)
retured_zone["Name"].should.equal(zone_b["HostedZone"]["Name"])
@mock_ec2
@mock_route53
def test_list_hosted_zones_by_vpc_with_multiple_vpcs():
# Create mock VPC so we can get a VPC ID
ec2c = boto3.client("ec2", region_name="us-east-1")
vpc_id = ec2c.create_vpc(CidrBlock="10.1.0.0/16").get("Vpc").get("VpcId")
region = "us-east-1"
# Create 3 Zones associate with the VPC.
zones = {}
conn = boto3.client("route53", region_name=region)
for zone in ["a", "b", "c"]:
zone_name = f"test.{zone}.com."
zones[zone] = conn.create_hosted_zone(
Name=zone_name,
CallerReference=str(hash("foo")),
HostedZoneConfig=dict(PrivateZone=True, Comment=f"test {zone} com"),
VPC={"VPCRegion": region, "VPCId": vpc_id},
)
# List the zones associated with this vpc
response = conn.list_hosted_zones_by_vpc(VPCId=vpc_id, VPCRegion=region)
response.should.have.key("ResponseMetadata")
response.should.have.key("HostedZoneSummaries")
response["HostedZoneSummaries"].should.have.length_of(3)
# Loop through all zone summaries and verify they match what was created
for summary in response["HostedZoneSummaries"]:
# use the zone name as the index
index = summary["Name"].split(".")[1]
zone_id = zones[index]["HostedZone"]["Id"].split("/")[2]
summary.should.have.key("HostedZoneId")
summary["HostedZoneId"].should.equal(zone_id)
summary.should.have.key("Name")
summary["Name"].should.equal(zones[index]["HostedZone"]["Name"])
@mock_route53
def test_change_resource_record_sets_crud_valid():
conn = boto3.client("route53", region_name="us-east-1")
@ -1568,3 +1371,14 @@ def test_list_resource_recordset_pagination():
response.should.have.key("MaxItems").equals("300")
response.shouldnt.have.key("NextRecordName")
response.shouldnt.have.key("NextRecordType")
@mock_route53
def test_get_dns_sec():
client = boto3.client("route53", region_name="us-east-1")
hosted_zone_id = client.create_hosted_zone(
Name="testdns.aws.com.", CallerReference=str(hash("foo"))
)["HostedZone"]["Id"]
dns_sec = client.get_dnssec(HostedZoneId=hosted_zone_id)
dns_sec.should.have.key("Status").equals({"ServeSignature": "NOT_SIGNING"})

View File

@ -59,6 +59,7 @@ def test_create_health_check_with_additional_options():
"Type": "HTTP",
"ResourcePath": "/",
"FullyQualifiedDomainName": "example.com",
"SearchString": "a good response",
"RequestInterval": 10,
"FailureThreshold": 2,
"MeasureLatency": True,
@ -73,9 +74,11 @@ def test_create_health_check_with_additional_options():
check.should.have.key("CallerReference").being.equal(
"test-route53-health-HealthCheck-asdf"
)
check.should.have.key("HealthCheckVersion").equal(1)
check.should.have.key("HealthCheckConfig")
#
config = check["HealthCheckConfig"]
check["HealthCheckConfig"].should.have.key("SearchString").equal("a good response")
config.should.have.key("MeasureLatency").being.equal(True)
config.should.have.key("Inverted").being.equal(True)
config.should.have.key("Disabled").being.equal(True)
@ -203,11 +206,93 @@ def test_get_unknown_health_check():
@mock_route53
def test_get_dns_sec():
def test_list_health_checks():
conn = boto3.client("route53", region_name="us-east-1")
conn.list_health_checks()["HealthChecks"].should.have.length_of(0)
check = conn.create_health_check(
CallerReference="?",
HealthCheckConfig={
"IPAddress": "10.0.0.25",
"Port": 80,
"Type": "HTTP",
"ResourcePath": "/",
"FullyQualifiedDomainName": "example.com",
"SearchString": "a good response",
"RequestInterval": 10,
"FailureThreshold": 2,
},
)["HealthCheck"]
checks = conn.list_health_checks()["HealthChecks"]
checks.should.have.length_of(1)
checks.should.contain(check)
@mock_route53
def test_delete_health_checks():
conn = boto3.client("route53", region_name="us-east-1")
conn.list_health_checks()["HealthChecks"].should.have.length_of(0)
check = conn.create_health_check(
CallerReference="?",
HealthCheckConfig={
"IPAddress": "10.0.0.25",
"Port": 80,
"Type": "HTTP",
"ResourcePath": "/",
"FullyQualifiedDomainName": "example.com",
"SearchString": "a good response",
"RequestInterval": 10,
"FailureThreshold": 2,
},
)["HealthCheck"]
conn.delete_health_check(HealthCheckId=check["Id"])
checks = conn.list_health_checks()["HealthChecks"]
checks.should.have.length_of(0)
@mock_route53
def test_update_health_check():
client = boto3.client("route53", region_name="us-east-1")
hosted_zone_id = client.create_hosted_zone(
Name="testdns.aws.com.", CallerReference=str(hash("foo"))
)["HostedZone"]["Id"]
dns_sec = client.get_dnssec(HostedZoneId=hosted_zone_id)
dns_sec.should.have.key("Status").equals({"ServeSignature": "NOT_SIGNING"})
hc_id = client.create_health_check(
CallerReference="callref",
HealthCheckConfig={
"Type": "CALCULATED",
"Inverted": False,
"Disabled": False,
"HealthThreshold": 1,
},
)["HealthCheck"]["Id"]
client.update_health_check(
HealthCheckId=hc_id,
IPAddress="0.0.0.0",
Port=80,
ResourcePath="rp",
FullyQualifiedDomainName="example.com",
SearchString="search",
FailureThreshold=123,
Inverted=False,
Disabled=False,
HealthThreshold=13,
ChildHealthChecks=["child"],
Regions=["us-east-1", "us-east-2", "us-west-1"],
)
config = client.get_health_check(HealthCheckId=hc_id)["HealthCheck"][
"HealthCheckConfig"
]
config.should.have.key("Type").equals("CALCULATED")
config.should.have.key("ResourcePath").equals("rp")
config.should.have.key("FullyQualifiedDomainName").equals("example.com")
config.should.have.key("SearchString").equals("search")
config.should.have.key("Inverted").equals(False)
config.should.have.key("Disabled").equals(False)
config.should.have.key("ChildHealthChecks").equals(["child"])
config.should.have.key("Regions").equals(["us-east-1", "us-east-2", "us-west-1"])

View File

@ -0,0 +1,236 @@
import boto3
import sure # noqa # pylint: disable=unused-import
import pytest
from botocore.exceptions import ClientError
from moto import mock_ec2, mock_route53
@mock_ec2
@mock_route53
def test_hosted_zone_private_zone_preserved():
# Create mock VPC so we can get a VPC ID
region = "us-east-1"
ec2c = boto3.client("ec2", region_name=region)
vpc_id = ec2c.create_vpc(CidrBlock="10.1.0.0/16").get("Vpc").get("VpcId")
# Create hosted_zone as a Private VPC Hosted Zone
conn = boto3.client("route53", region_name=region)
new_zone = conn.create_hosted_zone(
Name="testdns.aws.com.",
CallerReference=str(hash("foo")),
HostedZoneConfig=dict(PrivateZone=True, Comment="Test"),
VPC={"VPCRegion": region, "VPCId": vpc_id},
)
zone_id = new_zone["HostedZone"]["Id"].split("/")[-1]
hosted_zone = conn.get_hosted_zone(Id=zone_id)
hosted_zone["HostedZone"]["Config"]["PrivateZone"].should.equal(True)
hosted_zone.should.have.key("VPCs")
hosted_zone["VPCs"].should.have.length_of(1)
hosted_zone["VPCs"][0].should.have.key("VPCId")
hosted_zone["VPCs"][0].should.have.key("VPCRegion")
hosted_zone["VPCs"][0]["VPCId"].should.be.equal(vpc_id)
hosted_zone["VPCs"][0]["VPCRegion"].should.be.equal(region)
hosted_zones = conn.list_hosted_zones()
hosted_zones["HostedZones"][0]["Config"]["PrivateZone"].should.equal(True)
hosted_zones = conn.list_hosted_zones_by_name(DNSName="testdns.aws.com.")
hosted_zones["HostedZones"].should.have.length_of(1)
hosted_zones["HostedZones"][0]["Config"]["PrivateZone"].should.equal(True)
# create_hosted_zone statements with PrivateZone=True,
# but without a _valid_ vpc-id should NOT fail.
zone2_name = "testdns2.aws.com."
no_vpc_zone = conn.create_hosted_zone(
Name=zone2_name,
CallerReference=str(hash("foo")),
HostedZoneConfig=dict(PrivateZone=True, Comment="Test without VPC"),
)
zone_id = no_vpc_zone["HostedZone"]["Id"].split("/")[-1]
hosted_zone = conn.get_hosted_zone(Id=zone_id)
hosted_zone["HostedZone"]["Config"]["PrivateZone"].should.equal(True)
hosted_zone.should.have.key("VPCs")
hosted_zone["VPCs"].should.have.length_of(0)
hosted_zones = conn.list_hosted_zones()
hosted_zones["HostedZones"].should.have.length_of(2)
hosted_zones["HostedZones"][0]["Config"]["PrivateZone"].should.equal(True)
hosted_zones["HostedZones"][1]["Config"]["PrivateZone"].should.equal(True)
hosted_zones = conn.list_hosted_zones_by_name(DNSName=zone2_name)
hosted_zones["HostedZones"].should.have.length_of(1)
hosted_zones["HostedZones"][0]["Config"]["PrivateZone"].should.equal(True)
hosted_zones["HostedZones"][0]["Name"].should.equal(zone2_name)
@mock_ec2
@mock_route53
def test_list_hosted_zones_by_vpc_with_multiple_vpcs():
# Create mock VPC so we can get a VPC ID
ec2c = boto3.client("ec2", region_name="us-east-1")
vpc_id = ec2c.create_vpc(CidrBlock="10.1.0.0/16").get("Vpc").get("VpcId")
region = "us-east-1"
# Create 3 Zones associate with the VPC.
zones = {}
conn = boto3.client("route53", region_name=region)
for zone in ["a", "b", "c"]:
zone_name = f"test.{zone}.com."
zones[zone] = conn.create_hosted_zone(
Name=zone_name,
CallerReference=str(hash("foo")),
HostedZoneConfig=dict(PrivateZone=True, Comment=f"test {zone} com"),
VPC={"VPCRegion": region, "VPCId": vpc_id},
)
# List the zones associated with this vpc
response = conn.list_hosted_zones_by_vpc(VPCId=vpc_id, VPCRegion=region)
response.should.have.key("ResponseMetadata")
response.should.have.key("HostedZoneSummaries")
response["HostedZoneSummaries"].should.have.length_of(3)
# Loop through all zone summaries and verify they match what was created
for summary in response["HostedZoneSummaries"]:
# use the zone name as the index
index = summary["Name"].split(".")[1]
zone_id = zones[index]["HostedZone"]["Id"].split("/")[2]
summary.should.have.key("HostedZoneId")
summary["HostedZoneId"].should.equal(zone_id)
summary.should.have.key("Name")
summary["Name"].should.equal(zones[index]["HostedZone"]["Name"])
@mock_ec2
@mock_route53
def test_list_hosted_zones_by_vpc():
# Create mock VPC so we can get a VPC ID
ec2c = boto3.client("ec2", region_name="us-east-1")
vpc_id = ec2c.create_vpc(CidrBlock="10.1.0.0/16").get("Vpc").get("VpcId")
region = "us-east-1"
conn = boto3.client("route53", region_name=region)
zone_b = conn.create_hosted_zone(
Name="test.b.com.",
CallerReference=str(hash("foo")),
HostedZoneConfig=dict(PrivateZone=True, Comment="test com"),
VPC={"VPCRegion": region, "VPCId": vpc_id},
)
zone_id = zone_b["HostedZone"]["Id"].split("/")[2]
response = conn.list_hosted_zones_by_vpc(VPCId=vpc_id, VPCRegion=region)
response.should.have.key("ResponseMetadata")
response.should.have.key("HostedZoneSummaries")
response["HostedZoneSummaries"].should.have.length_of(1)
response["HostedZoneSummaries"][0].should.have.key("HostedZoneId")
retured_zone = response["HostedZoneSummaries"][0]
retured_zone["HostedZoneId"].should.equal(zone_id)
retured_zone["Name"].should.equal(zone_b["HostedZone"]["Name"])
@mock_ec2
@mock_route53
def test_route53_associate_vpc():
ec2c = boto3.client("ec2", region_name="us-east-1")
vpc_id = ec2c.create_vpc(CidrBlock="10.1.0.0/16")["Vpc"]["VpcId"]
conn = boto3.client("route53", region_name="us-east-1")
zone = conn.create_hosted_zone(
Name="test.b.com.",
CallerReference=str(hash("foo")),
HostedZoneConfig=dict(PrivateZone=True, Comment=""),
)
zone_id = zone["HostedZone"]["Id"].split("/")[2]
resp = conn.associate_vpc_with_hosted_zone(
HostedZoneId=zone_id,
VPC={"VPCId": vpc_id, "VPCRegion": "us-east-1"},
Comment="yolo",
)
resp.should.have.key("ChangeInfo")
resp["ChangeInfo"].should.have.key("Comment").equals("yolo")
@mock_ec2
@mock_route53
def test_route53_associate_vpc_with_public_Zone():
ec2c = boto3.client("ec2", region_name="us-east-1")
vpc_id = ec2c.create_vpc(CidrBlock="10.1.0.0/16")["Vpc"]["VpcId"]
conn = boto3.client("route53", region_name="us-east-1")
zone = conn.create_hosted_zone(
Name="test.b.com.",
CallerReference=str(hash("foo")),
)
zone_id = zone["HostedZone"]["Id"].split("/")[2]
with pytest.raises(ClientError) as exc:
conn.associate_vpc_with_hosted_zone(
HostedZoneId=zone_id,
VPC={"VPCId": vpc_id, "VPCRegion": "us-east-1"},
Comment="yolo",
)
err = exc.value.response["Error"]
err["Code"].should.equal("PublicZoneVPCAssociation")
err["Message"].should.equal(
"You're trying to associate a VPC with a public hosted zone. Amazon Route 53 doesn't support associating a VPC with a public hosted zone."
)
@mock_ec2
@mock_route53
def test_route53_associate_and_disassociate_vpc():
ec2c = boto3.client("ec2", region_name="us-east-1")
vpc_id1 = ec2c.create_vpc(CidrBlock="10.1.0.0/16").get("Vpc").get("VpcId")
vpc_id2 = ec2c.create_vpc(CidrBlock="10.1.0.1/16").get("Vpc").get("VpcId")
region = "us-east-1"
conn = boto3.client("route53", region_name=region)
zone = conn.create_hosted_zone(
Name="test.b.com.",
CallerReference=str(hash("foo")),
HostedZoneConfig=dict(PrivateZone=True, Comment="test com"),
VPC={"VPCRegion": region, "VPCId": vpc_id1},
)
zone_id = zone["HostedZone"]["Id"].split("/")[2]
conn.associate_vpc_with_hosted_zone(
HostedZoneId=zone_id,
VPC={"VPCId": vpc_id2, "VPCRegion": region},
)
zone_vpcs = conn.get_hosted_zone(Id=zone_id)["VPCs"]
zone_vpcs.should.have.length_of(2)
zone_vpcs.should.contain({"VPCRegion": region, "VPCId": vpc_id1})
zone_vpcs.should.contain({"VPCRegion": region, "VPCId": vpc_id2})
conn.disassociate_vpc_from_hosted_zone(HostedZoneId=zone_id, VPC={"VPCId": vpc_id1})
zone_vpcs = conn.get_hosted_zone(Id=zone_id)["VPCs"]
zone_vpcs.should.have.length_of(1)
zone_vpcs.should.contain({"VPCRegion": region, "VPCId": vpc_id2})
@mock_ec2
@mock_route53
def test_route53_disassociate_last_vpc():
ec2c = boto3.client("ec2", region_name="us-east-1")
vpc_id = ec2c.create_vpc(CidrBlock="10.1.0.0/16")["Vpc"]["VpcId"]
conn = boto3.client("route53", region_name="us-east-1")
zone = conn.create_hosted_zone(
Name="test.b.com.",
CallerReference=str(hash("foo")),
HostedZoneConfig=dict(PrivateZone=True, Comment="test com"),
VPC={"VPCRegion": "us-east-1", "VPCId": vpc_id},
)
zone_id = zone["HostedZone"]["Id"].split("/")[2]
with pytest.raises(ClientError) as exc:
conn.disassociate_vpc_from_hosted_zone(
HostedZoneId=zone_id, VPC={"VPCId": vpc_id}
)
err = exc.value.response["Error"]
err["Code"].should.equal("LastVPCAssociation")
err["Message"].should.equal(
"The VPC that you're trying to disassociate from the private hosted zone is the last VPC that is associated with the hosted zone. Amazon Route 53 doesn't support disassociating the last VPC from a hosted zone."
)