Browse Source

Improve error messaging for unknown templating parameters

pull/1280/head
Ross McFarland 5 months ago
parent
commit
871b2f2a7e
No known key found for this signature in database GPG Key ID: 943B179E15D3B22A
3 changed files with 70 additions and 4 deletions
  1. +4
    -0
      .changelog/af8522cac7e54d22a615eab351d445b3.md
  2. +23
    -3
      octodns/processor/templating.py
  3. +43
    -1
      tests/test_octodns_processor_templating.py

+ 4
- 0
.changelog/af8522cac7e54d22a615eab351d445b3.md View File

@ -0,0 +1,4 @@
---
type: patch
---
Improve error messaging for unknown templating parameters

+ 23
- 3
octodns/processor/templating.py View File

@ -5,6 +5,14 @@
from octodns.processor.base import BaseProcessor from octodns.processor.base import BaseProcessor
class TemplatingError(Exception):
def __init__(self, record, msg):
self.record = record
msg = f'Invalid record "{record.fqdn}", {msg}'
super().__init__(msg)
class Templating(BaseProcessor): class Templating(BaseProcessor):
''' '''
Record templating using python format. For simple records like TXT and CAA Record templating using python format. For simple records like TXT and CAA
@ -76,7 +84,7 @@ class Templating(BaseProcessor):
}, },
} }
def params(record):
def build_params(record):
return { return {
'record_name': record.decoded_name, 'record_name': record.decoded_name,
'record_decoded_name': record.decoded_name, 'record_decoded_name': record.decoded_name,
@ -90,12 +98,24 @@ class Templating(BaseProcessor):
**zone_params, **zone_params,
} }
def template(value, params, record):
try:
return value.template(params)
except KeyError as e:
raise TemplatingError(
record,
f'undefined template parameter "{e.args[0]}" in value',
) from e
for record in desired.records: for record in desired.records:
params = build_params(record)
if hasattr(record, 'values'): if hasattr(record, 'values'):
if record.values and not hasattr(record.values[0], 'template'): if record.values and not hasattr(record.values[0], 'template'):
# the (custom) value type does not support templating # the (custom) value type does not support templating
continue continue
new_values = [v.template(params(record)) for v in record.values]
new_values = [
template(v, params, record) for v in record.values
]
if record.values != new_values: if record.values != new_values:
new = record.copy() new = record.copy()
new.values = new_values new.values = new_values
@ -104,7 +124,7 @@ class Templating(BaseProcessor):
if not hasattr(record.value, 'template'): if not hasattr(record.value, 'template'):
# the (custom) value type does not support templating # the (custom) value type does not support templating
continue continue
new_value = record.value.template(params(record))
new_value = template(record.value, params, record)
if record.value != new_value: if record.value != new_value:
new = record.copy() new = record.copy()
new.value = new_value new.value = new_value


+ 43
- 1
tests/test_octodns_processor_templating.py View File

@ -5,7 +5,7 @@
from unittest import TestCase from unittest import TestCase
from unittest.mock import call, patch from unittest.mock import call, patch
from octodns.processor.templating import Templating
from octodns.processor.templating import Templating, TemplatingError
from octodns.record import Record, ValueMixin, ValuesMixin from octodns.record import Record, ValueMixin, ValuesMixin
from octodns.zone import Zone from octodns.zone import Zone
@ -225,3 +225,45 @@ class TemplatingTest(TestCase):
self.assertEqual('num_sources: 3', txt.values[0]) self.assertEqual('num_sources: 3', txt.values[0])
self.assertEqual('the_answer: 42', txt.values[1]) self.assertEqual('the_answer: 42', txt.values[1])
self.assertEqual('the_date: today', txt.values[2]) self.assertEqual('the_date: today', txt.values[2])
def test_bad_key(self):
templ = Templating('test')
zone = Zone('unit.tests.', [])
txt = Record.new(
zone,
'txt',
{'type': 'TXT', 'ttl': 42, 'value': 'this {bad} does not exist'},
)
zone.add_record(txt)
with self.assertRaises(TemplatingError) as ctx:
templ.process_source_zone(
zone, tuple(DummySource(i) for i in range(3))
)
self.assertEqual(
'Invalid record "txt.unit.tests.", undefined template parameter "bad" in value',
str(ctx.exception),
)
zone = Zone('unit.tests.', [])
cname = Record.new(
zone,
'cname',
{
'type': 'CNAME',
'ttl': 42,
'value': '_cname.{bad}something.else.',
},
lenient=True,
)
zone.add_record(cname)
with self.assertRaises(TemplatingError) as ctx:
templ.process_source_zone(
zone, tuple(DummySource(i) for i in range(3))
)
self.assertEqual(
'Invalid record "cname.unit.tests.", undefined template parameter "bad" in value',
str(ctx.exception),
)

Loading…
Cancel
Save