Skip to content

Commit

Permalink
Improve get_best_match_zone() to match by most matched components i…
Browse files Browse the repository at this point in the history
…nstead of by length of domain (zappa#1193)

* 🔧 improve `get_best_match_zone()` to match by most matched components instead of by length of domain.

* ♻️ refactor multiple loops into single loop
🔧 add '.' to test_domain_name_match_component testcase HostedZones zone, 'Name'.

* 🔧 variable name clarification.

* 📝 add comments for clarification

* ✅ add testcase where match is short and longer zone name comes first.
🔧 fix case where exact match is ignored over longest.

* 🔥 remove unused import
  • Loading branch information
monkut authored and Ian288 committed Jul 11, 2023
1 parent 7cb1e17 commit 5e78434
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 6 deletions.
41 changes: 41 additions & 0 deletions tests/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -1669,6 +1669,47 @@ def test_domain_name_match(self):
)
assert zone == "zone-public"

def test_domain_name_match_components(self):
# Simple sanity check
zone = Zappa.get_best_match_zone(
all_zones={
"HostedZones": [
{
"Name": "example.com.",
"Id": "zone-correct",
"Config": {"PrivateZone": False},
},
{
"Name": "beta.example.com.",
"Id": "zone-incorrect",
"Config": {"PrivateZone": False},
},
]
},
domain="some-beta.example.com",
)
assert zone == "zone-correct"

def test_domain_name_match_components_short(self):
zone = Zappa.get_best_match_zone(
all_zones={
"HostedZones": [
{
"Name": "beta.example.com.",
"Id": "zone-incorrect",
"Config": {"PrivateZone": False},
},
{
"Name": "example.com.",
"Id": "zone-correct",
"Config": {"PrivateZone": False},
},
]
},
domain="example.com",
)
assert zone == "zone-correct"

##
# Let's Encrypt / ACME
##
Expand Down
22 changes: 16 additions & 6 deletions zappa/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -3198,12 +3198,22 @@ def get_best_match_zone(all_zones, domain):
"""Return zone id which name is closer matched with domain name."""

# Related: https://github.com/Miserlou/Zappa/issues/459
public_zones = [zone for zone in all_zones["HostedZones"] if not zone["Config"]["PrivateZone"]]

zones = {zone["Name"][:-1]: zone["Id"] for zone in public_zones if zone["Name"][:-1] in domain}
if zones:
keys = max(zones.keys(), key=lambda a: len(a)) # get longest key -- best match.
return zones[keys]
domain_components = domain.split(".")[::-1] # match in reverse
candidate_zones = {}
for zone in all_zones["HostedZones"]:
if not zone["Config"]["PrivateZone"]:
public_zone_name = zone["Name"][:-1] # zone "Name" expected to end with "." - remove "."
zone_components = public_zone_name.split(".")[::-1] # reverse order
if all(z == d for z, d in zip(zone_components, domain_components)):
# zones that match the shortest comparison considered a candidate
candidate_zones[public_zone_name] = zone["Id"]

if candidate_zones:
if domain in candidate_zones: # if exact match use it
best_match_key = domain
else: # otherwise, use longest matched
best_match_key = max(candidate_zones.keys(), key=lambda a: len(a)) # get longest key -- best match.
return candidate_zones[best_match_key]
else:
return None

Expand Down

0 comments on commit 5e78434

Please sign in to comment.