From 2e494d636a5080a43f3dae9b670b95b0e37d9156 Mon Sep 17 00:00:00 2001 From: Noumbissi valere Gille Geovan Date: Fri, 8 Mar 2019 03:32:55 +0100 Subject: [PATCH] [openwrt] Allow configure DNS resolvers without the need of defining interfaces #117 Fixed the issue by defining two additional classes (DnsServer and DnsSearch) in the interfaces converter. These additional classes are to convert the dns configs when an interface is not provided in the netjson. when an interface is provided, the default converters in the Interface class is used to convert the dns to native config. this was left so because when an interface is defined, other options like DHCP servers might be available and the Interface class handles that very well. Test cases were added to test for these features and also to increase the coverage. Fixes #117 --- .../backends/openwrt/converters/__init__.py | 4 +- .../backends/openwrt/converters/interfaces.py | 63 +++++++++++++++++++ netjsonconfig/backends/openwrt/openwrt.py | 2 + tests/openwrt/test_interfaces.py | 27 ++++++++ 4 files changed, 95 insertions(+), 1 deletion(-) diff --git a/netjsonconfig/backends/openwrt/converters/__init__.py b/netjsonconfig/backends/openwrt/converters/__init__.py index 989eab33a..6ff0cf8e0 100644 --- a/netjsonconfig/backends/openwrt/converters/__init__.py +++ b/netjsonconfig/backends/openwrt/converters/__init__.py @@ -1,5 +1,7 @@ from .default import Default from .interfaces import Interfaces +from .interfaces import DnsServer +from .interfaces import DnsSearch from .general import General from .led import Led from .ntp import Ntp @@ -10,7 +12,7 @@ from .switch import Switch from .wireless import Wireless -__all__ = ['Default', 'Interfaces', 'General', +__all__ = ['Default', 'Interfaces', 'DnsServer', 'DnsSearch', 'General', 'Led', 'Ntp', 'OpenVpn', 'Radios', 'Routes', 'Rules', 'Switch', 'Wireless'] diff --git a/netjsonconfig/backends/openwrt/converters/interfaces.py b/netjsonconfig/backends/openwrt/converters/interfaces.py index ba15e1d60..0d80e834b 100644 --- a/netjsonconfig/backends/openwrt/converters/interfaces.py +++ b/netjsonconfig/backends/openwrt/converters/interfaces.py @@ -311,3 +311,66 @@ def __netjson_dns(self, interface, result): items = items.split() result.setdefault(netjson_key, []) result[netjson_key] += items + + +class DnsServer(OpenWrtConverter): + netjson_key = 'dns_servers' + intermediate_key = 'network' + _uci_types = ['dns'] + + def to_intermediate_loop(self, block, result, index=None): + """ + Convert dns_servers NetJson to intermediate data structure if + no interface was provided. + """ + if 'interfaces' not in self.backend.config: + if index > 1: + result['network'][0]['dns'] += ' ' + block + return result + options = { + '.type': 'dns', + '.name': 'dns', + 'dns': block + } + result.setdefault('network', []) + result['network'].append(self.sorted_dict(options)) + return result + + def to_netjson_loop(self, block, result, index=None): + if 'dns' in block: + items = block.pop('dns') + if isinstance(items, six.string_types): + items = items.split() + result.setdefault('dns_servers', []) + result['dns_servers'] += items + if 'dns_search' in block: + items = block.pop('dns_search') + if isinstance(items, six.string_types): + items = items.split() + result.setdefault('dns_search', []) + result['dns_search'] += items + return result + + +class DnsSearch(OpenWrtConverter): + netjson_key = 'dns_search' + intermediate_key = 'network' + _uci_types = ['dns'] + + def to_intermediate_loop(self, block, result, index=None): + """ + Convert dns_search NetJson to intermediate data structure if + no interface was provided. + """ + if 'interfaces' not in self.backend.config: + if index > 1: + result['network'][0]['dns_search'] += ' ' + block + return result + options = { + '.type': 'dns', + '.name': 'dns', + 'dns_search': block + } + result.setdefault('network', []) + result['network'].append(self.sorted_dict(options)) + return result diff --git a/netjsonconfig/backends/openwrt/openwrt.py b/netjsonconfig/backends/openwrt/openwrt.py index 0d18d91ff..b05525e57 100644 --- a/netjsonconfig/backends/openwrt/openwrt.py +++ b/netjsonconfig/backends/openwrt/openwrt.py @@ -15,6 +15,8 @@ class OpenWrt(BaseBackend): converters.Ntp, converters.Led, converters.Interfaces, + converters.DnsServer, + converters.DnsSearch, converters.Routes, converters.Rules, converters.Switch, diff --git a/tests/openwrt/test_interfaces.py b/tests/openwrt/test_interfaces.py index 0f17b4ccc..283b577cb 100644 --- a/tests/openwrt/test_interfaces.py +++ b/tests/openwrt/test_interfaces.py @@ -1027,6 +1027,33 @@ def test_parse_dns_list(self): o = OpenWrt(native=native) self.assertEqual(o.config, self._dns_netjson) + def test_render_dns_without_interface(self): + o = OpenWrt({ + "dns_servers": ["10.11.12.13", "8.8.8.8"], + "dns_search": ["netjson.org", "openwisp.org"], + }) + expected = self._tabs("""package network + +config dns 'dns' + option dns '10.11.12.13 8.8.8.8' + option dns_search 'netjson.org openwisp.org' +""") + self.assertEqual(o.render(), expected) + + def test_parse_dns_without_interface(self): + native = self._tabs("""package network + +config dns 'dns' + option dns '8.8.8.8 4.4.4.4' + option dns_search 'netjson.org openwisp.org' +""") + _dns_json = { + "dns_servers": ["8.8.8.8", "4.4.4.4"], + "dns_search": ["netjson.org", "openwisp.org"], + } + o = OpenWrt(native=native) + self.assertEqual(o.config, _dns_json) + def test_dns_dhcpv4_ignored(self): o = OpenWrt({ "interfaces": [