From 777a1a655a03e7bdd7a9703cf2979d329ce2301b Mon Sep 17 00:00:00 2001 From: Ross McFarland Date: Sun, 25 May 2025 16:43:52 -0700 Subject: [PATCH] working escaped_semicolons=false w/tests --- .../7a30ee9fb9dd433c9181ddd5628e5cd3.md | 4 ++ octodns/provider/yaml.py | 11 ++++-- tests/config-semis/escaped.semis.yaml | 8 ++++ tests/config-semis/unescaped.semis.yaml | 9 +++++ tests/test_octodns_provider_yaml.py | 39 +++++++++++++++++++ 5 files changed, 68 insertions(+), 3 deletions(-) create mode 100644 .changelog/7a30ee9fb9dd433c9181ddd5628e5cd3.md create mode 100644 tests/config-semis/escaped.semis.yaml create mode 100644 tests/config-semis/unescaped.semis.yaml diff --git a/.changelog/7a30ee9fb9dd433c9181ddd5628e5cd3.md b/.changelog/7a30ee9fb9dd433c9181ddd5628e5cd3.md new file mode 100644 index 0000000..5dc0db7 --- /dev/null +++ b/.changelog/7a30ee9fb9dd433c9181ddd5628e5cd3.md @@ -0,0 +1,4 @@ +--- +type: minor +--- +Add unescaped semicolons support to YamlProvider \ No newline at end of file diff --git a/octodns/provider/yaml.py b/octodns/provider/yaml.py index 4c704ac..6fa318c 100644 --- a/octodns/provider/yaml.py +++ b/octodns/provider/yaml.py @@ -334,11 +334,16 @@ class YamlProvider(BaseProvider): data = [data] for d in data: _type = d.get('type') - if not self.escaped_semicolons and _type in ('SPF', 'TXT'): + if not self.escaped_semicolons and _type in ( + 'SPF', + 'TXT', + ): if 'value' in d: - d['value'] = d[''].replace(';', '\\;') + d['value'] = d['value'].replace(';', '\\;') if 'values' in d: - d['values'] = [v.replace(';', '\\;') for v in d['values']] + d['values'] = [ + v.replace(';', '\\;') for v in d['values'] + ] if 'ttl' not in d: d['ttl'] = self.default_ttl record = Record.new( diff --git a/tests/config-semis/escaped.semis.yaml b/tests/config-semis/escaped.semis.yaml new file mode 100644 index 0000000..634ed15 --- /dev/null +++ b/tests/config-semis/escaped.semis.yaml @@ -0,0 +1,8 @@ +--- +one: + type: TXT + value: This has a semi-colon\; that is escaped. +two: + type: TXT + values: + - This has a semi-colon too\; that is escaped. diff --git a/tests/config-semis/unescaped.semis.yaml b/tests/config-semis/unescaped.semis.yaml new file mode 100644 index 0000000..d1c2a8d --- /dev/null +++ b/tests/config-semis/unescaped.semis.yaml @@ -0,0 +1,9 @@ +--- +one: + type: TXT + value: This has a semi-colon; that isn't escaped. +two: + type: TXT + values: + - This has a semi-colon too; that isn't escaped. + - ; diff --git a/tests/test_octodns_provider_yaml.py b/tests/test_octodns_provider_yaml.py index 77a4f1e..035439d 100644 --- a/tests/test_octodns_provider_yaml.py +++ b/tests/test_octodns_provider_yaml.py @@ -471,6 +471,45 @@ xn--dj-kia8a: # make sure that we get the idna one back self.assertEqual(idna, provider._zone_sources(zone)) + def test_unescaped_semicolons(self): + source = YamlProvider( + 'test', + join(dirname(__file__), 'config-semis'), + escaped_semicolons=False, + ) + + zone = Zone('unescaped.semis.', []) + source.populate(zone) + self.assertEqual(2, len(zone.records)) + one = next(r for r in zone.records if r.name == 'one') + self.assertTrue(one) + self.assertEqual( + ["This has a semi-colon\\; that isn't escaped."], one.values + ) + two = next(r for r in zone.records if r.name == 'two') + self.assertTrue(two) + self.assertEqual( + ["This has a semi-colon too\\; that isn't escaped.", '\\;'], + two.values, + ) + + zone = Zone('escaped.semis.', []) + source.populate(zone) + self.assertEqual(2, len(zone.records)) + one = next(r for r in zone.records if r.name == 'one') + self.assertTrue(one) + # self.assertEqual( + # ["This has a semi-colon\\; that isn't escaped."], one.values + # ) + two = next(r for r in zone.records if r.name == 'two') + self.assertTrue(two) + + +# self.assertEqual( +# ["This has a semi-colon too\\; that isn't escaped.", '\\;'], +# two.values, +# ) + class TestSplitYamlProvider(TestCase): def test_list_all_yaml_files(self):