Browse Source

Add trailing_dots parameter to templating processor

pull/1278/head
Jonathan Leroy 5 months ago
parent
commit
a5a1d50453
No known key found for this signature in database GPG Key ID: CF226DF21118649E
3 changed files with 76 additions and 10 deletions
  1. +4
    -0
      .changelog/3e57e696039c4f37a3062043be81199c.md
  2. +26
    -8
      octodns/processor/templating.py
  3. +46
    -2
      tests/test_octodns_processor_templating.py

+ 4
- 0
.changelog/3e57e696039c4f37a3062043be81199c.md View File

@ -0,0 +1,4 @@
---
type: patch
---
Add trailing_dots parameter to templating processor

+ 26
- 8
octodns/processor/templating.py View File

@ -15,6 +15,10 @@ class Templating(BaseProcessor):
templating: templating:
class: octodns.processor.templating.Templating class: octodns.processor.templating.Templating
# When `trailing_dots` is disabled, trailing dots are removed from all
# built-in variables values who represent a FQDN, like `{zone_name}`
# or `{record_fqdn}`. Optional. Default to `True`.
trailing_dots: False
# Any k/v present in context will be passed into the .format method and # Any k/v present in context will be passed into the .format method and
# thus be available as additional variables in the template. This is all # thus be available as additional variables in the template. This is all
# optional. # optional.
@ -55,16 +59,17 @@ class Templating(BaseProcessor):
''' '''
def __init__(self, id, *args, context={}, **kwargs):
def __init__(self, id, *args, trailing_dots=True, context={}, **kwargs):
super().__init__(id, *args, **kwargs) super().__init__(id, *args, **kwargs)
self.trailing_dots = trailing_dots
self.context = context self.context = context
def process_source_zone(self, desired, sources): def process_source_zone(self, desired, sources):
sources = sources or [] sources = sources or []
zone_params = { zone_params = {
'zone_name': desired.decoded_name.rstrip('.'),
'zone_decoded_name': desired.decoded_name.rstrip('.'),
'zone_encoded_name': desired.name.rstrip('.'),
'zone_name': desired.decoded_name,
'zone_decoded_name': desired.decoded_name,
'zone_encoded_name': desired.name,
'zone_num_records': len(desired.records), 'zone_num_records': len(desired.records),
'zone_source_ids': ', '.join(s.id for s in sources), 'zone_source_ids': ', '.join(s.id for s in sources),
# add any extra context provided to us, if the value is a callable # add any extra context provided to us, if the value is a callable
@ -75,20 +80,33 @@ class Templating(BaseProcessor):
for k, v in self.context.items() for k, v in self.context.items()
}, },
} }
if not self.trailing_dots:
zone_params = zone_params | {
'zone_name': desired.decoded_name[:-1],
'zone_decoded_name': desired.decoded_name[:-1],
'zone_encoded_name': desired.name[:-1],
}
def params(record): def params(record):
return {
record_params = {
'record_name': record.decoded_name, 'record_name': record.decoded_name,
'record_decoded_name': record.decoded_name, 'record_decoded_name': record.decoded_name,
'record_encoded_name': record.name, 'record_encoded_name': record.name,
'record_fqdn': record.decoded_fqdn.rstrip('.'),
'record_decoded_fqdn': record.decoded_fqdn.rstrip('.'),
'record_encoded_fqdn': record.fqdn.rstrip('.'),
'record_fqdn': record.decoded_fqdn,
'record_decoded_fqdn': record.decoded_fqdn,
'record_encoded_fqdn': record.fqdn,
'record_type': record._type, 'record_type': record._type,
'record_ttl': record.ttl, 'record_ttl': record.ttl,
'record_source_id': record.source.id if record.source else None, 'record_source_id': record.source.id if record.source else None,
**zone_params, **zone_params,
} }
if not self.trailing_dots:
record_params = record_params | {
'record_fqdn': record.decoded_fqdn[:-1],
'record_decoded_fqdn': record.decoded_fqdn[:-1],
'record_encoded_fqdn': record.fqdn[:-1],
}
return record_params
for record in desired.records: for record in desired.records:
if hasattr(record, 'values'): if hasattr(record, 'values'):


+ 46
- 2
tests/test_octodns_processor_templating.py View File

@ -74,7 +74,7 @@ class TemplatingTest(TestCase):
{ {
'type': 'CNAME', 'type': 'CNAME',
'ttl': 42, 'ttl': 42,
'value': '_cname.{zone_name}.something.else.',
'value': '_cname.{zone_name}something.else.',
}, },
lenient=True, lenient=True,
) )
@ -107,7 +107,7 @@ class TemplatingTest(TestCase):
{ {
'type': 'TXT', 'type': 'TXT',
'ttl': 42, 'ttl': 42,
'value': 'There are {zone_num_records} record(s) in {zone_name}.',
'value': 'There are {zone_num_records} record(s) in {zone_name}',
}, },
) )
zone.add_record(txt) zone.add_record(txt)
@ -162,6 +162,50 @@ class TemplatingTest(TestCase):
) )
zone.add_record(txt) zone.add_record(txt)
templ.process_source_zone(
zone, sources=[record_source, DummySource('other')]
)
mock_template.assert_called_once()
self.assertEqual(
call(
{
'record_name': 'txt',
'record_decoded_name': 'txt',
'record_encoded_name': 'txt',
'record_fqdn': 'txt.unit.tests.',
'record_decoded_fqdn': 'txt.unit.tests.',
'record_encoded_fqdn': 'txt.unit.tests.',
'record_type': 'TXT',
'record_ttl': 42,
'record_source_id': 'record',
'zone_name': 'unit.tests.',
'zone_decoded_name': 'unit.tests.',
'zone_encoded_name': 'unit.tests.',
'zone_num_records': 1,
'zone_source_ids': 'record, other',
}
),
mock_template.call_args,
)
@patch('octodns.record.TxtValue.template')
def test_trailing_dots(self, mock_template):
templ = Templating('test', trailing_dots=False)
zone = Zone('unit.tests.', [])
record_source = DummySource('record')
txt = Record.new(
zone,
'txt',
{
'type': 'TXT',
'ttl': 42,
'value': 'There are {zone_num_records} record(s) in {zone_name}.',
},
source=record_source,
)
zone.add_record(txt)
templ.process_source_zone( templ.process_source_zone(
zone, sources=[record_source, DummySource('other')] zone, sources=[record_source, DummySource('other')]
) )


Loading…
Cancel
Save