diff --git a/netjsonconfig/backends/openwrt/converters/firewall.py b/netjsonconfig/backends/openwrt/converters/firewall.py index a45cbd440..bd04031de 100644 --- a/netjsonconfig/backends/openwrt/converters/firewall.py +++ b/netjsonconfig/backends/openwrt/converters/firewall.py @@ -205,7 +205,31 @@ def __netjson_redirect(self, redirect): redirect["proto"] = ["tcp", "udp"] else: redirect["proto"] = [proto] + + if "weekdays" in redirect: + weekdays = redirect["weekdays"] + if not isinstance(weekdays, list): + weekdays = weekdays.split() + # UCI allows the first entry to be "!" which means negate the remaining + # entries + if weekdays[0] == "!": + all_days = ["sun", "mon", "tue", "wed", "thu", "fri", "sat"] + wd = set([x for x in weekdays[1:]]) + redirect["weekdays"] = list(set(all_days) - wd) + # Sort the days for predictability when testing + redirect["weekdays"].sort(key=lambda v: all_days.index(v)) + if "monthdays" in redirect: - redirect["monthdays"] = [int(x) for x in redirect["monthdays"]] + monthdays = redirect["monthdays"] + if not isinstance(monthdays, list): + monthdays = monthdays.split() + # UCI allows the first entry to be "!" which means negate the remaining + # entries + if monthdays[0] == "!": + all_days = set(range(1,32)) + md = set([int(x) for x in monthdays[1:]]) + redirect["monthdays"] = list(all_days - md) + else: + redirect["monthdays"] = [int(x) for x in monthdays] return self.type_cast(redirect) diff --git a/tests/openwrt/test_firewall.py b/tests/openwrt/test_firewall.py index 0fe7ca1eb..1a8c64d82 100644 --- a/tests/openwrt/test_firewall.py +++ b/tests/openwrt/test_firewall.py @@ -484,3 +484,43 @@ def test_redirect_monthdays_validation_error_2(self): o = OpenWrt({"firewall": {"redirects": [{"monthdays": [0, 2, 8]}]}}) with self.assertRaises(ValidationError): o.validate() + + _redirect_3_uci = textwrap.dedent( + """\ + package firewall + + config defaults 'defaults' + + config redirect 'redirect_Adblock DNS, port 53' + option name 'Adblock DNS, port 53' + option src 'lan' + option proto 'tcpudp' + option src_dport '53' + option dest_port '53' + option target 'DNAT' + option weekdays '! mon tue wed' + option monthdays '! 1 2 3 4 5' + """ + ) + + _redirect_3_netjson = { + "firewall": { + "redirects": [ + { + "name": "Adblock DNS, port 53", + "src": "lan", + "proto": ["tcp", "udp"], + "src_dport": "53", + "dest_port": "53", + "target": "DNAT", + "weekdays": ["sun", "thu", "fri", "sat"], + "monthdays": [6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31], + } + ] + } + } + + def test_parse_redirect_3(self): + o = OpenWrt(native=self._redirect_3_uci) + print(o.config) + self.assertEqual(o.config, self._redirect_3_netjson)