Skip to content

Commit

Permalink
Merge pull request #83 from rasturic/topic/add-ds-record-support
Browse files Browse the repository at this point in the history
Add DS record support
  • Loading branch information
ross authored Feb 5, 2024
2 parents 4ce9042 + 9d31ce7 commit 9dff89b
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 13 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
### Important

* Add `append_to_names` tag append parameter to sources
* Add `DS` record type support

## v0.0.6 - 2023-10-16 - Long overdue

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ zones:

#### Records

A, AAAA, CAA, CNAME, MX, NAPTR, NS, PTR, SPF, SRV, TXT
A, AAAA, CAA, CNAME, DS, MX, NAPTR, NS, PTR, SPF, SRV, TXT

#### Root NS Records

Expand Down
28 changes: 28 additions & 0 deletions octodns_route53/provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -312,9 +312,15 @@ def _values_for_quoted(self, record):
def _value_for_SRV(self, value, record):
return f'{value.priority} {value.weight} {value.port} {value.target}'

def _value_for_DS(self, value, record):
return f'{value.key_tag} {value.algorithm} {value.digest_type} {value.digest}'

def _values_for_SRV(self, record):
return [self._value_for_SRV(v, record) for v in record.values]

def _values_for_DS(self, record):
return [self._value_for_DS(v, record) for v in record.values]


class _Route53Alias(_Route53Record):
def __init__(self, provider, hosted_zone_id, record, value, creating):
Expand Down Expand Up @@ -752,6 +758,7 @@ class Route53Provider(_AuthMixin, BaseProvider):
'AAAA',
'CAA',
'CNAME',
'DS',
'MX',
'NAPTR',
'NS',
Expand Down Expand Up @@ -1000,6 +1007,27 @@ def _data_for_SRV(self, rrset):
'ttl': int(rrset['TTL']),
}

def _data_for_DS(self, rrset):
values = []
for rr in rrset['ResourceRecords']:
# digest may contain whitespace
key_tag, algorithm, digest_type, digest = rr['Value'].split(
maxsplit=3
)
values.append(
{
'key_tag': key_tag,
'algorithm': algorithm,
'digest_type': digest_type,
'digest': digest,
}
)
return {
'type': rrset['Type'],
'values': values,
'ttl': int(rrset['TTL']),
}

def _load_records(self, zone_id):
if zone_id not in self._r53_rrsets:
self.log.debug('_load_records: zone_id=%s loading', zone_id)
Expand Down
49 changes: 37 additions & 12 deletions tests/test_octodns_provider_route53.py
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,21 @@ class TestRoute53Provider(TestCase):
'value': {'flags': 0, 'tag': 'issue', 'value': 'ca.unit.tests'},
},
),
(
'dskey',
{
'ttl': 70,
'type': 'DS',
'values': [
{
'key_tag': 60485,
'algorithm': 5,
'digest_type': 1,
'digest': '2BB183AF5F22588179A53B0A 98631FAD1A292118',
}
],
},
),
(
'alias',
{
Expand Down Expand Up @@ -1114,6 +1129,16 @@ def test_populate(self):
'ResourceRecords': [{'Value': '0 issue "ca.unit.tests"'}],
'TTL': 69,
},
{
'Name': 'dskey.unit.tests.',
'Type': 'DS',
'ResourceRecords': [
{
'Value': '60485 5 1 2BB183AF5F22588179A53B0A 98631FAD1A292118'
}
],
'TTL': 70,
},
{
'AliasTarget': {
'HostedZoneId': 'Z119WBBTVP5WFX',
Expand Down Expand Up @@ -1243,7 +1268,7 @@ def test_sync(self):
)

plan = provider.plan(self.expected)
self.assertEqual(12, len(plan.changes))
self.assertEqual(13, len(plan.changes))
self.assertTrue(plan.exists)
for change in plan.changes:
self.assertIsInstance(change, Create)
Expand All @@ -1270,7 +1295,7 @@ def test_sync(self):
{'HostedZoneId': 'z42', 'ChangeBatch': ANY},
)

self.assertEqual(12, provider.apply(plan))
self.assertEqual(13, provider.apply(plan))
stubber.assert_no_pending_responses()

# Delete by monkey patching in a populate that includes an extra record
Expand Down Expand Up @@ -1536,7 +1561,7 @@ def test_sync_create(self):
stubber.add_response('list_hosted_zones', list_hosted_zones_resp, {})

plan = provider.plan(self.expected)
self.assertEqual(12, len(plan.changes))
self.assertEqual(13, len(plan.changes))
self.assertFalse(plan.exists)
for change in plan.changes:
self.assertIsInstance(change, Create)
Expand Down Expand Up @@ -1608,7 +1633,7 @@ def test_sync_create(self):
{'HostedZoneId': 'z42', 'ChangeBatch': ANY},
)

self.assertEqual(12, provider.apply(plan))
self.assertEqual(13, provider.apply(plan))
stubber.assert_no_pending_responses()

def test_sync_create_with_delegation_set(self):
Expand All @@ -1625,7 +1650,7 @@ def test_sync_create_with_delegation_set(self):
stubber.add_response('list_hosted_zones', list_hosted_zones_resp, {})

plan = provider.plan(self.expected)
self.assertEqual(12, len(plan.changes))
self.assertEqual(13, len(plan.changes))
self.assertFalse(plan.exists)
for change in plan.changes:
self.assertIsInstance(change, Create)
Expand Down Expand Up @@ -1701,7 +1726,7 @@ def test_sync_create_with_delegation_set(self):
{'HostedZoneId': 'z42', 'ChangeBatch': ANY},
)

self.assertEqual(12, provider.apply(plan))
self.assertEqual(13, provider.apply(plan))
stubber.assert_no_pending_responses()

def test_health_checks_pagination(self):
Expand Down Expand Up @@ -2641,7 +2666,7 @@ def test_plan_apply_with_get_zones_by_name_zone_not_exists(self):
)

plan = provider.plan(self.expected)
self.assertEqual(12, len(plan.changes))
self.assertEqual(13, len(plan.changes))

create_hosted_zone_resp = {
'HostedZone': {
Expand Down Expand Up @@ -2709,7 +2734,7 @@ def test_plan_apply_with_get_zones_by_name_zone_not_exists(self):
{'HostedZoneId': 'z42', 'ChangeBatch': ANY},
)

self.assertEqual(12, provider.apply(plan))
self.assertEqual(13, provider.apply(plan))
stubber.assert_no_pending_responses()

def test_plan_apply_with_get_zones_by_name_zone_exists(self):
Expand Down Expand Up @@ -2760,7 +2785,7 @@ def test_plan_apply_with_get_zones_by_name_zone_exists(self):
)

plan = provider.plan(self.expected)
self.assertEqual(13, len(plan.changes))
self.assertEqual(14, len(plan.changes))

stubber.add_response(
'list_health_checks',
Expand All @@ -2784,7 +2809,7 @@ def test_plan_apply_with_get_zones_by_name_zone_exists(self):
{'HostedZoneId': 'z42', 'ChangeBatch': ANY},
)

self.assertEqual(13, provider.apply(plan))
self.assertEqual(14, provider.apply(plan))
stubber.assert_no_pending_responses()

def test_extra_change_no_health_check(self):
Expand Down Expand Up @@ -3450,7 +3475,7 @@ def _get_test_plan(self, max_changes):
@patch('octodns_route53.Route53Provider._really_apply')
def test_apply_1(self, really_apply_mock, _):
# 18 RRs with max of 19 should only get applied in one call
provider, plan = self._get_test_plan(19)
provider, plan = self._get_test_plan(20)
provider.apply(plan)
really_apply_mock.assert_called_once()

Expand All @@ -3468,7 +3493,7 @@ def test_apply_3(self, really_apply_mock, _):
# with a max of seven modifications, three calls
provider, plan = self._get_test_plan(7)
provider.apply(plan)
self.assertEqual(3, really_apply_mock.call_count)
self.assertEqual(4, really_apply_mock.call_count)

@patch('octodns_route53.Route53Provider._load_records')
@patch('octodns_route53.Route53Provider._really_apply')
Expand Down

0 comments on commit 9dff89b

Please sign in to comment.