From 0155c4803670b1e9fdbdbcfdd0dad8cc35e13b6c Mon Sep 17 00:00:00 2001 From: michaelhtm <98621731+michaelhtm@users.noreply.github.com> Date: Thu, 24 Apr 2025 11:25:25 -0700 Subject: [PATCH] fix: support fqdn record names Currently we append the hostedZoneName to the RecordSet at create. If the recordSet name is fqdn, we want to avoid doing so. With this change, the hostedZoneName will not be appended to an FQDN --- pkg/resource/record_set/hooks.go | 8 ++++- pkg/resource/record_set/sdk.go | 9 ++++-- test/e2e/resources/record_set_fqdn.yaml | 11 +++++++ test/e2e/tests/test_record_set.py | 42 +++++++++++++++++++++++++ 4 files changed, 67 insertions(+), 3 deletions(-) create mode 100644 test/e2e/resources/record_set_fqdn.yaml diff --git a/pkg/resource/record_set/hooks.go b/pkg/resource/record_set/hooks.go index 04c3055..74d7531 100644 --- a/pkg/resource/record_set/hooks.go +++ b/pkg/resource/record_set/hooks.go @@ -317,7 +317,13 @@ func (rm *resourceManager) getDNSName( domain string, ) (dnsName string) { if r.ko.Spec.Name != nil { - dnsName += *r.ko.Spec.Name + "." + dnsName = *r.ko.Spec.Name + } + + if strings.HasSuffix(dnsName, ".") { + return dnsName + } else if len(dnsName) > 0 { + dnsName += "." } dnsName += domain return dnsName diff --git a/pkg/resource/record_set/sdk.go b/pkg/resource/record_set/sdk.go index af89c37..4fec8f9 100644 --- a/pkg/resource/record_set/sdk.go +++ b/pkg/resource/record_set/sdk.go @@ -120,8 +120,13 @@ func (rm *resourceManager) sdkFind( // the output to compare with the user specified subdomain. If a '*' value is // in the subdomain, ListResourceRecordSets returns it as an encoded value, so // this needs to be decoded before our comparison. - subdomain := strings.TrimSuffix(*elem.Name, domain) - subdomain = decodeRecordName(subdomain) + subdomain := "*" + if r.ko.Spec.Name != nil && strings.HasSuffix(*r.ko.Spec.Name, ".") { + subdomain = *r.ko.Spec.Name + } else { + subdomain = strings.TrimSuffix(*elem.Name, domain) + subdomain = decodeRecordName(subdomain) + } // If user supplied no subdomain, we know that records with subdomains cannot // be a match and vice versa. diff --git a/test/e2e/resources/record_set_fqdn.yaml b/test/e2e/resources/record_set_fqdn.yaml new file mode 100644 index 0000000..13f0471 --- /dev/null +++ b/test/e2e/resources/record_set_fqdn.yaml @@ -0,0 +1,11 @@ +apiVersion: route53.services.k8s.aws/v1alpha1 +kind: RecordSet +metadata: + name: $FQDN_RECORD_NAME +spec: + name: $FQDN_RECORD_NAME_SPEC + hostedZoneID: $HOSTED_ZONE_ID + recordType: A + resourceRecords: + - value: $IP_ADDR + ttl: 300 diff --git a/test/e2e/tests/test_record_set.py b/test/e2e/tests/test_record_set.py index a721ec8..ddc5462 100644 --- a/test/e2e/tests/test_record_set.py +++ b/test/e2e/tests/test_record_set.py @@ -74,6 +74,30 @@ def simple_record_set(private_hosted_zone): delete_route53_resource(ref) +@pytest.fixture(scope="function") +def fqdn_record_set(private_hosted_zone): + zone_id, domain = private_hosted_zone + parsed_zone_id = zone_id.split("/")[-1] + ip_address = socket.inet_ntoa(struct.pack('>I', random.randint(1, 0xffffffff))) + simple_record_name = random_suffix_name("fqdn-record-name", 32) + + replacements = REPLACEMENT_VALUES.copy() + replacements["FQDN_RECORD_NAME"] = simple_record_name + replacements["FQDN_RECORD_NAME_SPEC"] = simple_record_name+"hello-world.example.com." + replacements["HOSTED_ZONE_ID"] = parsed_zone_id + replacements["IP_ADDR"] = ip_address + + ref, cr = create_route53_resource( + "recordsets", + simple_record_name, + "record_set_fqdn", + replacements + ) + + yield ref, cr + + delete_route53_resource(ref) + def status_id_exists(ref): for _ in range(STATUS_UPDATE_RETRY_COUNT): record = get_route53_resource(ref) @@ -131,3 +155,21 @@ def test_crud_simple_record(self, route53_client, private_hosted_zone, simple_re # Check record set has been updated in AWS route53_validator.assert_record_set(updated, domain) + + + def test_cd_fqdn_record(self, route53_client, private_hosted_zone, fqdn_record_set): + zone_id, domain = private_hosted_zone + assert zone_id + + # Check hosted zone exists in AWS + route53_validator = Route53Validator(route53_client) + route53_validator.assert_hosted_zone(zone_id) + + ref, cr = fqdn_record_set + assert status_id_exists(ref) is True + + # Check record set exists in AWS + route53_validator.assert_record_set(cr, domain) + + # Ensure that the status eventually switches from PENDING to INSYNC + assert verify_status_insync(ref) is True