From 95037067559411d1894862618489084b77a80a6e Mon Sep 17 00:00:00 2001 From: Erik Olson Date: Mon, 14 Sep 2020 15:28:23 -0400 Subject: [PATCH 1/7] WIP, Test for DNS entries with TTL < 600s --- aws/client.py | 2 +- aws/route53/resources.py | 24 ++++++++++++++++++++++++ aws/route53/test_route53_zones.py | 13 +++++++++++++ 3 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 aws/route53/resources.py create mode 100644 aws/route53/test_route53_zones.py diff --git a/aws/client.py b/aws/client.py index 2e7e61b..3452bed 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() diff --git a/aws/route53/resources.py b/aws/route53/resources.py new file mode 100644 index 0000000..08d196e --- /dev/null +++ b/aws/route53/resources.py @@ -0,0 +1,24 @@ +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 names_in_zone(zone_id): + """ + """ + records = botocore_client.get( + "route53", + "list_resource_record_sets", + [], + {"HostedZoneId": zone_id, "StartRecordType": "CNAME"}).extract("ResourceRecordSets").flatten().values() + + for record in records: + print("found record {}".format(record)) diff --git a/aws/route53/test_route53_zones.py b/aws/route53/test_route53_zones.py new file mode 100644 index 0000000..5806517 --- /dev/null +++ b/aws/route53/test_route53_zones.py @@ -0,0 +1,13 @@ +import pytest + +from aws.route53.resources import zones, names_in_zone + +@pytest.mark.route53 +@pytest.mark.parametrize( + "zone", zones(), +) +def test_route53_zones(zone): + zone_id = zone['Id'].split('/')[2] + print(zone_id) + names_in_zone(zone_id) + assert (len(zone)) > 0 From 085789b171699fe28cb37e676a0166a496b4d2a7 Mon Sep 17 00:00:00 2001 From: Erik Olson Date: Tue, 15 Sep 2020 15:55:32 -0400 Subject: [PATCH 2/7] dunno --- aws/route53/resources.py | 21 +++++++++++---------- aws/route53/test_route53_zones.py | 18 +++++++++++------- 2 files changed, 22 insertions(+), 17 deletions(-) diff --git a/aws/route53/resources.py b/aws/route53/resources.py index 08d196e..8da2711 100644 --- a/aws/route53/resources.py +++ b/aws/route53/resources.py @@ -11,14 +11,15 @@ def zones(): .values() ) -def names_in_zone(zone_id): - """ - """ - records = botocore_client.get( - "route53", - "list_resource_record_sets", - [], - {"HostedZoneId": zone_id, "StartRecordType": "CNAME"}).extract("ResourceRecordSets").flatten().values() +def cnames(): + zone_list = zones() + print(zone_list) + for zone in zone_list: + zone_id = zone['Id'].split('/')[2] + + records = botocore_client.get("route53", "list_resource_record_sets", [], {"HostedZoneId": zone_id}).extract("ResourceRecordSets").flatten().values() + + for record in records: + print("record: {}".format(record)) - for record in records: - print("found record {}".format(record)) + return records diff --git a/aws/route53/test_route53_zones.py b/aws/route53/test_route53_zones.py index 5806517..9c6dbf2 100644 --- a/aws/route53/test_route53_zones.py +++ b/aws/route53/test_route53_zones.py @@ -1,13 +1,17 @@ import pytest -from aws.route53.resources import zones, names_in_zone +from aws.route53.resources import zones, cnames + +# @pytest.mark.route53 +# @pytest.mark.parametrize( +# "zone", zones(), +# ) +# def test_route53_zones(zone): +# assert (len(zone)) > 0 @pytest.mark.route53 @pytest.mark.parametrize( - "zone", zones(), + "cnames", cnames(), ) -def test_route53_zones(zone): - zone_id = zone['Id'].split('/')[2] - print(zone_id) - names_in_zone(zone_id) - assert (len(zone)) > 0 +def test_route53_cnames(cnames): + assert (len(cnames)) > 0 From e1044425587a0f951cb9f119f48b3429abd3c5ea Mon Sep 17 00:00:00 2001 From: Erik Olson Date: Thu, 17 Sep 2020 11:10:09 -0400 Subject: [PATCH 3/7] MVP, check that all CNAME TTLs are >= 600s --- aws/route53/resources.py | 21 ++++++++++++++------- aws/route53/test_route53_zones.py | 9 +-------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/aws/route53/resources.py b/aws/route53/resources.py index 8da2711..dbe7e51 100644 --- a/aws/route53/resources.py +++ b/aws/route53/resources.py @@ -1,5 +1,6 @@ from conftest import botocore_client + def zones(): """ https://botocore.amazonaws.com/v1/documentation/api/latest/reference/services/route53.html#Route53.Client.list_hosted_zones @@ -11,15 +12,21 @@ def zones(): .values() ) + def cnames(): + records = [] zone_list = zones() - print(zone_list) - for zone in zone_list: - zone_id = zone['Id'].split('/')[2] - records = botocore_client.get("route53", "list_resource_record_sets", [], {"HostedZoneId": zone_id}).extract("ResourceRecordSets").flatten().values() - - for record in records: - print("record: {}".format(record)) + for zone in zone_list: + 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_zones.py b/aws/route53/test_route53_zones.py index 9c6dbf2..43d4a12 100644 --- a/aws/route53/test_route53_zones.py +++ b/aws/route53/test_route53_zones.py @@ -2,16 +2,9 @@ from aws.route53.resources import zones, cnames -# @pytest.mark.route53 -# @pytest.mark.parametrize( -# "zone", zones(), -# ) -# def test_route53_zones(zone): -# assert (len(zone)) > 0 -@pytest.mark.route53 @pytest.mark.parametrize( "cnames", cnames(), ) def test_route53_cnames(cnames): - assert (len(cnames)) > 0 + assert int(cnames["TTL"]) >= 600, f"{cnames['Name']} TTL is {cnames['TTL']}" From 205059f82fb1e0b023b55b7baf9bdd6db098d49f Mon Sep 17 00:00:00 2001 From: Erik Olson Date: Thu, 17 Sep 2020 15:45:44 -0400 Subject: [PATCH 4/7] Add ids, __init__.py, other suggestions --- aws/route53/__init__.py | 0 aws/route53/resources.py | 3 +-- aws/route53/test_route53_zones.py | 5 +++-- 3 files changed, 4 insertions(+), 4 deletions(-) create mode 100644 aws/route53/__init__.py 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 index dbe7e51..a3550cc 100644 --- a/aws/route53/resources.py +++ b/aws/route53/resources.py @@ -15,9 +15,8 @@ def zones(): def cnames(): records = [] - zone_list = zones() - for zone in zone_list: + for zone in zones(): zone_id = zone["Id"].split("/")[2] zone_records = ( botocore_client.get( diff --git a/aws/route53/test_route53_zones.py b/aws/route53/test_route53_zones.py index 43d4a12..af32298 100644 --- a/aws/route53/test_route53_zones.py +++ b/aws/route53/test_route53_zones.py @@ -1,10 +1,11 @@ import pytest from aws.route53.resources import zones, cnames +from helpers import get_param_id @pytest.mark.parametrize( - "cnames", cnames(), + "cnames", cnames(), ids=lambda record: get_param_id(record, "Name") ) def test_route53_cnames(cnames): - assert int(cnames["TTL"]) >= 600, f"{cnames['Name']} TTL is {cnames['TTL']}" + assert int(cnames["TTL"]) >= 600, f"TTL is {cnames['TTL']}" From 7e1571b8f4f12e3f8c539f8cc25fb14ee458b53a Mon Sep 17 00:00:00 2001 From: AJ Bahnken Date: Wed, 4 Nov 2020 12:28:54 -0500 Subject: [PATCH 5/7] Fix cname route53 ttl test name and docstring --- ...t_route53_cnames_minimum_ttl_or_greater.py | 19 +++++++++++++++++++ aws/route53/test_route53_zones.py | 11 ----------- 2 files changed, 19 insertions(+), 11 deletions(-) create mode 100644 aws/route53/test_route53_cnames_minimum_ttl_or_greater.py delete mode 100644 aws/route53/test_route53_zones.py 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..152f138 --- /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 current set to {cnames['TTL']}" diff --git a/aws/route53/test_route53_zones.py b/aws/route53/test_route53_zones.py deleted file mode 100644 index af32298..0000000 --- a/aws/route53/test_route53_zones.py +++ /dev/null @@ -1,11 +0,0 @@ -import pytest - -from aws.route53.resources import zones, cnames -from helpers import get_param_id - - -@pytest.mark.parametrize( - "cnames", cnames(), ids=lambda record: get_param_id(record, "Name") -) -def test_route53_cnames(cnames): - assert int(cnames["TTL"]) >= 600, f"TTL is {cnames['TTL']}" From 597959da00f157177d6b87168cc47ad5fe0c457b Mon Sep 17 00:00:00 2001 From: AJ Bahnken Date: Wed, 4 Nov 2020 12:31:29 -0500 Subject: [PATCH 6/7] fixed assert msg typo --- aws/route53/test_route53_cnames_minimum_ttl_or_greater.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aws/route53/test_route53_cnames_minimum_ttl_or_greater.py b/aws/route53/test_route53_cnames_minimum_ttl_or_greater.py index 152f138..f6ec163 100644 --- a/aws/route53/test_route53_cnames_minimum_ttl_or_greater.py +++ b/aws/route53/test_route53_cnames_minimum_ttl_or_greater.py @@ -16,4 +16,4 @@ def test_route53_cnames_minimum_ttl_or_greater(cnames): """ assert ( int(cnames["TTL"]) >= MINIMUM_TTL - ), f"TTL is below the minimum of {MINIMUM_TTL}, it is current set to {cnames['TTL']}" + ), f"TTL is below the minimum of {MINIMUM_TTL}, it is currently set to {cnames['TTL']}" From a0214e0e26fc9fd51b7f80883eb71bf9e97744d2 Mon Sep 17 00:00:00 2001 From: AJ Bahnken Date: Wed, 4 Nov 2020 12:34:31 -0500 Subject: [PATCH 7/7] Added check in get_client to silent unneeded warning --- aws/client.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/aws/client.py b/aws/client.py index f83b15f..0216dde 100644 --- a/aws/client.py +++ b/aws/client.py @@ -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)