diff --git a/aws/client.py b/aws/client.py index 67d13ee..0216dde 100644 --- a/aws/client.py +++ b/aws/client.py @@ -11,7 +11,7 @@ import botocore.session -SERVICES_WITHOUT_REGIONS = ["iam", "s3"] +SERVICES_WITHOUT_REGIONS = ["iam", "s3", "route53"] @functools.lru_cache() @@ -41,7 +41,10 @@ def get_client(profile, region, service): """ session = get_session(profile) - if region not in session.get_available_regions(service): + if ( + region not in session.get_available_regions(service) + and service not in SERVICES_WITHOUT_REGIONS + ): warnings.warn("service {} not available in {}".format(service, region)) return session.create_client(service, region_name=region) diff --git a/aws/route53/__init__.py b/aws/route53/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/aws/route53/resources.py b/aws/route53/resources.py new file mode 100644 index 0000000..a3550cc --- /dev/null +++ b/aws/route53/resources.py @@ -0,0 +1,31 @@ +from conftest import botocore_client + + +def zones(): + """ + https://botocore.amazonaws.com/v1/documentation/api/latest/reference/services/route53.html#Route53.Client.list_hosted_zones + """ + return ( + botocore_client.get("route53", "list_hosted_zones", [], {}) + .extract_key("HostedZones") + .flatten() + .values() + ) + + +def cnames(): + records = [] + + for zone in zones(): + zone_id = zone["Id"].split("/")[2] + zone_records = ( + botocore_client.get( + "route53", "list_resource_record_sets", [], {"HostedZoneId": zone_id} + ) + .extract_key("ResourceRecordSets") + .flatten() + .values() + ) + records.extend([record for record in zone_records if record["Type"] == "CNAME"]) + + return records diff --git a/aws/route53/test_route53_cnames_minimum_ttl_or_greater.py b/aws/route53/test_route53_cnames_minimum_ttl_or_greater.py new file mode 100644 index 0000000..f6ec163 --- /dev/null +++ b/aws/route53/test_route53_cnames_minimum_ttl_or_greater.py @@ -0,0 +1,19 @@ +import pytest + +from aws.route53.resources import zones, cnames +from helpers import get_param_id + + +MINIMUM_TTL = 600 + + +@pytest.mark.parametrize( + "cnames", cnames(), ids=lambda record: get_param_id(record, "Name") +) +def test_route53_cnames_minimum_ttl_or_greater(cnames): + """ + Tests that CNAMEs in Route53 have a TTL of 600 seconds or more. + """ + assert ( + int(cnames["TTL"]) >= MINIMUM_TTL + ), f"TTL is below the minimum of {MINIMUM_TTL}, it is currently set to {cnames['TTL']}"