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