From a6f17205c215f910f5b81c85895c1b3bbdafeaa8 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Fri, 19 May 2017 01:37:13 +0400 Subject: [PATCH 001/183] [rasbian] Added backend skeleton --- bin/netjsonconfig | 4 ++-- docs/source/backends/raspbian.rst | 3 +++ netjsonconfig/backends/raspbian/__init__.py | 0 netjsonconfig/backends/raspbian/raspbian.py | 20 ++++++++++++++++++++ netjsonconfig/backends/raspbian/renderers.py | 5 +++++ netjsonconfig/backends/raspbian/schema.py | 7 +++++++ 6 files changed, 37 insertions(+), 2 deletions(-) create mode 100644 docs/source/backends/raspbian.rst create mode 100644 netjsonconfig/backends/raspbian/__init__.py create mode 100644 netjsonconfig/backends/raspbian/raspbian.py create mode 100644 netjsonconfig/backends/raspbian/renderers.py create mode 100644 netjsonconfig/backends/raspbian/schema.py diff --git a/bin/netjsonconfig b/bin/netjsonconfig index 317da7b54..c072edab5 100644 --- a/bin/netjsonconfig +++ b/bin/netjsonconfig @@ -56,7 +56,7 @@ output = parser.add_argument_group('output') output.add_argument('--backend', '-b', required=True, - choices=['openwrt', 'openwisp', 'openvpn'], + choices=['openwrt', 'openwisp', 'openvpn', 'raspbian'], action='store', type=str, help='Configuration backend') @@ -169,7 +169,7 @@ method_arguments = parse_method_arguments(args.args) backends = { 'openwrt': netjsonconfig.OpenWrt, 'openwisp': netjsonconfig.OpenWisp, - 'openvpn': netjsonconfig.OpenVpn + 'raspbian': netjsonconfig.Raspbian } backend_class = backends[args.backend] diff --git a/docs/source/backends/raspbian.rst b/docs/source/backends/raspbian.rst new file mode 100644 index 000000000..ce55eef7d --- /dev/null +++ b/docs/source/backends/raspbian.rst @@ -0,0 +1,3 @@ +================ +Raspbian Backend +================ diff --git a/netjsonconfig/backends/raspbian/__init__.py b/netjsonconfig/backends/raspbian/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/netjsonconfig/backends/raspbian/raspbian.py b/netjsonconfig/backends/raspbian/raspbian.py new file mode 100644 index 000000000..728ceda95 --- /dev/null +++ b/netjsonconfig/backends/raspbian/raspbian.py @@ -0,0 +1,20 @@ +from re + +from . import renderers +from ..base import BaseBackend +from .schema import schema + +class Rasbian(BaseBackend): + """ + Rasbian Backend + """ + schema = schema + env_path = 'netjsonconfig.baskend.openwrt' + renderers = [ + renderers.# + ] + @classmethod + def get_renderers(cls): + return # + def _generate_contents(self, tar): + return # \ No newline at end of file diff --git a/netjsonconfig/backends/raspbian/renderers.py b/netjsonconfig/backends/raspbian/renderers.py new file mode 100644 index 000000000..4ae21a95c --- /dev/null +++ b/netjsonconfig/backends/raspbian/renderers.py @@ -0,0 +1,5 @@ +from ..base import BaseRenderer + +class BaseRaspbianRenderer(BaseRenderer): + def cleanup(self, output): + return output \ No newline at end of file diff --git a/netjsonconfig/backends/raspbian/schema.py b/netjsonconfig/backends/raspbian/schema.py new file mode 100644 index 000000000..45f30ad1b --- /dev/null +++ b/netjsonconfig/backends/raspbian/schema.py @@ -0,0 +1,7 @@ +from ..schema import schema as default_schema +from ..schema import DEFAULT_FILE_MODE +from ..utils import merge_config + +schema = merge_config(default_schema, { + # +}) \ No newline at end of file From 24eecf428589837781b3f4b5c5c320756d21d0ff Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Fri, 19 May 2017 18:19:12 +0400 Subject: [PATCH 002/183] [raspbian] Added rasbian support to __init__ --- netjsonconfig/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/netjsonconfig/__init__.py b/netjsonconfig/__init__.py index 7e5e3c872..c783455c9 100644 --- a/netjsonconfig/__init__.py +++ b/netjsonconfig/__init__.py @@ -3,3 +3,4 @@ from .backends.openwrt.openwrt import OpenWrt # noqa from .backends.openwisp.openwisp import OpenWisp # noqa from .backends.openvpn.openvpn import OpenVpn # noqa +from .backedns.raspbian.raspbian import Raspbian #noqa From 9afcfee29f63e805043a8d5d1762727b7ba10033 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Fri, 19 May 2017 18:22:39 +0400 Subject: [PATCH 003/183] [raspbian] Created Rasbian class definition --- netjsonconfig/backends/raspbian/raspbian.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/netjsonconfig/backends/raspbian/raspbian.py b/netjsonconfig/backends/raspbian/raspbian.py index 728ceda95..f8c7a4287 100644 --- a/netjsonconfig/backends/raspbian/raspbian.py +++ b/netjsonconfig/backends/raspbian/raspbian.py @@ -11,10 +11,17 @@ class Rasbian(BaseBackend): schema = schema env_path = 'netjsonconfig.baskend.openwrt' renderers = [ - renderers.# + renderers.NetworkRenderer, + renderers.WirelessRenderer ] @classmethod def get_renderers(cls): - return # + pass + def _generate_contents(self, tar): - return # \ No newline at end of file + """ + Add configuration files to tar files instance. + + :param tar: tarfile instance + :return None + """ From d45df4c72aae7ac6cc2d503df9e57a33dc7dcb5b Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Fri, 19 May 2017 18:24:51 +0400 Subject: [PATCH 004/183] [raspbian] Added NetworkRenderer and WirelessRenderer --- netjsonconfig/backends/raspbian/renderers.py | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/netjsonconfig/backends/raspbian/renderers.py b/netjsonconfig/backends/raspbian/renderers.py index 4ae21a95c..c361bc3cc 100644 --- a/netjsonconfig/backends/raspbian/renderers.py +++ b/netjsonconfig/backends/raspbian/renderers.py @@ -1,5 +1,15 @@ from ..base import BaseRenderer -class BaseRaspbianRenderer(BaseRenderer): - def cleanup(self, output): - return output \ No newline at end of file +class NetworkRenderer(BaseRaspbianRenderer): + """ + Write configurations for + - resolv + - dns servers + """ + + +class WirelessRenderer(BaseRaspbianRenderer): + """ + Write configurations for + - interfaces + """ From 871fbac5c6a39ff57b435593f370c621946554ce Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Fri, 19 May 2017 18:25:57 +0400 Subject: [PATCH 005/183] [raspbian] Modified schema.py --- netjsonconfig/backends/raspbian/schema.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/netjsonconfig/backends/raspbian/schema.py b/netjsonconfig/backends/raspbian/schema.py index 45f30ad1b..0ef461194 100644 --- a/netjsonconfig/backends/raspbian/schema.py +++ b/netjsonconfig/backends/raspbian/schema.py @@ -2,6 +2,4 @@ from ..schema import DEFAULT_FILE_MODE from ..utils import merge_config -schema = merge_config(default_schema, { - # -}) \ No newline at end of file +schema = merge_config(default_schema, {}) From 30dc5d910926703164416dd9250ee696ec472b8b Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Fri, 19 May 2017 18:30:23 +0400 Subject: [PATCH 006/183] [raspbian] Added template files for wireless and network class --- netjsonconfig/backends/raspbian/templates/network.jinja2 | 0 netjsonconfig/backends/raspbian/templates/wireless.jinja2 | 0 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 netjsonconfig/backends/raspbian/templates/network.jinja2 create mode 100644 netjsonconfig/backends/raspbian/templates/wireless.jinja2 diff --git a/netjsonconfig/backends/raspbian/templates/network.jinja2 b/netjsonconfig/backends/raspbian/templates/network.jinja2 new file mode 100644 index 000000000..e69de29bb diff --git a/netjsonconfig/backends/raspbian/templates/wireless.jinja2 b/netjsonconfig/backends/raspbian/templates/wireless.jinja2 new file mode 100644 index 000000000..e69de29bb From 849c2ab24f6910dcce630ac01bbcfcd31b2f6522 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Fri, 19 May 2017 18:32:13 +0400 Subject: [PATCH 007/183] [raspbian] Added test files for network and wireless --- tests/raspbian/test_network.py | 3 +++ tests/raspbian/test_wireless.py | 3 +++ 2 files changed, 6 insertions(+) create mode 100644 tests/raspbian/test_network.py create mode 100644 tests/raspbian/test_wireless.py diff --git a/tests/raspbian/test_network.py b/tests/raspbian/test_network.py new file mode 100644 index 000000000..1dd0f73f1 --- /dev/null +++ b/tests/raspbian/test_network.py @@ -0,0 +1,3 @@ +import unitest + +from netjsonconfig import Raspbian diff --git a/tests/raspbian/test_wireless.py b/tests/raspbian/test_wireless.py new file mode 100644 index 000000000..1dd0f73f1 --- /dev/null +++ b/tests/raspbian/test_wireless.py @@ -0,0 +1,3 @@ +import unitest + +from netjsonconfig import Raspbian From 193cbe798af74980d360573800f6da28d7a1efbc Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Sat, 20 May 2017 19:15:27 +0400 Subject: [PATCH 008/183] [raspbian] Fixed various typos --- netjsonconfig/__init__.py | 2 +- netjsonconfig/backends/raspbian/raspbian.py | 2 +- netjsonconfig/backends/raspbian/renderers.py | 8 ++++++++ netjsonconfig/backends/raspbian/schema.py | 6 +++--- 4 files changed, 13 insertions(+), 5 deletions(-) diff --git a/netjsonconfig/__init__.py b/netjsonconfig/__init__.py index c783455c9..bed7d2092 100644 --- a/netjsonconfig/__init__.py +++ b/netjsonconfig/__init__.py @@ -3,4 +3,4 @@ from .backends.openwrt.openwrt import OpenWrt # noqa from .backends.openwisp.openwisp import OpenWisp # noqa from .backends.openvpn.openvpn import OpenVpn # noqa -from .backedns.raspbian.raspbian import Raspbian #noqa +from .backends.raspbian.raspbian import Raspbian #noqa diff --git a/netjsonconfig/backends/raspbian/raspbian.py b/netjsonconfig/backends/raspbian/raspbian.py index f8c7a4287..47c45da41 100644 --- a/netjsonconfig/backends/raspbian/raspbian.py +++ b/netjsonconfig/backends/raspbian/raspbian.py @@ -1,4 +1,4 @@ -from re +import re from . import renderers from ..base import BaseBackend diff --git a/netjsonconfig/backends/raspbian/renderers.py b/netjsonconfig/backends/raspbian/renderers.py index c361bc3cc..1269e6e79 100644 --- a/netjsonconfig/backends/raspbian/renderers.py +++ b/netjsonconfig/backends/raspbian/renderers.py @@ -1,5 +1,8 @@ from ..base import BaseRenderer +class BaseRaspbianRenderer(BaseRenderer): + def cleanup(self, output): + return output class NetworkRenderer(BaseRaspbianRenderer): """ Write configurations for @@ -13,3 +16,8 @@ class WirelessRenderer(BaseRaspbianRenderer): Write configurations for - interfaces """ + def _get_interface(self): + interfaces = self.config.get('interfaces', {}).copy() + print interfaces + # test_interface = [] + # if interfaces: diff --git a/netjsonconfig/backends/raspbian/schema.py b/netjsonconfig/backends/raspbian/schema.py index 0ef461194..9eacef02a 100644 --- a/netjsonconfig/backends/raspbian/schema.py +++ b/netjsonconfig/backends/raspbian/schema.py @@ -1,5 +1,5 @@ -from ..schema import schema as default_schema -from ..schema import DEFAULT_FILE_MODE -from ..utils import merge_config +from ...schema import schema as default_schema +from ...schema import DEFAULT_FILE_MODE +from ...utils import merge_config schema = merge_config(default_schema, {}) From 9bdee87106bead9fdc9d59d990e2df979238d9b0 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Sat, 20 May 2017 20:20:49 +0400 Subject: [PATCH 009/183] [raspbian] Initialized jinja templates --- netjsonconfig/backends/raspbian/raspbian.py | 5 +++-- netjsonconfig/backends/raspbian/renderers.py | 1 + netjsonconfig/backends/raspbian/templates/network.jinja2 | 3 +++ netjsonconfig/backends/raspbian/templates/wireless.jinja2 | 3 +++ 4 files changed, 10 insertions(+), 2 deletions(-) diff --git a/netjsonconfig/backends/raspbian/raspbian.py b/netjsonconfig/backends/raspbian/raspbian.py index 47c45da41..85c46cd27 100644 --- a/netjsonconfig/backends/raspbian/raspbian.py +++ b/netjsonconfig/backends/raspbian/raspbian.py @@ -4,12 +4,12 @@ from ..base import BaseBackend from .schema import schema -class Rasbian(BaseBackend): +class Raspbian(BaseBackend): """ Rasbian Backend """ schema = schema - env_path = 'netjsonconfig.baskend.openwrt' + env_path = 'netjsonconfig.backends.raspbian' renderers = [ renderers.NetworkRenderer, renderers.WirelessRenderer @@ -25,3 +25,4 @@ def _generate_contents(self, tar): :param tar: tarfile instance :return None """ + pass diff --git a/netjsonconfig/backends/raspbian/renderers.py b/netjsonconfig/backends/raspbian/renderers.py index 1269e6e79..610504969 100644 --- a/netjsonconfig/backends/raspbian/renderers.py +++ b/netjsonconfig/backends/raspbian/renderers.py @@ -3,6 +3,7 @@ class BaseRaspbianRenderer(BaseRenderer): def cleanup(self, output): return output + class NetworkRenderer(BaseRaspbianRenderer): """ Write configurations for diff --git a/netjsonconfig/backends/raspbian/templates/network.jinja2 b/netjsonconfig/backends/raspbian/templates/network.jinja2 index e69de29bb..c146caa9d 100644 --- a/netjsonconfig/backends/raspbian/templates/network.jinja2 +++ b/netjsonconfig/backends/raspbian/templates/network.jinja2 @@ -0,0 +1,3 @@ +{% if not is_empty %} + +{% endif %} diff --git a/netjsonconfig/backends/raspbian/templates/wireless.jinja2 b/netjsonconfig/backends/raspbian/templates/wireless.jinja2 index e69de29bb..c146caa9d 100644 --- a/netjsonconfig/backends/raspbian/templates/wireless.jinja2 +++ b/netjsonconfig/backends/raspbian/templates/wireless.jinja2 @@ -0,0 +1,3 @@ +{% if not is_empty %} + +{% endif %} From e29bc0b6312ae7f88536ea498fdca0b3768159bc Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Fri, 26 May 2017 02:02:21 +0400 Subject: [PATCH 010/183] [raspbian] dns_severs in NetworkRenderer --- netjsonconfig/backends/raspbian/renderers.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/netjsonconfig/backends/raspbian/renderers.py b/netjsonconfig/backends/raspbian/renderers.py index 610504969..a0cedfd36 100644 --- a/netjsonconfig/backends/raspbian/renderers.py +++ b/netjsonconfig/backends/raspbian/renderers.py @@ -10,6 +10,10 @@ class NetworkRenderer(BaseRaspbianRenderer): - resolv - dns servers """ + def _get_dns_servers(self): + dns_servers = self.config.get('dns_servers', []) + if dns_servers: + return dns_servers class WirelessRenderer(BaseRaspbianRenderer): @@ -18,7 +22,4 @@ class WirelessRenderer(BaseRaspbianRenderer): - interfaces """ def _get_interface(self): - interfaces = self.config.get('interfaces', {}).copy() - print interfaces - # test_interface = [] - # if interfaces: + interfaces = self.config.get('interfaces', {}) From 6f21e536c46d1243b0fef9b57eeb75dcfcd69110 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Fri, 26 May 2017 02:02:57 +0400 Subject: [PATCH 011/183] [raspbian] dns_server in template --- netjsonconfig/backends/raspbian/templates/network.jinja2 | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/netjsonconfig/backends/raspbian/templates/network.jinja2 b/netjsonconfig/backends/raspbian/templates/network.jinja2 index c146caa9d..08f78553e 100644 --- a/netjsonconfig/backends/raspbian/templates/network.jinja2 +++ b/netjsonconfig/backends/raspbian/templates/network.jinja2 @@ -1,3 +1,6 @@ {% if not is_empty %} - +resolv.conf +{% for dns_server in dns_servers %} +nameserver {{ dns_server}} +{% endfor %} {% endif %} From a08e03d55901379ddd917c80a03a71522a24eb75 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Fri, 26 May 2017 02:03:23 +0400 Subject: [PATCH 012/183] [raspbian] dns_server in template --- netjsonconfig/backends/raspbian/templates/network.jinja2 | 1 - 1 file changed, 1 deletion(-) diff --git a/netjsonconfig/backends/raspbian/templates/network.jinja2 b/netjsonconfig/backends/raspbian/templates/network.jinja2 index 08f78553e..6fb3b57ed 100644 --- a/netjsonconfig/backends/raspbian/templates/network.jinja2 +++ b/netjsonconfig/backends/raspbian/templates/network.jinja2 @@ -1,5 +1,4 @@ {% if not is_empty %} -resolv.conf {% for dns_server in dns_servers %} nameserver {{ dns_server}} {% endfor %} From ab98827ab20e902ab4df0060c29f29f17c518615 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Fri, 26 May 2017 02:10:19 +0400 Subject: [PATCH 013/183] [raspbian] dns_search in NetworkRenderer and template --- netjsonconfig/backends/raspbian/renderers.py | 5 +++++ netjsonconfig/backends/raspbian/templates/network.jinja2 | 3 +++ 2 files changed, 8 insertions(+) diff --git a/netjsonconfig/backends/raspbian/renderers.py b/netjsonconfig/backends/raspbian/renderers.py index a0cedfd36..014b2ac48 100644 --- a/netjsonconfig/backends/raspbian/renderers.py +++ b/netjsonconfig/backends/raspbian/renderers.py @@ -15,6 +15,11 @@ def _get_dns_servers(self): if dns_servers: return dns_servers + def _get_dns_search(self): + dns_search = self.config.get('dns_search', None) + if dns_search: + return dns_search + class WirelessRenderer(BaseRaspbianRenderer): """ diff --git a/netjsonconfig/backends/raspbian/templates/network.jinja2 b/netjsonconfig/backends/raspbian/templates/network.jinja2 index 6fb3b57ed..2c7780e0c 100644 --- a/netjsonconfig/backends/raspbian/templates/network.jinja2 +++ b/netjsonconfig/backends/raspbian/templates/network.jinja2 @@ -2,4 +2,7 @@ {% for dns_server in dns_servers %} nameserver {{ dns_server}} {% endfor %} +{% for dns_search in dns_search %} +search {{ dns_search }} +{% endfor %} {% endif %} From 41e7b04221feaa77afa643c51102bfeeed9af578 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Fri, 26 May 2017 02:20:35 +0400 Subject: [PATCH 014/183] [raspbian] Added test for dns_server --- tests/raspbian/test_network.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/tests/raspbian/test_network.py b/tests/raspbian/test_network.py index 1dd0f73f1..46395d761 100644 --- a/tests/raspbian/test_network.py +++ b/tests/raspbian/test_network.py @@ -1,3 +1,16 @@ -import unitest +import unittest from netjsonconfig import Raspbian +from netjsonconfig.exceptions import ValidationError +from netjsonconfig.utils import _TabsMixin + +class TestNetworkRenderer(unittest.TestCase, _TabsMixin): + def test_dns_server(self): + o = Raspbian({ + "dns_servers": [ + "10.254.0.1", + "10.254.0.2" + ] + }) + expected = self._tabs("""nameserver​ 10.254.0.1 +nameserver​ 10.254.0.2""") From d05e6850dc405907cce37d0f745981715701e1ee Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Fri, 26 May 2017 02:33:37 +0400 Subject: [PATCH 015/183] [raspbian] Added tests for dns_server and dns_search --- netjsonconfig/backends/raspbian/raspbian.py | 2 +- tests/raspbian/test_network.py | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/netjsonconfig/backends/raspbian/raspbian.py b/netjsonconfig/backends/raspbian/raspbian.py index 85c46cd27..0be89e4c0 100644 --- a/netjsonconfig/backends/raspbian/raspbian.py +++ b/netjsonconfig/backends/raspbian/raspbian.py @@ -6,7 +6,7 @@ class Raspbian(BaseBackend): """ - Rasbian Backend + Raspbian Backend """ schema = schema env_path = 'netjsonconfig.backends.raspbian' diff --git a/tests/raspbian/test_network.py b/tests/raspbian/test_network.py index 46395d761..fbcf55a52 100644 --- a/tests/raspbian/test_network.py +++ b/tests/raspbian/test_network.py @@ -14,3 +14,13 @@ def test_dns_server(self): }) expected = self._tabs("""nameserver​ 10.254.0.1 nameserver​ 10.254.0.2""") + self.assertEqual(o.render(), expected) + + def test_dns_search(self): + o = Raspbian({ + "dns_search": [ + "domain.com" + ] + }) + expected = self._tabs("""search​ domain.com""") + self.assertEqual(o.render(), expected) From 86c0e6fe2293826e2d4f2a75b751951c04545046 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Sun, 4 Jun 2017 04:02:40 +0530 Subject: [PATCH 016/183] [raspbian] Added convertors for dns_search and dns_servers --- netjsonconfig/backends/raspbian/converters.py | 38 +++++++++++++++++++ netjsonconfig/backends/raspbian/raspbian.py | 24 ++++-------- netjsonconfig/backends/raspbian/renderers.py | 29 +------------- 3 files changed, 47 insertions(+), 44 deletions(-) create mode 100644 netjsonconfig/backends/raspbian/converters.py diff --git a/netjsonconfig/backends/raspbian/converters.py b/netjsonconfig/backends/raspbian/converters.py new file mode 100644 index 000000000..31dcc09d9 --- /dev/null +++ b/netjsonconfig/backends/raspbian/converters.py @@ -0,0 +1,38 @@ +from ...utils import get_copy, sorted_dict +from ..base.converter import BaseConverter + + +class DNS_Servers(BaseConverter): + netjson_key = 'dns_servers' + + def to_intermediate(self): + result = [] + dns_servers = get_copy(self.netjson, self.netjson_key) + temp = { + 'nameserver': [], + } + for nameserver in dns_servers: + temp['nameserver'].append({ + 'ip': nameserver, + }) + result.append(sorted_dict(temp)) + print result + return (('dns_servers', result),) + + +class DNS_Search(BaseConverter): + netjson_key = 'dns_search' + + def to_intermediate(self): + result = [] + dns_search = get_copy(self.netjson, self.netjson_key) + temp = { + 'domain': [], + } + for domain in dns_search: + temp['domain'].append({ + 'domain': domain + }) + result.append(sorted_dict(temp)) + print result + return (('dns_search', result),) diff --git a/netjsonconfig/backends/raspbian/raspbian.py b/netjsonconfig/backends/raspbian/raspbian.py index 0be89e4c0..6c329333c 100644 --- a/netjsonconfig/backends/raspbian/raspbian.py +++ b/netjsonconfig/backends/raspbian/raspbian.py @@ -1,7 +1,8 @@ import re -from . import renderers -from ..base import BaseBackend +from .converters import * +from .renderers import Raspbian +from ..base.backend import BaseBackend from .schema import schema class Raspbian(BaseBackend): @@ -10,19 +11,8 @@ class Raspbian(BaseBackend): """ schema = schema env_path = 'netjsonconfig.backends.raspbian' - renderers = [ - renderers.NetworkRenderer, - renderers.WirelessRenderer + converters = [ + DNS_Servers, + DNS_Search ] - @classmethod - def get_renderers(cls): - pass - - def _generate_contents(self, tar): - """ - Add configuration files to tar files instance. - - :param tar: tarfile instance - :return None - """ - pass + renderer = Raspbian diff --git a/netjsonconfig/backends/raspbian/renderers.py b/netjsonconfig/backends/raspbian/renderers.py index 014b2ac48..a1da31c86 100644 --- a/netjsonconfig/backends/raspbian/renderers.py +++ b/netjsonconfig/backends/raspbian/renderers.py @@ -1,30 +1,5 @@ -from ..base import BaseRenderer +from ..base.renderer import BaseRenderer -class BaseRaspbianRenderer(BaseRenderer): +class Raspbian(BaseRenderer): def cleanup(self, output): return output - -class NetworkRenderer(BaseRaspbianRenderer): - """ - Write configurations for - - resolv - - dns servers - """ - def _get_dns_servers(self): - dns_servers = self.config.get('dns_servers', []) - if dns_servers: - return dns_servers - - def _get_dns_search(self): - dns_search = self.config.get('dns_search', None) - if dns_search: - return dns_search - - -class WirelessRenderer(BaseRaspbianRenderer): - """ - Write configurations for - - interfaces - """ - def _get_interface(self): - interfaces = self.config.get('interfaces', {}) From f22c0dee1863b24b940007dc85158dada3d67279 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Sun, 4 Jun 2017 04:19:16 +0530 Subject: [PATCH 017/183] [raspbian] Fixed flake8 and isort warnings --- netjsonconfig/__init__.py | 2 +- netjsonconfig/backends/raspbian/raspbian.py | 3 ++- netjsonconfig/backends/raspbian/renderers.py | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/netjsonconfig/__init__.py b/netjsonconfig/__init__.py index bed7d2092..9aa3a6a9e 100644 --- a/netjsonconfig/__init__.py +++ b/netjsonconfig/__init__.py @@ -3,4 +3,4 @@ from .backends.openwrt.openwrt import OpenWrt # noqa from .backends.openwisp.openwisp import OpenWisp # noqa from .backends.openvpn.openvpn import OpenVpn # noqa -from .backends.raspbian.raspbian import Raspbian #noqa +from .backends.raspbian.raspbian import Raspbian # noqa diff --git a/netjsonconfig/backends/raspbian/raspbian.py b/netjsonconfig/backends/raspbian/raspbian.py index 6c329333c..f43560248 100644 --- a/netjsonconfig/backends/raspbian/raspbian.py +++ b/netjsonconfig/backends/raspbian/raspbian.py @@ -1,10 +1,11 @@ import re -from .converters import * +from . import converters from .renderers import Raspbian from ..base.backend import BaseBackend from .schema import schema + class Raspbian(BaseBackend): """ Raspbian Backend diff --git a/netjsonconfig/backends/raspbian/renderers.py b/netjsonconfig/backends/raspbian/renderers.py index a1da31c86..a3c89e508 100644 --- a/netjsonconfig/backends/raspbian/renderers.py +++ b/netjsonconfig/backends/raspbian/renderers.py @@ -1,5 +1,6 @@ from ..base.renderer import BaseRenderer + class Raspbian(BaseRenderer): def cleanup(self, output): return output From e81257a233c2377318ea1598a955ea20786fedb0 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Sun, 4 Jun 2017 17:29:10 +0530 Subject: [PATCH 018/183] [raspbian] Removed unnecessary print statements --- netjsonconfig/backends/raspbian/converters.py | 2 -- netjsonconfig/backends/raspbian/raspbian.py | 2 +- netjsonconfig/backends/raspbian/templates/test.jinja2 | 7 +++++++ 3 files changed, 8 insertions(+), 3 deletions(-) create mode 100644 netjsonconfig/backends/raspbian/templates/test.jinja2 diff --git a/netjsonconfig/backends/raspbian/converters.py b/netjsonconfig/backends/raspbian/converters.py index 31dcc09d9..cf992ef0d 100644 --- a/netjsonconfig/backends/raspbian/converters.py +++ b/netjsonconfig/backends/raspbian/converters.py @@ -16,7 +16,6 @@ def to_intermediate(self): 'ip': nameserver, }) result.append(sorted_dict(temp)) - print result return (('dns_servers', result),) @@ -34,5 +33,4 @@ def to_intermediate(self): 'domain': domain }) result.append(sorted_dict(temp)) - print result return (('dns_search', result),) diff --git a/netjsonconfig/backends/raspbian/raspbian.py b/netjsonconfig/backends/raspbian/raspbian.py index f43560248..410578aa2 100644 --- a/netjsonconfig/backends/raspbian/raspbian.py +++ b/netjsonconfig/backends/raspbian/raspbian.py @@ -1,6 +1,6 @@ import re -from . import converters +from .converters import * from .renderers import Raspbian from ..base.backend import BaseBackend from .schema import schema diff --git a/netjsonconfig/backends/raspbian/templates/test.jinja2 b/netjsonconfig/backends/raspbian/templates/test.jinja2 new file mode 100644 index 000000000..a50795b53 --- /dev/null +++ b/netjsonconfig/backends/raspbian/templates/test.jinja2 @@ -0,0 +1,7 @@ +{% for namespace, block in data.items() %} + {% for element in block %} + {% for k,v in element.items() %} + {{ namespace }}.{{ k }} = {{ v }} + {% endfor %} + {% endfor %} +{% endfor %} From dcf64e8136eb1480b4979de062531e997bc0e093 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Sun, 4 Jun 2017 18:07:53 +0530 Subject: [PATCH 019/183] [raspbian] Added tests for resolv converters --- tests/raspbian/test_resolv.py | 41 +++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 tests/raspbian/test_resolv.py diff --git a/tests/raspbian/test_resolv.py b/tests/raspbian/test_resolv.py new file mode 100644 index 000000000..477f03143 --- /dev/null +++ b/tests/raspbian/test_resolv.py @@ -0,0 +1,41 @@ +import unittest + +from netjsonconfig import Raspbian + +class TestResovlConverter(unittest.TestCase): + + def test_dns_server(self): + o = Raspbian({ + "dns_servers": [ + "10.254.0.1", + "10.254.0.2" + ], + }) + + o.to_intermediate() + + expected = [OrderedDict([ + ('nameserver', [ + {'ip': '10.254.0.1'}, + {'ip': '10.254.0.2'} + ]) + ]) + ] + self.assertEqual(o.intermediate_data['dns_servers'], expected) + + def test_dns_search(self): + o = Raspbian({ + "dns_search": [ + "domain.com", + ], + }) + + o.to_intermediate() + + expected = [OrderedDict([ + ('domain', [ + {'domain': 'domain.com'} + ]) + ]) + ] + self.assertEqual(o.intermediate_data['dns_search'], expected) From 0b3d8ff45fc6e7c80e5a0cf47330d2f0f78e4f72 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Sun, 4 Jun 2017 22:12:49 +0530 Subject: [PATCH 020/183] [raspbian] Removed temporary template --- netjsonconfig/backends/raspbian/templates/test.jinja2 | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 netjsonconfig/backends/raspbian/templates/test.jinja2 diff --git a/netjsonconfig/backends/raspbian/templates/test.jinja2 b/netjsonconfig/backends/raspbian/templates/test.jinja2 deleted file mode 100644 index a50795b53..000000000 --- a/netjsonconfig/backends/raspbian/templates/test.jinja2 +++ /dev/null @@ -1,7 +0,0 @@ -{% for namespace, block in data.items() %} - {% for element in block %} - {% for k,v in element.items() %} - {{ namespace }}.{{ k }} = {{ v }} - {% endfor %} - {% endfor %} -{% endfor %} From 040acb998171233e1f114d60503d847f44779e16 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Mon, 5 Jun 2017 12:31:10 +0530 Subject: [PATCH 021/183] [raspian] Remove deprecated test files --- tests/raspbian/test_network.py | 26 -------------------------- tests/raspbian/test_wireless.py | 3 --- 2 files changed, 29 deletions(-) delete mode 100644 tests/raspbian/test_network.py delete mode 100644 tests/raspbian/test_wireless.py diff --git a/tests/raspbian/test_network.py b/tests/raspbian/test_network.py deleted file mode 100644 index fbcf55a52..000000000 --- a/tests/raspbian/test_network.py +++ /dev/null @@ -1,26 +0,0 @@ -import unittest - -from netjsonconfig import Raspbian -from netjsonconfig.exceptions import ValidationError -from netjsonconfig.utils import _TabsMixin - -class TestNetworkRenderer(unittest.TestCase, _TabsMixin): - def test_dns_server(self): - o = Raspbian({ - "dns_servers": [ - "10.254.0.1", - "10.254.0.2" - ] - }) - expected = self._tabs("""nameserver​ 10.254.0.1 -nameserver​ 10.254.0.2""") - self.assertEqual(o.render(), expected) - - def test_dns_search(self): - o = Raspbian({ - "dns_search": [ - "domain.com" - ] - }) - expected = self._tabs("""search​ domain.com""") - self.assertEqual(o.render(), expected) diff --git a/tests/raspbian/test_wireless.py b/tests/raspbian/test_wireless.py deleted file mode 100644 index 1dd0f73f1..000000000 --- a/tests/raspbian/test_wireless.py +++ /dev/null @@ -1,3 +0,0 @@ -import unitest - -from netjsonconfig import Raspbian From cc3e6e74bc7a1bba9d57df6b4e01a593e6818de3 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Mon, 5 Jun 2017 13:46:28 +0530 Subject: [PATCH 022/183] [raspbian] Initialized documentation page for Raspbian --- docs/source/backends/raspbian.rst | 9 +++++++++ docs/source/index.rst | 1 + 2 files changed, 10 insertions(+) diff --git a/docs/source/backends/raspbian.rst b/docs/source/backends/raspbian.rst index ce55eef7d..88a36ec6b 100644 --- a/docs/source/backends/raspbian.rst +++ b/docs/source/backends/raspbian.rst @@ -1,3 +1,12 @@ ================ Raspbian Backend ================ + +.. include:: ../_github.rst + +The ``Raspbian`` backend allows to Raspbian compatible configuration files. + +Initialization +-------------- + +.. automethod:: netjsonconfig.Raspbian.__init__ diff --git a/docs/source/index.rst b/docs/source/index.rst index 110b4c96b..6b65d36da 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -51,6 +51,7 @@ Contents: /backends/openwrt /backends/openwisp /backends/openvpn + /backends/raspbian /general/commandline_utility /general/running_tests /general/contributing From a8fadb48780e7ca074fa5d223346357bc30c50db Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Tue, 6 Jun 2017 20:01:35 +0530 Subject: [PATCH 023/183] [raspbian] Added converter for Wireless --- netjsonconfig/backends/raspbian/converters.py | 49 +++++++++++++------ netjsonconfig/backends/raspbian/raspbian.py | 1 + 2 files changed, 36 insertions(+), 14 deletions(-) diff --git a/netjsonconfig/backends/raspbian/converters.py b/netjsonconfig/backends/raspbian/converters.py index cf992ef0d..ce617639c 100644 --- a/netjsonconfig/backends/raspbian/converters.py +++ b/netjsonconfig/backends/raspbian/converters.py @@ -2,20 +2,47 @@ from ..base.converter import BaseConverter +class Wireless(BaseConverter): + netjson_key = 'interfaces' + + def to_intermediate(self): + result = [] + interfaces = get_copy(self.netjson, self.netjson_key) + for interface in interfaces: + if interface['type'] == 'wireless': + radio = interface['wireless'].get('radio') + mode = interface['wireless'].get('mode') + ssid = interface['wireless'].get('ssid') + temp = { + 'radio': radio, + 'mode': mode, + 'ssid': ssid, + } + bssid = interface['wireless'].get('bssid', None) + if bssid != None: + temp.update({'bssid': bssid}) + hidden = interface['wireless'].get('hidden', None) + if hidden != None: + temp.update({'hidden': hidden}) + encryption = interface['wireless'].get('encryption', None) + if encryption != None: + protocol = encryption.get('protocol') + key = encryption.get('key') + cipher = encryption.get('cipher', None) + if cipher != None: + temp.update({'cipher':cipher}) + result.append(temp) + return (('wireless', result),) + + class DNS_Servers(BaseConverter): netjson_key = 'dns_servers' def to_intermediate(self): result = [] dns_servers = get_copy(self.netjson, self.netjson_key) - temp = { - 'nameserver': [], - } for nameserver in dns_servers: - temp['nameserver'].append({ - 'ip': nameserver, - }) - result.append(sorted_dict(temp)) + result.append(nameserver) return (('dns_servers', result),) @@ -25,12 +52,6 @@ class DNS_Search(BaseConverter): def to_intermediate(self): result = [] dns_search = get_copy(self.netjson, self.netjson_key) - temp = { - 'domain': [], - } for domain in dns_search: - temp['domain'].append({ - 'domain': domain - }) - result.append(sorted_dict(temp)) + result.append(domain) return (('dns_search', result),) diff --git a/netjsonconfig/backends/raspbian/raspbian.py b/netjsonconfig/backends/raspbian/raspbian.py index 410578aa2..1b67eee99 100644 --- a/netjsonconfig/backends/raspbian/raspbian.py +++ b/netjsonconfig/backends/raspbian/raspbian.py @@ -13,6 +13,7 @@ class Raspbian(BaseBackend): schema = schema env_path = 'netjsonconfig.backends.raspbian' converters = [ + Wireless, DNS_Servers, DNS_Search ] From 15e813762c75d004c54bf9f50cdc58d80b3de68a Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Thu, 8 Jun 2017 00:18:11 +0530 Subject: [PATCH 024/183] [raspbian] Added renderers and templates for resolv and hostapd --- netjsonconfig/backends/raspbian/raspbian.py | 5 ++--- netjsonconfig/backends/raspbian/renderers.py | 6 +++++- .../backends/raspbian/templates/hostapd.jinja2 | 0 .../backends/raspbian/templates/resolv.jinja2 | 12 ++++++++++++ 4 files changed, 19 insertions(+), 4 deletions(-) create mode 100644 netjsonconfig/backends/raspbian/templates/hostapd.jinja2 create mode 100644 netjsonconfig/backends/raspbian/templates/resolv.jinja2 diff --git a/netjsonconfig/backends/raspbian/raspbian.py b/netjsonconfig/backends/raspbian/raspbian.py index 1b67eee99..95eb4c80b 100644 --- a/netjsonconfig/backends/raspbian/raspbian.py +++ b/netjsonconfig/backends/raspbian/raspbian.py @@ -1,7 +1,7 @@ import re from .converters import * -from .renderers import Raspbian +from .renderers import Resolv, Hostapd from ..base.backend import BaseBackend from .schema import schema @@ -13,8 +13,7 @@ class Raspbian(BaseBackend): schema = schema env_path = 'netjsonconfig.backends.raspbian' converters = [ - Wireless, DNS_Servers, DNS_Search ] - renderer = Raspbian + renderer = Resolv diff --git a/netjsonconfig/backends/raspbian/renderers.py b/netjsonconfig/backends/raspbian/renderers.py index a3c89e508..dacdf8799 100644 --- a/netjsonconfig/backends/raspbian/renderers.py +++ b/netjsonconfig/backends/raspbian/renderers.py @@ -1,6 +1,10 @@ from ..base.renderer import BaseRenderer -class Raspbian(BaseRenderer): +class Resolv(BaseRenderer): + def cleanup(self, output): + return output + +class Hostapd(BaseRenderer): def cleanup(self, output): return output diff --git a/netjsonconfig/backends/raspbian/templates/hostapd.jinja2 b/netjsonconfig/backends/raspbian/templates/hostapd.jinja2 new file mode 100644 index 000000000..e69de29bb diff --git a/netjsonconfig/backends/raspbian/templates/resolv.jinja2 b/netjsonconfig/backends/raspbian/templates/resolv.jinja2 new file mode 100644 index 000000000..dca04bdf0 --- /dev/null +++ b/netjsonconfig/backends/raspbian/templates/resolv.jinja2 @@ -0,0 +1,12 @@ +{% for i, j in data.items() %} +{% if i|string() == 'dns_servers' %} +{% for ip in j %} +nameserver {{ ip }} +{% endfor %} +{% elif i|string() == 'dns_search' %} +{% for domain in j %} +search {{ domain }} +{% endfor %} +{% else %} +{% endif %} +{% endfor %} From 1de87e4d71537f4dbb3cdb72e2b739c42b44a703 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Thu, 8 Jun 2017 00:19:08 +0530 Subject: [PATCH 025/183] [raspbian] Deleted deprecated jinja2 template files --- netjsonconfig/backends/raspbian/templates/network.jinja2 | 8 -------- netjsonconfig/backends/raspbian/templates/wireless.jinja2 | 3 --- 2 files changed, 11 deletions(-) delete mode 100644 netjsonconfig/backends/raspbian/templates/network.jinja2 delete mode 100644 netjsonconfig/backends/raspbian/templates/wireless.jinja2 diff --git a/netjsonconfig/backends/raspbian/templates/network.jinja2 b/netjsonconfig/backends/raspbian/templates/network.jinja2 deleted file mode 100644 index 2c7780e0c..000000000 --- a/netjsonconfig/backends/raspbian/templates/network.jinja2 +++ /dev/null @@ -1,8 +0,0 @@ -{% if not is_empty %} -{% for dns_server in dns_servers %} -nameserver {{ dns_server}} -{% endfor %} -{% for dns_search in dns_search %} -search {{ dns_search }} -{% endfor %} -{% endif %} diff --git a/netjsonconfig/backends/raspbian/templates/wireless.jinja2 b/netjsonconfig/backends/raspbian/templates/wireless.jinja2 deleted file mode 100644 index c146caa9d..000000000 --- a/netjsonconfig/backends/raspbian/templates/wireless.jinja2 +++ /dev/null @@ -1,3 +0,0 @@ -{% if not is_empty %} - -{% endif %} From ddc83030ff7a03fe60f79a8d2777ead87797b8e9 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Fri, 9 Jun 2017 02:36:30 +0530 Subject: [PATCH 026/183] [raspbian] Added converter for Radio and created a common template for all config files --- netjsonconfig/backends/raspbian/converters.py | 37 ++++++++++++++++--- netjsonconfig/backends/raspbian/raspbian.py | 6 ++- netjsonconfig/backends/raspbian/renderers.py | 12 ++++-- .../raspbian/templates/hostapd.jinja2 | 0 .../{resolv.jinja2 => raspbian.jinja2} | 2 + 5 files changed, 45 insertions(+), 12 deletions(-) delete mode 100644 netjsonconfig/backends/raspbian/templates/hostapd.jinja2 rename netjsonconfig/backends/raspbian/templates/{resolv.jinja2 => raspbian.jinja2} (87%) diff --git a/netjsonconfig/backends/raspbian/converters.py b/netjsonconfig/backends/raspbian/converters.py index ce617639c..93784a2c6 100644 --- a/netjsonconfig/backends/raspbian/converters.py +++ b/netjsonconfig/backends/raspbian/converters.py @@ -2,6 +2,34 @@ from ..base.converter import BaseConverter +class Radio(BaseConverter): + netjson_key = 'radios' + + def to_intermediate(self): + result = [] + radios = get_copy(self.netjson, self.netjson_key) + for radio in radios: + temp = { + 'name': radio['name'], + 'protocol': radio['protocol'], + 'channel': radio['channel'], + 'hwmode': self._get_hwmode(radio) + } + result.append(temp) + return (('wireless', result),) + + + def _get_hwmode(self, radio): + protocol = radio['protocol'] + if protocol in ['802.11a', '802.11b', '802.11g']: + return protocol[4:] + if radio['channel'] is 0: + return radio.get('hwmode') + elif radio['channel'] <= 13: + return '11g' + else: + return '11a' + class Wireless(BaseConverter): netjson_key = 'interfaces' @@ -10,13 +38,10 @@ def to_intermediate(self): interfaces = get_copy(self.netjson, self.netjson_key) for interface in interfaces: if interface['type'] == 'wireless': - radio = interface['wireless'].get('radio') - mode = interface['wireless'].get('mode') - ssid = interface['wireless'].get('ssid') temp = { - 'radio': radio, - 'mode': mode, - 'ssid': ssid, + 'radio': interface['wireless'].get('radio'), + 'mode': interface['wireless'].get('mode'), + 'ssid': interface['wireless'].get('ssid'), } bssid = interface['wireless'].get('bssid', None) if bssid != None: diff --git a/netjsonconfig/backends/raspbian/raspbian.py b/netjsonconfig/backends/raspbian/raspbian.py index 95eb4c80b..9b11d052e 100644 --- a/netjsonconfig/backends/raspbian/raspbian.py +++ b/netjsonconfig/backends/raspbian/raspbian.py @@ -1,7 +1,7 @@ import re from .converters import * -from .renderers import Resolv, Hostapd +from .renderers import Raspbian from ..base.backend import BaseBackend from .schema import schema @@ -13,7 +13,9 @@ class Raspbian(BaseBackend): schema = schema env_path = 'netjsonconfig.backends.raspbian' converters = [ + Radio, + Wireless, DNS_Servers, DNS_Search ] - renderer = Resolv + renderer = Raspbian diff --git a/netjsonconfig/backends/raspbian/renderers.py b/netjsonconfig/backends/raspbian/renderers.py index dacdf8799..0f7a7dd0a 100644 --- a/netjsonconfig/backends/raspbian/renderers.py +++ b/netjsonconfig/backends/raspbian/renderers.py @@ -1,10 +1,14 @@ from ..base.renderer import BaseRenderer -class Resolv(BaseRenderer): +class Raspbian(BaseRenderer): def cleanup(self, output): return output -class Hostapd(BaseRenderer): - def cleanup(self, output): - return output +# class Resolv(BaseRenderer): +# def cleanup(self, output): +# return output +# +# class Hostapd(BaseRenderer): +# def cleanup(self, output): +# return output diff --git a/netjsonconfig/backends/raspbian/templates/hostapd.jinja2 b/netjsonconfig/backends/raspbian/templates/hostapd.jinja2 deleted file mode 100644 index e69de29bb..000000000 diff --git a/netjsonconfig/backends/raspbian/templates/resolv.jinja2 b/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 similarity index 87% rename from netjsonconfig/backends/raspbian/templates/resolv.jinja2 rename to netjsonconfig/backends/raspbian/templates/raspbian.jinja2 index dca04bdf0..f9e4aa78a 100644 --- a/netjsonconfig/backends/raspbian/templates/resolv.jinja2 +++ b/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 @@ -1,3 +1,5 @@ +/etc/resolv.conf +---------------- {% for i, j in data.items() %} {% if i|string() == 'dns_servers' %} {% for ip in j %} From bfee537ab901aaa9423380afdfafcae7b866daf5 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Fri, 9 Jun 2017 02:39:42 +0530 Subject: [PATCH 027/183] [raspbian] Use camel case for class names --- netjsonconfig/backends/raspbian/converters.py | 4 ++-- netjsonconfig/backends/raspbian/raspbian.py | 4 ++-- netjsonconfig/backends/raspbian/renderers.py | 8 -------- 3 files changed, 4 insertions(+), 12 deletions(-) diff --git a/netjsonconfig/backends/raspbian/converters.py b/netjsonconfig/backends/raspbian/converters.py index 93784a2c6..ee25661d5 100644 --- a/netjsonconfig/backends/raspbian/converters.py +++ b/netjsonconfig/backends/raspbian/converters.py @@ -60,7 +60,7 @@ def to_intermediate(self): return (('wireless', result),) -class DNS_Servers(BaseConverter): +class DnsServers(BaseConverter): netjson_key = 'dns_servers' def to_intermediate(self): @@ -71,7 +71,7 @@ def to_intermediate(self): return (('dns_servers', result),) -class DNS_Search(BaseConverter): +class DnsSearch(BaseConverter): netjson_key = 'dns_search' def to_intermediate(self): diff --git a/netjsonconfig/backends/raspbian/raspbian.py b/netjsonconfig/backends/raspbian/raspbian.py index 9b11d052e..d0d88a1a8 100644 --- a/netjsonconfig/backends/raspbian/raspbian.py +++ b/netjsonconfig/backends/raspbian/raspbian.py @@ -15,7 +15,7 @@ class Raspbian(BaseBackend): converters = [ Radio, Wireless, - DNS_Servers, - DNS_Search + DnsServers, + DnsSearch, ] renderer = Raspbian diff --git a/netjsonconfig/backends/raspbian/renderers.py b/netjsonconfig/backends/raspbian/renderers.py index 0f7a7dd0a..a3c89e508 100644 --- a/netjsonconfig/backends/raspbian/renderers.py +++ b/netjsonconfig/backends/raspbian/renderers.py @@ -4,11 +4,3 @@ class Raspbian(BaseRenderer): def cleanup(self, output): return output - -# class Resolv(BaseRenderer): -# def cleanup(self, output): -# return output -# -# class Hostapd(BaseRenderer): -# def cleanup(self, output): -# return output From 89d167698e80b14722ef88d0dd0de8e9f49b86d5 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Mon, 12 Jun 2017 14:43:10 +0530 Subject: [PATCH 028/183] [raspbian] Added converter for interfaces and template for network/interfaces --- netjsonconfig/backends/raspbian/converters.py | 42 ++++++++++++++++++- netjsonconfig/backends/raspbian/raspbian.py | 1 + .../raspbian/templates/raspbian.jinja2 | 38 +++++++++++++++++ 3 files changed, 80 insertions(+), 1 deletion(-) diff --git a/netjsonconfig/backends/raspbian/converters.py b/netjsonconfig/backends/raspbian/converters.py index ee25661d5..c0e7ada1c 100644 --- a/netjsonconfig/backends/raspbian/converters.py +++ b/netjsonconfig/backends/raspbian/converters.py @@ -1,6 +1,6 @@ from ...utils import get_copy, sorted_dict from ..base.converter import BaseConverter - +from ipaddress import IPv4Interface, IPv6Interface class Radio(BaseConverter): netjson_key = 'radios' @@ -30,6 +30,46 @@ def _get_hwmode(self, radio): else: return '11a' +class Interfaces(BaseConverter): + netjson_key = 'interfaces' + + def to_intermediate(self): + result = [] + interfaces = get_copy(self.netjson, self.netjson_key) + address_list = [] + for interface in interfaces: + ifname = interface.get('name') + iftype = interface.get('type') + addresses = interface.get('addresses', None) + if addresses != None: + for address in addresses: + address.update({ + 'ifname': ifname, + 'iftype': iftype + }) + + address_list.append(address) + + for address in address_list: + if address.get('iftype') == 'ethernet': + if address.get('proto') == 'static': + if address.get('family') == 'ipv4': + addressmask = str(address.get('address')) + '/' + str(address.get('mask')) + temp = IPv4Interface(addressmask).with_netmask + netmask = temp[-15:] + address.update({'netmask': netmask}) + del address['mask'] + result.append(address) + elif address.get('family') == 'ipv6': + netmask = address.get('mask') + address.update({'netmask': netmask}) + del address['mask'] + result.append(address) + elif address.get('proto') == 'dhcp': + result.append(address) + return (('interfaces', result),) + + class Wireless(BaseConverter): netjson_key = 'interfaces' diff --git a/netjsonconfig/backends/raspbian/raspbian.py b/netjsonconfig/backends/raspbian/raspbian.py index d0d88a1a8..47f5417f5 100644 --- a/netjsonconfig/backends/raspbian/raspbian.py +++ b/netjsonconfig/backends/raspbian/raspbian.py @@ -14,6 +14,7 @@ class Raspbian(BaseBackend): env_path = 'netjsonconfig.backends.raspbian' converters = [ Radio, + Interfaces, Wireless, DnsServers, DnsSearch, diff --git a/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 b/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 index f9e4aa78a..760ebb710 100644 --- a/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 +++ b/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 @@ -1,3 +1,41 @@ +/etc/network/interfaces +----------------------- +{% for i, j in data.items() %} +{% if i|string() == 'interfaces' %} +{% for address in j %} +{% if address.get('iftype') == 'ethernet' %} +auto {{ address.get('ifname') }} +{% if address.get('proto') == 'static' %} +{% if address.get('family') == 'ipv4'%} +iface {{ address.get('ifname') }} inet {{ address.get('proto') }} + address {{ address.get('address') }} + netmask {{ address.get('netmask') }} +{% if address.get('gateway', None) != None %} + gateway {{ address.get('gateway')}} +{% endif %} +{% elif address.get('family') == 'ipv6' %} +iface {{ address.get('ifname') }} inet {{ address.get('proto') }} + address {{ address.get('address') }} + netmask {{ address.get('netmask') }} +{% if address.get('gateway', None) != None %} + gateway {{ address.get('gateway') }} +{% endif %} +{% endif %} +{% elif address.get('proto') == 'dhcp' %} +allow-hotplug {{ address.get('ifname') }} +{% if address.get('family') == 'ipv4'%} +iface {{ address.get('ifname') }} inet {{ address.get('proto') }} +{% elif address.get('family') == 'ipv6' %} +iface {{ address.get('ifname') }} inet6 {{ address.get('proto') }} +{% endif %} +{% endif %} + +{% endif %} +{% endfor %} +{% endif %} +{%endfor%} + + /etc/resolv.conf ---------------- {% for i, j in data.items() %} From 089cbd6061b64f909030c18570ecce770992a296 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Mon, 12 Jun 2017 17:43:00 +0530 Subject: [PATCH 029/183] [raspbian] Added support for bridge interface --- netjsonconfig/backends/raspbian/converters.py | 16 +++++++++- .../raspbian/templates/raspbian.jinja2 | 32 +++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/netjsonconfig/backends/raspbian/converters.py b/netjsonconfig/backends/raspbian/converters.py index c0e7ada1c..437f2354f 100644 --- a/netjsonconfig/backends/raspbian/converters.py +++ b/netjsonconfig/backends/raspbian/converters.py @@ -47,7 +47,8 @@ def to_intermediate(self): 'ifname': ifname, 'iftype': iftype }) - + if iftype == 'bridge': + address.update({'bridge_members': interface.get('bridge_members')}) address_list.append(address) for address in address_list: @@ -67,6 +68,19 @@ def to_intermediate(self): result.append(address) elif address.get('proto') == 'dhcp': result.append(address) + elif address.get('iftype') == 'bridge': + if address.get('family') == 'ipv4': + addressmask = str(address.get('address')) + '/' + str(address.get('mask')) + temp = IPv4Interface(addressmask).with_netmask + netmask = temp[-15:] + address.update({'netmask': netmask}) + del address['mask'] + result.append(address) + elif address.get('family') == 'ipv6': + netmask = address.get('mask') + address.update({'netmask': netmask}) + del address['mask'] + result.append(address) return (('interfaces', result),) diff --git a/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 b/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 index 760ebb710..8ddff3a2e 100644 --- a/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 +++ b/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 @@ -3,6 +3,7 @@ {% for i, j in data.items() %} {% if i|string() == 'interfaces' %} {% for address in j %} +{# Start of `ethernet` block #} {% if address.get('iftype') == 'ethernet' %} auto {{ address.get('ifname') }} {% if address.get('proto') == 'static' %} @@ -30,6 +31,37 @@ iface {{ address.get('ifname') }} inet6 {{ address.get('proto') }} {% endif %} {% endif %} +{# End of `ethernet` block #} +{# Start of `bridge` block #} +{% elif address.get('iftype') == 'bridge' %} +auto {{ address.get('ifname') }} +{% if address.get('proto') == 'static' %} +{% if address.get('family') == 'ipv4'%} +iface {{ address.get('ifname') }} inet {{ address.get('proto') }} + address {{ address.get('address') }} + netmask {{ address.get('netmask') }} +{% if address.get('gateway', None) != None %} + gateway {{ address.get('gateway')}} +{% endif %} + bridge_ports {{ address.get('bridge_members')[0] }} {{ address.get('bridge_members')[1] }} +{% elif address.get('family') == 'ipv6' %} +iface {{ address.get('ifname') }} inet {{ address.get('proto') }} + address {{ address.get('address') }} + netmask {{ address.get('netmask') }} +{% if address.get('gateway', None) != None %} + gateway {{ address.get('gateway') }} +{% endif %} + bridge_ports {{ address.get('bridge_members')[0] }} {{ address.get('bridge_members')[1] }} +{% endif %} +{% elif address.get('proto') == 'dhcp' %} +allow-hotplug {{ address.get('ifname') }} +{% if address.get('family') == 'ipv4'%} +iface {{ address.get('ifname') }} inet {{ address.get('proto') }} +{% elif address.get('family') == 'ipv6' %} +iface {{ address.get('ifname') }} inet6 {{ address.get('proto') }} +{% endif %} +{% endif %} +{# End of `bridge` block #} {% endif %} {% endfor %} {% endif %} From 621a892a86e96a18c0c4f5010c0ef0116cb9a393 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Mon, 12 Jun 2017 19:24:10 +0530 Subject: [PATCH 030/183] [raspbian] Combined ethernet and bridge template --- .../raspbian/templates/raspbian.jinja2 | 38 +++---------------- 1 file changed, 6 insertions(+), 32 deletions(-) diff --git a/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 b/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 index 8ddff3a2e..d92a3127c 100644 --- a/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 +++ b/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 @@ -3,37 +3,7 @@ {% for i, j in data.items() %} {% if i|string() == 'interfaces' %} {% for address in j %} -{# Start of `ethernet` block #} -{% if address.get('iftype') == 'ethernet' %} -auto {{ address.get('ifname') }} -{% if address.get('proto') == 'static' %} -{% if address.get('family') == 'ipv4'%} -iface {{ address.get('ifname') }} inet {{ address.get('proto') }} - address {{ address.get('address') }} - netmask {{ address.get('netmask') }} -{% if address.get('gateway', None) != None %} - gateway {{ address.get('gateway')}} -{% endif %} -{% elif address.get('family') == 'ipv6' %} -iface {{ address.get('ifname') }} inet {{ address.get('proto') }} - address {{ address.get('address') }} - netmask {{ address.get('netmask') }} -{% if address.get('gateway', None) != None %} - gateway {{ address.get('gateway') }} -{% endif %} -{% endif %} -{% elif address.get('proto') == 'dhcp' %} -allow-hotplug {{ address.get('ifname') }} -{% if address.get('family') == 'ipv4'%} -iface {{ address.get('ifname') }} inet {{ address.get('proto') }} -{% elif address.get('family') == 'ipv6' %} -iface {{ address.get('ifname') }} inet6 {{ address.get('proto') }} -{% endif %} -{% endif %} - -{# End of `ethernet` block #} -{# Start of `bridge` block #} -{% elif address.get('iftype') == 'bridge' %} +{% if address.get('iftype') == 'ethernet' or address.get('iftype') == 'bridge' %} auto {{ address.get('ifname') }} {% if address.get('proto') == 'static' %} {% if address.get('family') == 'ipv4'%} @@ -43,7 +13,9 @@ iface {{ address.get('ifname') }} inet {{ address.get('proto') }} {% if address.get('gateway', None) != None %} gateway {{ address.get('gateway')}} {% endif %} +{% if address.get('iftype') == 'bridge' %} bridge_ports {{ address.get('bridge_members')[0] }} {{ address.get('bridge_members')[1] }} +{% endif %} {% elif address.get('family') == 'ipv6' %} iface {{ address.get('ifname') }} inet {{ address.get('proto') }} address {{ address.get('address') }} @@ -51,7 +23,9 @@ iface {{ address.get('ifname') }} inet {{ address.get('proto') }} {% if address.get('gateway', None) != None %} gateway {{ address.get('gateway') }} {% endif %} +{% if address.get('iftype') == 'bridge' %} bridge_ports {{ address.get('bridge_members')[0] }} {{ address.get('bridge_members')[1] }} +{% endif %} {% endif %} {% elif address.get('proto') == 'dhcp' %} allow-hotplug {{ address.get('ifname') }} @@ -61,7 +35,7 @@ iface {{ address.get('ifname') }} inet {{ address.get('proto') }} iface {{ address.get('ifname') }} inet6 {{ address.get('proto') }} {% endif %} {% endif %} -{# End of `bridge` block #} + {% endif %} {% endfor %} {% endif %} From a45f003839bd618b674fa4a4e28590fc69687a9a Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Tue, 13 Jun 2017 00:36:49 +0530 Subject: [PATCH 031/183] [raspbian] Added tests for resolv and minor modifications in interfaces converter --- netjsonconfig/backends/raspbian/converters.py | 17 +---- .../raspbian/templates/raspbian.jinja2 | 2 +- tests/raspbian/__init__.py | 0 tests/raspbian/test_resolv.py | 76 ++++++++++++++----- 4 files changed, 61 insertions(+), 34 deletions(-) create mode 100644 tests/raspbian/__init__.py diff --git a/netjsonconfig/backends/raspbian/converters.py b/netjsonconfig/backends/raspbian/converters.py index 437f2354f..7bfa69e1e 100644 --- a/netjsonconfig/backends/raspbian/converters.py +++ b/netjsonconfig/backends/raspbian/converters.py @@ -52,12 +52,12 @@ def to_intermediate(self): address_list.append(address) for address in address_list: - if address.get('iftype') == 'ethernet': + if address.get('iftype') in ['ethernet', 'bridge', 'loopback']: if address.get('proto') == 'static': if address.get('family') == 'ipv4': addressmask = str(address.get('address')) + '/' + str(address.get('mask')) temp = IPv4Interface(addressmask).with_netmask - netmask = temp[-15:] + netmask = temp.split('/')[1] address.update({'netmask': netmask}) del address['mask'] result.append(address) @@ -68,19 +68,6 @@ def to_intermediate(self): result.append(address) elif address.get('proto') == 'dhcp': result.append(address) - elif address.get('iftype') == 'bridge': - if address.get('family') == 'ipv4': - addressmask = str(address.get('address')) + '/' + str(address.get('mask')) - temp = IPv4Interface(addressmask).with_netmask - netmask = temp[-15:] - address.update({'netmask': netmask}) - del address['mask'] - result.append(address) - elif address.get('family') == 'ipv6': - netmask = address.get('mask') - address.update({'netmask': netmask}) - del address['mask'] - result.append(address) return (('interfaces', result),) diff --git a/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 b/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 index d92a3127c..4338b634e 100644 --- a/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 +++ b/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 @@ -3,7 +3,7 @@ {% for i, j in data.items() %} {% if i|string() == 'interfaces' %} {% for address in j %} -{% if address.get('iftype') == 'ethernet' or address.get('iftype') == 'bridge' %} +{% if address.get('iftype') in ['ethernet', 'bridge', 'loopback'] %} auto {{ address.get('ifname') }} {% if address.get('proto') == 'static' %} {% if address.get('family') == 'ipv4'%} diff --git a/tests/raspbian/__init__.py b/tests/raspbian/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/raspbian/test_resolv.py b/tests/raspbian/test_resolv.py index 477f03143..a206e2c89 100644 --- a/tests/raspbian/test_resolv.py +++ b/tests/raspbian/test_resolv.py @@ -1,8 +1,11 @@ import unittest from netjsonconfig import Raspbian +from netjsonconfig.exceptions import ValidationError +from netjsonconfig.utils import _TabsMixin -class TestResovlConverter(unittest.TestCase): + +class TestResovlRenderer(unittest.TestCase, _TabsMixin): def test_dns_server(self): o = Raspbian({ @@ -12,16 +15,16 @@ def test_dns_server(self): ], }) - o.to_intermediate() + expected = '''/etc/network/interfaces +----------------------- + - expected = [OrderedDict([ - ('nameserver', [ - {'ip': '10.254.0.1'}, - {'ip': '10.254.0.2'} - ]) - ]) - ] - self.assertEqual(o.intermediate_data['dns_servers'], expected) +/etc/resolv.conf +---------------- +nameserver 10.254.0.1 +nameserver 10.254.0.2 +''' + self.assertEqual(o.render(), expected) def test_dns_search(self): o = Raspbian({ @@ -30,12 +33,49 @@ def test_dns_search(self): ], }) - o.to_intermediate() + expected = '''/etc/network/interfaces +----------------------- + + +/etc/resolv.conf +---------------- +search domain.com +''' + self.assertEqual(o.render(), expected) + + def test_dns_server_and_dns_search(self): + o = Raspbian({ + "dns_servers": [ + "10.11.12.13", + "8.8.8.8"], + "dns_search": [ + "netjson.org", + "openwisp.org" + ], + }) + + expected = '''/etc/network/interfaces +----------------------- + + +/etc/resolv.conf +---------------- +nameserver 10.11.12.13 +nameserver 8.8.8.8 +search netjson.org +search openwisp.org +''' + self.assertEqual(o.render(), expected) + + def test_no_dns_server_and_dns_search(self): + o = Raspbian({ + }) + + expected = '''/etc/network/interfaces +----------------------- + - expected = [OrderedDict([ - ('domain', [ - {'domain': 'domain.com'} - ]) - ]) - ] - self.assertEqual(o.intermediate_data['dns_search'], expected) +/etc/resolv.conf +---------------- +''' + self.assertEqual(o.render(), expected) From e4da2d4a9bbb4eb72e4853b619ead74e84a5e9c3 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Tue, 13 Jun 2017 14:17:00 +0530 Subject: [PATCH 032/183] [raspbian] Added tests for interfaces --- tests/raspbian/test_interfaces.py | 237 ++++++++++++++++++++++++++++++ 1 file changed, 237 insertions(+) create mode 100644 tests/raspbian/test_interfaces.py diff --git a/tests/raspbian/test_interfaces.py b/tests/raspbian/test_interfaces.py new file mode 100644 index 000000000..2860e9980 --- /dev/null +++ b/tests/raspbian/test_interfaces.py @@ -0,0 +1,237 @@ +import unittest + +from netjsonconfig import Raspbian +from netjsonconfig.exceptions import ValidationError +from netjsonconfig.utils import _TabsMixin + + +class TestInterfacesRenderer(unittest.TestCase, _TabsMixin): + + def test_interface_ipv4_static(self): + o = Raspbian({ + "interfaces": [ + { + "name": "eth0", + "type": "ethernet", + "addresses": [ + { + "family": "ipv4", + "proto": "static", + "address": "10.0.0.1", + "mask": 28 + } + ] + } + ] + }) + + expected = '''/etc/network/interfaces +----------------------- +auto eth0 +iface eth0 inet static + address 10.0.0.1 + netmask 255.255.255.240 + + + +/etc/resolv.conf +---------------- +''' + self.assertEqual(o.render(), expected) + + def test_interface_ipv6_static(self): + o = Raspbian({ + "interfaces": [ + { + "name": "eth0", + "type": "ethernet", + "addresses": [ + { + "family": "ipv6", + "proto": "static", + "address": "fe80::ba27:ebff:fe1c:5477", + "mask": 64 + } + ] + } + ] + }) + + expected = '''/etc/network/interfaces +----------------------- +auto eth0 +iface eth0 inet6 static + address fe80::ba27:ebff:fe1c:5477 + netmask 64 + + + +/etc/resolv.conf +---------------- +''' + self.assertEqual(o.render(), expected) + + def test_interface_multiple_static(self): + o = Raspbian({ + "interfaces": [ + { + "name": "eth0", + "type": "ethernet", + "addresses": [ + { + "family": "ipv4", + "proto": "static", + "address": "10.0.0.1", + "mask": 28 + }, + { + "family": "ipv6", + "proto": "static", + "address": "fe80::ba27:ebff:fe1c:5477", + "mask": 64 + } + ] + } + ] + }) + + expected = '''/etc/network/interfaces +----------------------- +auto eth0 +iface eth0 inet static + address 10.0.0.1 + netmask 255.255.255.240 +iface eth0 inet6 static + address fe80::ba27:ebff:fe1c:5477 + netmask 64 + + + +/etc/resolv.conf +---------------- +''' + + + def test_interface_ipv4_dhcp(self): + o = Raspbian({ + "interfaces": [ + { + "name": "eth0", + "type": "ethernet", + "addresses": [ + { + "proto": "dhcp", + "family": "ipv4" + } + ] + } + ] + }) + + expected = '''/etc/network/interfaces +----------------------- +auto eth0 +allow-hotplug eth0 +iface eth0 inet dhcp + + + +/etc/resolv.conf +---------------- +''' + self.assertEqual(o.render(), expected) + + def test_interface_ipv6_dhcp(self): + o = Raspbian({ + "interfaces": [ + { + "name": "eth0", + "type": "ethernet", + "addresses": [ + { + "proto": "dhcp", + "family": "ipv6" + } + ] + } + ] + }) + + expected = '''/etc/network/interfaces +----------------------- +auto eth0 +allow-hotplug eth0 +iface eth0 inet6 dhcp + + + +/etc/resolv.conf +---------------- +''' + self.assertEqual(o.render(), expected) + + def test_interface_multiple_dhcp(self): + o = Raspbian({ + "interfaces": [ + { + "name": "eth0", + "type": "ethernet", + "addresses": [ + + { + "proto": "dhcp", + "family": "ipv4" + }, + { + "proto": "dhcp", + "family": "ipv6" + } + ] + } + ] + }) + + expected = '''/etc/network/interfaces +----------------------- +auto eth0 +allow-hotplug eth0 +iface eth0 inet6 dhcp + + + +/etc/resolv.conf +---------------- +''' + self.assertEqual(o.render(), expected) + + def test_loopback(self): + o = Raspbian({ + "interfaces": [ + { + "name": "lo", + "type": "loopback", + "addresses": [ + { + "address": "127.0.0.1", + "mask": 8, + "proto": "static", + "family": "ipv4" + } + ] + } + ] + }) + + expected = '''/etc/network/interfaces +----------------------- +auto lo +iface lo inet static + address 127.0.0.1 + netmask 255.0.0.0 + + + +/etc/resolv.conf +---------------- +''' + self.assertEqual(o.render(), expected) From b276e1fc949768282b4cf583f8f9252805f64ecd Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Tue, 13 Jun 2017 15:28:39 +0530 Subject: [PATCH 033/183] [raspbian] Fixed bug for simple bridge interface --- netjsonconfig/backends/raspbian/converters.py | 10 ++++++++++ .../backends/raspbian/templates/raspbian.jinja2 | 6 +++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/netjsonconfig/backends/raspbian/converters.py b/netjsonconfig/backends/raspbian/converters.py index 7bfa69e1e..6582f38d8 100644 --- a/netjsonconfig/backends/raspbian/converters.py +++ b/netjsonconfig/backends/raspbian/converters.py @@ -50,6 +50,14 @@ def to_intermediate(self): if iftype == 'bridge': address.update({'bridge_members': interface.get('bridge_members')}) address_list.append(address) + else: + temp = { + 'ifname': ifname, + 'iftype': iftype, + } + if iftype == 'bridge': + temp.update({'bridge_members': interface.get('bridge_members')}) + address_list.append(temp) for address in address_list: if address.get('iftype') in ['ethernet', 'bridge', 'loopback']: @@ -68,6 +76,8 @@ def to_intermediate(self): result.append(address) elif address.get('proto') == 'dhcp': result.append(address) + else: + result.append(address) return (('interfaces', result),) diff --git a/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 b/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 index 4338b634e..ef6c75997 100644 --- a/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 +++ b/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 @@ -17,7 +17,7 @@ iface {{ address.get('ifname') }} inet {{ address.get('proto') }} bridge_ports {{ address.get('bridge_members')[0] }} {{ address.get('bridge_members')[1] }} {% endif %} {% elif address.get('family') == 'ipv6' %} -iface {{ address.get('ifname') }} inet {{ address.get('proto') }} +iface {{ address.get('ifname') }} inet6 {{ address.get('proto') }} address {{ address.get('address') }} netmask {{ address.get('netmask') }} {% if address.get('gateway', None) != None %} @@ -34,6 +34,10 @@ iface {{ address.get('ifname') }} inet {{ address.get('proto') }} {% elif address.get('family') == 'ipv6' %} iface {{ address.get('ifname') }} inet6 {{ address.get('proto') }} {% endif %} +{% else %} +{% if address.get('iftype') == 'bridge' %} + bridge_ports {{ address.get('bridge_members')[0] }} {{ address.get('bridge_members')[1] }} +{% endif %} {% endif %} {% endif %} From d7725a6e1c7b3838480864ac6b7fcab49b98e328 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Tue, 13 Jun 2017 16:28:09 +0530 Subject: [PATCH 034/183] [raspbian] Added tests for bridge interface --- tests/raspbian/test_interfaces.py | 67 +++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/tests/raspbian/test_interfaces.py b/tests/raspbian/test_interfaces.py index 2860e9980..754ae2ef5 100644 --- a/tests/raspbian/test_interfaces.py +++ b/tests/raspbian/test_interfaces.py @@ -110,6 +110,7 @@ def test_interface_multiple_static(self): /etc/resolv.conf ---------------- ''' + self.assertEqual(o.render(), expected) def test_interface_ipv4_dhcp(self): @@ -195,6 +196,7 @@ def test_interface_multiple_dhcp(self): ----------------------- auto eth0 allow-hotplug eth0 +iface eth0 inet dhcp iface eth0 inet6 dhcp @@ -231,6 +233,71 @@ def test_loopback(self): +/etc/resolv.conf +---------------- +''' + self.assertEqual(o.render(), expected) + + def test_simple_bridge(self): + o = Raspbian({ + "interfaces": [ + { + "network": "lan", + "name": "br-lan", + "type": "bridge", + "bridge_members": [ + "eth0", + "eth1" + ] + } + ] + }) + + expected = '''/etc/network/interfaces +----------------------- +auto br-lan + bridge_ports eth0 eth1 + + + +/etc/resolv.conf +---------------- +''' + self.assertEqual(o.render(), expected) + + def test_complex_bridge(self): + o = Raspbian({ + "interfaces": [ + { + "mtu": 1500, + "name": "brwifi", + "bridge_members": [ + "wlan0", + "vpn.40" + ], + "addresses": [ + { + "mask": 64, + "family": "ipv6", + "proto": "static", + "address": "fe80::8029:23ff:fe7d:c214" + } + ], + "type": "bridge", + } + ] + }) + + expected = '''/etc/network/interfaces +----------------------- +auto brwifi +iface brwifi inet6 static + address fe80::8029:23ff:fe7d:c214 + netmask 64 + bridge_ports wlan0 vpn.40 + + + /etc/resolv.conf ---------------- ''' From ba566ca85fe4ea962ab561a6d679c40f07a6cfc3 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Wed, 14 Jun 2017 01:30:06 +0530 Subject: [PATCH 035/183] [raspbian] Fixed isort and flake8 warnings --- netjsonconfig/backends/raspbian/converters.py | 19 ++++++++++--------- netjsonconfig/backends/raspbian/raspbian.py | 4 +--- tests/raspbian/test_interfaces.py | 2 -- tests/raspbian/test_resolv.py | 1 - 4 files changed, 11 insertions(+), 15 deletions(-) diff --git a/netjsonconfig/backends/raspbian/converters.py b/netjsonconfig/backends/raspbian/converters.py index 6582f38d8..4a7e4f8fe 100644 --- a/netjsonconfig/backends/raspbian/converters.py +++ b/netjsonconfig/backends/raspbian/converters.py @@ -1,6 +1,7 @@ -from ...utils import get_copy, sorted_dict +from ...utils import get_copy from ..base.converter import BaseConverter -from ipaddress import IPv4Interface, IPv6Interface +from ipaddress import IPv4Interface + class Radio(BaseConverter): netjson_key = 'radios' @@ -18,7 +19,6 @@ def to_intermediate(self): result.append(temp) return (('wireless', result),) - def _get_hwmode(self, radio): protocol = radio['protocol'] if protocol in ['802.11a', '802.11b', '802.11g']: @@ -30,6 +30,7 @@ def _get_hwmode(self, radio): else: return '11a' + class Interfaces(BaseConverter): netjson_key = 'interfaces' @@ -41,7 +42,7 @@ def to_intermediate(self): ifname = interface.get('name') iftype = interface.get('type') addresses = interface.get('addresses', None) - if addresses != None: + if addresses is not None: for address in addresses: address.update({ 'ifname': ifname, @@ -95,18 +96,18 @@ def to_intermediate(self): 'ssid': interface['wireless'].get('ssid'), } bssid = interface['wireless'].get('bssid', None) - if bssid != None: + if bssid is not None: temp.update({'bssid': bssid}) hidden = interface['wireless'].get('hidden', None) - if hidden != None: + if hidden is not None: temp.update({'hidden': hidden}) encryption = interface['wireless'].get('encryption', None) - if encryption != None: + if encryption is not None: protocol = encryption.get('protocol') key = encryption.get('key') cipher = encryption.get('cipher', None) - if cipher != None: - temp.update({'cipher':cipher}) + if cipher is not None: + temp.update({'cipher': cipher}) result.append(temp) return (('wireless', result),) diff --git a/netjsonconfig/backends/raspbian/raspbian.py b/netjsonconfig/backends/raspbian/raspbian.py index 47f5417f5..6738684bf 100644 --- a/netjsonconfig/backends/raspbian/raspbian.py +++ b/netjsonconfig/backends/raspbian/raspbian.py @@ -1,6 +1,4 @@ -import re - -from .converters import * +from .converters import Radio, Interfaces, Wireless, DnsServers, DnsSearch from .renderers import Raspbian from ..base.backend import BaseBackend from .schema import schema diff --git a/tests/raspbian/test_interfaces.py b/tests/raspbian/test_interfaces.py index 754ae2ef5..1012b9756 100644 --- a/tests/raspbian/test_interfaces.py +++ b/tests/raspbian/test_interfaces.py @@ -1,7 +1,6 @@ import unittest from netjsonconfig import Raspbian -from netjsonconfig.exceptions import ValidationError from netjsonconfig.utils import _TabsMixin @@ -112,7 +111,6 @@ def test_interface_multiple_static(self): ''' self.assertEqual(o.render(), expected) - def test_interface_ipv4_dhcp(self): o = Raspbian({ "interfaces": [ diff --git a/tests/raspbian/test_resolv.py b/tests/raspbian/test_resolv.py index a206e2c89..1b0ee1f06 100644 --- a/tests/raspbian/test_resolv.py +++ b/tests/raspbian/test_resolv.py @@ -1,7 +1,6 @@ import unittest from netjsonconfig import Raspbian -from netjsonconfig.exceptions import ValidationError from netjsonconfig.utils import _TabsMixin From 9a7aec1475d827753220e255ee365f7c07871a49 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Wed, 14 Jun 2017 23:30:54 +0530 Subject: [PATCH 036/183] [raspbian] Modified interface converter to fix multiple interface bug --- netjsonconfig/backends/raspbian/converters.py | 72 ++++++++++--------- 1 file changed, 38 insertions(+), 34 deletions(-) diff --git a/netjsonconfig/backends/raspbian/converters.py b/netjsonconfig/backends/raspbian/converters.py index 4a7e4f8fe..86e498fdc 100644 --- a/netjsonconfig/backends/raspbian/converters.py +++ b/netjsonconfig/backends/raspbian/converters.py @@ -37,48 +37,52 @@ class Interfaces(BaseConverter): def to_intermediate(self): result = [] interfaces = get_copy(self.netjson, self.netjson_key) - address_list = [] for interface in interfaces: ifname = interface.get('name') iftype = interface.get('type') addresses = interface.get('addresses', None) + new_interface = {} if addresses is not None: for address in addresses: - address.update({ + new_interface.update({ 'ifname': ifname, - 'iftype': iftype - }) + 'iftype': iftype, + }) if iftype == 'bridge': - address.update({'bridge_members': interface.get('bridge_members')}) - address_list.append(address) - else: - temp = { - 'ifname': ifname, - 'iftype': iftype, - } - if iftype == 'bridge': - temp.update({'bridge_members': interface.get('bridge_members')}) - address_list.append(temp) - - for address in address_list: - if address.get('iftype') in ['ethernet', 'bridge', 'loopback']: - if address.get('proto') == 'static': - if address.get('family') == 'ipv4': - addressmask = str(address.get('address')) + '/' + str(address.get('mask')) - temp = IPv4Interface(addressmask).with_netmask - netmask = temp.split('/')[1] - address.update({'netmask': netmask}) - del address['mask'] - result.append(address) - elif address.get('family') == 'ipv6': - netmask = address.get('mask') - address.update({'netmask': netmask}) - del address['mask'] - result.append(address) - elif address.get('proto') == 'dhcp': - result.append(address) - else: - result.append(address) + new_interface.update({ + 'bridge_members': bridge_members, + }) + if iftype in ['ethernet', 'bridge', 'loopback']: + if address.get('proto') == 'static': + if address.get('family') == 'ipv4': + addressmask = str(address.get('address')) + '/' + str(address.get('mask')) + new_interface.update({ + 'ip4address': address.get('address'), + 'ipv4netmask': IPv4Interface(addressmask).with_netmask.split('/')[1] + }) + if address.get('gateway', None) is not None: + new_interface.update({ + 'ipv4gateway': address.get('gateway'), + }) + if address.get('family') == 'ipv6': + new_interface.update({ + 'ipv6address': address.get('address'), + 'ipv6netmask': address.get('mask') + }) + if address.get('gateway', None) is not None: + new_interface.update({ + 'ipv6gateway': address.get('gateway'), + }) + elif address.get('proto') == 'dhcp': + if address.get('family') == 'ipv4': + new_interface.update({ + 'ipv4dhcp': True, + }) + elif address.get('family') == 'ipv6': + new_interface.update({ + 'ipv6dhcp': True, + }) + result.append(new_interface) return (('interfaces', result),) From 1729063490003c7f700aeee600af294a8c04eb12 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Thu, 15 Jun 2017 01:46:39 +0530 Subject: [PATCH 037/183] [raspbian] Modified interface coverter for bridge support --- netjsonconfig/backends/raspbian/converters.py | 46 ++++++++++++------- 1 file changed, 30 insertions(+), 16 deletions(-) diff --git a/netjsonconfig/backends/raspbian/converters.py b/netjsonconfig/backends/raspbian/converters.py index 86e498fdc..f8046a1c9 100644 --- a/netjsonconfig/backends/raspbian/converters.py +++ b/netjsonconfig/backends/raspbian/converters.py @@ -41,47 +41,61 @@ def to_intermediate(self): ifname = interface.get('name') iftype = interface.get('type') addresses = interface.get('addresses', None) - new_interface = {} + new_interface = { + 'ifname': ifname, + 'iftype': iftype, + } + address_list = [] + if iftype == 'bridge': + new_interface.update({ + 'bridge_members': interface.get('bridge_members'), + }) if addresses is not None: for address in addresses: - new_interface.update({ - 'ifname': ifname, - 'iftype': iftype, - }) - if iftype == 'bridge': - new_interface.update({ - 'bridge_members': bridge_members, - }) + print address + new_address = {} if iftype in ['ethernet', 'bridge', 'loopback']: if address.get('proto') == 'static': if address.get('family') == 'ipv4': addressmask = str(address.get('address')) + '/' + str(address.get('mask')) - new_interface.update({ - 'ip4address': address.get('address'), + new_address.update({ + 'proto': 'static', + 'family': 'ipv4', + 'ipv4address': address.get('address'), 'ipv4netmask': IPv4Interface(addressmask).with_netmask.split('/')[1] }) if address.get('gateway', None) is not None: - new_interface.update({ + new_address.update({ 'ipv4gateway': address.get('gateway'), }) if address.get('family') == 'ipv6': - new_interface.update({ + new_address.update({ + 'proto': 'static', + 'family': 'ipv6', 'ipv6address': address.get('address'), 'ipv6netmask': address.get('mask') }) if address.get('gateway', None) is not None: - new_interface.update({ + new_address.update({ 'ipv6gateway': address.get('gateway'), }) elif address.get('proto') == 'dhcp': if address.get('family') == 'ipv4': - new_interface.update({ + new_address.update({ + 'proto': 'dhcp', + 'family': 'ipv4', 'ipv4dhcp': True, }) elif address.get('family') == 'ipv6': - new_interface.update({ + new_address.update({ + 'proto': 'dhcp', + 'family': 'ipv6', 'ipv6dhcp': True, }) + address_list.append(new_address) + new_interface.update({ + 'address': address_list + }) result.append(new_interface) return (('interfaces', result),) From 0359d63bfec6daa05fabba5cb93eafd3eb51fd45 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Thu, 15 Jun 2017 01:49:26 +0530 Subject: [PATCH 038/183] [raspbian] Modified template for new intermediate data structure for interfaces --- .../raspbian/templates/raspbian.jinja2 | 54 ++++++++++--------- 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 b/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 index ef6c75997..06ecfa8ff 100644 --- a/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 +++ b/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 @@ -2,48 +2,50 @@ ----------------------- {% for i, j in data.items() %} {% if i|string() == 'interfaces' %} -{% for address in j %} -{% if address.get('iftype') in ['ethernet', 'bridge', 'loopback'] %} -auto {{ address.get('ifname') }} +{% for interface in j %} +auto {{ interface.get('ifname') }} +{% if interface.get('address') != None %} +{% for address in interface.get('address') %} {% if address.get('proto') == 'static' %} -{% if address.get('family') == 'ipv4'%} -iface {{ address.get('ifname') }} inet {{ address.get('proto') }} - address {{ address.get('address') }} - netmask {{ address.get('netmask') }} +{% if address.get('family') == 'ipv4' %} +iface {{ interface.get('ifname') }} inet {{ address.get('proto') }} + address {{ address.get('ipv4address') }} + netmask {{ address.get('ipv4netmask') }} {% if address.get('gateway', None) != None %} - gateway {{ address.get('gateway')}} + gateway {{ address.get('ipv4gateway')}} +{% endif %} +{% if interface.get('iftype') == 'bridge' %} + bridge_ports {{ interface.get('bridge_members')[0] }} {{ interface.get('bridge_members')[1] }} {% endif %} -{% if address.get('iftype') == 'bridge' %} - bridge_ports {{ address.get('bridge_members')[0] }} {{ address.get('bridge_members')[1] }} -{% endif %} {% elif address.get('family') == 'ipv6' %} -iface {{ address.get('ifname') }} inet6 {{ address.get('proto') }} - address {{ address.get('address') }} - netmask {{ address.get('netmask') }} +iface {{ interface.get('ifname') }} inet6 {{ address.get('proto') }} + address {{ address.get('ipv6address') }} + netmask {{ address.get('ipv6netmask') }} {% if address.get('gateway', None) != None %} - gateway {{ address.get('gateway') }} + gateway {{ address.get('ipv6gateway') }} +{% endif %} +{% if interface.get('iftype') == 'bridge' %} + bridge_ports {{ interface.get('bridge_members')[0] }} {{ interface.get('bridge_members')[1] }} {% endif %} -{% if address.get('iftype') == 'bridge' %} - bridge_ports {{ address.get('bridge_members')[0] }} {{ address.get('bridge_members')[1] }} -{% endif %} {% endif %} {% elif address.get('proto') == 'dhcp' %} -allow-hotplug {{ address.get('ifname') }} +allow-hotplug {{ interface.get('ifname') }} {% if address.get('family') == 'ipv4'%} -iface {{ address.get('ifname') }} inet {{ address.get('proto') }} +iface {{ interface.get('ifname') }} inet {{ address.get('proto') }} {% elif address.get('family') == 'ipv6' %} -iface {{ address.get('ifname') }} inet6 {{ address.get('proto') }} +iface {{ interface.get('ifname') }} inet6 {{ address.get('proto') }} {% endif %} +{% endif%} +{% endfor %} {% else %} -{% if address.get('iftype') == 'bridge' %} - bridge_ports {{ address.get('bridge_members')[0] }} {{ address.get('bridge_members')[1] }} -{% endif %} +{% if interface.get('iftype') == 'bridge' %} + bridge_ports {{ interface.get('bridge_members')[0] }} {{ interface.get('bridge_members')[1] }} {% endif %} - {% endif %} + {% endfor %} {% endif %} -{%endfor%} +{% endfor%} /etc/resolv.conf From 1fd1ba2638805de73821b80f36d722452672fd56 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Thu, 15 Jun 2017 14:26:17 +0530 Subject: [PATCH 039/183] [raspbian] Added tests for interfaces --- netjsonconfig/backends/raspbian/converters.py | 1 - tests/raspbian/test_interfaces.py | 157 +++++++++++++++++- 2 files changed, 151 insertions(+), 7 deletions(-) diff --git a/netjsonconfig/backends/raspbian/converters.py b/netjsonconfig/backends/raspbian/converters.py index f8046a1c9..83c018a18 100644 --- a/netjsonconfig/backends/raspbian/converters.py +++ b/netjsonconfig/backends/raspbian/converters.py @@ -52,7 +52,6 @@ def to_intermediate(self): }) if addresses is not None: for address in addresses: - print address new_address = {} if iftype in ['ethernet', 'bridge', 'loopback']: if address.get('proto') == 'static': diff --git a/tests/raspbian/test_interfaces.py b/tests/raspbian/test_interfaces.py index 1012b9756..f1f8a69e7 100644 --- a/tests/raspbian/test_interfaces.py +++ b/tests/raspbian/test_interfaces.py @@ -6,7 +6,7 @@ class TestInterfacesRenderer(unittest.TestCase, _TabsMixin): - def test_interface_ipv4_static(self): + def test_ipv4_static(self): o = Raspbian({ "interfaces": [ { @@ -38,7 +38,7 @@ def test_interface_ipv4_static(self): ''' self.assertEqual(o.render(), expected) - def test_interface_ipv6_static(self): + def test_ipv6_static(self): o = Raspbian({ "interfaces": [ { @@ -70,7 +70,7 @@ def test_interface_ipv6_static(self): ''' self.assertEqual(o.render(), expected) - def test_interface_multiple_static(self): + def test_multiple_static(self): o = Raspbian({ "interfaces": [ { @@ -111,7 +111,7 @@ def test_interface_multiple_static(self): ''' self.assertEqual(o.render(), expected) - def test_interface_ipv4_dhcp(self): + def test_ipv4_dhcp(self): o = Raspbian({ "interfaces": [ { @@ -140,7 +140,7 @@ def test_interface_ipv4_dhcp(self): ''' self.assertEqual(o.render(), expected) - def test_interface_ipv6_dhcp(self): + def test_ipv6_dhcp(self): o = Raspbian({ "interfaces": [ { @@ -169,7 +169,7 @@ def test_interface_ipv6_dhcp(self): ''' self.assertEqual(o.render(), expected) - def test_interface_multiple_dhcp(self): + def test_multiple_dhcp(self): o = Raspbian({ "interfaces": [ { @@ -201,6 +201,151 @@ def test_interface_multiple_dhcp(self): /etc/resolv.conf ---------------- +''' + self.assertEqual(o.render(), expected) + + def test_multiple_ip(self): + o = Raspbian({ + "interfaces": [ + { + "name": "eth0.1", + "type": "ethernet", + "autostart": True, + "addresses": [ + { + "address": "192.168.1.1", + "mask": 24, + "proto": "static", + "family": "ipv4" + }, + { + "address": "192.168.2.1", + "mask": 24, + "proto": "static", + "family": "ipv4" + }, + { + "address": "fd87::1", + "mask": 128, + "proto": "static", + "family": "ipv6" + }, + { + "address": "fd87::2", + "mask": 128, + "proto": "static", + "family": "ipv6" + } + ] + } + ] + }) + + expected = '''/etc/network/interfaces +----------------------- +auto eth0.1 +iface eth0.1 inet static + address 192.168.1.1 + netmask 255.255.255.0 +iface eth0.1 inet static + address 192.168.2.1 + netmask 255.255.255.0 +iface eth0.1 inet6 static + address fd87::1 + netmask 128 +iface eth0.1 inet6 static + address fd87::2 + netmask 128 + + + +/etc/resolv.conf +---------------- +''' + self.assertEqual(o.render(), expected) + + def test_multiple_ip_and_dhcp(self): + o = Raspbian({ + "interfaces": [ + { + "name": "eth0", + "type": "ethernet", + "addresses": [ + { + "proto": "dhcp", + "family": "ipv4" + }, + { + "address": "192.168.1.1", + "mask": 24, + "proto": "static", + "family": "ipv4" + }, + { + "address": "192.168.2.1", + "mask": 24, + "proto": "static", + "family": "ipv4" + }, + ] + } + ] + }) + + expected = '''/etc/network/interfaces +----------------------- +auto eth0 +allow-hotplug eth0 +iface eth0 inet dhcp +iface eth0 inet static + address 192.168.1.1 + netmask 255.255.255.0 +iface eth0 inet static + address 192.168.2.1 + netmask 255.255.255.0 + + + +/etc/resolv.conf +---------------- +''' + self.assertEqual(o.render(), expected) + + def test_interface_with_resolv(self): + o = Raspbian({ + "interfaces": [ + { + "name": "eth0", + "type": "ethernet", + "addresses": [ + { + "address": "192.168.1.1", + "mask": 24, + "proto": "static", + "family": "ipv4" + } + ] + } + ], + "dns_servers": ["10.11.12.13", "8.8.8.8"], + "dns_search": ["netjson.org", "openwisp.org"], + }) + + expected = '''/etc/network/interfaces +----------------------- +auto eth0 +iface eth0 inet static + address 192.168.1.1 + netmask 255.255.255.0 + + + +/etc/resolv.conf +---------------- +nameserver 10.11.12.13 +nameserver 8.8.8.8 +search netjson.org +search openwisp.org ''' self.assertEqual(o.render(), expected) From 4eaaba40a1f7a01fb27328fe63b329cae611b268 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Thu, 15 Jun 2017 15:56:24 +0530 Subject: [PATCH 040/183] [raspbian] Removed unncessary objects from intermediate data structure --- netjsonconfig/backends/raspbian/converters.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/netjsonconfig/backends/raspbian/converters.py b/netjsonconfig/backends/raspbian/converters.py index 83c018a18..c2ecd3440 100644 --- a/netjsonconfig/backends/raspbian/converters.py +++ b/netjsonconfig/backends/raspbian/converters.py @@ -83,13 +83,11 @@ def to_intermediate(self): new_address.update({ 'proto': 'dhcp', 'family': 'ipv4', - 'ipv4dhcp': True, }) elif address.get('family') == 'ipv6': new_address.update({ 'proto': 'dhcp', 'family': 'ipv6', - 'ipv6dhcp': True, }) address_list.append(new_address) new_interface.update({ From 032867f6f7615726e79f676f0b2cf0c3ddb3bc54 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Sat, 17 Jun 2017 20:34:20 +0530 Subject: [PATCH 041/183] [raspbian] Renders section only if config exists --- .../backends/raspbian/templates/raspbian.jinja2 | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 b/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 index 06ecfa8ff..6e6780682 100644 --- a/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 +++ b/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 @@ -1,7 +1,7 @@ -/etc/network/interfaces ------------------------ {% for i, j in data.items() %} {% if i|string() == 'interfaces' %} +/etc/network/interfaces +----------------------- {% for interface in j %} auto {{ interface.get('ifname') }} {% if interface.get('address') != None %} @@ -44,14 +44,9 @@ iface {{ interface.get('ifname') }} inet6 {{ address.get('proto') }} {% endif %} {% endfor %} -{% endif %} -{% endfor%} - - +{% elif i|string() == 'dns_servers' %} /etc/resolv.conf ---------------- -{% for i, j in data.items() %} -{% if i|string() == 'dns_servers' %} {% for ip in j %} nameserver {{ ip }} {% endfor %} @@ -61,4 +56,4 @@ search {{ domain }} {% endfor %} {% else %} {% endif %} -{% endfor %} +{% endfor%} From 66ba9d6586ff30a887ef399dd6677931569abc9f Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Sat, 17 Jun 2017 20:34:57 +0530 Subject: [PATCH 042/183] [raspbian] Modified tests for new renders --- tests/raspbian/test_interfaces.py | 55 ------------------------------- tests/raspbian/test_resolv.py | 26 +++------------ 2 files changed, 4 insertions(+), 77 deletions(-) diff --git a/tests/raspbian/test_interfaces.py b/tests/raspbian/test_interfaces.py index f1f8a69e7..3bf0f2be5 100644 --- a/tests/raspbian/test_interfaces.py +++ b/tests/raspbian/test_interfaces.py @@ -31,10 +31,6 @@ def test_ipv4_static(self): address 10.0.0.1 netmask 255.255.255.240 - - -/etc/resolv.conf ----------------- ''' self.assertEqual(o.render(), expected) @@ -63,10 +59,6 @@ def test_ipv6_static(self): address fe80::ba27:ebff:fe1c:5477 netmask 64 - - -/etc/resolv.conf ----------------- ''' self.assertEqual(o.render(), expected) @@ -104,10 +96,6 @@ def test_multiple_static(self): address fe80::ba27:ebff:fe1c:5477 netmask 64 - - -/etc/resolv.conf ----------------- ''' self.assertEqual(o.render(), expected) @@ -133,10 +121,6 @@ def test_ipv4_dhcp(self): allow-hotplug eth0 iface eth0 inet dhcp - - -/etc/resolv.conf ----------------- ''' self.assertEqual(o.render(), expected) @@ -162,10 +146,6 @@ def test_ipv6_dhcp(self): allow-hotplug eth0 iface eth0 inet6 dhcp - - -/etc/resolv.conf ----------------- ''' self.assertEqual(o.render(), expected) @@ -197,10 +177,6 @@ def test_multiple_dhcp(self): iface eth0 inet dhcp iface eth0 inet6 dhcp - - -/etc/resolv.conf ----------------- ''' self.assertEqual(o.render(), expected) @@ -229,12 +205,6 @@ def test_multiple_ip(self): "mask": 128, "proto": "static", "family": "ipv6" - }, - { - "address": "fd87::2", - "mask": 128, - "proto": "static", - "family": "ipv6" } ] } @@ -253,14 +223,7 @@ def test_multiple_ip(self): iface eth0.1 inet6 static address fd87::1 netmask 128 -iface eth0.1 inet6 static - address fd87::2 - netmask 128 - - -/etc/resolv.conf ----------------- ''' self.assertEqual(o.render(), expected) @@ -304,10 +267,6 @@ def test_multiple_ip_and_dhcp(self): address 192.168.2.1 netmask 255.255.255.0 - - -/etc/resolv.conf ----------------- ''' self.assertEqual(o.render(), expected) @@ -338,8 +297,6 @@ def test_interface_with_resolv(self): address 192.168.1.1 netmask 255.255.255.0 - - /etc/resolv.conf ---------------- nameserver 10.11.12.13 @@ -374,10 +331,6 @@ def test_loopback(self): address 127.0.0.1 netmask 255.0.0.0 - - -/etc/resolv.conf ----------------- ''' self.assertEqual(o.render(), expected) @@ -401,10 +354,6 @@ def test_simple_bridge(self): auto br-lan bridge_ports eth0 eth1 - - -/etc/resolv.conf ----------------- ''' self.assertEqual(o.render(), expected) @@ -439,9 +388,5 @@ def test_complex_bridge(self): netmask 64 bridge_ports wlan0 vpn.40 - - -/etc/resolv.conf ----------------- ''' self.assertEqual(o.render(), expected) diff --git a/tests/raspbian/test_resolv.py b/tests/raspbian/test_resolv.py index 1b0ee1f06..d3f8f33c5 100644 --- a/tests/raspbian/test_resolv.py +++ b/tests/raspbian/test_resolv.py @@ -14,11 +14,7 @@ def test_dns_server(self): ], }) - expected = '''/etc/network/interfaces ------------------------ - - -/etc/resolv.conf + expected = '''/etc/resolv.conf ---------------- nameserver 10.254.0.1 nameserver 10.254.0.2 @@ -32,11 +28,7 @@ def test_dns_search(self): ], }) - expected = '''/etc/network/interfaces ------------------------ - - -/etc/resolv.conf + expected = '''/etc/resolv.conf ---------------- search domain.com ''' @@ -53,11 +45,7 @@ def test_dns_server_and_dns_search(self): ], }) - expected = '''/etc/network/interfaces ------------------------ - - -/etc/resolv.conf + expected = '''/etc/resolv.conf ---------------- nameserver 10.11.12.13 nameserver 8.8.8.8 @@ -70,11 +58,5 @@ def test_no_dns_server_and_dns_search(self): o = Raspbian({ }) - expected = '''/etc/network/interfaces ------------------------ - - -/etc/resolv.conf ----------------- -''' + expected = '''''' self.assertEqual(o.render(), expected) From 89d68712dbe10afea51df5ce71be535019a9ca98 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Sat, 17 Jun 2017 20:39:51 +0530 Subject: [PATCH 043/183] [raspian] Removed allow-hotpug --- netjsonconfig/backends/raspbian/templates/raspbian.jinja2 | 1 - tests/raspbian/test_interfaces.py | 4 ---- 2 files changed, 5 deletions(-) diff --git a/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 b/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 index 6e6780682..d6459644b 100644 --- a/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 +++ b/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 @@ -29,7 +29,6 @@ iface {{ interface.get('ifname') }} inet6 {{ address.get('proto') }} {% endif %} {% endif %} {% elif address.get('proto') == 'dhcp' %} -allow-hotplug {{ interface.get('ifname') }} {% if address.get('family') == 'ipv4'%} iface {{ interface.get('ifname') }} inet {{ address.get('proto') }} {% elif address.get('family') == 'ipv6' %} diff --git a/tests/raspbian/test_interfaces.py b/tests/raspbian/test_interfaces.py index 3bf0f2be5..064ca8821 100644 --- a/tests/raspbian/test_interfaces.py +++ b/tests/raspbian/test_interfaces.py @@ -118,7 +118,6 @@ def test_ipv4_dhcp(self): expected = '''/etc/network/interfaces ----------------------- auto eth0 -allow-hotplug eth0 iface eth0 inet dhcp ''' @@ -143,7 +142,6 @@ def test_ipv6_dhcp(self): expected = '''/etc/network/interfaces ----------------------- auto eth0 -allow-hotplug eth0 iface eth0 inet6 dhcp ''' @@ -173,7 +171,6 @@ def test_multiple_dhcp(self): expected = '''/etc/network/interfaces ----------------------- auto eth0 -allow-hotplug eth0 iface eth0 inet dhcp iface eth0 inet6 dhcp @@ -258,7 +255,6 @@ def test_multiple_ip_and_dhcp(self): expected = '''/etc/network/interfaces ----------------------- auto eth0 -allow-hotplug eth0 iface eth0 inet dhcp iface eth0 inet static address 192.168.1.1 From 6ef27eea538f43f825006a333fe073b5123030ac Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Sun, 18 Jun 2017 14:56:56 +0530 Subject: [PATCH 044/183] [raspbian] Added initial documentation for Network Interfaces and Bridge Interfaces --- docs/source/backends/raspbian.rst | 293 ++++++++++++++++++++++++++++++ 1 file changed, 293 insertions(+) diff --git a/docs/source/backends/raspbian.rst b/docs/source/backends/raspbian.rst index 88a36ec6b..241c6aec1 100644 --- a/docs/source/backends/raspbian.rst +++ b/docs/source/backends/raspbian.rst @@ -10,3 +10,296 @@ Initialization -------------- .. automethod:: netjsonconfig.Raspbian.__init__ + + +Render method +------------- + +.. automethod:: netjsonconfig.OpenWrt.render + +Code example: + +.. code-block:: python + + from netjsonconfig import OpenWrt + + o = Raspbian({ + "interfaces": [ + { + "name": "eth0.1", + "type": "ethernet", + "addresses": [ + { + "address": "192.168.1.1", + "mask": 24, + "proto": "static", + "family": "ipv4" + }, + { + "address": "192.168.2.1", + "mask": 24, + "proto": "static", + "family": "ipv4" + }, + { + "address": "fd87::1", + "mask": 128, + "proto": "static", + "family": "ipv6" + } + ] + } + ] + }) + print o.render() + +Will return the following output:: + + /etc/network/interfaces + ----------------------- + auto eth0.1 + iface eth0.1 inet static + address 192.168.1.1 + netmask 255.255.255.0 + iface eth0.1 inet static + address 192.168.2.1 + netmask 255.255.255.0 + iface eth0.1 inet6 static + address fd87::1 + netmask 128 + +Network interfaces +------------------ + +The network interface settings reside in the ``interfaces`` key of the +*configuration dictionary*, which must contain a list of +`NetJSON interface objects `_ +(see the link for the detailed specification). + +There are 3 main type of interfaces: + +* **network interfaces**: may be of type ``ethernet``, ``virtual``, ``loopback`` or ``other`` +* **wireless interfaces**: must be of type ``wireless`` +* **bridge interfaces**: must be of type ``bridge`` + +Loopback Interface +~~~~~~~~~~~~~~~~~~ + +The following *configuration dictionary*: + +.. code-block:: python + + { + "interfaces": [ + { + "name": "lo", + "type": "loopback", + "addresses": [ + { + "address": "127.0.0.1", + "mask": 8, + "proto": "static", + "family": "ipv4" + } + ] + } + ] + } + +Will be rendered as follows:: + + /etc/network/interfaces + ----------------------- + auto lo + iface lo inet static + address 127.0.0.1 + netmask 255.0.0.0 + +Dualstack (IPv4 & IPv6) +~~~~~~~~~~~~~~~~~~~~~~~ + +The following *configuration dictionary*: + +.. code-block:: python + + { + "interfaces": [ + { + "name": "eth0", + "type": "ethernet", + "addresses": [ + { + "family": "ipv4", + "proto": "static", + "address": "10.27.251.1", + "mask": 24 + }, + { + "family": "ipv6", + "proto": "static", + "address": "fdb4:5f35:e8fd::1", + "mask": 48 + } + ] + } + ] + } + +Will be rendered as follows:: + + /etc/network/interfaces + ----------------------- + auto eth0 + iface eth0 inet static + address 10.27.251.1 + netmask 255.255.255.0 + iface eth0 inet6 static + address fdb4:5f35:e8fd::1 + netmask 48 + +DNS Servers and Search Domains +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +DNS servers can be set using ``dns_servers``, while search domains can be set using +``dns_search``. + +If specified, these values will be automatically added in every interface which has +at least one static ip address; interfaces which have no ip address configured or are using +dynamic ip address configuration won't get the ``dns`` option in the UCI output, eg: + +.. code-block:: python + + { + "dns_servers": ["10.11.12.13", "8.8.8.8"], + "dns_search": ["openwisp.org", "netjson.org"], + "interfaces": [ + { + "name": "eth0", + "type": "ethernet", + "addresses": [ + { + "address": "192.168.1.1", + "mask": 24, + "proto": "static", + "family": "ipv4" + } + ] + }, + { + "name": "eth1", + "type": "ethernet", + "addresses": [ + { + "proto": "dhcp", + "family": "ipv4" + } + ] + } + ] + } + +Will return the following UCI output:: + + /etc/network/interfaces + ----------------------- + auto eth0 + iface eth0 inet static + address 192.168.1.1 + netmask 255.255.255.0 + + auto eth1 + iface eth1 inet dhcp + + /etc/resolv.conf + ---------------- + nameserver 10.11.12.13 + nameserver 8.8.8.8 + search openwisp.org + search netjson.org + +DHCP IPv6 Ethernet Interface +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The following *configuration dictionary*: + +.. code-block:: python + + { + "interfaces": [ + { + "name": "eth0", + "type": "ethernet", + "addresses": [ + { + "proto": "dhcp", + "family": "ipv6" + } + ] + } + ] + } + +Will be rendered as follows:: + + /etc/network/interfaces + ----------------------- + auto eth0 + iface eth0 inet6 dhcp + +Bridge Interfaces +----------------- + +Interfaces of type ``bridge`` can contain a option that is specific for network bridges: + +* ``bridge_members``: interfaces that are members of the bridge + +.. note:: + The bridge members must be active when creating the bridge + +Installing the Software +~~~~~~~~~~~~~~~~~~~~~~~ + +To create a bridge interface you will need to install a program called `brctl` and +is included in `bridge-utils `_. +You can install it using this command:: + + $ aptitude install bridge-utils + + +Bridge Interface Example +~~~~~~~~~~~~~~~~~~~~~~~~ + +The following *configuration dictionary*: + +.. code-block:: python + + { + "interfaces": [ + { + "name": "lan_bridge", + "type": "bridge", + "bridge_members": [ + "eth0:0", + "eth0:1" + ], + "addresses": [ + { + "address": "172.17.0.2", + "mask": 24, + "proto": "static", + "family": "ipv4" + } + ] + } + ] + } + +Will be rendered as follows:: + + /etc/network/interfaces + ----------------------- + auto lan_bridge + iface lan_bridge inet static + address 172.17.0.2 + netmask 255.255.255.0 + bridge_ports eth0:0 eth0:1 From 9036115583101a633785eee7c54687cd499db6fe Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Sun, 18 Jun 2017 16:42:12 +0530 Subject: [PATCH 045/183] [raspbian] Added support for mtu --- netjsonconfig/backends/raspbian/converters.py | 5 +++++ .../backends/raspbian/templates/raspbian.jinja2 | 12 ++++++++++++ 2 files changed, 17 insertions(+) diff --git a/netjsonconfig/backends/raspbian/converters.py b/netjsonconfig/backends/raspbian/converters.py index c2ecd3440..f001fa107 100644 --- a/netjsonconfig/backends/raspbian/converters.py +++ b/netjsonconfig/backends/raspbian/converters.py @@ -50,6 +50,11 @@ def to_intermediate(self): new_interface.update({ 'bridge_members': interface.get('bridge_members'), }) + mtu = interface.get('mtu', None) + if mtu is not None: + new_interface.update({ + 'mtu': mtu + }) if addresses is not None: for address in addresses: new_address = {} diff --git a/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 b/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 index d6459644b..80bb37cf6 100644 --- a/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 +++ b/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 @@ -14,6 +14,9 @@ iface {{ interface.get('ifname') }} inet {{ address.get('proto') }} {% if address.get('gateway', None) != None %} gateway {{ address.get('ipv4gateway')}} {% endif %} +{% if interface.get('mtu', None) != None %} + mtu {{ interface.get('mtu') }} +{% endif %} {% if interface.get('iftype') == 'bridge' %} bridge_ports {{ interface.get('bridge_members')[0] }} {{ interface.get('bridge_members')[1] }} {% endif %} @@ -24,6 +27,9 @@ iface {{ interface.get('ifname') }} inet6 {{ address.get('proto') }} {% if address.get('gateway', None) != None %} gateway {{ address.get('ipv6gateway') }} {% endif %} +{% if interface.get('mtu', None) != None %} + mtu {{ interface.get('mtu') }} +{% endif %} {% if interface.get('iftype') == 'bridge' %} bridge_ports {{ interface.get('bridge_members')[0] }} {{ interface.get('bridge_members')[1] }} {% endif %} @@ -31,8 +37,14 @@ iface {{ interface.get('ifname') }} inet6 {{ address.get('proto') }} {% elif address.get('proto') == 'dhcp' %} {% if address.get('family') == 'ipv4'%} iface {{ interface.get('ifname') }} inet {{ address.get('proto') }} +{% if interface.get('mtu', None) != None %} + pre-up /sbin/ifconfig $IFACE mtu {{ interface.get('mtu') }} +{% endif %} {% elif address.get('family') == 'ipv6' %} iface {{ interface.get('ifname') }} inet6 {{ address.get('proto') }} +{% if interface.get('mtu', None) != None %} + pre-up /sbin/ifconfig $IFACE mtu {{ interface.get('mtu') }} +{% endif %} {% endif %} {% endif%} {% endfor %} From 49ef8bf90da72d0904e10906c63e12e71e7047ec Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Sun, 18 Jun 2017 16:43:52 +0530 Subject: [PATCH 046/183] [raspbian] Added support for mac --- netjsonconfig/backends/raspbian/converters.py | 5 +++++ .../backends/raspbian/templates/raspbian.jinja2 | 12 ++++++++++++ 2 files changed, 17 insertions(+) diff --git a/netjsonconfig/backends/raspbian/converters.py b/netjsonconfig/backends/raspbian/converters.py index f001fa107..421999be3 100644 --- a/netjsonconfig/backends/raspbian/converters.py +++ b/netjsonconfig/backends/raspbian/converters.py @@ -55,6 +55,11 @@ def to_intermediate(self): new_interface.update({ 'mtu': mtu }) + mac = interface.get('mac', None) + if mac is not None: + new_interface.update({ + 'mac': mac + }) if addresses is not None: for address in addresses: new_address = {} diff --git a/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 b/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 index 80bb37cf6..ad8c4df17 100644 --- a/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 +++ b/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 @@ -17,6 +17,9 @@ iface {{ interface.get('ifname') }} inet {{ address.get('proto') }} {% if interface.get('mtu', None) != None %} mtu {{ interface.get('mtu') }} {% endif %} +{% if interface.get('mac', None) != None %} + hwaddress {{ interface.get('mac') }} +{% endif %} {% if interface.get('iftype') == 'bridge' %} bridge_ports {{ interface.get('bridge_members')[0] }} {{ interface.get('bridge_members')[1] }} {% endif %} @@ -30,6 +33,9 @@ iface {{ interface.get('ifname') }} inet6 {{ address.get('proto') }} {% if interface.get('mtu', None) != None %} mtu {{ interface.get('mtu') }} {% endif %} +{% if interface.get('mac', None) != None %} + hwaddress {{ interface.get('mac') }} +{% endif %} {% if interface.get('iftype') == 'bridge' %} bridge_ports {{ interface.get('bridge_members')[0] }} {{ interface.get('bridge_members')[1] }} {% endif %} @@ -40,11 +46,17 @@ iface {{ interface.get('ifname') }} inet {{ address.get('proto') }} {% if interface.get('mtu', None) != None %} pre-up /sbin/ifconfig $IFACE mtu {{ interface.get('mtu') }} {% endif %} +{% if interface.get('mac', None) != None %} + hwaddress {{ interface.get('mac') }} +{% endif %} {% elif address.get('family') == 'ipv6' %} iface {{ interface.get('ifname') }} inet6 {{ address.get('proto') }} {% if interface.get('mtu', None) != None %} pre-up /sbin/ifconfig $IFACE mtu {{ interface.get('mtu') }} {% endif %} +{% if interface.get('mac', None) != None %} + hwaddress {{ interface.get('mac') }} +{% endif %} {% endif %} {% endif%} {% endfor %} From cd146056041b0da83a92127b09da3cfd46ff0831 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Mon, 19 Jun 2017 15:15:06 +0530 Subject: [PATCH 047/183] [raspbian] Added mtu output to tests --- tests/raspbian/test_interfaces.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/raspbian/test_interfaces.py b/tests/raspbian/test_interfaces.py index 064ca8821..2dcae7f65 100644 --- a/tests/raspbian/test_interfaces.py +++ b/tests/raspbian/test_interfaces.py @@ -382,6 +382,7 @@ def test_complex_bridge(self): iface brwifi inet6 static address fe80::8029:23ff:fe7d:c214 netmask 64 + mtu 1500 bridge_ports wlan0 vpn.40 ''' From f2688a9895a6addff59947cffe8b8f9bcac6691c Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Tue, 20 Jun 2017 14:51:25 +0530 Subject: [PATCH 048/183] [raspbian] Changed template style --- netjsonconfig/backends/raspbian/templates/raspbian.jinja2 | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 b/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 index ad8c4df17..16f45342e 100644 --- a/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 +++ b/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 @@ -1,7 +1,6 @@ {% for i, j in data.items() %} {% if i|string() == 'interfaces' %} -/etc/network/interfaces ------------------------ +config: /etc/network/interfaces {% for interface in j %} auto {{ interface.get('ifname') }} {% if interface.get('address') != None %} @@ -68,8 +67,7 @@ iface {{ interface.get('ifname') }} inet6 {{ address.get('proto') }} {% endfor %} {% elif i|string() == 'dns_servers' %} -/etc/resolv.conf ----------------- +config: /etc/resolv.conf {% for ip in j %} nameserver {{ ip }} {% endfor %} From 269b270211ddf313a165cd8e0525aa582224b13e Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Tue, 20 Jun 2017 15:09:43 +0530 Subject: [PATCH 049/183] [raspbian] Modified tests with new template design --- tests/raspbian/test_interfaces.py | 39 +++++++++++-------------------- tests/raspbian/test_resolv.py | 9 +++---- 2 files changed, 16 insertions(+), 32 deletions(-) diff --git a/tests/raspbian/test_interfaces.py b/tests/raspbian/test_interfaces.py index 2dcae7f65..6e98c2ae9 100644 --- a/tests/raspbian/test_interfaces.py +++ b/tests/raspbian/test_interfaces.py @@ -24,8 +24,7 @@ def test_ipv4_static(self): ] }) - expected = '''/etc/network/interfaces ------------------------ + expected = '''config: /etc/network/interfaces auto eth0 iface eth0 inet static address 10.0.0.1 @@ -52,8 +51,7 @@ def test_ipv6_static(self): ] }) - expected = '''/etc/network/interfaces ------------------------ + expected = '''config: /etc/network/interfaces auto eth0 iface eth0 inet6 static address fe80::ba27:ebff:fe1c:5477 @@ -86,8 +84,7 @@ def test_multiple_static(self): ] }) - expected = '''/etc/network/interfaces ------------------------ + expected = '''config: /etc/network/interfaces auto eth0 iface eth0 inet static address 10.0.0.1 @@ -115,8 +112,7 @@ def test_ipv4_dhcp(self): ] }) - expected = '''/etc/network/interfaces ------------------------ + expected = '''config: /etc/network/interfaces auto eth0 iface eth0 inet dhcp @@ -139,8 +135,7 @@ def test_ipv6_dhcp(self): ] }) - expected = '''/etc/network/interfaces ------------------------ + expected = '''config: /etc/network/interfaces auto eth0 iface eth0 inet6 dhcp @@ -168,8 +163,7 @@ def test_multiple_dhcp(self): ] }) - expected = '''/etc/network/interfaces ------------------------ + expected = '''config: /etc/network/interfaces auto eth0 iface eth0 inet dhcp iface eth0 inet6 dhcp @@ -208,8 +202,7 @@ def test_multiple_ip(self): ] }) - expected = '''/etc/network/interfaces ------------------------ + expected = '''config: /etc/network/interfaces auto eth0.1 iface eth0.1 inet static address 192.168.1.1 @@ -252,8 +245,7 @@ def test_multiple_ip_and_dhcp(self): ] }) - expected = '''/etc/network/interfaces ------------------------ + expected = '''config: /etc/network/interfaces auto eth0 iface eth0 inet dhcp iface eth0 inet static @@ -286,15 +278,13 @@ def test_interface_with_resolv(self): "dns_search": ["netjson.org", "openwisp.org"], }) - expected = '''/etc/network/interfaces ------------------------ + expected = '''config: /etc/network/interfaces auto eth0 iface eth0 inet static address 192.168.1.1 netmask 255.255.255.0 -/etc/resolv.conf ----------------- +config: /etc/resolv.conf nameserver 10.11.12.13 nameserver 8.8.8.8 search netjson.org @@ -320,8 +310,7 @@ def test_loopback(self): ] }) - expected = '''/etc/network/interfaces ------------------------ + expected = '''config: /etc/network/interfaces auto lo iface lo inet static address 127.0.0.1 @@ -345,8 +334,7 @@ def test_simple_bridge(self): ] }) - expected = '''/etc/network/interfaces ------------------------ + expected = '''config: /etc/network/interfaces auto br-lan bridge_ports eth0 eth1 @@ -376,8 +364,7 @@ def test_complex_bridge(self): ] }) - expected = '''/etc/network/interfaces ------------------------ + expected = '''config: /etc/network/interfaces auto brwifi iface brwifi inet6 static address fe80::8029:23ff:fe7d:c214 diff --git a/tests/raspbian/test_resolv.py b/tests/raspbian/test_resolv.py index d3f8f33c5..cd18d37c0 100644 --- a/tests/raspbian/test_resolv.py +++ b/tests/raspbian/test_resolv.py @@ -14,8 +14,7 @@ def test_dns_server(self): ], }) - expected = '''/etc/resolv.conf ----------------- + expected = '''config: /etc/resolv.conf nameserver 10.254.0.1 nameserver 10.254.0.2 ''' @@ -28,8 +27,7 @@ def test_dns_search(self): ], }) - expected = '''/etc/resolv.conf ----------------- + expected = '''config: /etc/resolv.conf search domain.com ''' self.assertEqual(o.render(), expected) @@ -45,8 +43,7 @@ def test_dns_server_and_dns_search(self): ], }) - expected = '''/etc/resolv.conf ----------------- + expected = '''config: /etc/resolv.conf nameserver 10.11.12.13 nameserver 8.8.8.8 search netjson.org From 69214a67208cfc68265a62a461ad3e38188e0d57 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Wed, 21 Jun 2017 23:23:18 +0530 Subject: [PATCH 050/183] [raspbian] Modified interface template --- netjsonconfig/backends/raspbian/templates/raspbian.jinja2 | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 b/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 index 16f45342e..a12b5a450 100644 --- a/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 +++ b/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 @@ -1,7 +1,8 @@ {% for i, j in data.items() %} {% if i|string() == 'interfaces' %} -config: /etc/network/interfaces {% for interface in j %} +{% if interface.get('iftype') in ['ethernet', 'bridge', 'loopback'] %} +config: /etc/network/interfaces auto {{ interface.get('ifname') }} {% if interface.get('address') != None %} {% for address in interface.get('address') %} @@ -64,6 +65,7 @@ iface {{ interface.get('ifname') }} inet6 {{ address.get('proto') }} bridge_ports {{ interface.get('bridge_members')[0] }} {{ interface.get('bridge_members')[1] }} {% endif %} {% endif %} +{% endif %} {% endfor %} {% elif i|string() == 'dns_servers' %} From 42a5860890c99225f8331fd7a12c77b6622f6eb5 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Tue, 27 Jun 2017 01:51:06 +0530 Subject: [PATCH 051/183] [raspbian] Added Wireless Configuration support --- netjsonconfig/backends/raspbian/converters.py | 98 ++++---- netjsonconfig/backends/raspbian/raspbian.py | 3 +- .../raspbian/templates/raspbian.jinja2 | 23 ++ tests/raspbian/test_hostapd.py | 233 ++++++++++++++++++ 4 files changed, 309 insertions(+), 48 deletions(-) create mode 100644 tests/raspbian/test_hostapd.py diff --git a/netjsonconfig/backends/raspbian/converters.py b/netjsonconfig/backends/raspbian/converters.py index 421999be3..7cfb924cc 100644 --- a/netjsonconfig/backends/raspbian/converters.py +++ b/netjsonconfig/backends/raspbian/converters.py @@ -3,34 +3,6 @@ from ipaddress import IPv4Interface -class Radio(BaseConverter): - netjson_key = 'radios' - - def to_intermediate(self): - result = [] - radios = get_copy(self.netjson, self.netjson_key) - for radio in radios: - temp = { - 'name': radio['name'], - 'protocol': radio['protocol'], - 'channel': radio['channel'], - 'hwmode': self._get_hwmode(radio) - } - result.append(temp) - return (('wireless', result),) - - def _get_hwmode(self, radio): - protocol = radio['protocol'] - if protocol in ['802.11a', '802.11b', '802.11g']: - return protocol[4:] - if radio['channel'] is 0: - return radio.get('hwmode') - elif radio['channel'] <= 13: - return '11g' - else: - return '11a' - - class Interfaces(BaseConverter): netjson_key = 'interfaces' @@ -115,27 +87,61 @@ def to_intermediate(self): interfaces = get_copy(self.netjson, self.netjson_key) for interface in interfaces: if interface['type'] == 'wireless': - temp = { - 'radio': interface['wireless'].get('radio'), - 'mode': interface['wireless'].get('mode'), - 'ssid': interface['wireless'].get('ssid'), + new_interface = { + 'ifname': interface.get('name'), + 'iftype': interface.get('type'), + 'ssid': interface['wireless'].get('ssid') } - bssid = interface['wireless'].get('bssid', None) - if bssid is not None: - temp.update({'bssid': bssid}) - hidden = interface['wireless'].get('hidden', None) - if hidden is not None: - temp.update({'hidden': hidden}) - encryption = interface['wireless'].get('encryption', None) - if encryption is not None: - protocol = encryption.get('protocol') - key = encryption.get('key') - cipher = encryption.get('cipher', None) - if cipher is not None: - temp.update({'cipher': cipher}) - result.append(temp) + wireless = interface.get('wireless') + # radio_num = interface['wireless'].get('radio') + # radios = get_copy(self.netjson, 'radios') + # print radios + # if radios is not None: + # req_radio = [radio for radio in radios if radio['name'] == radio_num][0] + # hwmode = self._get_hwmode(req_radio) + # channel = req_radio['channel'] + # protocol = req_radio['protocol'].replace(".", "") + # new_interface.update({ + # 'hwmode': hwmode, + # 'channel': channel, + # 'protocol': protocol + # }) + new_interface.update({'encryption': self._get_encryption(wireless)}) + result.append(new_interface) return (('wireless', result),) + def _get_hwmode(self, radio): + protocol = radio['protocol'] + if protocol in ['802.11a', '802.11b', '802.11g']: + return protocol[1:] + if radio['channel'] is 0: + return radio.get('hwmode') + elif radio['channel'] <= 13: + return 'g' + else: + return 'a' + + def _get_encryption(self, wireless): + encryption = wireless.get('encryption') + disabled = encryption.get('disabled', False) + new_encryption = {} + if encryption.get('protocol') is not 'none' and encryption.get('disabled') is not True: + protocol, method = encryption.get('protocol').split("_") + if protocol in ['wpa', 'wpa2']: + auth_algs = '1' + wpa = '1' if protocol == 'wpa' else '2' + wpa_key_mgmt = 'WPA-PSK' if method == 'personal' else 'WPA-EAP' + wpa_passphrase = encryption.get('key') + new_encryption.update({ + 'auth_algs': auth_algs, + 'wpa': wpa, + 'wpa_key_mgmt': wpa_key_mgmt, + 'wpa_passphrase': wpa_passphrase + }) + if encryption.get('cipher', None) is not None or 'auto': + wpa_pairwise = str(encryption.get('cipher').replace('+', ' ')).upper() + new_encryption.update({'wpa_pairwise': wpa_pairwise}) + return new_encryption class DnsServers(BaseConverter): netjson_key = 'dns_servers' diff --git a/netjsonconfig/backends/raspbian/raspbian.py b/netjsonconfig/backends/raspbian/raspbian.py index 6738684bf..59f73cfa3 100644 --- a/netjsonconfig/backends/raspbian/raspbian.py +++ b/netjsonconfig/backends/raspbian/raspbian.py @@ -1,4 +1,4 @@ -from .converters import Radio, Interfaces, Wireless, DnsServers, DnsSearch +from .converters import Interfaces, Wireless, DnsServers, DnsSearch from .renderers import Raspbian from ..base.backend import BaseBackend from .schema import schema @@ -11,7 +11,6 @@ class Raspbian(BaseBackend): schema = schema env_path = 'netjsonconfig.backends.raspbian' converters = [ - Radio, Interfaces, Wireless, DnsServers, diff --git a/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 b/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 index a12b5a450..ca766b2ae 100644 --- a/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 +++ b/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 @@ -80,3 +80,26 @@ search {{ domain }} {% else %} {% endif %} {% endfor%} +{% for i, j in data.items() %} +{% if i|string() == 'wireless' %} +{% for wireless in j %} +config: /etc/hostapd/hostapd.conf +interface={{ wireless.get('ifname') }} +driver=nl80211 +hw_mode= +channel= +ieee80211n= +wmm_enabled= +ssid={{ wireless.get('ssid') }} +{% if wireless.get('encryption') != {} %} +auth_algs={{ wireless.get('encryption').get('auth_algs') }} +wpa={{ wireless.get('encryption').get('wpa') }} +wpa_key_mgmt={{ wireless.get('encryption').get('wpa_key_mgmt') }} +wpa_passphrase={{ wireless.get('encryption').get('wpa_passphrase') }} +{% if wireless.get('encryption', None).get('wpa_pairwise') != 'AUTO' %} +wpa_pairwise={{ wireless.get('encryption').get('wpa_pairwise')}} +{% endif %} +{% endif %} +{% endfor %} +{% endif %} +{% endfor %} diff --git a/tests/raspbian/test_hostapd.py b/tests/raspbian/test_hostapd.py new file mode 100644 index 000000000..b330de667 --- /dev/null +++ b/tests/raspbian/test_hostapd.py @@ -0,0 +1,233 @@ +import unittest + +from netjsonconfig import Raspbian +from netjsonconfig.utils import _TabsMixin + + +class TestHostapdRenderer(unittest.TestCase, _TabsMixin): + + def test_wpa2_personal(self): + o = Raspbian({ + "interfaces": [ + { + "name": "wlan0", + "type": "wireless", + "wireless": { + "radio": "radio0", + "mode": "access_point", + "ssid": "wpa2-personal", + "encryption": { + "protocol": "wpa2_personal", + "cipher": "tkip+ccmp", + "key": "passphrase012345" + } + } + } + ] + }) + + expected = ''' +config: /etc/hostapd/hostapd.conf +interface=wlan0 +driver=nl80211 +hw_mode= +channel= +ieee80211n= +wmm_enabled= +ssid=wpa2-personal +auth_algs=1 +wpa=2 +wpa_key_mgmt=WPA-PSK +wpa_passphrase=passphrase012345 +wpa_pairwise=TKIP CCMP +''' + self.assertEqual(o.render(), expected) + + def test_wpa_personal(self): + o = Raspbian({ + "interfaces": [ + { + "name": "wlan0", + "type": "wireless", + "wireless": { + "radio": "radio0", + "mode": "access_point", + "ssid": "wpa-personal", + "encryption": { + "protocol": "wpa_personal", + "cipher": "auto", + "key": "passphrase012345" + } + } + } + ] + }) + + expected = ''' +config: /etc/hostapd/hostapd.conf +interface=wlan0 +driver=nl80211 +hw_mode= +channel= +ieee80211n= +wmm_enabled= +ssid=wpa-personal +auth_algs=1 +wpa=1 +wpa_key_mgmt=WPA-PSK +wpa_passphrase=passphrase012345 +''' + self.assertEqual(o.render(), expected) + + def test_wep_open(self): + o = Raspbian({ + "interfaces": [ + { + "name": "wlan0", + "type": "wireless", + "wireless": { + "radio": "radio0", + "mode": "access_point", + "ssid": "wep", + "encryption": { + "protocol": "wep_open", + "key": "wepkey1234567" + } + } + } + ] + }) + + expected = '''''' + self.assertEqual(o.render(), expected) + + def test_wep_shared(self): + o = Raspbian({ + "interfaces": [ + { + "name": "wlan0", + "type": "wireless", + "wireless": { + "radio": "radio0", + "mode": "access_point", + "ssid": "wep", + "encryption": { + "protocol": "wep_shared", + "key": "wepkey1234567" + } + } + } + ] + }) + + expected = '''''' + self.assertEqual(o.render(), expected) + + def test_encryption_disabled(self): + o = Raspbian({ + "interfaces": [ + { + "name": "wlan0", + "type": "wireless", + "wireless": { + "radio": "radio0", + "mode": "access_point", + "ssid": "MyNetwork", + "encryption": { + "disabled": True, + "protocol": "wpa2_personal", + "cipher": "tkip+ccmp", + "key": "passphrase012345" + } + } + } + ] + }) + + expected = ''' +config: /etc/hostapd/hostapd.conf +interface=wlan0 +driver=nl80211 +hw_mode= +channel= +ieee80211n= +wmm_enabled= +ssid=MyNetwork +''' + self.assertEqual(o.render(), expected) + + def test_no_encryption(self): + o = Raspbian({ + "interfaces": [ + { + "name": "wlan0", + "type": "wireless", + "wireless": { + "radio": "radio0", + "mode": "access_point", + "ssid": "open", + "encryption": {"protocol": "none"} + } + } + ] + }) + + expected = ''' +config: /etc/hostapd/hostapd.conf +interface=wlan0 +driver=nl80211 +hw_mode= +channel= +ieee80211n= +wmm_enabled= +ssid=open +''' + self.assertEqual(o.render(), expected) + + def test_wpa2_personal_adhoc(self): + o = Raspbian({ + "interfaces": [ + { + "name": "wlan0", + "type": "wireless", + "wireless": { + "radio": "radio0", + "mode": "adhoc", + "ssid": "encrypted-adhoc", + "bssid": "00:26:b9:20:5f:09", + "encryption": { + "protocol": "wpa2_personal", + "cipher": "auto", + "key": "passphrase012345" + } + } + } + ] + }) + + expected = '''''' + self.assertEqual(o.render(), expected) + + def test_wps(self): + o = Raspbian({ + "interfaces": [ + { + "name": "wlan0", + "type": "wireless", + "wireless": { + "radio": "radio0", + "mode": "access_point", + "ssid": "wps-ssid", + "encryption": { + "protocol": "wps", + "wps_label": False, + "wps_pushbutton": True, + "wps_pin": "" + } + } + } + ] + }) + + expected = '''''' + self.assertEqual(o.render(), expected) From 09d8fd1cfe8300421339b49c63527b5a06c29273 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Tue, 27 Jun 2017 15:37:08 +0530 Subject: [PATCH 052/183] [raspbian] Modified tests with radio settings --- tests/raspbian/test_hostapd.py | 120 ++++++++++++++++++++++++++++----- 1 file changed, 104 insertions(+), 16 deletions(-) diff --git a/tests/raspbian/test_hostapd.py b/tests/raspbian/test_hostapd.py index b330de667..06cbeb099 100644 --- a/tests/raspbian/test_hostapd.py +++ b/tests/raspbian/test_hostapd.py @@ -8,6 +8,17 @@ class TestHostapdRenderer(unittest.TestCase, _TabsMixin): def test_wpa2_personal(self): o = Raspbian({ + "radios": [ + { + "name": "radio0", + "phy": "phy0", + "driver": "mac80211", + "protocol": "802.11n", + "channel": 3, + "channel_width": 20, + "tx_power": 3 + }, + ], "interfaces": [ { "name": "wlan0", @@ -30,10 +41,10 @@ def test_wpa2_personal(self): config: /etc/hostapd/hostapd.conf interface=wlan0 driver=nl80211 -hw_mode= -channel= -ieee80211n= -wmm_enabled= +hw_mode=g +channel=3 +ieee80211n=1 +wmm_enabled=1 ssid=wpa2-personal auth_algs=1 wpa=2 @@ -45,6 +56,17 @@ def test_wpa2_personal(self): def test_wpa_personal(self): o = Raspbian({ + "radios": [ + { + "name": "radio0", + "phy": "phy0", + "driver": "mac80211", + "protocol": "802.11n", + "channel": 3, + "channel_width": 20, + "tx_power": 3 + }, + ], "interfaces": [ { "name": "wlan0", @@ -67,10 +89,10 @@ def test_wpa_personal(self): config: /etc/hostapd/hostapd.conf interface=wlan0 driver=nl80211 -hw_mode= -channel= -ieee80211n= -wmm_enabled= +hw_mode=g +channel=3 +ieee80211n=1 +wmm_enabled=1 ssid=wpa-personal auth_algs=1 wpa=1 @@ -81,6 +103,17 @@ def test_wpa_personal(self): def test_wep_open(self): o = Raspbian({ + "radios": [ + { + "name": "radio0", + "phy": "phy0", + "driver": "mac80211", + "protocol": "802.11n", + "channel": 3, + "channel_width": 20, + "tx_power": 3 + }, + ], "interfaces": [ { "name": "wlan0", @@ -103,6 +136,17 @@ def test_wep_open(self): def test_wep_shared(self): o = Raspbian({ + "radios": [ + { + "name": "radio0", + "phy": "phy0", + "driver": "mac80211", + "protocol": "802.11n", + "channel": 3, + "channel_width": 20, + "tx_power": 3 + }, + ], "interfaces": [ { "name": "wlan0", @@ -125,6 +169,17 @@ def test_wep_shared(self): def test_encryption_disabled(self): o = Raspbian({ + "radios": [ + { + "name": "radio0", + "phy": "phy0", + "driver": "mac80211", + "protocol": "802.11n", + "channel": 3, + "channel_width": 20, + "tx_power": 3 + }, + ], "interfaces": [ { "name": "wlan0", @@ -148,16 +203,27 @@ def test_encryption_disabled(self): config: /etc/hostapd/hostapd.conf interface=wlan0 driver=nl80211 -hw_mode= -channel= -ieee80211n= -wmm_enabled= +hw_mode=g +channel=3 +ieee80211n=1 +wmm_enabled=1 ssid=MyNetwork ''' self.assertEqual(o.render(), expected) def test_no_encryption(self): o = Raspbian({ + "radios": [ + { + "name": "radio0", + "phy": "phy0", + "driver": "mac80211", + "protocol": "802.11n", + "channel": 3, + "channel_width": 20, + "tx_power": 3 + }, + ], "interfaces": [ { "name": "wlan0", @@ -176,16 +242,27 @@ def test_no_encryption(self): config: /etc/hostapd/hostapd.conf interface=wlan0 driver=nl80211 -hw_mode= -channel= -ieee80211n= -wmm_enabled= +hw_mode=g +channel=3 +ieee80211n=1 +wmm_enabled=1 ssid=open ''' self.assertEqual(o.render(), expected) def test_wpa2_personal_adhoc(self): o = Raspbian({ + "radios": [ + { + "name": "radio0", + "phy": "phy0", + "driver": "mac80211", + "protocol": "802.11n", + "channel": 3, + "channel_width": 20, + "tx_power": 3 + }, + ], "interfaces": [ { "name": "wlan0", @@ -210,6 +287,17 @@ def test_wpa2_personal_adhoc(self): def test_wps(self): o = Raspbian({ + "radios": [ + { + "name": "radio0", + "phy": "phy0", + "driver": "mac80211", + "protocol": "802.11n", + "channel": 3, + "channel_width": 20, + "tx_power": 3 + }, + ], "interfaces": [ { "name": "wlan0", From 42c823cc6bb2f5ee73b3ba3c870dd0f5551267d0 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Tue, 27 Jun 2017 15:38:16 +0530 Subject: [PATCH 053/183] [raspbian] Added support for radio settings --- netjsonconfig/backends/raspbian/converters.py | 25 +++++++++---------- .../raspbian/templates/raspbian.jinja2 | 8 +++--- 2 files changed, 16 insertions(+), 17 deletions(-) diff --git a/netjsonconfig/backends/raspbian/converters.py b/netjsonconfig/backends/raspbian/converters.py index 7cfb924cc..e22419146 100644 --- a/netjsonconfig/backends/raspbian/converters.py +++ b/netjsonconfig/backends/raspbian/converters.py @@ -93,19 +93,18 @@ def to_intermediate(self): 'ssid': interface['wireless'].get('ssid') } wireless = interface.get('wireless') - # radio_num = interface['wireless'].get('radio') - # radios = get_copy(self.netjson, 'radios') - # print radios - # if radios is not None: - # req_radio = [radio for radio in radios if radio['name'] == radio_num][0] - # hwmode = self._get_hwmode(req_radio) - # channel = req_radio['channel'] - # protocol = req_radio['protocol'].replace(".", "") - # new_interface.update({ - # 'hwmode': hwmode, - # 'channel': channel, - # 'protocol': protocol - # }) + radio_num = interface['wireless'].get('radio') + radios = get_copy(self.netjson, 'radios') + if radios is not None: + req_radio = [radio for radio in radios if radio['name'] == radio_num][0] + hwmode = self._get_hwmode(req_radio) + channel = req_radio['channel'] + protocol = req_radio['protocol'].replace(".", "") + new_interface.update({ + 'hwmode': hwmode, + 'channel': channel, + 'protocol': protocol + }) new_interface.update({'encryption': self._get_encryption(wireless)}) result.append(new_interface) return (('wireless', result),) diff --git a/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 b/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 index ca766b2ae..664a3f0dd 100644 --- a/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 +++ b/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 @@ -86,10 +86,10 @@ search {{ domain }} config: /etc/hostapd/hostapd.conf interface={{ wireless.get('ifname') }} driver=nl80211 -hw_mode= -channel= -ieee80211n= -wmm_enabled= +hw_mode={{ wireless.get('hwmode')}} +channel={{ wireless.get('channel')}} +ieee80211n={{ '1' if wireless.get('protocol') == '80211n' }} +wmm_enabled=1 ssid={{ wireless.get('ssid') }} {% if wireless.get('encryption') != {} %} auth_algs={{ wireless.get('encryption').get('auth_algs') }} From 1a72b526b7dc79c33683082963379f8b9cb68573 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Tue, 27 Jun 2017 15:43:10 +0530 Subject: [PATCH 054/183] [raspbian] Combined hostapd.conf with template --- .../backends/raspbian/templates/raspbian.jinja2 | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 b/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 index 664a3f0dd..bd7d79c48 100644 --- a/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 +++ b/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 @@ -77,11 +77,7 @@ nameserver {{ ip }} {% for domain in j %} search {{ domain }} {% endfor %} -{% else %} -{% endif %} -{% endfor%} -{% for i, j in data.items() %} -{% if i|string() == 'wireless' %} +{% elif i|string() == 'wireless' %} {% for wireless in j %} config: /etc/hostapd/hostapd.conf interface={{ wireless.get('ifname') }} @@ -101,5 +97,6 @@ wpa_pairwise={{ wireless.get('encryption').get('wpa_pairwise')}} {% endif %} {% endif %} {% endfor %} +{% else %} {% endif %} -{% endfor %} +{% endfor%} From fde55d1ce50c17a2486e8adadad3d9953b796d8d Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Tue, 27 Jun 2017 19:13:03 +0530 Subject: [PATCH 055/183] [raspbian] Fixed bug with missing encryption block --- netjsonconfig/backends/raspbian/converters.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/netjsonconfig/backends/raspbian/converters.py b/netjsonconfig/backends/raspbian/converters.py index e22419146..fad539283 100644 --- a/netjsonconfig/backends/raspbian/converters.py +++ b/netjsonconfig/backends/raspbian/converters.py @@ -121,7 +121,9 @@ def _get_hwmode(self, radio): return 'a' def _get_encryption(self, wireless): - encryption = wireless.get('encryption') + encryption = wireless.get('encryption', None) + if encryption is None: + return {} disabled = encryption.get('disabled', False) new_encryption = {} if encryption.get('protocol') is not 'none' and encryption.get('disabled') is not True: From 08b966b55fd11441507700bf9418fc7b4082e482 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Tue, 27 Jun 2017 19:42:52 +0530 Subject: [PATCH 056/183] [raspbian] Removed wmm as default from template --- netjsonconfig/backends/raspbian/templates/raspbian.jinja2 | 1 - 1 file changed, 1 deletion(-) diff --git a/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 b/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 index bd7d79c48..0d2efe2f8 100644 --- a/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 +++ b/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 @@ -85,7 +85,6 @@ driver=nl80211 hw_mode={{ wireless.get('hwmode')}} channel={{ wireless.get('channel')}} ieee80211n={{ '1' if wireless.get('protocol') == '80211n' }} -wmm_enabled=1 ssid={{ wireless.get('ssid') }} {% if wireless.get('encryption') != {} %} auth_algs={{ wireless.get('encryption').get('auth_algs') }} From 049e36ea1c2683869143147dbea4dee835f82c8d Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Tue, 27 Jun 2017 19:44:07 +0530 Subject: [PATCH 057/183] [raspbian] Modified hostapd tests by removing default wmm --- tests/raspbian/test_hostapd.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tests/raspbian/test_hostapd.py b/tests/raspbian/test_hostapd.py index 06cbeb099..929f2d29f 100644 --- a/tests/raspbian/test_hostapd.py +++ b/tests/raspbian/test_hostapd.py @@ -44,7 +44,6 @@ def test_wpa2_personal(self): hw_mode=g channel=3 ieee80211n=1 -wmm_enabled=1 ssid=wpa2-personal auth_algs=1 wpa=2 @@ -92,7 +91,6 @@ def test_wpa_personal(self): hw_mode=g channel=3 ieee80211n=1 -wmm_enabled=1 ssid=wpa-personal auth_algs=1 wpa=1 @@ -206,7 +204,6 @@ def test_encryption_disabled(self): hw_mode=g channel=3 ieee80211n=1 -wmm_enabled=1 ssid=MyNetwork ''' self.assertEqual(o.render(), expected) @@ -245,7 +242,6 @@ def test_no_encryption(self): hw_mode=g channel=3 ieee80211n=1 -wmm_enabled=1 ssid=open ''' self.assertEqual(o.render(), expected) From fd8e4588c3b3c1ee14974c0d91b7d505dfad53c1 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Wed, 28 Jun 2017 02:55:30 +0530 Subject: [PATCH 058/183] [raspbian] Documentation on wireless configuration --- docs/source/backends/raspbian.rst | 219 ++++++++++++++++++++++++++++-- 1 file changed, 205 insertions(+), 14 deletions(-) diff --git a/docs/source/backends/raspbian.rst b/docs/source/backends/raspbian.rst index 241c6aec1..a29d78257 100644 --- a/docs/source/backends/raspbian.rst +++ b/docs/source/backends/raspbian.rst @@ -55,8 +55,7 @@ Code example: Will return the following output:: - /etc/network/interfaces - ----------------------- + config: /etc/network/interfaces auto eth0.1 iface eth0.1 inet static address 192.168.1.1 @@ -108,8 +107,7 @@ The following *configuration dictionary*: Will be rendered as follows:: - /etc/network/interfaces - ----------------------- + config: /etc/network/interfaces auto lo iface lo inet static address 127.0.0.1 @@ -147,8 +145,7 @@ The following *configuration dictionary*: Will be rendered as follows:: - /etc/network/interfaces - ----------------------- + config: /etc/network/interfaces auto eth0 iface eth0 inet static address 10.27.251.1 @@ -200,8 +197,7 @@ dynamic ip address configuration won't get the ``dns`` option in the UCI output, Will return the following UCI output:: - /etc/network/interfaces - ----------------------- + config: /etc/network/interfaces auto eth0 iface eth0 inet static address 192.168.1.1 @@ -210,8 +206,7 @@ Will return the following UCI output:: auto eth1 iface eth1 inet dhcp - /etc/resolv.conf - ---------------- + config: /etc/resolv.conf nameserver 10.11.12.13 nameserver 8.8.8.8 search openwisp.org @@ -241,8 +236,7 @@ The following *configuration dictionary*: Will be rendered as follows:: - /etc/network/interfaces - ----------------------- + config: /etc/network/interfaces auto eth0 iface eth0 inet6 dhcp @@ -296,10 +290,207 @@ The following *configuration dictionary*: Will be rendered as follows:: - /etc/network/interfaces - ----------------------- + config: /etc/network/interfaces auto lan_bridge iface lan_bridge inet static address 172.17.0.2 netmask 255.255.255.0 bridge_ports eth0:0 eth0:1 + + +Wireless Settings +----------------- + +To use a Raspberry Pi as various we need first install the required packages. +You can install it using this command:: + + $ sudo apt-get install hostapd dnsmasq + +* **hostapd** - The package allows you to use the wireless interface in various + modes +* **dnsmasq** - The package converts the Raspberry Pi into a DHCP and DNS server + +Configure your interface +~~~~~~~~~~~~~~~~~~~~~~~~ + +Let us say that ``wlan0`` is our wireless interface which we will be using. +First we need to setup a static IP for our wireless interface. Edit the +``wlan0`` section in interface configuration file ``/etc/network/interfaces``:: + auto wlan0 + iface wlan0 inet static + address 172.128.1.1 + netmask 255.255.255.0 + network 172.128.1.0 + broadcast 172.128.1.255 + +Reload ``wlan0`` interface with ``sudo ifdown wlan0; sudo ifup wlan0`` + +Configure hostapd +~~~~~~~~~~~~~~~~~ + +Create a new configuration file ``/etc/hostapd/hostapd.conf``. The contents of this +configuration will be generated by the render method using NetJSON DeviceConfiguration. + +You can check if your wireless service is working by running ``/usr/sbin/hostapd /etc/hostapd/hostapd.conf``. +At this point you should be able to see your wireless network. If you try to connect +to this network, it will authenticate but will not recieve any IP address until +dnsmasq is setup. Use **Ctrl+C** to stop it. +If you want the wireless service to start automatically at boot, find the line:: + #DAEMON_CONF="" + +in ``/etc/default/hostapd`` and replace it with:: + + DAEMON_CONF="/etc/hostapd/hostapd.conf" + +Configure dnsmasq +~~~~~~~~~~~~~~~~~ + +By default ``/etc/dnsmasq.conf`` contains the complete documentation for how the +file needs to be used. It is advisable to create a copy of the original ``dnsmasq.conf``. +After creating the backup, delete the original file and create a new file ``/etc/dnsmasq.conf`` +Setup your DNS and DHCP server. Below is an example configuration file:: + # User interface wlan0 + interface=wlan0 + # Specify the address to listen on + listen-address=172.128.1.1 + # Bind only the interfaces it is listening on + bind-interfaces + # Forward DNS requests to Google DNS + server=8.8.8.8 + # Never forward plain names (without a dot or domain part) + domain-needed + # Never forward addresses in the non-routed address spaces + bogus-priv + # Assign IP addresses between 172.128.1.50 and 172.128.1.150 with a 12 hour lease time + dhcp-range=172.128.1.50,172.128.1.150,12h + +Setup IPv4 Forwarding +~~~~~~~~~~~~~~~~~~~~~ + +We need to enable packet forwarding. Open ``/etc/sysctl.conf`` and uncomment the +following line:: + + #net.ipv4.ip_forward=1 + +This will enable on the next reboot. Incase you want to activate it immediately:: + + sudo sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward" + +Let us assume we have internet connection on ``eth0``. We will need to configure +a NAT between the ``wlan0`` and ``eth0`` interface. It can be done using the followin +commands:: + + sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE + sudo iptables -A FORWARD -i eth0 -o wlan0 -m state --state RELATED,ESTABLISHED -j ACCEPT + sudo iptables -A FORWARD -i wlan0 -o eth0 -j ACCEPT + +These rules need to be applied every time the Raspberry Pi is rebooted. Run :: + + sudo sh -c "iptables-save > /etc/iptables.ipv4.nat" + +Now open the `/etc/rc.local` file and just above the line ``exit 0``, add the following line:: + + iptables-restore < /etc/iptables.ipv4.nat + +Now we just need to start our services:: + + sudo service hostapd start + sudo service dnsmasq start + +You should now be able to connect to your wireless network setup on the Raspberry Pi + +Wireless access point +~~~~~~~~~~~~~~~~~~~~~ + +The following *configuration dictionary* represent one of the most +common wireless access point configuration: + +.. code-block:: python + + { + "radios": [ + { + "name": "radio0", + "phy": "phy0", + "driver": "mac80211", + "protocol": "802.11n", + "channel": 3, + "channel_width": 20, + "tx_power": 3 + }, + ], + "interfaces": [ + { + "name": "wlan0", + "type": "wireless", + "wireless": { + "radio": "radio0", + "mode": "access_point", + "ssid": "myWiFi" + } + } + ] + } + +Will be rendered as follows:: + + config: /etc/hostapd/hostapd.conf + interface=wlan0 + driver=nl80211 + hw_mode=g + channel=3 + ieee80211n=1 + ssid=myWiFi + +WPA2 Personal (Pre-Shared Key) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The following example shows a typical wireless access +point using *WPA2 Personal (Pre-Shared Key)* encryption: + +.. code-block:: python + + { + "radios": [ + { + "name": "radio0", + "phy": "phy0", + "driver": "mac80211", + "protocol": "802.11n", + "channel": 3, + "channel_width": 20, + "tx_power": 3 + } + ], + "interfaces": [ + { + "name": "wlan0", + "type": "wireless", + "wireless": { + "radio": "radio0", + "mode": "access_point", + "ssid": "wpa2-personal", + "encryption": { + "protocol": "wpa2_personal", + "cipher": "tkip+ccmp", + "key": "passphrase012345" + } + } + } + ] + } + +Will be rendered as follows:: + + config: /etc/hostapd/hostapd.conf + interface=wlan0 + driver=nl80211 + hw_mode=g + channel=3 + ieee80211n=1 + ssid=wpa2-personal + auth_algs=1 + wpa=2 + wpa_key_mgmt=WPA-PSK + wpa_passphrase=passphrase012345 + wpa_pairwise=TKIP CCMP From 907dae2cde5445324428f57e54bc1e247602d813 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Wed, 28 Jun 2017 13:59:53 +0530 Subject: [PATCH 059/183] [raspbian] Modified ieee80211n protocol --- netjsonconfig/backends/raspbian/templates/raspbian.jinja2 | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 b/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 index 0d2efe2f8..71d8f63f9 100644 --- a/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 +++ b/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 @@ -84,7 +84,9 @@ interface={{ wireless.get('ifname') }} driver=nl80211 hw_mode={{ wireless.get('hwmode')}} channel={{ wireless.get('channel')}} -ieee80211n={{ '1' if wireless.get('protocol') == '80211n' }} +{% if wireless.get('protocol') == '80211n' %} +ieee80211n=1 +{% endif%} ssid={{ wireless.get('ssid') }} {% if wireless.get('encryption') != {} %} auth_algs={{ wireless.get('encryption').get('auth_algs') }} From 6deabd57ba99c1bced147571d628e3cd3e702f78 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Wed, 28 Jun 2017 17:32:01 +0530 Subject: [PATCH 060/183] [raspbian] Added support for AdHoc mode --- netjsonconfig/backends/raspbian/converters.py | 9 ++++++++- .../backends/raspbian/templates/raspbian.jinja2 | 15 +++++++++++++-- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/netjsonconfig/backends/raspbian/converters.py b/netjsonconfig/backends/raspbian/converters.py index fad539283..fccd85afc 100644 --- a/netjsonconfig/backends/raspbian/converters.py +++ b/netjsonconfig/backends/raspbian/converters.py @@ -32,9 +32,16 @@ def to_intermediate(self): new_interface.update({ 'mac': mac }) + if iftype == 'wireless' and interface.get('wireless').get('mode') == 'adhoc': + wireless = interface.get('wireless') + new_interface.update({ + 'essid': wireless.get('ssid'), + 'mode': wireless.get('mode') + }) if addresses is not None: for address in addresses: new_address = {} + print address if iftype in ['ethernet', 'bridge', 'loopback']: if address.get('proto') == 'static': if address.get('family') == 'ipv4': @@ -86,7 +93,7 @@ def to_intermediate(self): result = [] interfaces = get_copy(self.netjson, self.netjson_key) for interface in interfaces: - if interface['type'] == 'wireless': + if interface['type'] == 'wireless' and interface.get('wireless').get('mode') is not 'adhoc' : new_interface = { 'ifname': interface.get('name'), 'iftype': interface.get('type'), diff --git a/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 b/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 index 71d8f63f9..47f504aa4 100644 --- a/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 +++ b/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 @@ -1,7 +1,18 @@ {% for i, j in data.items() %} {% if i|string() == 'interfaces' %} {% for interface in j %} -{% if interface.get('iftype') in ['ethernet', 'bridge', 'loopback'] %} +{% if interface.get('iftype') == 'wireless' %} +config: /etc/network/interfaces +{% if interface.get('mode') == 'adhoc' %} +auto {{ interface.get('iftype') }} +iface {{ interface.get('iftype') }} inet static + address 172.128.1.1 + netmask 255.255.255.0 + wireless-channel 1 + wireless-essid {{ interface.get('essid') }} + wireless-mode ad-hoc +{% endif %} +{% elif interface.get('iftype') in ['ethernet', 'bridge', 'loopback'] %} config: /etc/network/interfaces auto {{ interface.get('ifname') }} {% if interface.get('address') != None %} @@ -86,7 +97,7 @@ hw_mode={{ wireless.get('hwmode')}} channel={{ wireless.get('channel')}} {% if wireless.get('protocol') == '80211n' %} ieee80211n=1 -{% endif%} +{% endif %} ssid={{ wireless.get('ssid') }} {% if wireless.get('encryption') != {} %} auth_algs={{ wireless.get('encryption').get('auth_algs') }} From 8d80e91663befbe39a0b985f52a007f20ca4da9f Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Wed, 28 Jun 2017 17:35:06 +0530 Subject: [PATCH 061/183] [raspbian] Fixed render error --- netjsonconfig/backends/raspbian/templates/raspbian.jinja2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 b/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 index 47f504aa4..af31722fd 100644 --- a/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 +++ b/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 @@ -2,8 +2,8 @@ {% if i|string() == 'interfaces' %} {% for interface in j %} {% if interface.get('iftype') == 'wireless' %} -config: /etc/network/interfaces {% if interface.get('mode') == 'adhoc' %} +config: /etc/network/interfaces auto {{ interface.get('iftype') }} iface {{ interface.get('iftype') }} inet static address 172.128.1.1 From 6ca6bb301dec6106702253f363bccb5217fe801d Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Wed, 28 Jun 2017 17:48:08 +0530 Subject: [PATCH 062/183] [raspbian] Added documentation on adhoc --- docs/source/backends/raspbian.rst | 36 +++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/docs/source/backends/raspbian.rst b/docs/source/backends/raspbian.rst index a29d78257..b639de701 100644 --- a/docs/source/backends/raspbian.rst +++ b/docs/source/backends/raspbian.rst @@ -442,6 +442,42 @@ Will be rendered as follows:: ieee80211n=1 ssid=myWiFi +Wireless AdHoc Mode +~~~~~~~~~~~~~~~~~~~ + +In wireless adhoc mode, the ``bssid`` property is required. + +The following example: + +.. code-block:: python + + { + "interfaces": [ + { + "name": "wlan0", + "type": "wireless", + "wireless": { + "radio": "radio0", + "ssid": "freifunk", + "mode": "adhoc", + "bssid": "02:b8:c0:00:00:00" + } + } + ] + } + +Will result in:: + + config: /etc/network/interfaces + auto wireless + iface wireless inet static + address 172.128.1.1 + netmask 255.255.255.0 + wireless-channel 1 + wireless-essid freifunk + wireless-mode ad-hoc + + WPA2 Personal (Pre-Shared Key) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ From bd906214511b69043ab8958bc0a2cb201aff8330 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Wed, 28 Jun 2017 17:59:16 +0530 Subject: [PATCH 063/183] [raspbian] Added test for Adhoc mode --- tests/raspbian/test_hostapd.py | 35 ------------------------------- tests/raspbian/test_interfaces.py | 25 ++++++++++++++++++++++ 2 files changed, 25 insertions(+), 35 deletions(-) diff --git a/tests/raspbian/test_hostapd.py b/tests/raspbian/test_hostapd.py index 929f2d29f..2cb7c2197 100644 --- a/tests/raspbian/test_hostapd.py +++ b/tests/raspbian/test_hostapd.py @@ -246,41 +246,6 @@ def test_no_encryption(self): ''' self.assertEqual(o.render(), expected) - def test_wpa2_personal_adhoc(self): - o = Raspbian({ - "radios": [ - { - "name": "radio0", - "phy": "phy0", - "driver": "mac80211", - "protocol": "802.11n", - "channel": 3, - "channel_width": 20, - "tx_power": 3 - }, - ], - "interfaces": [ - { - "name": "wlan0", - "type": "wireless", - "wireless": { - "radio": "radio0", - "mode": "adhoc", - "ssid": "encrypted-adhoc", - "bssid": "00:26:b9:20:5f:09", - "encryption": { - "protocol": "wpa2_personal", - "cipher": "auto", - "key": "passphrase012345" - } - } - } - ] - }) - - expected = '''''' - self.assertEqual(o.render(), expected) - def test_wps(self): o = Raspbian({ "radios": [ diff --git a/tests/raspbian/test_interfaces.py b/tests/raspbian/test_interfaces.py index 6e98c2ae9..d5d7b0b64 100644 --- a/tests/raspbian/test_interfaces.py +++ b/tests/raspbian/test_interfaces.py @@ -319,6 +319,31 @@ def test_loopback(self): ''' self.assertEqual(o.render(), expected) + def test_adhoc_wireless(self): + o = Raspbian({ + "interfaces": [ + { + "name": "wlan0", + "type": "wireless", + "wireless": { + "radio": "radio0", + "ssid": "freifunk", + "mode": "adhoc", + "bssid": "02:b8:c0:00:00:00" + } + } + ] + }) + + expected = '''config: /etc/network/interfaces +auto wireless +iface wireless inet static + address 172.128.1.1 + netmask 255.255.255.0 + wireless-channel 1 + wireless-essid freifunk + wireless-mode ad-hoc +''' def test_simple_bridge(self): o = Raspbian({ "interfaces": [ From f1094fefa6d27c17848279f80abed7ad0f27a49b Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Sat, 1 Jul 2017 19:50:52 +0530 Subject: [PATCH 064/183] [raspbian] Fixed isort and flake8 errors --- netjsonconfig/backends/raspbian/converters.py | 6 +++--- tests/raspbian/test_interfaces.py | 3 +++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/netjsonconfig/backends/raspbian/converters.py b/netjsonconfig/backends/raspbian/converters.py index fccd85afc..11f5bdf57 100644 --- a/netjsonconfig/backends/raspbian/converters.py +++ b/netjsonconfig/backends/raspbian/converters.py @@ -41,7 +41,6 @@ def to_intermediate(self): if addresses is not None: for address in addresses: new_address = {} - print address if iftype in ['ethernet', 'bridge', 'loopback']: if address.get('proto') == 'static': if address.get('family') == 'ipv4': @@ -93,7 +92,7 @@ def to_intermediate(self): result = [] interfaces = get_copy(self.netjson, self.netjson_key) for interface in interfaces: - if interface['type'] == 'wireless' and interface.get('wireless').get('mode') is not 'adhoc' : + if interface['type'] == 'wireless' and interface.get('wireless').get('mode') is not 'adhoc': new_interface = { 'ifname': interface.get('name'), 'iftype': interface.get('type'), @@ -133,7 +132,7 @@ def _get_encryption(self, wireless): return {} disabled = encryption.get('disabled', False) new_encryption = {} - if encryption.get('protocol') is not 'none' and encryption.get('disabled') is not True: + if encryption.get('protocol') is not 'none' and disabled is not True: protocol, method = encryption.get('protocol').split("_") if protocol in ['wpa', 'wpa2']: auth_algs = '1' @@ -151,6 +150,7 @@ def _get_encryption(self, wireless): new_encryption.update({'wpa_pairwise': wpa_pairwise}) return new_encryption + class DnsServers(BaseConverter): netjson_key = 'dns_servers' diff --git a/tests/raspbian/test_interfaces.py b/tests/raspbian/test_interfaces.py index d5d7b0b64..85bb358af 100644 --- a/tests/raspbian/test_interfaces.py +++ b/tests/raspbian/test_interfaces.py @@ -343,7 +343,10 @@ def test_adhoc_wireless(self): wireless-channel 1 wireless-essid freifunk wireless-mode ad-hoc + ''' + self.assertEqual(o.render(), expected) + def test_simple_bridge(self): o = Raspbian({ "interfaces": [ From 95e34451d3be0f43835a56c650ebea2a42990f5c Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Mon, 3 Jul 2017 19:31:22 +0530 Subject: [PATCH 065/183] [raspbian] Refactored interfaces converter --- netjsonconfig/backends/raspbian/converters.py | 182 ++++++++++++------ 1 file changed, 119 insertions(+), 63 deletions(-) diff --git a/netjsonconfig/backends/raspbian/converters.py b/netjsonconfig/backends/raspbian/converters.py index 11f5bdf57..43e4b4eff 100644 --- a/netjsonconfig/backends/raspbian/converters.py +++ b/netjsonconfig/backends/raspbian/converters.py @@ -10,80 +10,136 @@ def to_intermediate(self): result = [] interfaces = get_copy(self.netjson, self.netjson_key) for interface in interfaces: + new_interface = {} ifname = interface.get('name') iftype = interface.get('type') - addresses = interface.get('addresses', None) - new_interface = { - 'ifname': ifname, - 'iftype': iftype, - } - address_list = [] - if iftype == 'bridge': - new_interface.update({ - 'bridge_members': interface.get('bridge_members'), - }) - mtu = interface.get('mtu', None) - if mtu is not None: + + if iftype in ['ethernet', 'bridge', 'loopback']: new_interface.update({ - 'mtu': mtu + 'ifname': ifname, + 'iftype': iftype }) - mac = interface.get('mac', None) - if mac is not None: + addresses = self._get_address(interface) new_interface.update({ - 'mac': mac + 'address': addresses }) - if iftype == 'wireless' and interface.get('wireless').get('mode') == 'adhoc': - wireless = interface.get('wireless') + mac = interface.get('mac', False) + if mac: + new_interface.update({'mac': mac}) + mtu = interface.get('mtu', False) + if mtu: + new_interface.update({'mtu': mtu}) + txqueuelen = interface.get('txqueuelen', False) + if txqueuelen: + new_interface.update({'txqueuelen': txqueuelen}) + autostart = interface.get('autostart', False) + if autostart: + new_interface.update({'autostart': autostart}) + if iftype == 'bridge': new_interface.update({ - 'essid': wireless.get('ssid'), - 'mode': wireless.get('mode') + 'bridge_members': interface.get('bridge_members') }) - if addresses is not None: - for address in addresses: - new_address = {} - if iftype in ['ethernet', 'bridge', 'loopback']: - if address.get('proto') == 'static': - if address.get('family') == 'ipv4': - addressmask = str(address.get('address')) + '/' + str(address.get('mask')) - new_address.update({ - 'proto': 'static', - 'family': 'ipv4', - 'ipv4address': address.get('address'), - 'ipv4netmask': IPv4Interface(addressmask).with_netmask.split('/')[1] - }) - if address.get('gateway', None) is not None: - new_address.update({ - 'ipv4gateway': address.get('gateway'), - }) - if address.get('family') == 'ipv6': - new_address.update({ - 'proto': 'static', - 'family': 'ipv6', - 'ipv6address': address.get('address'), - 'ipv6netmask': address.get('mask') - }) - if address.get('gateway', None) is not None: - new_address.update({ - 'ipv6gateway': address.get('gateway'), - }) - elif address.get('proto') == 'dhcp': - if address.get('family') == 'ipv4': - new_address.update({ - 'proto': 'dhcp', - 'family': 'ipv4', - }) - elif address.get('family') == 'ipv6': - new_address.update({ - 'proto': 'dhcp', - 'family': 'ipv6', - }) - address_list.append(new_address) - new_interface.update({ - 'address': address_list - }) result.append(new_interface) return (('interfaces', result),) + def _get_address(self, interface): + addresses = interface.get('addresses', False) + if addresses: + for address in addresses: + if address.get('proto') == 'static': + if address.get('family') == 'ipv4': + address_mask = str(address.get('address')) + '/' + str(address.get('mask')) + address['netmask'] = IPv4Interface(address_mask).with_netmask.split('/')[1] + del address['mask'] + if address.get('family') == 'ipv6': + address['netmask'] = address['mask'] + del address['mask'] + return addresses + +# [{'iftype': 'ethernet', 'ifname': 'eth0', 'address': [{'ipv4address': '10.0.0.1', 'ipv4netmask': '255.255.255.240', 'proto': 'static', 'family': 'ipv4'}, {'proto': 'static', 'family': 'ipv6', 'ipv6address': 'fe80::ba27:ebff:fe1c:5477', 'ipv6netmask': 64}]}] + + +# class Interfaces(BaseConverter): +# netjson_key = 'interfaces' +# +# def to_intermediate(self): +# result = [] +# interfaces = get_copy(self.netjson, self.netjson_key) +# for interface in interfaces: +# ifname = interface.get('name') +# iftype = interface.get('type') +# addresses = interface.get('addresses', None) +# new_interface = { +# 'ifname': ifname, +# 'iftype': iftype, +# } +# address_list = [] +# if iftype == 'bridge': +# new_interface.update({ +# 'bridge_members': interface.get('bridge_members'), +# }) +# mtu = interface.get('mtu', None) +# if mtu is not None: +# new_interface.update({ +# 'mtu': mtu +# }) +# mac = interface.get('mac', None) +# if mac is not None: +# new_interface.update({ +# 'mac': mac +# }) +# if iftype == 'wireless' and interface.get('wireless').get('mode') == 'adhoc': +# wireless = interface.get('wireless') +# new_interface.update({ +# 'essid': wireless.get('ssid'), +# 'mode': wireless.get('mode') +# }) +# if addresses is not None: +# for address in addresses: +# new_address = {} +# if iftype in ['ethernet', 'bridge', 'loopback']: +# if address.get('proto') == 'static': +# if address.get('family') == 'ipv4': +# addressmask = str(address.get('address')) + '/' + str(address.get('mask')) +# new_address.update({ +# 'proto': 'static', +# 'family': 'ipv4', +# 'ipv4address': address.get('address'), +# 'ipv4netmask': IPv4Interface(addressmask).with_netmask.split('/')[1] +# }) +# if address.get('gateway', None) is not None: +# new_address.update({ +# 'ipv4gateway': address.get('gateway'), +# }) +# if address.get('family') == 'ipv6': +# new_address.update({ +# 'proto': 'static', +# 'family': 'ipv6', +# 'ipv6address': address.get('address'), +# 'ipv6netmask': address.get('mask') +# }) +# if address.get('gateway', None) is not None: +# new_address.update({ +# 'ipv6gateway': address.get('gateway'), +# }) +# elif address.get('proto') == 'dhcp': +# if address.get('family') == 'ipv4': +# new_address.update({ +# 'proto': 'dhcp', +# 'family': 'ipv4', +# }) +# elif address.get('family') == 'ipv6': +# new_address.update({ +# 'proto': 'dhcp', +# 'family': 'ipv6', +# }) +# address_list.append(new_address) +# new_interface.update({ +# 'address': address_list +# }) +# result.append(new_interface) +# return (('interfaces', result),) + class Wireless(BaseConverter): netjson_key = 'interfaces' From db1e1d085c0c8eb94d901367ea7eeec3b2847bd4 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Mon, 3 Jul 2017 20:16:29 +0530 Subject: [PATCH 066/183] [raspbian] Modifed template for updfated intermediate_data --- .../backends/raspbian/templates/raspbian.jinja2 | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 b/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 index af31722fd..dd7600555 100644 --- a/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 +++ b/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 @@ -20,10 +20,10 @@ auto {{ interface.get('ifname') }} {% if address.get('proto') == 'static' %} {% if address.get('family') == 'ipv4' %} iface {{ interface.get('ifname') }} inet {{ address.get('proto') }} - address {{ address.get('ipv4address') }} - netmask {{ address.get('ipv4netmask') }} + address {{ address.get('address') }} + netmask {{ address.get('netmask') }} {% if address.get('gateway', None) != None %} - gateway {{ address.get('ipv4gateway')}} + gateway {{ address.get('gateway')}} {% endif %} {% if interface.get('mtu', None) != None %} mtu {{ interface.get('mtu') }} @@ -36,8 +36,8 @@ iface {{ interface.get('ifname') }} inet {{ address.get('proto') }} {% endif %} {% elif address.get('family') == 'ipv6' %} iface {{ interface.get('ifname') }} inet6 {{ address.get('proto') }} - address {{ address.get('ipv6address') }} - netmask {{ address.get('ipv6netmask') }} + address {{ address.get('address') }} + netmask {{ address.get('netmask') }} {% if address.get('gateway', None) != None %} gateway {{ address.get('ipv6gateway') }} {% endif %} From 96c6149b5baed16d536a32951ad95e200c2918cc Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Mon, 3 Jul 2017 20:18:09 +0530 Subject: [PATCH 067/183] [raspbian] Removed old commented interfaces converter --- netjsonconfig/backends/raspbian/converters.py | 84 ------------------- 1 file changed, 84 deletions(-) diff --git a/netjsonconfig/backends/raspbian/converters.py b/netjsonconfig/backends/raspbian/converters.py index 43e4b4eff..a125981e4 100644 --- a/netjsonconfig/backends/raspbian/converters.py +++ b/netjsonconfig/backends/raspbian/converters.py @@ -56,90 +56,6 @@ def _get_address(self, interface): del address['mask'] return addresses -# [{'iftype': 'ethernet', 'ifname': 'eth0', 'address': [{'ipv4address': '10.0.0.1', 'ipv4netmask': '255.255.255.240', 'proto': 'static', 'family': 'ipv4'}, {'proto': 'static', 'family': 'ipv6', 'ipv6address': 'fe80::ba27:ebff:fe1c:5477', 'ipv6netmask': 64}]}] - - -# class Interfaces(BaseConverter): -# netjson_key = 'interfaces' -# -# def to_intermediate(self): -# result = [] -# interfaces = get_copy(self.netjson, self.netjson_key) -# for interface in interfaces: -# ifname = interface.get('name') -# iftype = interface.get('type') -# addresses = interface.get('addresses', None) -# new_interface = { -# 'ifname': ifname, -# 'iftype': iftype, -# } -# address_list = [] -# if iftype == 'bridge': -# new_interface.update({ -# 'bridge_members': interface.get('bridge_members'), -# }) -# mtu = interface.get('mtu', None) -# if mtu is not None: -# new_interface.update({ -# 'mtu': mtu -# }) -# mac = interface.get('mac', None) -# if mac is not None: -# new_interface.update({ -# 'mac': mac -# }) -# if iftype == 'wireless' and interface.get('wireless').get('mode') == 'adhoc': -# wireless = interface.get('wireless') -# new_interface.update({ -# 'essid': wireless.get('ssid'), -# 'mode': wireless.get('mode') -# }) -# if addresses is not None: -# for address in addresses: -# new_address = {} -# if iftype in ['ethernet', 'bridge', 'loopback']: -# if address.get('proto') == 'static': -# if address.get('family') == 'ipv4': -# addressmask = str(address.get('address')) + '/' + str(address.get('mask')) -# new_address.update({ -# 'proto': 'static', -# 'family': 'ipv4', -# 'ipv4address': address.get('address'), -# 'ipv4netmask': IPv4Interface(addressmask).with_netmask.split('/')[1] -# }) -# if address.get('gateway', None) is not None: -# new_address.update({ -# 'ipv4gateway': address.get('gateway'), -# }) -# if address.get('family') == 'ipv6': -# new_address.update({ -# 'proto': 'static', -# 'family': 'ipv6', -# 'ipv6address': address.get('address'), -# 'ipv6netmask': address.get('mask') -# }) -# if address.get('gateway', None) is not None: -# new_address.update({ -# 'ipv6gateway': address.get('gateway'), -# }) -# elif address.get('proto') == 'dhcp': -# if address.get('family') == 'ipv4': -# new_address.update({ -# 'proto': 'dhcp', -# 'family': 'ipv4', -# }) -# elif address.get('family') == 'ipv6': -# new_address.update({ -# 'proto': 'dhcp', -# 'family': 'ipv6', -# }) -# address_list.append(new_address) -# new_interface.update({ -# 'address': address_list -# }) -# result.append(new_interface) -# return (('interfaces', result),) - class Wireless(BaseConverter): netjson_key = 'interfaces' From 44ae72b07fe501d8bc838fc09412de2d648e0b04 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Tue, 4 Jul 2017 00:58:03 +0530 Subject: [PATCH 068/183] [raspbian] Added adhoc support --- netjsonconfig/backends/raspbian/converters.py | 39 +++++++++++-------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/netjsonconfig/backends/raspbian/converters.py b/netjsonconfig/backends/raspbian/converters.py index a125981e4..ec82f5bc7 100644 --- a/netjsonconfig/backends/raspbian/converters.py +++ b/netjsonconfig/backends/raspbian/converters.py @@ -13,28 +13,33 @@ def to_intermediate(self): new_interface = {} ifname = interface.get('name') iftype = interface.get('type') - + new_interface.update({ + 'ifname': ifname, + 'iftype': iftype + }) if iftype in ['ethernet', 'bridge', 'loopback']: - new_interface.update({ - 'ifname': ifname, - 'iftype': iftype - }) addresses = self._get_address(interface) new_interface.update({ 'address': addresses }) - mac = interface.get('mac', False) - if mac: - new_interface.update({'mac': mac}) - mtu = interface.get('mtu', False) - if mtu: - new_interface.update({'mtu': mtu}) - txqueuelen = interface.get('txqueuelen', False) - if txqueuelen: - new_interface.update({'txqueuelen': txqueuelen}) - autostart = interface.get('autostart', False) - if autostart: - new_interface.update({'autostart': autostart}) + mac = interface.get('mac', False) + if mac: + new_interface.update({'mac': mac}) + mtu = interface.get('mtu', False) + if mtu: + new_interface.update({'mtu': mtu}) + txqueuelen = interface.get('txqueuelen', False) + if txqueuelen: + new_interface.update({'txqueuelen': txqueuelen}) + autostart = interface.get('autostart', False) + if autostart: + new_interface.update({'autostart': autostart}) + if iftype == 'wireless' and interface.get('wireless').get('mode') == 'adhoc': + wireless = interface.get('wireless') + new_interface.update({ + 'essid': wireless.get('ssid'), + 'mode': wireless.get('mode') + }) if iftype == 'bridge': new_interface.update({ 'bridge_members': interface.get('bridge_members') From 288f01a55e954fee90d7e9b56a372e96a8964d14 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Tue, 4 Jul 2017 01:25:05 +0530 Subject: [PATCH 069/183] [raspbian] Seprated main loop for each config file in template --- .../backends/raspbian/templates/raspbian.jinja2 | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 b/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 index dd7600555..ce1e92d57 100644 --- a/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 +++ b/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 @@ -79,7 +79,10 @@ iface {{ interface.get('ifname') }} inet6 {{ address.get('proto') }} {% endif %} {% endfor %} -{% elif i|string() == 'dns_servers' %} +{% endif %} +{% endfor%} +{% for i, j in data.items() %} +{% if i|string() == 'dns_servers' %} config: /etc/resolv.conf {% for ip in j %} nameserver {{ ip }} @@ -88,7 +91,10 @@ nameserver {{ ip }} {% for domain in j %} search {{ domain }} {% endfor %} -{% elif i|string() == 'wireless' %} +{% endif %} +{% endfor%} +{% for i, j in data.items() %} +{% if i|string() == 'wireless' %} {% for wireless in j %} config: /etc/hostapd/hostapd.conf interface={{ wireless.get('ifname') }} @@ -111,4 +117,4 @@ wpa_pairwise={{ wireless.get('encryption').get('wpa_pairwise')}} {% endfor %} {% else %} {% endif %} -{% endfor%} +{% endfor %} From 56e1e9962498f1606b62a3795c2b782842e5d281 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Tue, 4 Jul 2017 02:08:11 +0530 Subject: [PATCH 070/183] [raspbian] Fixed single dns_search template rendering --- netjsonconfig/backends/raspbian/templates/raspbian.jinja2 | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 b/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 index ce1e92d57..8eef3e3f4 100644 --- a/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 +++ b/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 @@ -81,9 +81,15 @@ iface {{ interface.get('ifname') }} inet6 {{ address.get('proto') }} {% endfor %} {% endif %} {% endfor%} +{% set count = [1] %} {% for i, j in data.items() %} -{% if i|string() == 'dns_servers' %} +{% if i|string() in ['dns_servers', 'dns_search'] %} +{% if count == [1] %} config: /etc/resolv.conf +{% if count.append(count.pop() + 1) %}{% endif %} +{% endif %} +{% endif %} +{% if i|string() == 'dns_servers' %} {% for ip in j %} nameserver {{ ip }} {% endfor %} From 75f53d44d97f66b71eeeaee4926be075e69ee58c Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Tue, 4 Jul 2017 16:55:00 +0530 Subject: [PATCH 071/183] [raspbian] Added support for NTP --- netjsonconfig/backends/raspbian/converters.py | 12 +++++++++ netjsonconfig/backends/raspbian/raspbian.py | 3 ++- .../raspbian/templates/raspbian.jinja2 | 8 ++++++ tests/raspbian/test_system.py | 27 +++++++++++++++++++ 4 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 tests/raspbian/test_system.py diff --git a/netjsonconfig/backends/raspbian/converters.py b/netjsonconfig/backends/raspbian/converters.py index ec82f5bc7..244da5909 100644 --- a/netjsonconfig/backends/raspbian/converters.py +++ b/netjsonconfig/backends/raspbian/converters.py @@ -148,3 +148,15 @@ def to_intermediate(self): for domain in dns_search: result.append(domain) return (('dns_search', result),) + + +class Ntp(BaseConverter): + netjson_key = 'ntp' + + def to_intermediate(self): + result = [] + ntp = get_copy(self.netjson, self.netjson_key) + if ntp.get('enabled', False) == True: + for server in ntp.get('server'): + result.append(server) + return (('ntp', result),) diff --git a/netjsonconfig/backends/raspbian/raspbian.py b/netjsonconfig/backends/raspbian/raspbian.py index 59f73cfa3..3f7a70581 100644 --- a/netjsonconfig/backends/raspbian/raspbian.py +++ b/netjsonconfig/backends/raspbian/raspbian.py @@ -1,4 +1,4 @@ -from .converters import Interfaces, Wireless, DnsServers, DnsSearch +from .converters import Interfaces, Wireless, DnsServers, DnsSearch, Ntp from .renderers import Raspbian from ..base.backend import BaseBackend from .schema import schema @@ -15,5 +15,6 @@ class Raspbian(BaseBackend): Wireless, DnsServers, DnsSearch, + Ntp ] renderer = Raspbian diff --git a/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 b/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 index 8eef3e3f4..906f965ab 100644 --- a/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 +++ b/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 @@ -124,3 +124,11 @@ wpa_pairwise={{ wireless.get('encryption').get('wpa_pairwise')}} {% else %} {% endif %} {% endfor %} +{% for i, j in data.items() %} +{% if i|string() == 'ntp' %} +config: /etc/ntp.conf +{% for server in j %} +server {{ server }} +{% endfor %} +{% endif %} +{% endfor %} diff --git a/tests/raspbian/test_system.py b/tests/raspbian/test_system.py new file mode 100644 index 000000000..04d4183b9 --- /dev/null +++ b/tests/raspbian/test_system.py @@ -0,0 +1,27 @@ +import unittest + +from netjsonconfig import Raspbian +from netjsonconfig.utils import _TabsMixin + +class TestSystemRender(unittest.TestCase, _TabsMixin): + + def test_ntp(self): + o = Raspbian({ + "ntp": { + "enabled": True, + "enable_server": False, + "server": [ + "0.openwrt.pool.ntp.org", + "1.openwrt.pool.ntp.org", + "2.openwrt.pool.ntp.org", + "3.openwrt.pool.ntp.org" + ] + } + }) + + expected = '''config: /etc/ntp.config +server 0.openwrt.pool.ntp.org +server 1.openwrt.pool.ntp.org +server 2.openwrt.pool.ntp.org +server 3.openwrt.pool.ntp.org +''' From cb92bde0db0383855955e740dc04b8323ac10892 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Tue, 4 Jul 2017 17:00:54 +0530 Subject: [PATCH 072/183] [raspbian] Fix isort and flake8 errors --- netjsonconfig/backends/raspbian/converters.py | 4 ++-- tests/raspbian/test_system.py | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/netjsonconfig/backends/raspbian/converters.py b/netjsonconfig/backends/raspbian/converters.py index 244da5909..102bc7a89 100644 --- a/netjsonconfig/backends/raspbian/converters.py +++ b/netjsonconfig/backends/raspbian/converters.py @@ -154,9 +154,9 @@ class Ntp(BaseConverter): netjson_key = 'ntp' def to_intermediate(self): - result = [] + result = [] ntp = get_copy(self.netjson, self.netjson_key) - if ntp.get('enabled', False) == True: + if ntp.get('enabled', False): for server in ntp.get('server'): result.append(server) return (('ntp', result),) diff --git a/tests/raspbian/test_system.py b/tests/raspbian/test_system.py index 04d4183b9..3066d0505 100644 --- a/tests/raspbian/test_system.py +++ b/tests/raspbian/test_system.py @@ -3,6 +3,7 @@ from netjsonconfig import Raspbian from netjsonconfig.utils import _TabsMixin + class TestSystemRender(unittest.TestCase, _TabsMixin): def test_ntp(self): @@ -25,3 +26,4 @@ def test_ntp(self): server 2.openwrt.pool.ntp.org server 3.openwrt.pool.ntp.org ''' + self.assertEqual(o.render(), expected) From 839f3462bdde4f073859d48380bca6258ae7918c Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Wed, 5 Jul 2017 17:23:19 +0530 Subject: [PATCH 073/183] [raspbian] Added documentation for NTP settings --- docs/source/backends/raspbian.rst | 48 ++++++++++++++++++++++++++++++- tests/raspbian/test_system.py | 2 +- 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/docs/source/backends/raspbian.rst b/docs/source/backends/raspbian.rst index b639de701..95b4972ad 100644 --- a/docs/source/backends/raspbian.rst +++ b/docs/source/backends/raspbian.rst @@ -476,7 +476,7 @@ Will result in:: wireless-channel 1 wireless-essid freifunk wireless-mode ad-hoc - + WPA2 Personal (Pre-Shared Key) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -530,3 +530,49 @@ Will be rendered as follows:: wpa_key_mgmt=WPA-PSK wpa_passphrase=passphrase012345 wpa_pairwise=TKIP CCMP + +NTP settings +------------ + +The Network Time Protocol settings reside in the ``ntp`` key of the +*configuration dictionary*, which is a custom NetJSON extension not present in +the original NetJSON RFC. + +The ``ntp`` key must contain a dictionary, the allowed options are: + ++-------------------+---------+---------------------+ +| key name | type | function | ++===================+=========+=====================+ +| ``enabled`` | boolean | ntp client enabled | ++-------------------+---------+---------------------+ +| ``enable_server`` | boolean | ntp server enabled | ++-------------------+---------+---------------------+ +| ``server`` | list | list of ntp servers | ++-------------------+---------+---------------------+ + +NTP settings example +~~~~~~~~~~~~~~~~~~~~ + +The following *configuration dictionary* : + +.. code-block:: python + + { + "ntp": { + "enabled": True, + "enable_server": False, + "server": [ + "0.openwrt.pool.ntp.org", + "1.openwrt.pool.ntp.org", + "2.openwrt.pool.ntp.org", + "3.openwrt.pool.ntp.org" + ] + } + +Will be rendered as follows:: + + config: /etc/ntp.conf + server 0.openwrt.pool.ntp.org + server 1.openwrt.pool.ntp.org + server 2.openwrt.pool.ntp.org + server 3.openwrt.pool.ntp.org diff --git a/tests/raspbian/test_system.py b/tests/raspbian/test_system.py index 3066d0505..03633040e 100644 --- a/tests/raspbian/test_system.py +++ b/tests/raspbian/test_system.py @@ -20,7 +20,7 @@ def test_ntp(self): } }) - expected = '''config: /etc/ntp.config + expected = '''config: /etc/ntp.conf server 0.openwrt.pool.ntp.org server 1.openwrt.pool.ntp.org server 2.openwrt.pool.ntp.org From 5dc6fa95c37cf626ab9dc08730ef832d17bd5b0e Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Thu, 6 Jul 2017 15:16:43 +0530 Subject: [PATCH 074/183] [raspbian] Added converter/template/tests for general settings --- netjsonconfig/backends/raspbian/converters.py | 8 +++++++ netjsonconfig/backends/raspbian/raspbian.py | 3 ++- .../raspbian/templates/raspbian.jinja2 | 22 +++++++++++++++++++ tests/raspbian/test_system.py | 20 +++++++++++++++++ 4 files changed, 52 insertions(+), 1 deletion(-) diff --git a/netjsonconfig/backends/raspbian/converters.py b/netjsonconfig/backends/raspbian/converters.py index 102bc7a89..d0caaa6a9 100644 --- a/netjsonconfig/backends/raspbian/converters.py +++ b/netjsonconfig/backends/raspbian/converters.py @@ -3,6 +3,14 @@ from ipaddress import IPv4Interface +class General(BaseConverter): + netjson_key = 'general' + + def to_intermediate(self): + result = [] + general = get_copy(self.netjson, self.netjson_key) + result.append(general) + return (('general', result),) class Interfaces(BaseConverter): netjson_key = 'interfaces' diff --git a/netjsonconfig/backends/raspbian/raspbian.py b/netjsonconfig/backends/raspbian/raspbian.py index 3f7a70581..feb1d3155 100644 --- a/netjsonconfig/backends/raspbian/raspbian.py +++ b/netjsonconfig/backends/raspbian/raspbian.py @@ -1,4 +1,4 @@ -from .converters import Interfaces, Wireless, DnsServers, DnsSearch, Ntp +from .converters import General, Interfaces, Wireless, DnsServers, DnsSearch, Ntp from .renderers import Raspbian from ..base.backend import BaseBackend from .schema import schema @@ -11,6 +11,7 @@ class Raspbian(BaseBackend): schema = schema env_path = 'netjsonconfig.backends.raspbian' converters = [ + General, Interfaces, Wireless, DnsServers, diff --git a/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 b/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 index 906f965ab..f4a03ca70 100644 --- a/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 +++ b/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 @@ -1,4 +1,26 @@ {% for i, j in data.items() %} +{% if i|string() == 'general' %} +{% for general in j %} +{% if general.get('hostname') %} +config: /etc/hostname +{{ general.get('hostname') }} + +{% endif %} +{% endfor %} +{% endif %} +{% endfor %} +{% for i, j in data.items() %} +{% if i|string() == 'general' %} +{% for general in j %} +{% if general.get('timezone') %} +run commands: +$ timedatectl set-timezone {{ general.get('timezone') }} + +{% endif %} +{% endfor %} +{% endif %} +{% endfor%} +{% for i, j in data.items() %} {% if i|string() == 'interfaces' %} {% for interface in j %} {% if interface.get('iftype') == 'wireless' %} diff --git a/tests/raspbian/test_system.py b/tests/raspbian/test_system.py index 03633040e..a433ca501 100644 --- a/tests/raspbian/test_system.py +++ b/tests/raspbian/test_system.py @@ -6,6 +6,26 @@ class TestSystemRender(unittest.TestCase, _TabsMixin): + def test_general(self): + o = Raspbian({ + "general": { + "hostname": "test-system", + "timezone": "Europe/Rome", + "custom_setting": True, + "empty_setting1": None, + "empty_setting2": "" + } + }) + + expected = '''config: /etc/hostname +test-system + +run commands: +$ timedatectl set-timezone Europe/Rome + +''' + self.assertEqual(o.render(), expected) + def test_ntp(self): o = Raspbian({ "ntp": { From 1de1fecae9706ef17787c121833030b12a94a1e9 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Thu, 6 Jul 2017 10:03:40 +0000 Subject: [PATCH 075/183] [raspbian] Added documentation for general settings --- docs/source/backends/raspbian.rst | 36 +++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/docs/source/backends/raspbian.rst b/docs/source/backends/raspbian.rst index 95b4972ad..a790bde67 100644 --- a/docs/source/backends/raspbian.rst +++ b/docs/source/backends/raspbian.rst @@ -67,6 +67,42 @@ Will return the following output:: address fd87::1 netmask 128 +General settings +---------------- + +The general settings reside in the ``general`` key of the +*configuration dictionary*, which follows the +`NetJSON General object `_ definition +(see the link for the detailed specification). + +General settings example +~~~~~~~~~~~~~~~~~~~~~~~~ + +The following *configuration dictionary*: + +.. code-block:: python + + { + "general": { + "hostname": "routerA", + "timezone": "UTC", + "ula_prefix": "fd8e:f40a:6701::/48" + } + } + +Will be rendered as follows:: + + config: /etc/hostname + routerA + + run commands: + $ timedatectl set-timezone UTC + +After modifying the config files run the following command to change the +hostname:: + + $ /etc/init.d/hostname.sh start + Network interfaces ------------------ From e3abeece906af821bd5288b202c8dd182e8de0fd Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Fri, 7 Jul 2017 18:13:51 +0530 Subject: [PATCH 076/183] [raspbian] Created seprate files for each converter --- netjsonconfig/backends/raspbian/converters.py | 170 ------------------ .../backends/raspbian/converters/__init__.py | 9 + .../backends/raspbian/converters/base.py | 6 + .../backends/raspbian/converters/dnssearch.py | 13 ++ .../raspbian/converters/dnsservers.py | 13 ++ .../backends/raspbian/converters/general.py | 12 ++ .../raspbian/converters/interfaces.py | 62 +++++++ .../backends/raspbian/converters/ntp.py | 14 ++ .../backends/raspbian/converters/wireless.py | 68 +++++++ netjsonconfig/backends/raspbian/raspbian.py | 16 +- .../raspbian/{renderers.py => renderer.py} | 0 11 files changed, 205 insertions(+), 178 deletions(-) delete mode 100644 netjsonconfig/backends/raspbian/converters.py create mode 100644 netjsonconfig/backends/raspbian/converters/__init__.py create mode 100644 netjsonconfig/backends/raspbian/converters/base.py create mode 100644 netjsonconfig/backends/raspbian/converters/dnssearch.py create mode 100644 netjsonconfig/backends/raspbian/converters/dnsservers.py create mode 100644 netjsonconfig/backends/raspbian/converters/general.py create mode 100644 netjsonconfig/backends/raspbian/converters/interfaces.py create mode 100644 netjsonconfig/backends/raspbian/converters/ntp.py create mode 100644 netjsonconfig/backends/raspbian/converters/wireless.py rename netjsonconfig/backends/raspbian/{renderers.py => renderer.py} (100%) diff --git a/netjsonconfig/backends/raspbian/converters.py b/netjsonconfig/backends/raspbian/converters.py deleted file mode 100644 index d0caaa6a9..000000000 --- a/netjsonconfig/backends/raspbian/converters.py +++ /dev/null @@ -1,170 +0,0 @@ -from ...utils import get_copy -from ..base.converter import BaseConverter -from ipaddress import IPv4Interface - - -class General(BaseConverter): - netjson_key = 'general' - - def to_intermediate(self): - result = [] - general = get_copy(self.netjson, self.netjson_key) - result.append(general) - return (('general', result),) -class Interfaces(BaseConverter): - netjson_key = 'interfaces' - - def to_intermediate(self): - result = [] - interfaces = get_copy(self.netjson, self.netjson_key) - for interface in interfaces: - new_interface = {} - ifname = interface.get('name') - iftype = interface.get('type') - new_interface.update({ - 'ifname': ifname, - 'iftype': iftype - }) - if iftype in ['ethernet', 'bridge', 'loopback']: - addresses = self._get_address(interface) - new_interface.update({ - 'address': addresses - }) - mac = interface.get('mac', False) - if mac: - new_interface.update({'mac': mac}) - mtu = interface.get('mtu', False) - if mtu: - new_interface.update({'mtu': mtu}) - txqueuelen = interface.get('txqueuelen', False) - if txqueuelen: - new_interface.update({'txqueuelen': txqueuelen}) - autostart = interface.get('autostart', False) - if autostart: - new_interface.update({'autostart': autostart}) - if iftype == 'wireless' and interface.get('wireless').get('mode') == 'adhoc': - wireless = interface.get('wireless') - new_interface.update({ - 'essid': wireless.get('ssid'), - 'mode': wireless.get('mode') - }) - if iftype == 'bridge': - new_interface.update({ - 'bridge_members': interface.get('bridge_members') - }) - result.append(new_interface) - return (('interfaces', result),) - - def _get_address(self, interface): - addresses = interface.get('addresses', False) - if addresses: - for address in addresses: - if address.get('proto') == 'static': - if address.get('family') == 'ipv4': - address_mask = str(address.get('address')) + '/' + str(address.get('mask')) - address['netmask'] = IPv4Interface(address_mask).with_netmask.split('/')[1] - del address['mask'] - if address.get('family') == 'ipv6': - address['netmask'] = address['mask'] - del address['mask'] - return addresses - - -class Wireless(BaseConverter): - netjson_key = 'interfaces' - - def to_intermediate(self): - result = [] - interfaces = get_copy(self.netjson, self.netjson_key) - for interface in interfaces: - if interface['type'] == 'wireless' and interface.get('wireless').get('mode') is not 'adhoc': - new_interface = { - 'ifname': interface.get('name'), - 'iftype': interface.get('type'), - 'ssid': interface['wireless'].get('ssid') - } - wireless = interface.get('wireless') - radio_num = interface['wireless'].get('radio') - radios = get_copy(self.netjson, 'radios') - if radios is not None: - req_radio = [radio for radio in radios if radio['name'] == radio_num][0] - hwmode = self._get_hwmode(req_radio) - channel = req_radio['channel'] - protocol = req_radio['protocol'].replace(".", "") - new_interface.update({ - 'hwmode': hwmode, - 'channel': channel, - 'protocol': protocol - }) - new_interface.update({'encryption': self._get_encryption(wireless)}) - result.append(new_interface) - return (('wireless', result),) - - def _get_hwmode(self, radio): - protocol = radio['protocol'] - if protocol in ['802.11a', '802.11b', '802.11g']: - return protocol[1:] - if radio['channel'] is 0: - return radio.get('hwmode') - elif radio['channel'] <= 13: - return 'g' - else: - return 'a' - - def _get_encryption(self, wireless): - encryption = wireless.get('encryption', None) - if encryption is None: - return {} - disabled = encryption.get('disabled', False) - new_encryption = {} - if encryption.get('protocol') is not 'none' and disabled is not True: - protocol, method = encryption.get('protocol').split("_") - if protocol in ['wpa', 'wpa2']: - auth_algs = '1' - wpa = '1' if protocol == 'wpa' else '2' - wpa_key_mgmt = 'WPA-PSK' if method == 'personal' else 'WPA-EAP' - wpa_passphrase = encryption.get('key') - new_encryption.update({ - 'auth_algs': auth_algs, - 'wpa': wpa, - 'wpa_key_mgmt': wpa_key_mgmt, - 'wpa_passphrase': wpa_passphrase - }) - if encryption.get('cipher', None) is not None or 'auto': - wpa_pairwise = str(encryption.get('cipher').replace('+', ' ')).upper() - new_encryption.update({'wpa_pairwise': wpa_pairwise}) - return new_encryption - - -class DnsServers(BaseConverter): - netjson_key = 'dns_servers' - - def to_intermediate(self): - result = [] - dns_servers = get_copy(self.netjson, self.netjson_key) - for nameserver in dns_servers: - result.append(nameserver) - return (('dns_servers', result),) - - -class DnsSearch(BaseConverter): - netjson_key = 'dns_search' - - def to_intermediate(self): - result = [] - dns_search = get_copy(self.netjson, self.netjson_key) - for domain in dns_search: - result.append(domain) - return (('dns_search', result),) - - -class Ntp(BaseConverter): - netjson_key = 'ntp' - - def to_intermediate(self): - result = [] - ntp = get_copy(self.netjson, self.netjson_key) - if ntp.get('enabled', False): - for server in ntp.get('server'): - result.append(server) - return (('ntp', result),) diff --git a/netjsonconfig/backends/raspbian/converters/__init__.py b/netjsonconfig/backends/raspbian/converters/__init__.py new file mode 100644 index 000000000..0486a106c --- /dev/null +++ b/netjsonconfig/backends/raspbian/converters/__init__.py @@ -0,0 +1,9 @@ +from .general import General +from .interfaces import Interfaces +from .ntp import Ntp +from .wireless import Wireless +from .dnsservers import DnsServers +from .dnssearch import DnsSearch + +__all__ = ['General', 'Interface', 'Ntp', 'Wireless', + 'DnsServers', 'DnsSearch'] diff --git a/netjsonconfig/backends/raspbian/converters/base.py b/netjsonconfig/backends/raspbian/converters/base.py new file mode 100644 index 000000000..6c16a73b3 --- /dev/null +++ b/netjsonconfig/backends/raspbian/converters/base.py @@ -0,0 +1,6 @@ +from ...base.converter import BaseConverter + + +class RaspbianConverter(BaseConverter): + def test_function(self): + return 'Nothing' diff --git a/netjsonconfig/backends/raspbian/converters/dnssearch.py b/netjsonconfig/backends/raspbian/converters/dnssearch.py new file mode 100644 index 000000000..f24e932ba --- /dev/null +++ b/netjsonconfig/backends/raspbian/converters/dnssearch.py @@ -0,0 +1,13 @@ +from ....utils import get_copy +from .base import RaspbianConverter + + +class DnsSearch(RaspbianConverter): + netjson_key = 'dns_search' + + def to_intermediate(self): + result = [] + dns_search = get_copy(self.netjson, self.netjson_key) + for domain in dns_search: + result.append(domain) + return (('dns_search', result),) diff --git a/netjsonconfig/backends/raspbian/converters/dnsservers.py b/netjsonconfig/backends/raspbian/converters/dnsservers.py new file mode 100644 index 000000000..df99c4dc2 --- /dev/null +++ b/netjsonconfig/backends/raspbian/converters/dnsservers.py @@ -0,0 +1,13 @@ +from ....utils import get_copy +from .base import RaspbianConverter + + +class DnsServers(RaspbianConverter): + netjson_key = 'dns_servers' + + def to_intermediate(self): + result = [] + dns_servers = get_copy(self.netjson, self.netjson_key) + for nameserver in dns_servers: + result.append(nameserver) + return (('dns_servers', result),) diff --git a/netjsonconfig/backends/raspbian/converters/general.py b/netjsonconfig/backends/raspbian/converters/general.py new file mode 100644 index 000000000..c14947cfb --- /dev/null +++ b/netjsonconfig/backends/raspbian/converters/general.py @@ -0,0 +1,12 @@ +from ....utils import get_copy +from .base import RaspbianConverter + + +class General(RaspbianConverter): + netjson_key = 'general' + + def to_intermediate(self): + result = [] + general = get_copy(self.netjson, self.netjson_key) + result.append(general) + return (('general', result),) diff --git a/netjsonconfig/backends/raspbian/converters/interfaces.py b/netjsonconfig/backends/raspbian/converters/interfaces.py new file mode 100644 index 000000000..9c5959d07 --- /dev/null +++ b/netjsonconfig/backends/raspbian/converters/interfaces.py @@ -0,0 +1,62 @@ +from ....utils import get_copy +from .base import RaspbianConverter +from ipaddress import IPv4Interface + + +class Interfaces(RaspbianConverter): + netjson_key = 'interfaces' + + def to_intermediate(self): + result = [] + interfaces = get_copy(self.netjson, self.netjson_key) + for interface in interfaces: + new_interface = {} + ifname = interface.get('name') + iftype = interface.get('type') + new_interface.update({ + 'ifname': ifname, + 'iftype': iftype + }) + if iftype in ['ethernet', 'bridge', 'loopback']: + addresses = self._get_address(interface) + new_interface.update({ + 'address': addresses + }) + mac = interface.get('mac', False) + if mac: + new_interface.update({'mac': mac}) + mtu = interface.get('mtu', False) + if mtu: + new_interface.update({'mtu': mtu}) + txqueuelen = interface.get('txqueuelen', False) + if txqueuelen: + new_interface.update({'txqueuelen': txqueuelen}) + autostart = interface.get('autostart', False) + if autostart: + new_interface.update({'autostart': autostart}) + if iftype == 'wireless' and interface.get('wireless').get('mode') == 'adhoc': + wireless = interface.get('wireless') + new_interface.update({ + 'essid': wireless.get('ssid'), + 'mode': wireless.get('mode') + }) + if iftype == 'bridge': + new_interface.update({ + 'bridge_members': interface.get('bridge_members') + }) + result.append(new_interface) + return (('interfaces', result),) + + def _get_address(self, interface): + addresses = interface.get('addresses', False) + if addresses: + for address in addresses: + if address.get('proto') == 'static': + if address.get('family') == 'ipv4': + address_mask = str(address.get('address')) + '/' + str(address.get('mask')) + address['netmask'] = IPv4Interface(address_mask).with_netmask.split('/')[1] + del address['mask'] + if address.get('family') == 'ipv6': + address['netmask'] = address['mask'] + del address['mask'] + return addresses diff --git a/netjsonconfig/backends/raspbian/converters/ntp.py b/netjsonconfig/backends/raspbian/converters/ntp.py new file mode 100644 index 000000000..41ed693f7 --- /dev/null +++ b/netjsonconfig/backends/raspbian/converters/ntp.py @@ -0,0 +1,14 @@ +from ....utils import get_copy +from .base import RaspbianConverter + + +class Ntp(RaspbianConverter): + netjson_key = 'ntp' + + def to_intermediate(self): + result = [] + ntp = get_copy(self.netjson, self.netjson_key) + if ntp.get('enabled', False): + for server in ntp.get('server'): + result.append(server) + return (('ntp', result),) diff --git a/netjsonconfig/backends/raspbian/converters/wireless.py b/netjsonconfig/backends/raspbian/converters/wireless.py new file mode 100644 index 000000000..f004c1eea --- /dev/null +++ b/netjsonconfig/backends/raspbian/converters/wireless.py @@ -0,0 +1,68 @@ +from ....utils import get_copy +from .base import RaspbianConverter + + +class Wireless(RaspbianConverter): + netjson_key = 'interfaces' + + def to_intermediate(self): + result = [] + interfaces = get_copy(self.netjson, self.netjson_key) + for interface in interfaces: + if interface['type'] == 'wireless' and interface.get('wireless').get('mode') is not 'adhoc': + new_interface = { + 'ifname': interface.get('name'), + 'iftype': interface.get('type'), + 'ssid': interface['wireless'].get('ssid') + } + wireless = interface.get('wireless') + radio_num = interface['wireless'].get('radio') + radios = get_copy(self.netjson, 'radios') + if radios is not None: + req_radio = [radio for radio in radios if radio['name'] == radio_num][0] + hwmode = self._get_hwmode(req_radio) + channel = req_radio['channel'] + protocol = req_radio['protocol'].replace(".", "") + new_interface.update({ + 'hwmode': hwmode, + 'channel': channel, + 'protocol': protocol + }) + new_interface.update({'encryption': self._get_encryption(wireless)}) + result.append(new_interface) + return (('wireless', result),) + + def _get_hwmode(self, radio): + protocol = radio['protocol'] + if protocol in ['802.11a', '802.11b', '802.11g']: + return protocol[1:] + if radio['channel'] is 0: + return radio.get('hwmode') + elif radio['channel'] <= 13: + return 'g' + else: + return 'a' + + def _get_encryption(self, wireless): + encryption = wireless.get('encryption', None) + if encryption is None: + return {} + disabled = encryption.get('disabled', False) + new_encryption = {} + if encryption.get('protocol') is not 'none' and disabled is not True: + protocol, method = encryption.get('protocol').split("_") + if protocol in ['wpa', 'wpa2']: + auth_algs = '1' + wpa = '1' if protocol == 'wpa' else '2' + wpa_key_mgmt = 'WPA-PSK' if method == 'personal' else 'WPA-EAP' + wpa_passphrase = encryption.get('key') + new_encryption.update({ + 'auth_algs': auth_algs, + 'wpa': wpa, + 'wpa_key_mgmt': wpa_key_mgmt, + 'wpa_passphrase': wpa_passphrase + }) + if encryption.get('cipher', None) is not None or 'auto': + wpa_pairwise = str(encryption.get('cipher').replace('+', ' ')).upper() + new_encryption.update({'wpa_pairwise': wpa_pairwise}) + return new_encryption diff --git a/netjsonconfig/backends/raspbian/raspbian.py b/netjsonconfig/backends/raspbian/raspbian.py index feb1d3155..3a35d372e 100644 --- a/netjsonconfig/backends/raspbian/raspbian.py +++ b/netjsonconfig/backends/raspbian/raspbian.py @@ -1,5 +1,5 @@ -from .converters import General, Interfaces, Wireless, DnsServers, DnsSearch, Ntp -from .renderers import Raspbian +from . import converters +from .renderer import Raspbian from ..base.backend import BaseBackend from .schema import schema @@ -11,11 +11,11 @@ class Raspbian(BaseBackend): schema = schema env_path = 'netjsonconfig.backends.raspbian' converters = [ - General, - Interfaces, - Wireless, - DnsServers, - DnsSearch, - Ntp + converters.General, + converters.Interfaces, + converters.Wireless, + converters.DnsServers, + converters.DnsSearch, + converters.Ntp ] renderer = Raspbian diff --git a/netjsonconfig/backends/raspbian/renderers.py b/netjsonconfig/backends/raspbian/renderer.py similarity index 100% rename from netjsonconfig/backends/raspbian/renderers.py rename to netjsonconfig/backends/raspbian/renderer.py From 017a9aee819dff6b739d3f672feccfd6d8c12341 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Wed, 12 Jul 2017 21:16:31 +0530 Subject: [PATCH 077/183] [raspbian] Skipped unimplemented tests --- tests/raspbian/test_hostapd.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/raspbian/test_hostapd.py b/tests/raspbian/test_hostapd.py index 2cb7c2197..1876e798c 100644 --- a/tests/raspbian/test_hostapd.py +++ b/tests/raspbian/test_hostapd.py @@ -1,5 +1,5 @@ import unittest - +from unittest import skip from netjsonconfig import Raspbian from netjsonconfig.utils import _TabsMixin @@ -99,6 +99,7 @@ def test_wpa_personal(self): ''' self.assertEqual(o.render(), expected) + @unittest.skip('Test skipping') def test_wep_open(self): o = Raspbian({ "radios": [ @@ -132,6 +133,7 @@ def test_wep_open(self): expected = '''''' self.assertEqual(o.render(), expected) + @unittest.skip('Test skipping') def test_wep_shared(self): o = Raspbian({ "radios": [ @@ -246,6 +248,7 @@ def test_no_encryption(self): ''' self.assertEqual(o.render(), expected) + @unittest.skip('Test skipping') def test_wps(self): o = Raspbian({ "radios": [ From 67ca7d95d47b8f38acf97d7ff2751830ca2ac5d1 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Wed, 12 Jul 2017 21:17:17 +0530 Subject: [PATCH 078/183] [raspbian] Added tests for mtu and mac --- tests/raspbian/test_interfaces.py | 51 +++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/tests/raspbian/test_interfaces.py b/tests/raspbian/test_interfaces.py index 85bb358af..e93876535 100644 --- a/tests/raspbian/test_interfaces.py +++ b/tests/raspbian/test_interfaces.py @@ -217,6 +217,57 @@ def test_multiple_ip(self): ''' self.assertEqual(o.render(), expected) + def test_mtu(self): + o = Raspbian({ + "interfaces": [ + { + "mtu": 1500, + "name": "eth1", + "addresses": [ + { + "family": "ipv4", + "proto": "dhcp" + } + ], + "type": "ethernet", + } + ], + }) + + expected = '''config: /etc/network/interfaces +auto eth1 +iface eth1 inet dhcp + pre-up /sbin/ifconfig $IFACE mtu 1500 + +''' + self.assertEqual(o.render(), expected) + + def test_mac(self): + o = Raspbian({ + "interfaces": [ + { + "name": "eth1", + "addresses": [ + { + "family": "ipv4", + "proto": "dhcp" + } + ], + "type": "ethernet", + "mac": "52:54:00:56:46:c0" + } + ], + }) + + expected = '''config: /etc/network/interfaces +auto eth1 +iface eth1 inet dhcp + hwaddress 52:54:00:56:46:c0 + +''' + + self.assertEqual(o.render(), expected) + def test_multiple_ip_and_dhcp(self): o = Raspbian({ "interfaces": [ From 310524c282f45326e76ba7ffc3f719433fb2f654 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Wed, 12 Jul 2017 21:57:52 +0530 Subject: [PATCH 079/183] [raspbian] Added support for multiple template rendering --- netjsonconfig/backends/raspbian/raspbian.py | 22 +++++- netjsonconfig/backends/raspbian/renderer.py | 29 +++++++- .../raspbian/templates/commands.jinja2 | 11 +++ .../raspbian/templates/hostapd.jinja2 | 25 +++++++ .../raspbian/templates/hostname.jinja2 | 11 +++ .../{raspbian.jinja2 => interfaces.jinja2} | 73 ------------------- .../backends/raspbian/templates/ntp.jinja2 | 8 ++ .../backends/raspbian/templates/resolv.jinja2 | 18 +++++ tests/raspbian/test_hostapd.py | 16 ++-- 9 files changed, 127 insertions(+), 86 deletions(-) create mode 100644 netjsonconfig/backends/raspbian/templates/commands.jinja2 create mode 100644 netjsonconfig/backends/raspbian/templates/hostapd.jinja2 create mode 100644 netjsonconfig/backends/raspbian/templates/hostname.jinja2 rename netjsonconfig/backends/raspbian/templates/{raspbian.jinja2 => interfaces.jinja2} (60%) create mode 100644 netjsonconfig/backends/raspbian/templates/ntp.jinja2 create mode 100644 netjsonconfig/backends/raspbian/templates/resolv.jinja2 diff --git a/netjsonconfig/backends/raspbian/raspbian.py b/netjsonconfig/backends/raspbian/raspbian.py index 3a35d372e..c8c56f655 100644 --- a/netjsonconfig/backends/raspbian/raspbian.py +++ b/netjsonconfig/backends/raspbian/raspbian.py @@ -1,5 +1,5 @@ from . import converters -from .renderer import Raspbian +from .renderer import * from ..base.backend import BaseBackend from .schema import schema @@ -18,4 +18,22 @@ class Raspbian(BaseBackend): converters.DnsSearch, converters.Ntp ] - renderer = Raspbian + renderer = [ + Hostname, + Hostapd, + Interfaces, + Resolv, + Ntp, + Commands + ] + + def render(self, files=True): + self.validate() + if self.intermediate_data is None: + self.to_intermediate() + output = '' + for renderer_class in self.renderer: + renderer = renderer_class(self) + output += renderer.render() + del renderer + return output diff --git a/netjsonconfig/backends/raspbian/renderer.py b/netjsonconfig/backends/raspbian/renderer.py index a3c89e508..89aa11cd5 100644 --- a/netjsonconfig/backends/raspbian/renderer.py +++ b/netjsonconfig/backends/raspbian/renderer.py @@ -1,6 +1,29 @@ from ..base.renderer import BaseRenderer -class Raspbian(BaseRenderer): - def cleanup(self, output): - return output +class RaspbianRenderer(BaseRenderer): + pass + + +class Commands(RaspbianRenderer): + pass + + +class Hostname(RaspbianRenderer): + pass + + +class Hostapd(RaspbianRenderer): + pass + + +class Interfaces(RaspbianRenderer): + pass + + +class Resolv(RaspbianRenderer): + pass + + +class Ntp(RaspbianRenderer): + pass diff --git a/netjsonconfig/backends/raspbian/templates/commands.jinja2 b/netjsonconfig/backends/raspbian/templates/commands.jinja2 new file mode 100644 index 000000000..f08aa97d5 --- /dev/null +++ b/netjsonconfig/backends/raspbian/templates/commands.jinja2 @@ -0,0 +1,11 @@ +{% for i, j in data.items() %} +{% if i|string() == 'general' %} +{% for general in j %} +{% if general.get('timezone') %} +run commands: +$ timedatectl set-timezone {{ general.get('timezone') }} + +{% endif %} +{% endfor %} +{% endif %} +{% endfor%} diff --git a/netjsonconfig/backends/raspbian/templates/hostapd.jinja2 b/netjsonconfig/backends/raspbian/templates/hostapd.jinja2 new file mode 100644 index 000000000..455864d97 --- /dev/null +++ b/netjsonconfig/backends/raspbian/templates/hostapd.jinja2 @@ -0,0 +1,25 @@ +{% for i, j in data.items() %} +{% if i|string() == 'wireless' %} +{% for wireless in j %} +config: /etc/hostapd/hostapd.conf +interface={{ wireless.get('ifname') }} +driver=nl80211 +hw_mode={{ wireless.get('hwmode')}} +channel={{ wireless.get('channel')}} +{% if wireless.get('protocol') == '80211n' %} +ieee80211n=1 +{% endif %} +ssid={{ wireless.get('ssid') }} +{% if wireless.get('encryption') != {} %} +auth_algs={{ wireless.get('encryption').get('auth_algs') }} +wpa={{ wireless.get('encryption').get('wpa') }} +wpa_key_mgmt={{ wireless.get('encryption').get('wpa_key_mgmt') }} +wpa_passphrase={{ wireless.get('encryption').get('wpa_passphrase') }} +{% if wireless.get('encryption', None).get('wpa_pairwise') != 'AUTO' %} +wpa_pairwise={{ wireless.get('encryption').get('wpa_pairwise')}} +{% endif %} +{% endif %} +{% endfor %} +{% else %} +{% endif %} +{% endfor %} diff --git a/netjsonconfig/backends/raspbian/templates/hostname.jinja2 b/netjsonconfig/backends/raspbian/templates/hostname.jinja2 new file mode 100644 index 000000000..c2e8852c3 --- /dev/null +++ b/netjsonconfig/backends/raspbian/templates/hostname.jinja2 @@ -0,0 +1,11 @@ +{% for i, j in data.items() %} +{% if i|string() == 'general' %} +{% for general in j %} +{% if general.get('hostname') %} +config: /etc/hostname +{{ general.get('hostname') }} + +{% endif %} +{% endfor %} +{% endif %} +{% endfor %} diff --git a/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 b/netjsonconfig/backends/raspbian/templates/interfaces.jinja2 similarity index 60% rename from netjsonconfig/backends/raspbian/templates/raspbian.jinja2 rename to netjsonconfig/backends/raspbian/templates/interfaces.jinja2 index f4a03ca70..76125d5ce 100644 --- a/netjsonconfig/backends/raspbian/templates/raspbian.jinja2 +++ b/netjsonconfig/backends/raspbian/templates/interfaces.jinja2 @@ -1,26 +1,4 @@ {% for i, j in data.items() %} -{% if i|string() == 'general' %} -{% for general in j %} -{% if general.get('hostname') %} -config: /etc/hostname -{{ general.get('hostname') }} - -{% endif %} -{% endfor %} -{% endif %} -{% endfor %} -{% for i, j in data.items() %} -{% if i|string() == 'general' %} -{% for general in j %} -{% if general.get('timezone') %} -run commands: -$ timedatectl set-timezone {{ general.get('timezone') }} - -{% endif %} -{% endfor %} -{% endif %} -{% endfor%} -{% for i, j in data.items() %} {% if i|string() == 'interfaces' %} {% for interface in j %} {% if interface.get('iftype') == 'wireless' %} @@ -103,54 +81,3 @@ iface {{ interface.get('ifname') }} inet6 {{ address.get('proto') }} {% endfor %} {% endif %} {% endfor%} -{% set count = [1] %} -{% for i, j in data.items() %} -{% if i|string() in ['dns_servers', 'dns_search'] %} -{% if count == [1] %} -config: /etc/resolv.conf -{% if count.append(count.pop() + 1) %}{% endif %} -{% endif %} -{% endif %} -{% if i|string() == 'dns_servers' %} -{% for ip in j %} -nameserver {{ ip }} -{% endfor %} -{% elif i|string() == 'dns_search' %} -{% for domain in j %} -search {{ domain }} -{% endfor %} -{% endif %} -{% endfor%} -{% for i, j in data.items() %} -{% if i|string() == 'wireless' %} -{% for wireless in j %} -config: /etc/hostapd/hostapd.conf -interface={{ wireless.get('ifname') }} -driver=nl80211 -hw_mode={{ wireless.get('hwmode')}} -channel={{ wireless.get('channel')}} -{% if wireless.get('protocol') == '80211n' %} -ieee80211n=1 -{% endif %} -ssid={{ wireless.get('ssid') }} -{% if wireless.get('encryption') != {} %} -auth_algs={{ wireless.get('encryption').get('auth_algs') }} -wpa={{ wireless.get('encryption').get('wpa') }} -wpa_key_mgmt={{ wireless.get('encryption').get('wpa_key_mgmt') }} -wpa_passphrase={{ wireless.get('encryption').get('wpa_passphrase') }} -{% if wireless.get('encryption', None).get('wpa_pairwise') != 'AUTO' %} -wpa_pairwise={{ wireless.get('encryption').get('wpa_pairwise')}} -{% endif %} -{% endif %} -{% endfor %} -{% else %} -{% endif %} -{% endfor %} -{% for i, j in data.items() %} -{% if i|string() == 'ntp' %} -config: /etc/ntp.conf -{% for server in j %} -server {{ server }} -{% endfor %} -{% endif %} -{% endfor %} diff --git a/netjsonconfig/backends/raspbian/templates/ntp.jinja2 b/netjsonconfig/backends/raspbian/templates/ntp.jinja2 new file mode 100644 index 000000000..108256f8b --- /dev/null +++ b/netjsonconfig/backends/raspbian/templates/ntp.jinja2 @@ -0,0 +1,8 @@ +{% for i, j in data.items() %} +{% if i|string() == 'ntp' %} +config: /etc/ntp.conf +{% for server in j %} +server {{ server }} +{% endfor %} +{% endif %} +{% endfor %} diff --git a/netjsonconfig/backends/raspbian/templates/resolv.jinja2 b/netjsonconfig/backends/raspbian/templates/resolv.jinja2 new file mode 100644 index 000000000..1b3a03a61 --- /dev/null +++ b/netjsonconfig/backends/raspbian/templates/resolv.jinja2 @@ -0,0 +1,18 @@ +{% set count = [1] %} +{% for i, j in data.items() %} +{% if i|string() in ['dns_servers', 'dns_search'] %} +{% if count == [1] %} +config: /etc/resolv.conf +{% if count.append(count.pop() + 1) %}{% endif %} +{% endif %} +{% endif %} +{% if i|string() == 'dns_servers' %} +{% for ip in j %} +nameserver {{ ip }} +{% endfor %} +{% elif i|string() == 'dns_search' %} +{% for domain in j %} +search {{ domain }} +{% endfor %} +{% endif %} +{% endfor%} diff --git a/tests/raspbian/test_hostapd.py b/tests/raspbian/test_hostapd.py index 1876e798c..7d2e2b6f6 100644 --- a/tests/raspbian/test_hostapd.py +++ b/tests/raspbian/test_hostapd.py @@ -37,8 +37,7 @@ def test_wpa2_personal(self): ] }) - expected = ''' -config: /etc/hostapd/hostapd.conf + expected = '''config: /etc/hostapd/hostapd.conf interface=wlan0 driver=nl80211 hw_mode=g @@ -50,6 +49,7 @@ def test_wpa2_personal(self): wpa_key_mgmt=WPA-PSK wpa_passphrase=passphrase012345 wpa_pairwise=TKIP CCMP + ''' self.assertEqual(o.render(), expected) @@ -84,8 +84,7 @@ def test_wpa_personal(self): ] }) - expected = ''' -config: /etc/hostapd/hostapd.conf + expected = '''config: /etc/hostapd/hostapd.conf interface=wlan0 driver=nl80211 hw_mode=g @@ -96,6 +95,7 @@ def test_wpa_personal(self): wpa=1 wpa_key_mgmt=WPA-PSK wpa_passphrase=passphrase012345 + ''' self.assertEqual(o.render(), expected) @@ -199,14 +199,14 @@ def test_encryption_disabled(self): ] }) - expected = ''' -config: /etc/hostapd/hostapd.conf + expected = '''config: /etc/hostapd/hostapd.conf interface=wlan0 driver=nl80211 hw_mode=g channel=3 ieee80211n=1 ssid=MyNetwork + ''' self.assertEqual(o.render(), expected) @@ -237,14 +237,14 @@ def test_no_encryption(self): ] }) - expected = ''' -config: /etc/hostapd/hostapd.conf + expected = '''config: /etc/hostapd/hostapd.conf interface=wlan0 driver=nl80211 hw_mode=g channel=3 ieee80211n=1 ssid=open + ''' self.assertEqual(o.render(), expected) From 5a419d70f57c0218a16dfb70a69953ba046afa76 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Wed, 12 Jul 2017 23:22:06 +0530 Subject: [PATCH 080/183] [raspbian] isort and flake8 errors --- .../backends/raspbian/converters/__init__.py | 4 +-- .../raspbian/converters/interfaces.py | 3 ++- netjsonconfig/backends/raspbian/raspbian.py | 2 +- netjsonconfig/backends/raspbian/schema.py | 1 - tests/raspbian/test_hostapd.py | 2 +- tests/raspbian/test_interfaces.py | 26 +++++++++---------- 6 files changed, 19 insertions(+), 19 deletions(-) diff --git a/netjsonconfig/backends/raspbian/converters/__init__.py b/netjsonconfig/backends/raspbian/converters/__init__.py index 0486a106c..6f4a7420a 100644 --- a/netjsonconfig/backends/raspbian/converters/__init__.py +++ b/netjsonconfig/backends/raspbian/converters/__init__.py @@ -5,5 +5,5 @@ from .dnsservers import DnsServers from .dnssearch import DnsSearch -__all__ = ['General', 'Interface', 'Ntp', 'Wireless', - 'DnsServers', 'DnsSearch'] +__all__ = ['General', 'Interfaces', 'Ntp', 'Wireless', + 'DnsServers', 'DnsSearch'] diff --git a/netjsonconfig/backends/raspbian/converters/interfaces.py b/netjsonconfig/backends/raspbian/converters/interfaces.py index 9c5959d07..b0279230d 100644 --- a/netjsonconfig/backends/raspbian/converters/interfaces.py +++ b/netjsonconfig/backends/raspbian/converters/interfaces.py @@ -1,6 +1,7 @@ +from ipaddress import IPv4Interface + from ....utils import get_copy from .base import RaspbianConverter -from ipaddress import IPv4Interface class Interfaces(RaspbianConverter): diff --git a/netjsonconfig/backends/raspbian/raspbian.py b/netjsonconfig/backends/raspbian/raspbian.py index c8c56f655..a86011f06 100644 --- a/netjsonconfig/backends/raspbian/raspbian.py +++ b/netjsonconfig/backends/raspbian/raspbian.py @@ -1,6 +1,6 @@ from . import converters -from .renderer import * from ..base.backend import BaseBackend +from .renderer import Commands, Hostapd, Hostname, Interfaces, Ntp, Resolv from .schema import schema diff --git a/netjsonconfig/backends/raspbian/schema.py b/netjsonconfig/backends/raspbian/schema.py index 9eacef02a..7f6033803 100644 --- a/netjsonconfig/backends/raspbian/schema.py +++ b/netjsonconfig/backends/raspbian/schema.py @@ -1,5 +1,4 @@ from ...schema import schema as default_schema -from ...schema import DEFAULT_FILE_MODE from ...utils import merge_config schema = merge_config(default_schema, {}) diff --git a/tests/raspbian/test_hostapd.py b/tests/raspbian/test_hostapd.py index 7d2e2b6f6..857b148be 100644 --- a/tests/raspbian/test_hostapd.py +++ b/tests/raspbian/test_hostapd.py @@ -1,5 +1,5 @@ import unittest -from unittest import skip + from netjsonconfig import Raspbian from netjsonconfig.utils import _TabsMixin diff --git a/tests/raspbian/test_interfaces.py b/tests/raspbian/test_interfaces.py index e93876535..0c114bb99 100644 --- a/tests/raspbian/test_interfaces.py +++ b/tests/raspbian/test_interfaces.py @@ -219,7 +219,7 @@ def test_multiple_ip(self): def test_mtu(self): o = Raspbian({ - "interfaces": [ + "interfaces": [ { "mtu": 1500, "name": "eth1", @@ -245,18 +245,18 @@ def test_mtu(self): def test_mac(self): o = Raspbian({ "interfaces": [ - { - "name": "eth1", - "addresses": [ - { - "family": "ipv4", - "proto": "dhcp" - } - ], - "type": "ethernet", - "mac": "52:54:00:56:46:c0" - } - ], + { + "name": "eth1", + "addresses": [ + { + "family": "ipv4", + "proto": "dhcp" + } + ], + "type": "ethernet", + "mac": "52:54:00:56:46:c0" + } + ], }) expected = '''config: /etc/network/interfaces From 26047d1a01b7c6a28af9e330b3ed1b198625d60f Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Thu, 13 Jul 2017 14:32:33 +0530 Subject: [PATCH 081/183] [raspbian] Changed template format --- .../backends/raspbian/converters/base.py | 3 +- netjsonconfig/backends/raspbian/raspbian.py | 1 - .../raspbian/templates/hostapd.jinja2 | 2 +- .../raspbian/templates/hostname.jinja2 | 2 +- .../raspbian/templates/interfaces.jinja2 | 4 +-- .../backends/raspbian/templates/ntp.jinja2 | 2 +- .../backends/raspbian/templates/resolv.jinja2 | 2 +- tests/raspbian/test_hostapd.py | 8 ++--- tests/raspbian/test_interfaces.py | 32 +++++++++---------- tests/raspbian/test_resolv.py | 6 ++-- tests/raspbian/test_system.py | 4 +-- 11 files changed, 32 insertions(+), 34 deletions(-) diff --git a/netjsonconfig/backends/raspbian/converters/base.py b/netjsonconfig/backends/raspbian/converters/base.py index 6c16a73b3..0fe911040 100644 --- a/netjsonconfig/backends/raspbian/converters/base.py +++ b/netjsonconfig/backends/raspbian/converters/base.py @@ -2,5 +2,4 @@ class RaspbianConverter(BaseConverter): - def test_function(self): - return 'Nothing' + pass diff --git a/netjsonconfig/backends/raspbian/raspbian.py b/netjsonconfig/backends/raspbian/raspbian.py index a86011f06..1069402e7 100644 --- a/netjsonconfig/backends/raspbian/raspbian.py +++ b/netjsonconfig/backends/raspbian/raspbian.py @@ -9,7 +9,6 @@ class Raspbian(BaseBackend): Raspbian Backend """ schema = schema - env_path = 'netjsonconfig.backends.raspbian' converters = [ converters.General, converters.Interfaces, diff --git a/netjsonconfig/backends/raspbian/templates/hostapd.jinja2 b/netjsonconfig/backends/raspbian/templates/hostapd.jinja2 index 455864d97..0db4a544a 100644 --- a/netjsonconfig/backends/raspbian/templates/hostapd.jinja2 +++ b/netjsonconfig/backends/raspbian/templates/hostapd.jinja2 @@ -1,7 +1,7 @@ {% for i, j in data.items() %} {% if i|string() == 'wireless' %} {% for wireless in j %} -config: /etc/hostapd/hostapd.conf +# config: /etc/hostapd/hostapd.conf interface={{ wireless.get('ifname') }} driver=nl80211 hw_mode={{ wireless.get('hwmode')}} diff --git a/netjsonconfig/backends/raspbian/templates/hostname.jinja2 b/netjsonconfig/backends/raspbian/templates/hostname.jinja2 index c2e8852c3..aa0e1f46e 100644 --- a/netjsonconfig/backends/raspbian/templates/hostname.jinja2 +++ b/netjsonconfig/backends/raspbian/templates/hostname.jinja2 @@ -2,7 +2,7 @@ {% if i|string() == 'general' %} {% for general in j %} {% if general.get('hostname') %} -config: /etc/hostname +# config: /etc/hostname {{ general.get('hostname') }} {% endif %} diff --git a/netjsonconfig/backends/raspbian/templates/interfaces.jinja2 b/netjsonconfig/backends/raspbian/templates/interfaces.jinja2 index 76125d5ce..b38896751 100644 --- a/netjsonconfig/backends/raspbian/templates/interfaces.jinja2 +++ b/netjsonconfig/backends/raspbian/templates/interfaces.jinja2 @@ -3,7 +3,7 @@ {% for interface in j %} {% if interface.get('iftype') == 'wireless' %} {% if interface.get('mode') == 'adhoc' %} -config: /etc/network/interfaces +# config: /etc/network/interfaces auto {{ interface.get('iftype') }} iface {{ interface.get('iftype') }} inet static address 172.128.1.1 @@ -13,7 +13,7 @@ iface {{ interface.get('iftype') }} inet static wireless-mode ad-hoc {% endif %} {% elif interface.get('iftype') in ['ethernet', 'bridge', 'loopback'] %} -config: /etc/network/interfaces +# config: /etc/network/interfaces auto {{ interface.get('ifname') }} {% if interface.get('address') != None %} {% for address in interface.get('address') %} diff --git a/netjsonconfig/backends/raspbian/templates/ntp.jinja2 b/netjsonconfig/backends/raspbian/templates/ntp.jinja2 index 108256f8b..05eb3912e 100644 --- a/netjsonconfig/backends/raspbian/templates/ntp.jinja2 +++ b/netjsonconfig/backends/raspbian/templates/ntp.jinja2 @@ -1,6 +1,6 @@ {% for i, j in data.items() %} {% if i|string() == 'ntp' %} -config: /etc/ntp.conf +# config: /etc/ntp.conf {% for server in j %} server {{ server }} {% endfor %} diff --git a/netjsonconfig/backends/raspbian/templates/resolv.jinja2 b/netjsonconfig/backends/raspbian/templates/resolv.jinja2 index 1b3a03a61..99505c19e 100644 --- a/netjsonconfig/backends/raspbian/templates/resolv.jinja2 +++ b/netjsonconfig/backends/raspbian/templates/resolv.jinja2 @@ -2,7 +2,7 @@ {% for i, j in data.items() %} {% if i|string() in ['dns_servers', 'dns_search'] %} {% if count == [1] %} -config: /etc/resolv.conf +# config: /etc/resolv.conf {% if count.append(count.pop() + 1) %}{% endif %} {% endif %} {% endif %} diff --git a/tests/raspbian/test_hostapd.py b/tests/raspbian/test_hostapd.py index 857b148be..0081733e8 100644 --- a/tests/raspbian/test_hostapd.py +++ b/tests/raspbian/test_hostapd.py @@ -37,7 +37,7 @@ def test_wpa2_personal(self): ] }) - expected = '''config: /etc/hostapd/hostapd.conf + expected = '''# config: /etc/hostapd/hostapd.conf interface=wlan0 driver=nl80211 hw_mode=g @@ -84,7 +84,7 @@ def test_wpa_personal(self): ] }) - expected = '''config: /etc/hostapd/hostapd.conf + expected = '''# config: /etc/hostapd/hostapd.conf interface=wlan0 driver=nl80211 hw_mode=g @@ -199,7 +199,7 @@ def test_encryption_disabled(self): ] }) - expected = '''config: /etc/hostapd/hostapd.conf + expected = '''# config: /etc/hostapd/hostapd.conf interface=wlan0 driver=nl80211 hw_mode=g @@ -237,7 +237,7 @@ def test_no_encryption(self): ] }) - expected = '''config: /etc/hostapd/hostapd.conf + expected = '''# config: /etc/hostapd/hostapd.conf interface=wlan0 driver=nl80211 hw_mode=g diff --git a/tests/raspbian/test_interfaces.py b/tests/raspbian/test_interfaces.py index 0c114bb99..bd6e37343 100644 --- a/tests/raspbian/test_interfaces.py +++ b/tests/raspbian/test_interfaces.py @@ -24,7 +24,7 @@ def test_ipv4_static(self): ] }) - expected = '''config: /etc/network/interfaces + expected = '''# config: /etc/network/interfaces auto eth0 iface eth0 inet static address 10.0.0.1 @@ -51,7 +51,7 @@ def test_ipv6_static(self): ] }) - expected = '''config: /etc/network/interfaces + expected = '''# config: /etc/network/interfaces auto eth0 iface eth0 inet6 static address fe80::ba27:ebff:fe1c:5477 @@ -84,7 +84,7 @@ def test_multiple_static(self): ] }) - expected = '''config: /etc/network/interfaces + expected = '''# config: /etc/network/interfaces auto eth0 iface eth0 inet static address 10.0.0.1 @@ -112,7 +112,7 @@ def test_ipv4_dhcp(self): ] }) - expected = '''config: /etc/network/interfaces + expected = '''# config: /etc/network/interfaces auto eth0 iface eth0 inet dhcp @@ -135,7 +135,7 @@ def test_ipv6_dhcp(self): ] }) - expected = '''config: /etc/network/interfaces + expected = '''# config: /etc/network/interfaces auto eth0 iface eth0 inet6 dhcp @@ -163,7 +163,7 @@ def test_multiple_dhcp(self): ] }) - expected = '''config: /etc/network/interfaces + expected = '''# config: /etc/network/interfaces auto eth0 iface eth0 inet dhcp iface eth0 inet6 dhcp @@ -202,7 +202,7 @@ def test_multiple_ip(self): ] }) - expected = '''config: /etc/network/interfaces + expected = '''# config: /etc/network/interfaces auto eth0.1 iface eth0.1 inet static address 192.168.1.1 @@ -234,7 +234,7 @@ def test_mtu(self): ], }) - expected = '''config: /etc/network/interfaces + expected = '''# config: /etc/network/interfaces auto eth1 iface eth1 inet dhcp pre-up /sbin/ifconfig $IFACE mtu 1500 @@ -259,7 +259,7 @@ def test_mac(self): ], }) - expected = '''config: /etc/network/interfaces + expected = '''# config: /etc/network/interfaces auto eth1 iface eth1 inet dhcp hwaddress 52:54:00:56:46:c0 @@ -296,7 +296,7 @@ def test_multiple_ip_and_dhcp(self): ] }) - expected = '''config: /etc/network/interfaces + expected = '''# config: /etc/network/interfaces auto eth0 iface eth0 inet dhcp iface eth0 inet static @@ -329,13 +329,13 @@ def test_interface_with_resolv(self): "dns_search": ["netjson.org", "openwisp.org"], }) - expected = '''config: /etc/network/interfaces + expected = '''# config: /etc/network/interfaces auto eth0 iface eth0 inet static address 192.168.1.1 netmask 255.255.255.0 -config: /etc/resolv.conf +# config: /etc/resolv.conf nameserver 10.11.12.13 nameserver 8.8.8.8 search netjson.org @@ -361,7 +361,7 @@ def test_loopback(self): ] }) - expected = '''config: /etc/network/interfaces + expected = '''# config: /etc/network/interfaces auto lo iface lo inet static address 127.0.0.1 @@ -386,7 +386,7 @@ def test_adhoc_wireless(self): ] }) - expected = '''config: /etc/network/interfaces + expected = '''# config: /etc/network/interfaces auto wireless iface wireless inet static address 172.128.1.1 @@ -413,7 +413,7 @@ def test_simple_bridge(self): ] }) - expected = '''config: /etc/network/interfaces + expected = '''# config: /etc/network/interfaces auto br-lan bridge_ports eth0 eth1 @@ -443,7 +443,7 @@ def test_complex_bridge(self): ] }) - expected = '''config: /etc/network/interfaces + expected = '''# config: /etc/network/interfaces auto brwifi iface brwifi inet6 static address fe80::8029:23ff:fe7d:c214 diff --git a/tests/raspbian/test_resolv.py b/tests/raspbian/test_resolv.py index cd18d37c0..86c227b09 100644 --- a/tests/raspbian/test_resolv.py +++ b/tests/raspbian/test_resolv.py @@ -14,7 +14,7 @@ def test_dns_server(self): ], }) - expected = '''config: /etc/resolv.conf + expected = '''# config: /etc/resolv.conf nameserver 10.254.0.1 nameserver 10.254.0.2 ''' @@ -27,7 +27,7 @@ def test_dns_search(self): ], }) - expected = '''config: /etc/resolv.conf + expected = '''# config: /etc/resolv.conf search domain.com ''' self.assertEqual(o.render(), expected) @@ -43,7 +43,7 @@ def test_dns_server_and_dns_search(self): ], }) - expected = '''config: /etc/resolv.conf + expected = '''# config: /etc/resolv.conf nameserver 10.11.12.13 nameserver 8.8.8.8 search netjson.org diff --git a/tests/raspbian/test_system.py b/tests/raspbian/test_system.py index a433ca501..24ea99c3a 100644 --- a/tests/raspbian/test_system.py +++ b/tests/raspbian/test_system.py @@ -17,7 +17,7 @@ def test_general(self): } }) - expected = '''config: /etc/hostname + expected = '''# config: /etc/hostname test-system run commands: @@ -40,7 +40,7 @@ def test_ntp(self): } }) - expected = '''config: /etc/ntp.conf + expected = '''# config: /etc/ntp.conf server 0.openwrt.pool.ntp.org server 1.openwrt.pool.ntp.org server 2.openwrt.pool.ntp.org From 20356538635fe452b2587bba58c3dd83b306c9a8 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Thu, 13 Jul 2017 16:24:08 +0530 Subject: [PATCH 082/183] [raspbian] Remove render method from Raspbian backend --- netjsonconfig/backends/raspbian/raspbian.py | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/netjsonconfig/backends/raspbian/raspbian.py b/netjsonconfig/backends/raspbian/raspbian.py index 1069402e7..f845f0052 100644 --- a/netjsonconfig/backends/raspbian/raspbian.py +++ b/netjsonconfig/backends/raspbian/raspbian.py @@ -17,7 +17,7 @@ class Raspbian(BaseBackend): converters.DnsSearch, converters.Ntp ] - renderer = [ + renderers = [ Hostname, Hostapd, Interfaces, @@ -25,14 +25,3 @@ class Raspbian(BaseBackend): Ntp, Commands ] - - def render(self, files=True): - self.validate() - if self.intermediate_data is None: - self.to_intermediate() - output = '' - for renderer_class in self.renderer: - renderer = renderer_class(self) - output += renderer.render() - del renderer - return output From 880195f9af461465c2275ff634a6484f421447d7 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Fri, 14 Jul 2017 02:27:08 +0530 Subject: [PATCH 083/183] [raspbian] Added support for 802.11ac --- netjsonconfig/backends/raspbian/converters/wireless.py | 4 +--- netjsonconfig/backends/raspbian/templates/hostapd.jinja2 | 5 +++++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/netjsonconfig/backends/raspbian/converters/wireless.py b/netjsonconfig/backends/raspbian/converters/wireless.py index f004c1eea..3d1e791ff 100644 --- a/netjsonconfig/backends/raspbian/converters/wireless.py +++ b/netjsonconfig/backends/raspbian/converters/wireless.py @@ -35,9 +35,7 @@ def to_intermediate(self): def _get_hwmode(self, radio): protocol = radio['protocol'] if protocol in ['802.11a', '802.11b', '802.11g']: - return protocol[1:] - if radio['channel'] is 0: - return radio.get('hwmode') + return protocol[-1:] elif radio['channel'] <= 13: return 'g' else: diff --git a/netjsonconfig/backends/raspbian/templates/hostapd.jinja2 b/netjsonconfig/backends/raspbian/templates/hostapd.jinja2 index 0db4a544a..996f76324 100644 --- a/netjsonconfig/backends/raspbian/templates/hostapd.jinja2 +++ b/netjsonconfig/backends/raspbian/templates/hostapd.jinja2 @@ -4,11 +4,16 @@ # config: /etc/hostapd/hostapd.conf interface={{ wireless.get('ifname') }} driver=nl80211 +{% if wireless.get('protocol') == 'a' or 'b' or 'g' %} hw_mode={{ wireless.get('hwmode')}} +{% endif %} channel={{ wireless.get('channel')}} {% if wireless.get('protocol') == '80211n' %} ieee80211n=1 {% endif %} +{% if wireless.get('protocol') == '80211ac' %} +ieee80211ac=1 +{% endif %} ssid={{ wireless.get('ssid') }} {% if wireless.get('encryption') != {} %} auth_algs={{ wireless.get('encryption').get('auth_algs') }} From 27158a438e6a4a9e9c360e18f26f5654c5e2bb21 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Fri, 14 Jul 2017 02:27:29 +0530 Subject: [PATCH 084/183] [raspbian] Added tests for radio settings --- tests/raspbian/test_radios.py | 235 ++++++++++++++++++++++++++++++++++ 1 file changed, 235 insertions(+) create mode 100644 tests/raspbian/test_radios.py diff --git a/tests/raspbian/test_radios.py b/tests/raspbian/test_radios.py new file mode 100644 index 000000000..27d09578e --- /dev/null +++ b/tests/raspbian/test_radios.py @@ -0,0 +1,235 @@ +import unittest + +from netjsonconfig import Raspbian +from netjsonconfig.utils import _TabsMixin + + +class TestRadio(unittest.TestCase, _TabsMixin): + + def test_radio_multi(self): + o = Raspbian({ + "radios": [ + { + "name": "radio0", + "phy": "phy0", + "driver": "mac80211", + "protocol": "802.11n", + "channel": 11, + "channel_width": 20, + "tx_power": 5, + "country": "IT" + }, + { + "name": "radio1", + "phy": "phy1", + "driver": "mac80211", + "protocol": "802.11n", + "channel": 36, + "channel_width": 20, + "tx_power": 4, + "country": "IT" + } + ], + "interfaces": [ + { + "name": "wlan0", + "type": "wireless", + "wireless": { + "radio": "radio0", + "mode": "access_point", + "ssid": "myWiFi" + } + } + ] + }) + + expected = '''# config: /etc/hostapd/hostapd.conf +interface=wlan0 +driver=nl80211 +hw_mode=g +channel=11 +ieee80211n=1 +ssid=myWiFi + +''' + self.assertEqual(o.render(), expected) + + def test_radio_n_24ghz(self): + o = Raspbian({ + "radios": [ + { + "name": "radio0", + "phy": "phy0", + "driver": "mac80211", + "protocol": "802.11n", + "channel": 3, + "channel_width": 20, + "tx_power": 3 + } + ], + "interfaces": [ + { + "name": "wlan0", + "type": "wireless", + "wireless": { + "radio": "radio0", + "mode": "access_point", + "ssid": "myWiFi" + } + } + ] + }) + + expected = '''# config: /etc/hostapd/hostapd.conf +interface=wlan0 +driver=nl80211 +hw_mode=g +channel=3 +ieee80211n=1 +ssid=myWiFi + +''' + self.assertEqual(o.render(), expected) + + def test_radio_n_5ghz(self): + o = Raspbian({ + "radios": [ + { + "name": "radio0", + "phy": "phy0", + "driver": "mac80211", + "protocol": "802.11n", + "channel": 36, + "channel_width": 20, + "tx_power": 3 + } + ], + "interfaces": [ + { + "name": "wlan0", + "type": "wireless", + "wireless": { + "radio": "radio0", + "mode": "access_point", + "ssid": "myWiFi" + } + } + ] + }) + + expected = '''# config: /etc/hostapd/hostapd.conf +interface=wlan0 +driver=nl80211 +hw_mode=a +channel=36 +ieee80211n=1 +ssid=myWiFi + +''' + self.assertEqual(o.render(), expected) + + def test_radio_ac(self): + o = Raspbian({ + "radios": [ + { + "name": "radio0", + "phy": "phy0", + "driver": "mac80211", + "protocol": "802.11ac", + "channel": 132, + "channel_width": 80, + } + ], + "interfaces": [ + { + "name": "wlan0", + "type": "wireless", + "wireless": { + "radio": "radio0", + "mode": "access_point", + "ssid": "myWiFi" + } + } + ] + }) + + expected = '''# config: /etc/hostapd/hostapd.conf +interface=wlan0 +driver=nl80211 +hw_mode=a +channel=132 +ieee80211ac=1 +ssid=myWiFi + +''' + self.assertEqual(o.render(), expected) + + def test_radio_a(self): + o = Raspbian({ + "radios": [ + { + "name": "radio0", + "phy": "phy0", + "driver": "mac80211", + "protocol": "802.11a", + "channel": 0, + "channel_width": 20 + } + ], + "interfaces": [ + { + "name": "wlan0", + "type": "wireless", + "wireless": { + "radio": "radio0", + "mode": "access_point", + "ssid": "myWiFi" + } + } + ] + }) + + expected = '''# config: /etc/hostapd/hostapd.conf +interface=wlan0 +driver=nl80211 +hw_mode=a +channel=0 +ssid=myWiFi + +''' + self.assertEqual(o.render(), expected) + + def test_radio_g(self): + o = Raspbian({ + "radios": [ + { + "name": "radio0", + "phy": "phy0", + "driver": "mac80211", + "protocol": "802.11g", + "channel": 0, + "channel_width": 20 + } + ], + "interfaces": [ + { + "name": "wlan0", + "type": "wireless", + "wireless": { + "radio": "radio0", + "mode": "access_point", + "ssid": "myWiFi" + } + } + ] + }) + + expected = '''# config: /etc/hostapd/hostapd.conf +interface=wlan0 +driver=nl80211 +hw_mode=g +channel=0 +ssid=myWiFi + +''' + self.assertEqual(o.render(), expected) From 8a1ecda4c585cef3bceea5dac59c52170b4ab810 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Sun, 16 Jul 2017 23:59:09 +0530 Subject: [PATCH 085/183] [raspbian] Improve readability of templates --- netjsonconfig/backends/raspbian/renderer.py | 3 + .../raspbian/templates/commands.jinja2 | 16 +- .../raspbian/templates/hostapd.jinja2 | 55 +++--- .../raspbian/templates/hostname.jinja2 | 16 +- .../raspbian/templates/interfaces.jinja2 | 160 +++++++++--------- .../backends/raspbian/templates/ntp.jinja2 | 12 +- .../backends/raspbian/templates/resolv.jinja2 | 32 ++-- tests/raspbian/test_interfaces.py | 68 ++++---- 8 files changed, 182 insertions(+), 180 deletions(-) diff --git a/netjsonconfig/backends/raspbian/renderer.py b/netjsonconfig/backends/raspbian/renderer.py index 89aa11cd5..d845cbd9b 100644 --- a/netjsonconfig/backends/raspbian/renderer.py +++ b/netjsonconfig/backends/raspbian/renderer.py @@ -2,6 +2,9 @@ class RaspbianRenderer(BaseRenderer): + def cleanup(self, output): + output = output.replace(' ', '') + return output pass diff --git a/netjsonconfig/backends/raspbian/templates/commands.jinja2 b/netjsonconfig/backends/raspbian/templates/commands.jinja2 index f08aa97d5..c0df22fb5 100644 --- a/netjsonconfig/backends/raspbian/templates/commands.jinja2 +++ b/netjsonconfig/backends/raspbian/templates/commands.jinja2 @@ -1,11 +1,11 @@ {% for i, j in data.items() %} -{% if i|string() == 'general' %} -{% for general in j %} -{% if general.get('timezone') %} -run commands: -$ timedatectl set-timezone {{ general.get('timezone') }} + {% if i|string() == 'general' %} + {% for general in j %} + {% if general.get('timezone') %} + run commands: + $ timedatectl set-timezone {{ general.get('timezone') }} -{% endif %} -{% endfor %} -{% endif %} + {% endif %} + {% endfor %} + {% endif %} {% endfor%} diff --git a/netjsonconfig/backends/raspbian/templates/hostapd.jinja2 b/netjsonconfig/backends/raspbian/templates/hostapd.jinja2 index 996f76324..c0937c8f4 100644 --- a/netjsonconfig/backends/raspbian/templates/hostapd.jinja2 +++ b/netjsonconfig/backends/raspbian/templates/hostapd.jinja2 @@ -1,30 +1,29 @@ {% for i, j in data.items() %} -{% if i|string() == 'wireless' %} -{% for wireless in j %} -# config: /etc/hostapd/hostapd.conf -interface={{ wireless.get('ifname') }} -driver=nl80211 -{% if wireless.get('protocol') == 'a' or 'b' or 'g' %} -hw_mode={{ wireless.get('hwmode')}} -{% endif %} -channel={{ wireless.get('channel')}} -{% if wireless.get('protocol') == '80211n' %} -ieee80211n=1 -{% endif %} -{% if wireless.get('protocol') == '80211ac' %} -ieee80211ac=1 -{% endif %} -ssid={{ wireless.get('ssid') }} -{% if wireless.get('encryption') != {} %} -auth_algs={{ wireless.get('encryption').get('auth_algs') }} -wpa={{ wireless.get('encryption').get('wpa') }} -wpa_key_mgmt={{ wireless.get('encryption').get('wpa_key_mgmt') }} -wpa_passphrase={{ wireless.get('encryption').get('wpa_passphrase') }} -{% if wireless.get('encryption', None).get('wpa_pairwise') != 'AUTO' %} -wpa_pairwise={{ wireless.get('encryption').get('wpa_pairwise')}} -{% endif %} -{% endif %} -{% endfor %} -{% else %} -{% endif %} + {% if i|string() == 'wireless' %} + {% for wireless in j %} + # config: /etc/hostapd/hostapd.conf + interface={{ wireless.get('ifname') }} + driver=nl80211 + {% if wireless.get('protocol') == 'a' or 'b' or 'g' %} + hw_mode={{ wireless.get('hwmode')}} + {% endif %} + channel={{ wireless.get('channel')}} + {% if wireless.get('protocol') == '80211n' %} + ieee80211n=1 + {% endif %} + {% if wireless.get('protocol') == '80211ac' %} + ieee80211ac=1 + {% endif %} + ssid={{ wireless.get('ssid') }} + {% if wireless.get('encryption') != {} %} + auth_algs={{ wireless.get('encryption').get('auth_algs') }} + wpa={{ wireless.get('encryption').get('wpa') }} + wpa_key_mgmt={{ wireless.get('encryption').get('wpa_key_mgmt') }} + wpa_passphrase={{ wireless.get('encryption').get('wpa_passphrase') }} + {% if wireless.get('encryption', None).get('wpa_pairwise') != 'AUTO' %} + wpa_pairwise={{ wireless.get('encryption').get('wpa_pairwise')}} + {% endif %} + {% endif %} + {% endfor %} + {% endif %} {% endfor %} diff --git a/netjsonconfig/backends/raspbian/templates/hostname.jinja2 b/netjsonconfig/backends/raspbian/templates/hostname.jinja2 index aa0e1f46e..d66d7d8dd 100644 --- a/netjsonconfig/backends/raspbian/templates/hostname.jinja2 +++ b/netjsonconfig/backends/raspbian/templates/hostname.jinja2 @@ -1,11 +1,11 @@ {% for i, j in data.items() %} -{% if i|string() == 'general' %} -{% for general in j %} -{% if general.get('hostname') %} -# config: /etc/hostname -{{ general.get('hostname') }} + {% if i|string() == 'general' %} + {% for general in j %} + {% if general.get('hostname') %} + # config: /etc/hostname + {{ general.get('hostname') }} -{% endif %} -{% endfor %} -{% endif %} + {% endif %} + {% endfor %} + {% endif %} {% endfor %} diff --git a/netjsonconfig/backends/raspbian/templates/interfaces.jinja2 b/netjsonconfig/backends/raspbian/templates/interfaces.jinja2 index b38896751..f4b06844e 100644 --- a/netjsonconfig/backends/raspbian/templates/interfaces.jinja2 +++ b/netjsonconfig/backends/raspbian/templates/interfaces.jinja2 @@ -1,83 +1,83 @@ {% for i, j in data.items() %} -{% if i|string() == 'interfaces' %} -{% for interface in j %} -{% if interface.get('iftype') == 'wireless' %} -{% if interface.get('mode') == 'adhoc' %} -# config: /etc/network/interfaces -auto {{ interface.get('iftype') }} -iface {{ interface.get('iftype') }} inet static - address 172.128.1.1 - netmask 255.255.255.0 - wireless-channel 1 - wireless-essid {{ interface.get('essid') }} - wireless-mode ad-hoc -{% endif %} -{% elif interface.get('iftype') in ['ethernet', 'bridge', 'loopback'] %} -# config: /etc/network/interfaces -auto {{ interface.get('ifname') }} -{% if interface.get('address') != None %} -{% for address in interface.get('address') %} -{% if address.get('proto') == 'static' %} -{% if address.get('family') == 'ipv4' %} -iface {{ interface.get('ifname') }} inet {{ address.get('proto') }} - address {{ address.get('address') }} - netmask {{ address.get('netmask') }} -{% if address.get('gateway', None) != None %} - gateway {{ address.get('gateway')}} -{% endif %} -{% if interface.get('mtu', None) != None %} - mtu {{ interface.get('mtu') }} -{% endif %} -{% if interface.get('mac', None) != None %} - hwaddress {{ interface.get('mac') }} -{% endif %} -{% if interface.get('iftype') == 'bridge' %} - bridge_ports {{ interface.get('bridge_members')[0] }} {{ interface.get('bridge_members')[1] }} -{% endif %} -{% elif address.get('family') == 'ipv6' %} -iface {{ interface.get('ifname') }} inet6 {{ address.get('proto') }} - address {{ address.get('address') }} - netmask {{ address.get('netmask') }} -{% if address.get('gateway', None) != None %} - gateway {{ address.get('ipv6gateway') }} -{% endif %} -{% if interface.get('mtu', None) != None %} - mtu {{ interface.get('mtu') }} -{% endif %} -{% if interface.get('mac', None) != None %} - hwaddress {{ interface.get('mac') }} -{% endif %} -{% if interface.get('iftype') == 'bridge' %} - bridge_ports {{ interface.get('bridge_members')[0] }} {{ interface.get('bridge_members')[1] }} -{% endif %} -{% endif %} -{% elif address.get('proto') == 'dhcp' %} -{% if address.get('family') == 'ipv4'%} -iface {{ interface.get('ifname') }} inet {{ address.get('proto') }} -{% if interface.get('mtu', None) != None %} - pre-up /sbin/ifconfig $IFACE mtu {{ interface.get('mtu') }} -{% endif %} -{% if interface.get('mac', None) != None %} - hwaddress {{ interface.get('mac') }} -{% endif %} -{% elif address.get('family') == 'ipv6' %} -iface {{ interface.get('ifname') }} inet6 {{ address.get('proto') }} -{% if interface.get('mtu', None) != None %} - pre-up /sbin/ifconfig $IFACE mtu {{ interface.get('mtu') }} -{% endif %} -{% if interface.get('mac', None) != None %} - hwaddress {{ interface.get('mac') }} -{% endif %} -{% endif %} -{% endif%} -{% endfor %} -{% else %} -{% if interface.get('iftype') == 'bridge' %} - bridge_ports {{ interface.get('bridge_members')[0] }} {{ interface.get('bridge_members')[1] }} -{% endif %} -{% endif %} -{% endif %} + {% if i|string() == 'interfaces' %} + {% for interface in j %} + {% if interface.get('iftype') == 'wireless' %} + {% if interface.get('mode') == 'adhoc' %} + # config: /etc/network/interfaces + auto {{ interface.get('iftype') }} + iface {{ interface.get('iftype') }} inet static + address 172.128.1.1 + netmask 255.255.255.0 + wireless-channel 1 + wireless-essid {{ interface.get('essid') }} + wireless-mode ad-hoc + {% endif %} + {% elif interface.get('iftype') in ['ethernet', 'bridge', 'loopback'] %} + # config: /etc/network/interfaces + auto {{ interface.get('ifname') }} + {% if interface.get('address') != None %} + {% for address in interface.get('address') %} + {% if address.get('proto') == 'static' %} + {% if address.get('family') == 'ipv4' %} + iface {{ interface.get('ifname') }} inet {{ address.get('proto') }} + address {{ address.get('address') }} + netmask {{ address.get('netmask') }} + {% if address.get('gateway', None) != None %} + gateway {{ address.get('gateway')}} + {% endif %} + {% if interface.get('mtu', None) != None %} + mtu {{ interface.get('mtu') }} + {% endif %} + {% if interface.get('mac', None) != None %} + hwaddress {{ interface.get('mac') }} + {% endif %} + {% if interface.get('iftype') == 'bridge' %} + bridge_ports {{ interface.get('bridge_members')[0] }} {{ interface.get('bridge_members')[1] }} + {% endif %} + {% elif address.get('family') == 'ipv6' %} + iface {{ interface.get('ifname') }} inet6 {{ address.get('proto') }} + address {{ address.get('address') }} + netmask {{ address.get('netmask') }} + {% if address.get('gateway', None) != None %} + gateway {{ address.get('ipv6gateway') }} + {% endif %} + {% if interface.get('mtu', None) != None %} + mtu {{ interface.get('mtu') }} + {% endif %} + {% if interface.get('mac', None) != None %} + hwaddress {{ interface.get('mac') }} + {% endif %} + {% if interface.get('iftype') == 'bridge' %} + bridge_ports {{ interface.get('bridge_members')[0] }} {{ interface.get('bridge_members')[1] }} + {% endif %} + {% endif %} + {% elif address.get('proto') == 'dhcp' %} + {% if address.get('family') == 'ipv4'%} + iface {{ interface.get('ifname') }} inet {{ address.get('proto') }} + {% if interface.get('mtu', None) != None %} + pre-up /sbin/ifconfig $IFACE mtu {{ interface.get('mtu') }} + {% endif %} + {% if interface.get('mac', None) != None %} + hwaddress {{ interface.get('mac') }} + {% endif %} + {% elif address.get('family') == 'ipv6' %} + iface {{ interface.get('ifname') }} inet6 {{ address.get('proto') }} + {% if interface.get('mtu', None) != None %} + pre-up /sbin/ifconfig $IFACE mtu {{ interface.get('mtu') }} + {% endif %} + {% if interface.get('mac', None) != None %} + hwaddress {{ interface.get('mac') }} + {% endif %} + {% endif %} + {% endif%} + {% endfor %} + {% else %} + {% if interface.get('iftype') == 'bridge' %} + bridge_ports {{ interface.get('bridge_members')[0] }} {{ interface.get('bridge_members')[1] }} + {% endif %} + {% endif %} + {% endif %} -{% endfor %} -{% endif %} + {% endfor %} + {% endif %} {% endfor%} diff --git a/netjsonconfig/backends/raspbian/templates/ntp.jinja2 b/netjsonconfig/backends/raspbian/templates/ntp.jinja2 index 05eb3912e..3112fdcbf 100644 --- a/netjsonconfig/backends/raspbian/templates/ntp.jinja2 +++ b/netjsonconfig/backends/raspbian/templates/ntp.jinja2 @@ -1,8 +1,8 @@ {% for i, j in data.items() %} -{% if i|string() == 'ntp' %} -# config: /etc/ntp.conf -{% for server in j %} -server {{ server }} -{% endfor %} -{% endif %} + {% if i|string() == 'ntp' %} + # config: /etc/ntp.conf + {% for server in j %} + server {{ server }} + {% endfor %} + {% endif %} {% endfor %} diff --git a/netjsonconfig/backends/raspbian/templates/resolv.jinja2 b/netjsonconfig/backends/raspbian/templates/resolv.jinja2 index 99505c19e..cf077ab9e 100644 --- a/netjsonconfig/backends/raspbian/templates/resolv.jinja2 +++ b/netjsonconfig/backends/raspbian/templates/resolv.jinja2 @@ -1,18 +1,18 @@ {% set count = [1] %} -{% for i, j in data.items() %} -{% if i|string() in ['dns_servers', 'dns_search'] %} -{% if count == [1] %} -# config: /etc/resolv.conf -{% if count.append(count.pop() + 1) %}{% endif %} -{% endif %} -{% endif %} -{% if i|string() == 'dns_servers' %} -{% for ip in j %} -nameserver {{ ip }} -{% endfor %} -{% elif i|string() == 'dns_search' %} -{% for domain in j %} -search {{ domain }} -{% endfor %} -{% endif %} + {% for i, j in data.items() %} + {% if i|string() in ['dns_servers', 'dns_search'] %} + {% if count == [1] %} + # config: /etc/resolv.conf + {% if count.append(count.pop() + 1) %}{% endif %} + {% endif %} + {% endif %} + {% if i|string() == 'dns_servers' %} + {% for ip in j %} + nameserver {{ ip }} + {% endfor %} + {% elif i|string() == 'dns_search' %} + {% for domain in j %} + search {{ domain }} + {% endfor %} + {% endif %} {% endfor%} diff --git a/tests/raspbian/test_interfaces.py b/tests/raspbian/test_interfaces.py index bd6e37343..9f5f49a74 100644 --- a/tests/raspbian/test_interfaces.py +++ b/tests/raspbian/test_interfaces.py @@ -27,8 +27,8 @@ def test_ipv4_static(self): expected = '''# config: /etc/network/interfaces auto eth0 iface eth0 inet static - address 10.0.0.1 - netmask 255.255.255.240 +address 10.0.0.1 +netmask 255.255.255.240 ''' self.assertEqual(o.render(), expected) @@ -54,8 +54,8 @@ def test_ipv6_static(self): expected = '''# config: /etc/network/interfaces auto eth0 iface eth0 inet6 static - address fe80::ba27:ebff:fe1c:5477 - netmask 64 +address fe80::ba27:ebff:fe1c:5477 +netmask 64 ''' self.assertEqual(o.render(), expected) @@ -87,11 +87,11 @@ def test_multiple_static(self): expected = '''# config: /etc/network/interfaces auto eth0 iface eth0 inet static - address 10.0.0.1 - netmask 255.255.255.240 +address 10.0.0.1 +netmask 255.255.255.240 iface eth0 inet6 static - address fe80::ba27:ebff:fe1c:5477 - netmask 64 +address fe80::ba27:ebff:fe1c:5477 +netmask 64 ''' self.assertEqual(o.render(), expected) @@ -205,14 +205,14 @@ def test_multiple_ip(self): expected = '''# config: /etc/network/interfaces auto eth0.1 iface eth0.1 inet static - address 192.168.1.1 - netmask 255.255.255.0 +address 192.168.1.1 +netmask 255.255.255.0 iface eth0.1 inet static - address 192.168.2.1 - netmask 255.255.255.0 +address 192.168.2.1 +netmask 255.255.255.0 iface eth0.1 inet6 static - address fd87::1 - netmask 128 +address fd87::1 +netmask 128 ''' self.assertEqual(o.render(), expected) @@ -237,7 +237,7 @@ def test_mtu(self): expected = '''# config: /etc/network/interfaces auto eth1 iface eth1 inet dhcp - pre-up /sbin/ifconfig $IFACE mtu 1500 +pre-up /sbin/ifconfig $IFACE mtu 1500 ''' self.assertEqual(o.render(), expected) @@ -262,7 +262,7 @@ def test_mac(self): expected = '''# config: /etc/network/interfaces auto eth1 iface eth1 inet dhcp - hwaddress 52:54:00:56:46:c0 +hwaddress 52:54:00:56:46:c0 ''' @@ -300,11 +300,11 @@ def test_multiple_ip_and_dhcp(self): auto eth0 iface eth0 inet dhcp iface eth0 inet static - address 192.168.1.1 - netmask 255.255.255.0 +address 192.168.1.1 +netmask 255.255.255.0 iface eth0 inet static - address 192.168.2.1 - netmask 255.255.255.0 +address 192.168.2.1 +netmask 255.255.255.0 ''' self.assertEqual(o.render(), expected) @@ -332,8 +332,8 @@ def test_interface_with_resolv(self): expected = '''# config: /etc/network/interfaces auto eth0 iface eth0 inet static - address 192.168.1.1 - netmask 255.255.255.0 +address 192.168.1.1 +netmask 255.255.255.0 # config: /etc/resolv.conf nameserver 10.11.12.13 @@ -364,8 +364,8 @@ def test_loopback(self): expected = '''# config: /etc/network/interfaces auto lo iface lo inet static - address 127.0.0.1 - netmask 255.0.0.0 +address 127.0.0.1 +netmask 255.0.0.0 ''' self.assertEqual(o.render(), expected) @@ -389,11 +389,11 @@ def test_adhoc_wireless(self): expected = '''# config: /etc/network/interfaces auto wireless iface wireless inet static - address 172.128.1.1 - netmask 255.255.255.0 - wireless-channel 1 - wireless-essid freifunk - wireless-mode ad-hoc +address 172.128.1.1 +netmask 255.255.255.0 +wireless-channel 1 +wireless-essid freifunk +wireless-mode ad-hoc ''' self.assertEqual(o.render(), expected) @@ -415,7 +415,7 @@ def test_simple_bridge(self): expected = '''# config: /etc/network/interfaces auto br-lan - bridge_ports eth0 eth1 +bridge_ports eth0 eth1 ''' self.assertEqual(o.render(), expected) @@ -446,10 +446,10 @@ def test_complex_bridge(self): expected = '''# config: /etc/network/interfaces auto brwifi iface brwifi inet6 static - address fe80::8029:23ff:fe7d:c214 - netmask 64 - mtu 1500 - bridge_ports wlan0 vpn.40 +address fe80::8029:23ff:fe7d:c214 +netmask 64 +mtu 1500 +bridge_ports wlan0 vpn.40 ''' self.assertEqual(o.render(), expected) From b8e491ede430c992dad2bed7a9a892f427cb8faa Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Mon, 17 Jul 2017 01:37:38 +0530 Subject: [PATCH 086/183] [raspbian] Added support for generating tar.gz file --- netjsonconfig/backends/raspbian/raspbian.py | 15 +++++++++++++++ .../backends/raspbian/templates/hostapd.jinja2 | 1 + .../backends/raspbian/templates/hostname.jinja2 | 1 + .../raspbian/templates/interfaces.jinja2 | 2 ++ .../backends/raspbian/templates/ntp.jinja2 | 1 + .../backends/raspbian/templates/resolv.jinja2 | 1 + tests/raspbian/test_hostapd.py | 4 ++++ tests/raspbian/test_interfaces.py | 16 ++++++++++++++++ tests/raspbian/test_radios.py | 6 ++++++ tests/raspbian/test_resolv.py | 3 +++ tests/raspbian/test_system.py | 2 ++ 11 files changed, 52 insertions(+) diff --git a/netjsonconfig/backends/raspbian/raspbian.py b/netjsonconfig/backends/raspbian/raspbian.py index f845f0052..320917005 100644 --- a/netjsonconfig/backends/raspbian/raspbian.py +++ b/netjsonconfig/backends/raspbian/raspbian.py @@ -1,3 +1,4 @@ +import re from . import converters from ..base.backend import BaseBackend from .renderer import Commands, Hostapd, Hostname, Interfaces, Ntp, Resolv @@ -25,3 +26,17 @@ class Raspbian(BaseBackend): Ntp, Commands ] + + def _generate_contents(self, tar): + text = self.render(files=False) + config_files_pattern = re.compile('^# config:\s', flags=re.MULTILINE) + config_files = config_files_pattern.split(text) + if '' in config_files: + config_files.remove('') + for config_file in config_files: + lines = config_file.split('\n') + file_name = lines[0] + text_contents = '\n'.join(lines[2:]) + self._add_file(tar=tar, + name='{0}'.format(file_name), + contents=text_contents) diff --git a/netjsonconfig/backends/raspbian/templates/hostapd.jinja2 b/netjsonconfig/backends/raspbian/templates/hostapd.jinja2 index c0937c8f4..3ca70370c 100644 --- a/netjsonconfig/backends/raspbian/templates/hostapd.jinja2 +++ b/netjsonconfig/backends/raspbian/templates/hostapd.jinja2 @@ -2,6 +2,7 @@ {% if i|string() == 'wireless' %} {% for wireless in j %} # config: /etc/hostapd/hostapd.conf + interface={{ wireless.get('ifname') }} driver=nl80211 {% if wireless.get('protocol') == 'a' or 'b' or 'g' %} diff --git a/netjsonconfig/backends/raspbian/templates/hostname.jinja2 b/netjsonconfig/backends/raspbian/templates/hostname.jinja2 index d66d7d8dd..9d9b80164 100644 --- a/netjsonconfig/backends/raspbian/templates/hostname.jinja2 +++ b/netjsonconfig/backends/raspbian/templates/hostname.jinja2 @@ -3,6 +3,7 @@ {% for general in j %} {% if general.get('hostname') %} # config: /etc/hostname + {{ general.get('hostname') }} {% endif %} diff --git a/netjsonconfig/backends/raspbian/templates/interfaces.jinja2 b/netjsonconfig/backends/raspbian/templates/interfaces.jinja2 index f4b06844e..d54c54cbc 100644 --- a/netjsonconfig/backends/raspbian/templates/interfaces.jinja2 +++ b/netjsonconfig/backends/raspbian/templates/interfaces.jinja2 @@ -4,6 +4,7 @@ {% if interface.get('iftype') == 'wireless' %} {% if interface.get('mode') == 'adhoc' %} # config: /etc/network/interfaces + auto {{ interface.get('iftype') }} iface {{ interface.get('iftype') }} inet static address 172.128.1.1 @@ -14,6 +15,7 @@ {% endif %} {% elif interface.get('iftype') in ['ethernet', 'bridge', 'loopback'] %} # config: /etc/network/interfaces + auto {{ interface.get('ifname') }} {% if interface.get('address') != None %} {% for address in interface.get('address') %} diff --git a/netjsonconfig/backends/raspbian/templates/ntp.jinja2 b/netjsonconfig/backends/raspbian/templates/ntp.jinja2 index 3112fdcbf..491869941 100644 --- a/netjsonconfig/backends/raspbian/templates/ntp.jinja2 +++ b/netjsonconfig/backends/raspbian/templates/ntp.jinja2 @@ -1,6 +1,7 @@ {% for i, j in data.items() %} {% if i|string() == 'ntp' %} # config: /etc/ntp.conf + {% for server in j %} server {{ server }} {% endfor %} diff --git a/netjsonconfig/backends/raspbian/templates/resolv.jinja2 b/netjsonconfig/backends/raspbian/templates/resolv.jinja2 index cf077ab9e..68845b800 100644 --- a/netjsonconfig/backends/raspbian/templates/resolv.jinja2 +++ b/netjsonconfig/backends/raspbian/templates/resolv.jinja2 @@ -3,6 +3,7 @@ {% if i|string() in ['dns_servers', 'dns_search'] %} {% if count == [1] %} # config: /etc/resolv.conf + {% if count.append(count.pop() + 1) %}{% endif %} {% endif %} {% endif %} diff --git a/tests/raspbian/test_hostapd.py b/tests/raspbian/test_hostapd.py index 0081733e8..1a76c0389 100644 --- a/tests/raspbian/test_hostapd.py +++ b/tests/raspbian/test_hostapd.py @@ -38,6 +38,7 @@ def test_wpa2_personal(self): }) expected = '''# config: /etc/hostapd/hostapd.conf + interface=wlan0 driver=nl80211 hw_mode=g @@ -85,6 +86,7 @@ def test_wpa_personal(self): }) expected = '''# config: /etc/hostapd/hostapd.conf + interface=wlan0 driver=nl80211 hw_mode=g @@ -200,6 +202,7 @@ def test_encryption_disabled(self): }) expected = '''# config: /etc/hostapd/hostapd.conf + interface=wlan0 driver=nl80211 hw_mode=g @@ -238,6 +241,7 @@ def test_no_encryption(self): }) expected = '''# config: /etc/hostapd/hostapd.conf + interface=wlan0 driver=nl80211 hw_mode=g diff --git a/tests/raspbian/test_interfaces.py b/tests/raspbian/test_interfaces.py index 9f5f49a74..7d13cc385 100644 --- a/tests/raspbian/test_interfaces.py +++ b/tests/raspbian/test_interfaces.py @@ -25,6 +25,7 @@ def test_ipv4_static(self): }) expected = '''# config: /etc/network/interfaces + auto eth0 iface eth0 inet static address 10.0.0.1 @@ -52,6 +53,7 @@ def test_ipv6_static(self): }) expected = '''# config: /etc/network/interfaces + auto eth0 iface eth0 inet6 static address fe80::ba27:ebff:fe1c:5477 @@ -85,6 +87,7 @@ def test_multiple_static(self): }) expected = '''# config: /etc/network/interfaces + auto eth0 iface eth0 inet static address 10.0.0.1 @@ -113,6 +116,7 @@ def test_ipv4_dhcp(self): }) expected = '''# config: /etc/network/interfaces + auto eth0 iface eth0 inet dhcp @@ -136,6 +140,7 @@ def test_ipv6_dhcp(self): }) expected = '''# config: /etc/network/interfaces + auto eth0 iface eth0 inet6 dhcp @@ -164,6 +169,7 @@ def test_multiple_dhcp(self): }) expected = '''# config: /etc/network/interfaces + auto eth0 iface eth0 inet dhcp iface eth0 inet6 dhcp @@ -203,6 +209,7 @@ def test_multiple_ip(self): }) expected = '''# config: /etc/network/interfaces + auto eth0.1 iface eth0.1 inet static address 192.168.1.1 @@ -235,6 +242,7 @@ def test_mtu(self): }) expected = '''# config: /etc/network/interfaces + auto eth1 iface eth1 inet dhcp pre-up /sbin/ifconfig $IFACE mtu 1500 @@ -260,6 +268,7 @@ def test_mac(self): }) expected = '''# config: /etc/network/interfaces + auto eth1 iface eth1 inet dhcp hwaddress 52:54:00:56:46:c0 @@ -297,6 +306,7 @@ def test_multiple_ip_and_dhcp(self): }) expected = '''# config: /etc/network/interfaces + auto eth0 iface eth0 inet dhcp iface eth0 inet static @@ -330,12 +340,14 @@ def test_interface_with_resolv(self): }) expected = '''# config: /etc/network/interfaces + auto eth0 iface eth0 inet static address 192.168.1.1 netmask 255.255.255.0 # config: /etc/resolv.conf + nameserver 10.11.12.13 nameserver 8.8.8.8 search netjson.org @@ -362,6 +374,7 @@ def test_loopback(self): }) expected = '''# config: /etc/network/interfaces + auto lo iface lo inet static address 127.0.0.1 @@ -387,6 +400,7 @@ def test_adhoc_wireless(self): }) expected = '''# config: /etc/network/interfaces + auto wireless iface wireless inet static address 172.128.1.1 @@ -414,6 +428,7 @@ def test_simple_bridge(self): }) expected = '''# config: /etc/network/interfaces + auto br-lan bridge_ports eth0 eth1 @@ -444,6 +459,7 @@ def test_complex_bridge(self): }) expected = '''# config: /etc/network/interfaces + auto brwifi iface brwifi inet6 static address fe80::8029:23ff:fe7d:c214 diff --git a/tests/raspbian/test_radios.py b/tests/raspbian/test_radios.py index 27d09578e..994b88b7e 100644 --- a/tests/raspbian/test_radios.py +++ b/tests/raspbian/test_radios.py @@ -44,6 +44,7 @@ def test_radio_multi(self): }) expected = '''# config: /etc/hostapd/hostapd.conf + interface=wlan0 driver=nl80211 hw_mode=g @@ -81,6 +82,7 @@ def test_radio_n_24ghz(self): }) expected = '''# config: /etc/hostapd/hostapd.conf + interface=wlan0 driver=nl80211 hw_mode=g @@ -118,6 +120,7 @@ def test_radio_n_5ghz(self): }) expected = '''# config: /etc/hostapd/hostapd.conf + interface=wlan0 driver=nl80211 hw_mode=a @@ -154,6 +157,7 @@ def test_radio_ac(self): }) expected = '''# config: /etc/hostapd/hostapd.conf + interface=wlan0 driver=nl80211 hw_mode=a @@ -190,6 +194,7 @@ def test_radio_a(self): }) expected = '''# config: /etc/hostapd/hostapd.conf + interface=wlan0 driver=nl80211 hw_mode=a @@ -225,6 +230,7 @@ def test_radio_g(self): }) expected = '''# config: /etc/hostapd/hostapd.conf + interface=wlan0 driver=nl80211 hw_mode=g diff --git a/tests/raspbian/test_resolv.py b/tests/raspbian/test_resolv.py index 86c227b09..1f9b19d0d 100644 --- a/tests/raspbian/test_resolv.py +++ b/tests/raspbian/test_resolv.py @@ -15,6 +15,7 @@ def test_dns_server(self): }) expected = '''# config: /etc/resolv.conf + nameserver 10.254.0.1 nameserver 10.254.0.2 ''' @@ -28,6 +29,7 @@ def test_dns_search(self): }) expected = '''# config: /etc/resolv.conf + search domain.com ''' self.assertEqual(o.render(), expected) @@ -44,6 +46,7 @@ def test_dns_server_and_dns_search(self): }) expected = '''# config: /etc/resolv.conf + nameserver 10.11.12.13 nameserver 8.8.8.8 search netjson.org diff --git a/tests/raspbian/test_system.py b/tests/raspbian/test_system.py index 24ea99c3a..399326fd9 100644 --- a/tests/raspbian/test_system.py +++ b/tests/raspbian/test_system.py @@ -18,6 +18,7 @@ def test_general(self): }) expected = '''# config: /etc/hostname + test-system run commands: @@ -41,6 +42,7 @@ def test_ntp(self): }) expected = '''# config: /etc/ntp.conf + server 0.openwrt.pool.ntp.org server 1.openwrt.pool.ntp.org server 2.openwrt.pool.ntp.org From 57b2b33a6ef196389eaf829d92888dec666127af Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Mon, 17 Jul 2017 19:02:50 +0530 Subject: [PATCH 087/183] [raspbian] Added tests for generate and write methods --- tests/raspbian/test_backend.py | 67 ++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 tests/raspbian/test_backend.py diff --git a/tests/raspbian/test_backend.py b/tests/raspbian/test_backend.py new file mode 100644 index 000000000..d605ee258 --- /dev/null +++ b/tests/raspbian/test_backend.py @@ -0,0 +1,67 @@ +import os +import tarfile +import unittest + +from netjsonconfig import Raspbian +from netjsonconfig.utils import _TabsMixin + +class TestBackend(unittest.TestCase, _TabsMixin): + + def test_generate(self): + o = Raspbian({ + "interfaces": [ + { + "name": "eth0", + "type": "ethernet", + "addresses": [ + { + "address": "192.168.1.1", + "mask": 24, + "proto": "static", + "family": "ipv4" + } + ] + } + ], + "dns_servers": [ + "10.11.12.13", + "8.8.8.8" + ], + "dns_search": [ + "netjson.org", + "openwisp.org" + ] + }) + tar = tarfile.open(fileobj=o.generate(), mode='r') + self.assertEqual(len(tar.getmembers()), 2) + + interface = tar.getmember('/etc/network/interfaces') + contents = tar.extractfile(interface).read().decode() + expected = self._tabs('''auto eth0 +iface eth0 inet static +address 192.168.1.1 +netmask 255.255.255.0 + +''') + self.assertEqual(contents, expected) + + resolv = tar.getmember('/etc/resolv.conf') + contents = tar.extractfile(resolv).read().decode() + expected = self._tabs('''nameserver 10.11.12.13 +nameserver 8.8.8.8 +search netjson.org +search openwisp.org +''') + self.assertEqual(contents, expected) + + def test_write(self): + o = Raspbian({ + "general": { + "hostname": "test" + } + }) + o.write(name='test', path='/tmp') + tar = tarfile.open('/tmp/test.tar.gz', mode='r') + self.assertEqual(len(tar.getmembers()), 1) + tar.close() + os.remove('/tmp/test.tar.gz') From 8b753f1af06bc3ce9f0fad799f400b63a506956c Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Mon, 17 Jul 2017 22:54:08 +0530 Subject: [PATCH 088/183] [raspbia] Added documentation for write and generate method --- docs/source/backends/raspbian.rst | 69 +++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/docs/source/backends/raspbian.rst b/docs/source/backends/raspbian.rst index a790bde67..92a83a15e 100644 --- a/docs/source/backends/raspbian.rst +++ b/docs/source/backends/raspbian.rst @@ -67,6 +67,72 @@ Will return the following output:: address fd87::1 netmask 128 +Generate method +--------------- + +.. automethod:: netjsonconfig.Raspbian.generate + +Code example: + +.. code-block:: python + + >>> import tarfile + >>> from netjsonconfig import Raspbian + >>> + >>> o = Raspbian({ + ... "interfaces": [ + ... { + ... "name": "eth0", + ... "type": "ethernet", + ... "addresses": [ + ... { + ... "proto": "dhcp", + ... "family": "ipv4" + ... } + ... ] + ... } + ... ] + ... }) + >>> stream = o.generate() + >>> print(stream) + <_io.BytesIO object at 0x7f8bc6efb620> + >>> tar = tarfile.open(fileobj=stream, mode='r:gz') + >>> print(tar.getmembers()) + [] + +The ``generate`` method does not write to disk but instead returns a instance of +``io.BytesIO`` which contains a tar.gz file object. + +Write method +------------ + +.. automethod:: netjsonconfig.OpenWrt.write + +Example: + +.. code-block:: python + + >>> import tarfile + >>> from netjsonconfig import Raspbian + >>> + >>> o = Raspbian({ + ... "interfaces": [ + ... { + ... "name": "eth0", + ... "type": "ethernet", + ... "addresses": [ + ... { + ... "proto": "dhcp", + ... "family": "ipv4" + ... } + ... ] + ... } + ... ] + ... }) + >>> o.write('dhcp-router', path='/tmp/') + +Writes the configuration archive in ``/tmp/dhcp-router.tar.gz`` + General settings ---------------- @@ -352,6 +418,7 @@ Configure your interface Let us say that ``wlan0`` is our wireless interface which we will be using. First we need to setup a static IP for our wireless interface. Edit the ``wlan0`` section in interface configuration file ``/etc/network/interfaces``:: + auto wlan0 iface wlan0 inet static address 172.128.1.1 @@ -372,6 +439,7 @@ At this point you should be able to see your wireless network. If you try to con to this network, it will authenticate but will not recieve any IP address until dnsmasq is setup. Use **Ctrl+C** to stop it. If you want the wireless service to start automatically at boot, find the line:: + #DAEMON_CONF="" in ``/etc/default/hostapd`` and replace it with:: @@ -385,6 +453,7 @@ By default ``/etc/dnsmasq.conf`` contains the complete documentation for how the file needs to be used. It is advisable to create a copy of the original ``dnsmasq.conf``. After creating the backup, delete the original file and create a new file ``/etc/dnsmasq.conf`` Setup your DNS and DHCP server. Below is an example configuration file:: + # User interface wlan0 interface=wlan0 # Specify the address to listen on From 9ea936414a7731c9fddb19163a1b8084b4a1b591 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Tue, 18 Jul 2017 18:43:35 +0530 Subject: [PATCH 089/183] [raspbian] Improved interfaces jinja2 template --- .../raspbian/converters/interfaces.py | 2 +- .../raspbian/templates/interfaces.jinja2 | 32 ++++++++++--------- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/netjsonconfig/backends/raspbian/converters/interfaces.py b/netjsonconfig/backends/raspbian/converters/interfaces.py index b0279230d..1a9c57628 100644 --- a/netjsonconfig/backends/raspbian/converters/interfaces.py +++ b/netjsonconfig/backends/raspbian/converters/interfaces.py @@ -18,7 +18,7 @@ def to_intermediate(self): 'ifname': ifname, 'iftype': iftype }) - if iftype in ['ethernet', 'bridge', 'loopback']: + if iftype in ['ethernet', 'bridge', 'loopback', 'wireless']: addresses = self._get_address(interface) new_interface.update({ 'address': addresses diff --git a/netjsonconfig/backends/raspbian/templates/interfaces.jinja2 b/netjsonconfig/backends/raspbian/templates/interfaces.jinja2 index d54c54cbc..776e48a47 100644 --- a/netjsonconfig/backends/raspbian/templates/interfaces.jinja2 +++ b/netjsonconfig/backends/raspbian/templates/interfaces.jinja2 @@ -1,23 +1,11 @@ {% for i, j in data.items() %} {% if i|string() == 'interfaces' %} {% for interface in j %} - {% if interface.get('iftype') == 'wireless' %} - {% if interface.get('mode') == 'adhoc' %} - # config: /etc/network/interfaces - - auto {{ interface.get('iftype') }} - iface {{ interface.get('iftype') }} inet static - address 172.128.1.1 - netmask 255.255.255.0 - wireless-channel 1 - wireless-essid {{ interface.get('essid') }} - wireless-mode ad-hoc - {% endif %} - {% elif interface.get('iftype') in ['ethernet', 'bridge', 'loopback'] %} + {% if interface.get('iftype') in ['ethernet', 'bridge', 'loopback', 'wireless'] %} + {% if interface.get('address') != None %} # config: /etc/network/interfaces - + auto {{ interface.get('ifname') }} - {% if interface.get('address') != None %} {% for address in interface.get('address') %} {% if address.get('proto') == 'static' %} {% if address.get('family') == 'ipv4' %} @@ -75,8 +63,22 @@ {% endfor %} {% else %} {% if interface.get('iftype') == 'bridge' %} + # config: /etc/network/interfaces + + auto {{ interface.get('ifname') }} bridge_ports {{ interface.get('bridge_members')[0] }} {{ interface.get('bridge_members')[1] }} {% endif %} + {% if interface.get('mode') == 'adhoc' %} + # config: /etc/network/interfaces + + auto {{ interface.get('iftype') }} + iface {{ interface.get('iftype') }} inet static + address 172.128.1.1 + netmask 255.255.255.0 + wireless-channel 1 + wireless-essid {{ interface.get('essid') }} + wireless-mode ad-hoc + {% endif %} {% endif %} {% endif %} From 8319e0069d8afa59b2f541acff46fbd7578df702 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Wed, 19 Jul 2017 15:52:21 +0530 Subject: [PATCH 090/183] [raspbian] Added support for ipv4 static routes --- .../backends/raspbian/converters/interfaces.py | 17 ++++++++++++++--- .../raspbian/templates/interfaces.jinja2 | 5 +++++ 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/netjsonconfig/backends/raspbian/converters/interfaces.py b/netjsonconfig/backends/raspbian/converters/interfaces.py index 1a9c57628..2592c2663 100644 --- a/netjsonconfig/backends/raspbian/converters/interfaces.py +++ b/netjsonconfig/backends/raspbian/converters/interfaces.py @@ -1,4 +1,4 @@ -from ipaddress import IPv4Interface +from ipaddress import IPv4Interface, ip_network from ....utils import get_copy from .base import RaspbianConverter @@ -10,6 +10,7 @@ class Interfaces(RaspbianConverter): def to_intermediate(self): result = [] interfaces = get_copy(self.netjson, self.netjson_key) + routes = get_copy(self.netjson, 'routes') for interface in interfaces: new_interface = {} ifname = interface.get('name') @@ -19,7 +20,7 @@ def to_intermediate(self): 'iftype': iftype }) if iftype in ['ethernet', 'bridge', 'loopback', 'wireless']: - addresses = self._get_address(interface) + addresses = self._get_address(interface, routes) new_interface.update({ 'address': addresses }) @@ -48,15 +49,25 @@ def to_intermediate(self): result.append(new_interface) return (('interfaces', result),) - def _get_address(self, interface): + def _get_address(self, interface, routes): addresses = interface.get('addresses', False) if addresses: for address in addresses: if address.get('proto') == 'static': if address.get('family') == 'ipv4': + address_mask = str(address.get('address')) + '/' + str(address.get('mask')) address['netmask'] = IPv4Interface(address_mask).with_netmask.split('/')[1] del address['mask'] + if routes: + for route in routes: + if ip_network(route.get('next')).version == 4: + destination = IPv4Interface(route['destination']).with_netmask + dest, dest_mask = destination.split('/') + route['dest'] = dest + route['dest_mask'] = dest_mask + del route['destination'] + address['route'] = route if address.get('family') == 'ipv6': address['netmask'] = address['mask'] del address['mask'] diff --git a/netjsonconfig/backends/raspbian/templates/interfaces.jinja2 b/netjsonconfig/backends/raspbian/templates/interfaces.jinja2 index 776e48a47..2a68ec789 100644 --- a/netjsonconfig/backends/raspbian/templates/interfaces.jinja2 +++ b/netjsonconfig/backends/raspbian/templates/interfaces.jinja2 @@ -15,6 +15,11 @@ {% if address.get('gateway', None) != None %} gateway {{ address.get('gateway')}} {% endif %} + {% if address.get('route') != None %} + {% set route = address.get('route')%} + post-up route add -net {{ route.get('dest') }} netmask {{ route.get('dest_mask') }} gw {{ route.get('next') }} + pre-up route del -net {{ route.get('dest') }} netmask {{ route.get('dest_mask') }} gw {{ route.get('next') }} + {% endif %} {% if interface.get('mtu', None) != None %} mtu {{ interface.get('mtu') }} {% endif %} From e96f61aa9792cf0a6c69e4fa2269e7ccd487df2f Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Wed, 19 Jul 2017 15:57:54 +0530 Subject: [PATCH 091/183] [raspbian] Fixed isort and flake8 errors --- netjsonconfig/backends/raspbian/raspbian.py | 1 + tests/raspbian/test_backend.py | 1 + 2 files changed, 2 insertions(+) diff --git a/netjsonconfig/backends/raspbian/raspbian.py b/netjsonconfig/backends/raspbian/raspbian.py index 320917005..ab4320487 100644 --- a/netjsonconfig/backends/raspbian/raspbian.py +++ b/netjsonconfig/backends/raspbian/raspbian.py @@ -1,4 +1,5 @@ import re + from . import converters from ..base.backend import BaseBackend from .renderer import Commands, Hostapd, Hostname, Interfaces, Ntp, Resolv diff --git a/tests/raspbian/test_backend.py b/tests/raspbian/test_backend.py index d605ee258..49ba04364 100644 --- a/tests/raspbian/test_backend.py +++ b/tests/raspbian/test_backend.py @@ -5,6 +5,7 @@ from netjsonconfig import Raspbian from netjsonconfig.utils import _TabsMixin + class TestBackend(unittest.TestCase, _TabsMixin): def test_generate(self): From 248a3a4c3861decb18749e366f817a2c538880f4 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Wed, 19 Jul 2017 17:48:13 +0530 Subject: [PATCH 092/183] [raspbian] Added support for manual mode in interfaces --- .../raspbian/templates/interfaces.jinja2 | 13 +++++----- tests/raspbian/test_hostapd.py | 16 +++++++++++++ tests/raspbian/test_interfaces.py | 4 ++-- tests/raspbian/test_radios.py | 24 +++++++++++++++++++ 4 files changed, 48 insertions(+), 9 deletions(-) diff --git a/netjsonconfig/backends/raspbian/templates/interfaces.jinja2 b/netjsonconfig/backends/raspbian/templates/interfaces.jinja2 index 2a68ec789..85265c39a 100644 --- a/netjsonconfig/backends/raspbian/templates/interfaces.jinja2 +++ b/netjsonconfig/backends/raspbian/templates/interfaces.jinja2 @@ -2,8 +2,8 @@ {% if i|string() == 'interfaces' %} {% for interface in j %} {% if interface.get('iftype') in ['ethernet', 'bridge', 'loopback', 'wireless'] %} - {% if interface.get('address') != None %} # config: /etc/network/interfaces + {% if interface.get('address') != None %} auto {{ interface.get('ifname') }} {% for address in interface.get('address') %} @@ -67,17 +67,16 @@ {% endif%} {% endfor %} {% else %} - {% if interface.get('iftype') == 'bridge' %} - # config: /etc/network/interfaces auto {{ interface.get('ifname') }} + {% if interface.get('iftype') == 'wireless' and interface.get('mode') != 'adhoc' %} + iface {{ interface.get('ifname') }} inet manual + {% endif %} + {% if interface.get('iftype') == 'bridge' %} bridge_ports {{ interface.get('bridge_members')[0] }} {{ interface.get('bridge_members')[1] }} {% endif %} {% if interface.get('mode') == 'adhoc' %} - # config: /etc/network/interfaces - - auto {{ interface.get('iftype') }} - iface {{ interface.get('iftype') }} inet static + iface {{ interface.get('ifname') }} inet static address 172.128.1.1 netmask 255.255.255.0 wireless-channel 1 diff --git a/tests/raspbian/test_hostapd.py b/tests/raspbian/test_hostapd.py index 1a76c0389..b092911df 100644 --- a/tests/raspbian/test_hostapd.py +++ b/tests/raspbian/test_hostapd.py @@ -50,6 +50,10 @@ def test_wpa2_personal(self): wpa_key_mgmt=WPA-PSK wpa_passphrase=passphrase012345 wpa_pairwise=TKIP CCMP +# config: /etc/network/interfaces + +auto wlan0 +iface wlan0 inet manual ''' self.assertEqual(o.render(), expected) @@ -97,6 +101,10 @@ def test_wpa_personal(self): wpa=1 wpa_key_mgmt=WPA-PSK wpa_passphrase=passphrase012345 +# config: /etc/network/interfaces + +auto wlan0 +iface wlan0 inet manual ''' self.assertEqual(o.render(), expected) @@ -209,6 +217,10 @@ def test_encryption_disabled(self): channel=3 ieee80211n=1 ssid=MyNetwork +# config: /etc/network/interfaces + +auto wlan0 +iface wlan0 inet manual ''' self.assertEqual(o.render(), expected) @@ -248,6 +260,10 @@ def test_no_encryption(self): channel=3 ieee80211n=1 ssid=open +# config: /etc/network/interfaces + +auto wlan0 +iface wlan0 inet manual ''' self.assertEqual(o.render(), expected) diff --git a/tests/raspbian/test_interfaces.py b/tests/raspbian/test_interfaces.py index 7d13cc385..ee9598031 100644 --- a/tests/raspbian/test_interfaces.py +++ b/tests/raspbian/test_interfaces.py @@ -401,8 +401,8 @@ def test_adhoc_wireless(self): expected = '''# config: /etc/network/interfaces -auto wireless -iface wireless inet static +auto wlan0 +iface wlan0 inet static address 172.128.1.1 netmask 255.255.255.0 wireless-channel 1 diff --git a/tests/raspbian/test_radios.py b/tests/raspbian/test_radios.py index 994b88b7e..7587ad8a4 100644 --- a/tests/raspbian/test_radios.py +++ b/tests/raspbian/test_radios.py @@ -51,6 +51,10 @@ def test_radio_multi(self): channel=11 ieee80211n=1 ssid=myWiFi +# config: /etc/network/interfaces + +auto wlan0 +iface wlan0 inet manual ''' self.assertEqual(o.render(), expected) @@ -89,6 +93,10 @@ def test_radio_n_24ghz(self): channel=3 ieee80211n=1 ssid=myWiFi +# config: /etc/network/interfaces + +auto wlan0 +iface wlan0 inet manual ''' self.assertEqual(o.render(), expected) @@ -127,6 +135,10 @@ def test_radio_n_5ghz(self): channel=36 ieee80211n=1 ssid=myWiFi +# config: /etc/network/interfaces + +auto wlan0 +iface wlan0 inet manual ''' self.assertEqual(o.render(), expected) @@ -164,6 +176,10 @@ def test_radio_ac(self): channel=132 ieee80211ac=1 ssid=myWiFi +# config: /etc/network/interfaces + +auto wlan0 +iface wlan0 inet manual ''' self.assertEqual(o.render(), expected) @@ -200,6 +216,10 @@ def test_radio_a(self): hw_mode=a channel=0 ssid=myWiFi +# config: /etc/network/interfaces + +auto wlan0 +iface wlan0 inet manual ''' self.assertEqual(o.render(), expected) @@ -236,6 +256,10 @@ def test_radio_g(self): hw_mode=g channel=0 ssid=myWiFi +# config: /etc/network/interfaces + +auto wlan0 +iface wlan0 inet manual ''' self.assertEqual(o.render(), expected) From 8103382afce1b131b96d4d3942673a2d130a48db Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Wed, 19 Jul 2017 18:40:35 +0530 Subject: [PATCH 093/183] [raspbian] Further modified static routes implementation --- .../raspbian/converters/interfaces.py | 19 ++--- .../raspbian/templates/interfaces.jinja2 | 18 ++++- tests/raspbian/test_routes.py | 73 +++++++++++++++++++ 3 files changed, 97 insertions(+), 13 deletions(-) create mode 100644 tests/raspbian/test_routes.py diff --git a/netjsonconfig/backends/raspbian/converters/interfaces.py b/netjsonconfig/backends/raspbian/converters/interfaces.py index 2592c2663..9a03c1703 100644 --- a/netjsonconfig/backends/raspbian/converters/interfaces.py +++ b/netjsonconfig/backends/raspbian/converters/interfaces.py @@ -24,6 +24,16 @@ def to_intermediate(self): new_interface.update({ 'address': addresses }) + if routes: + for route in routes: + if ip_network(route.get('next')).version == 4: + route['version'] = 4 + destination = IPv4Interface(route['destination']).with_netmask + dest, dest_mask = destination.split('/') + route['dest'] = dest + route['dest_mask'] = dest_mask + del route['destination'] + new_interface.update({'route': route}) mac = interface.get('mac', False) if mac: new_interface.update({'mac': mac}) @@ -59,15 +69,6 @@ def _get_address(self, interface, routes): address_mask = str(address.get('address')) + '/' + str(address.get('mask')) address['netmask'] = IPv4Interface(address_mask).with_netmask.split('/')[1] del address['mask'] - if routes: - for route in routes: - if ip_network(route.get('next')).version == 4: - destination = IPv4Interface(route['destination']).with_netmask - dest, dest_mask = destination.split('/') - route['dest'] = dest - route['dest_mask'] = dest_mask - del route['destination'] - address['route'] = route if address.get('family') == 'ipv6': address['netmask'] = address['mask'] del address['mask'] diff --git a/netjsonconfig/backends/raspbian/templates/interfaces.jinja2 b/netjsonconfig/backends/raspbian/templates/interfaces.jinja2 index 85265c39a..13139292f 100644 --- a/netjsonconfig/backends/raspbian/templates/interfaces.jinja2 +++ b/netjsonconfig/backends/raspbian/templates/interfaces.jinja2 @@ -15,8 +15,8 @@ {% if address.get('gateway', None) != None %} gateway {{ address.get('gateway')}} {% endif %} - {% if address.get('route') != None %} - {% set route = address.get('route')%} + {% if interface.get('route') != None %} + {% set route = interface.get('route')%} post-up route add -net {{ route.get('dest') }} netmask {{ route.get('dest_mask') }} gw {{ route.get('next') }} pre-up route del -net {{ route.get('dest') }} netmask {{ route.get('dest_mask') }} gw {{ route.get('next') }} {% endif %} @@ -34,7 +34,7 @@ address {{ address.get('address') }} netmask {{ address.get('netmask') }} {% if address.get('gateway', None) != None %} - gateway {{ address.get('ipv6gateway') }} + gateway {{ address.get('gateway') }} {% endif %} {% if interface.get('mtu', None) != None %} mtu {{ interface.get('mtu') }} @@ -49,6 +49,11 @@ {% elif address.get('proto') == 'dhcp' %} {% if address.get('family') == 'ipv4'%} iface {{ interface.get('ifname') }} inet {{ address.get('proto') }} + {% if interface.get('route') != None %} + {% set route = interface.get('route')%} + post-up route add -net {{ route.get('dest') }} netmask {{ route.get('dest_mask') }} gw {{ route.get('next') }} + pre-up route del -net {{ route.get('dest') }} netmask {{ route.get('dest_mask') }} gw {{ route.get('next') }} + {% endif %} {% if interface.get('mtu', None) != None %} pre-up /sbin/ifconfig $IFACE mtu {{ interface.get('mtu') }} {% endif %} @@ -69,8 +74,13 @@ {% else %} auto {{ interface.get('ifname') }} - {% if interface.get('iftype') == 'wireless' and interface.get('mode') != 'adhoc' %} + {% if interface.get('iftype') in ['ethernet', 'wireless'] and interface.get('mode') != 'adhoc' %} iface {{ interface.get('ifname') }} inet manual + {% if interface.get('route') != None %} + {% set route = interface.get('route')%} + post-up route add -net {{ route.get('dest') }} netmask {{ route.get('dest_mask') }} gw {{ route.get('next') }} + pre-up route del -net {{ route.get('dest') }} netmask {{ route.get('dest_mask') }} gw {{ route.get('next') }} + {% endif %} {% endif %} {% if interface.get('iftype') == 'bridge' %} bridge_ports {{ interface.get('bridge_members')[0] }} {{ interface.get('bridge_members')[1] }} diff --git a/tests/raspbian/test_routes.py b/tests/raspbian/test_routes.py new file mode 100644 index 000000000..051f3bd05 --- /dev/null +++ b/tests/raspbian/test_routes.py @@ -0,0 +1,73 @@ +import unittest + +from netjsonconfig import Raspbian +from netjsonconfig.utils import _TabsMixin + + +class TestStaticRouteRenderer(unittest.TestCase, _TabsMixin): + + def test_ipv4_manual_route(self): + o = Raspbian({ + "interfaces": [ + { + "name": "eth0", + "type": "ethernet" + } + ], + "routes": [ + { + "device": "eth0", + "destination": "192.168.4.1/24", + "next": "192.168.2.2", + "cost": 2, + }, + ] + }) + + expected = '''# config: /etc/network/interfaces + +auto eth0 +iface eth0 inet manual +post-up route add -net 192.168.4.1 netmask 255.255.255.0 gw 192.168.2.2 +pre-up route del -net 192.168.4.1 netmask 255.255.255.0 gw 192.168.2.2 + +''' + self.assertEqual(o.render(), expected) + + def test_ipv4_static_route(self): + o = Raspbian({ + "interfaces": [ + { + "name": "eth0", + "type": "ethernet", + "addresses": [ + { + "family": "ipv4", + "proto": "static", + "address": "10.0.0.1", + "mask": 28 + } + ] + } + ], + "routes": [ + { + "device": "eth0", + "destination": "192.168.4.1/24", + "next": "192.168.2.2", + "cost": 2, + }, + ] + }) + + expected = '''# config: /etc/network/interfaces + +auto eth0 +iface eth0 inet static +address 10.0.0.1 +netmask 255.255.255.240 +post-up route add -net 192.168.4.1 netmask 255.255.255.0 gw 192.168.2.2 +pre-up route del -net 192.168.4.1 netmask 255.255.255.0 gw 192.168.2.2 + +''' + self.assertEqual(o.render(), expected) From 295828bcf03390461fa0cf7299139df26655fb27 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Thu, 20 Jul 2017 00:18:03 +0530 Subject: [PATCH 094/183] [raspbian] Added support for ipv6 static routes --- .../backends/raspbian/converters/interfaces.py | 4 +++- .../backends/raspbian/templates/interfaces.jinja2 | 15 ++++++++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/netjsonconfig/backends/raspbian/converters/interfaces.py b/netjsonconfig/backends/raspbian/converters/interfaces.py index 9a03c1703..55ed9f188 100644 --- a/netjsonconfig/backends/raspbian/converters/interfaces.py +++ b/netjsonconfig/backends/raspbian/converters/interfaces.py @@ -33,7 +33,9 @@ def to_intermediate(self): route['dest'] = dest route['dest_mask'] = dest_mask del route['destination'] - new_interface.update({'route': route}) + elif ip_network(route.get('next')).version == 6: + route['version'] = 6 + new_interface.update({'route': route}) mac = interface.get('mac', False) if mac: new_interface.update({'mac': mac}) diff --git a/netjsonconfig/backends/raspbian/templates/interfaces.jinja2 b/netjsonconfig/backends/raspbian/templates/interfaces.jinja2 index 13139292f..8b5b8354d 100644 --- a/netjsonconfig/backends/raspbian/templates/interfaces.jinja2 +++ b/netjsonconfig/backends/raspbian/templates/interfaces.jinja2 @@ -36,6 +36,11 @@ {% if address.get('gateway', None) != None %} gateway {{ address.get('gateway') }} {% endif %} + {% if interface.get('route') != None %} + {% set route = interface.get('route')%} + up ip -6 route add {{ route.get('destination') }} via {{ route.get('next')}} dev eth0 + down ip -6 route del {{ route.get('destination') }} via {{ route.get('next')}} dev eth0 + {% endif %} {% if interface.get('mtu', None) != None %} mtu {{ interface.get('mtu') }} {% endif %} @@ -62,6 +67,11 @@ {% endif %} {% elif address.get('family') == 'ipv6' %} iface {{ interface.get('ifname') }} inet6 {{ address.get('proto') }} + {% if interface.get('route') != None %} + {% set route = interface.get('route') %} + up ip -6 route add {{ route.get('destination') }} via {{ route.get('next')}} dev eth0 + down ip -6 route del {{ route.get('destination') }} via {{ route.get('next')}} dev eth0 + {% endif %} {% if interface.get('mtu', None) != None %} pre-up /sbin/ifconfig $IFACE mtu {{ interface.get('mtu') }} {% endif %} @@ -76,10 +86,13 @@ auto {{ interface.get('ifname') }} {% if interface.get('iftype') in ['ethernet', 'wireless'] and interface.get('mode') != 'adhoc' %} iface {{ interface.get('ifname') }} inet manual - {% if interface.get('route') != None %} {% set route = interface.get('route')%} + {% if interface.get('route') != None and route.get('version') == 4 %} post-up route add -net {{ route.get('dest') }} netmask {{ route.get('dest_mask') }} gw {{ route.get('next') }} pre-up route del -net {{ route.get('dest') }} netmask {{ route.get('dest_mask') }} gw {{ route.get('next') }} + {% elif interface.get('route') != None and route.get('version') == 6 %} + up ip -6 route add {{ route.get('destination') }} via {{ route.get('next')}} dev eth0 + down ip -6 route del {{ route.get('destination') }} via {{ route.get('next')}} dev eth0 {% endif %} {% endif %} {% if interface.get('iftype') == 'bridge' %} From 32818d0203cbc81cfe3e59e5c50133d84845c19e Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Thu, 20 Jul 2017 00:18:29 +0530 Subject: [PATCH 095/183] [raspbian] Added tests for static routes --- tests/raspbian/test_routes.py | 67 +++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/tests/raspbian/test_routes.py b/tests/raspbian/test_routes.py index 051f3bd05..f5aa45917 100644 --- a/tests/raspbian/test_routes.py +++ b/tests/raspbian/test_routes.py @@ -69,5 +69,72 @@ def test_ipv4_static_route(self): post-up route add -net 192.168.4.1 netmask 255.255.255.0 gw 192.168.2.2 pre-up route del -net 192.168.4.1 netmask 255.255.255.0 gw 192.168.2.2 +''' + self.assertEqual(o.render(), expected) + + def test_ipv6_manual_route(self): + o = Raspbian({ + "interfaces": [ + { + "name": "eth0", + "type": "ethernet" + } + ], + "routes": [ + { + "device": "eth0", + "destination": "fd89::1/128", + "next": "fd88::1", + "cost": 0, + } + ] + }) + + expected = '''# config: /etc/network/interfaces + +auto eth0 +iface eth0 inet manual +up ip -6 route add fd89::1/128 via fd88::1 dev eth0 +down ip -6 route del fd89::1/128 via fd88::1 dev eth0 + +''' + + self.assertEqual(o.render(), expected) + + def test_ipv6_static_route(self): + o = Raspbian({ + "interfaces": [ + { + "name": "eth0", + "type": "ethernet", + "addresses": [ + { + "family": "ipv6", + "proto": "static", + "address": "fe80::ba27:ebff:fe1c:5477", + "mask": 64 + } + ] + } + ], + "routes": [ + { + "device": "eth0", + "destination": "fd89::1/128", + "next": "fd88::1", + "cost": 0, + } + ] + }) + + expected = '''# config: /etc/network/interfaces + +auto eth0 +iface eth0 inet6 static +address fe80::ba27:ebff:fe1c:5477 +netmask 64 +up ip -6 route add fd89::1/128 via fd88::1 dev eth0 +down ip -6 route del fd89::1/128 via fd88::1 dev eth0 + ''' self.assertEqual(o.render(), expected) From c8558a92d84303dd28ba41d081a6364c49fbefc5 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Thu, 20 Jul 2017 01:47:57 +0530 Subject: [PATCH 096/183] [raspbian] Simplifed jinja2 templates --- .../raspbian/templates/hostapd.jinja2 | 52 ++--- .../raspbian/templates/hostname.jinja2 | 14 +- .../raspbian/templates/interfaces.jinja2 | 214 +++++++++--------- .../backends/raspbian/templates/ntp.jinja2 | 14 +- .../backends/raspbian/templates/resolv.jinja2 | 29 +-- 5 files changed, 150 insertions(+), 173 deletions(-) diff --git a/netjsonconfig/backends/raspbian/templates/hostapd.jinja2 b/netjsonconfig/backends/raspbian/templates/hostapd.jinja2 index 3ca70370c..aca7b6eb2 100644 --- a/netjsonconfig/backends/raspbian/templates/hostapd.jinja2 +++ b/netjsonconfig/backends/raspbian/templates/hostapd.jinja2 @@ -1,30 +1,26 @@ -{% for i, j in data.items() %} - {% if i|string() == 'wireless' %} - {% for wireless in j %} - # config: /etc/hostapd/hostapd.conf - - interface={{ wireless.get('ifname') }} - driver=nl80211 - {% if wireless.get('protocol') == 'a' or 'b' or 'g' %} - hw_mode={{ wireless.get('hwmode')}} - {% endif %} - channel={{ wireless.get('channel')}} - {% if wireless.get('protocol') == '80211n' %} - ieee80211n=1 - {% endif %} - {% if wireless.get('protocol') == '80211ac' %} - ieee80211ac=1 - {% endif %} - ssid={{ wireless.get('ssid') }} - {% if wireless.get('encryption') != {} %} - auth_algs={{ wireless.get('encryption').get('auth_algs') }} - wpa={{ wireless.get('encryption').get('wpa') }} - wpa_key_mgmt={{ wireless.get('encryption').get('wpa_key_mgmt') }} - wpa_passphrase={{ wireless.get('encryption').get('wpa_passphrase') }} - {% if wireless.get('encryption', None).get('wpa_pairwise') != 'AUTO' %} - wpa_pairwise={{ wireless.get('encryption').get('wpa_pairwise')}} - {% endif %} - {% endif %} - {% endfor %} +{% for wireless in data.wireless %} + # config: /etc/hostapd/hostapd.conf + + interface={{ wireless.get('ifname') }} + driver=nl80211 + {% if wireless.get('protocol') == 'a' or 'b' or 'g' %} + hw_mode={{ wireless.get('hwmode')}} + {% endif %} + channel={{ wireless.get('channel')}} + {% if wireless.get('protocol') == '80211n' %} + ieee80211n=1 + {% endif %} + {% if wireless.get('protocol') == '80211ac' %} + ieee80211ac=1 + {% endif %} + ssid={{ wireless.get('ssid') }} + {% if wireless.get('encryption') != {} %} + auth_algs={{ wireless.get('encryption').get('auth_algs') }} + wpa={{ wireless.get('encryption').get('wpa') }} + wpa_key_mgmt={{ wireless.get('encryption').get('wpa_key_mgmt') }} + wpa_passphrase={{ wireless.get('encryption').get('wpa_passphrase') }} + {% if wireless.get('encryption', None).get('wpa_pairwise') != 'AUTO' %} + wpa_pairwise={{ wireless.get('encryption').get('wpa_pairwise')}} + {% endif %} {% endif %} {% endfor %} diff --git a/netjsonconfig/backends/raspbian/templates/hostname.jinja2 b/netjsonconfig/backends/raspbian/templates/hostname.jinja2 index 9d9b80164..6c1df440f 100644 --- a/netjsonconfig/backends/raspbian/templates/hostname.jinja2 +++ b/netjsonconfig/backends/raspbian/templates/hostname.jinja2 @@ -1,12 +1,8 @@ -{% for i, j in data.items() %} - {% if i|string() == 'general' %} - {% for general in j %} - {% if general.get('hostname') %} - # config: /etc/hostname - - {{ general.get('hostname') }} +{% for general in data.general %} + {% if general.get('hostname') %} + # config: /etc/hostname + + {{ general.get('hostname') }} - {% endif %} - {% endfor %} {% endif %} {% endfor %} diff --git a/netjsonconfig/backends/raspbian/templates/interfaces.jinja2 b/netjsonconfig/backends/raspbian/templates/interfaces.jinja2 index 8b5b8354d..abda34457 100644 --- a/netjsonconfig/backends/raspbian/templates/interfaces.jinja2 +++ b/netjsonconfig/backends/raspbian/templates/interfaces.jinja2 @@ -1,114 +1,110 @@ -{% for i, j in data.items() %} - {% if i|string() == 'interfaces' %} - {% for interface in j %} - {% if interface.get('iftype') in ['ethernet', 'bridge', 'loopback', 'wireless'] %} - # config: /etc/network/interfaces - {% if interface.get('address') != None %} +{% for interface in data.interfaces %} + {% if interface.get('iftype') in ['ethernet', 'bridge', 'loopback', 'wireless'] %} + # config: /etc/network/interfaces + {% if interface.get('address') != None %} - auto {{ interface.get('ifname') }} - {% for address in interface.get('address') %} - {% if address.get('proto') == 'static' %} - {% if address.get('family') == 'ipv4' %} - iface {{ interface.get('ifname') }} inet {{ address.get('proto') }} - address {{ address.get('address') }} - netmask {{ address.get('netmask') }} - {% if address.get('gateway', None) != None %} - gateway {{ address.get('gateway')}} - {% endif %} - {% if interface.get('route') != None %} - {% set route = interface.get('route')%} - post-up route add -net {{ route.get('dest') }} netmask {{ route.get('dest_mask') }} gw {{ route.get('next') }} - pre-up route del -net {{ route.get('dest') }} netmask {{ route.get('dest_mask') }} gw {{ route.get('next') }} - {% endif %} - {% if interface.get('mtu', None) != None %} - mtu {{ interface.get('mtu') }} - {% endif %} - {% if interface.get('mac', None) != None %} - hwaddress {{ interface.get('mac') }} - {% endif %} - {% if interface.get('iftype') == 'bridge' %} - bridge_ports {{ interface.get('bridge_members')[0] }} {{ interface.get('bridge_members')[1] }} - {% endif %} - {% elif address.get('family') == 'ipv6' %} - iface {{ interface.get('ifname') }} inet6 {{ address.get('proto') }} - address {{ address.get('address') }} - netmask {{ address.get('netmask') }} - {% if address.get('gateway', None) != None %} - gateway {{ address.get('gateway') }} - {% endif %} - {% if interface.get('route') != None %} - {% set route = interface.get('route')%} - up ip -6 route add {{ route.get('destination') }} via {{ route.get('next')}} dev eth0 - down ip -6 route del {{ route.get('destination') }} via {{ route.get('next')}} dev eth0 - {% endif %} - {% if interface.get('mtu', None) != None %} - mtu {{ interface.get('mtu') }} - {% endif %} - {% if interface.get('mac', None) != None %} - hwaddress {{ interface.get('mac') }} - {% endif %} - {% if interface.get('iftype') == 'bridge' %} - bridge_ports {{ interface.get('bridge_members')[0] }} {{ interface.get('bridge_members')[1] }} - {% endif %} - {% endif %} - {% elif address.get('proto') == 'dhcp' %} - {% if address.get('family') == 'ipv4'%} - iface {{ interface.get('ifname') }} inet {{ address.get('proto') }} - {% if interface.get('route') != None %} - {% set route = interface.get('route')%} - post-up route add -net {{ route.get('dest') }} netmask {{ route.get('dest_mask') }} gw {{ route.get('next') }} - pre-up route del -net {{ route.get('dest') }} netmask {{ route.get('dest_mask') }} gw {{ route.get('next') }} - {% endif %} - {% if interface.get('mtu', None) != None %} - pre-up /sbin/ifconfig $IFACE mtu {{ interface.get('mtu') }} - {% endif %} - {% if interface.get('mac', None) != None %} - hwaddress {{ interface.get('mac') }} - {% endif %} - {% elif address.get('family') == 'ipv6' %} - iface {{ interface.get('ifname') }} inet6 {{ address.get('proto') }} - {% if interface.get('route') != None %} - {% set route = interface.get('route') %} - up ip -6 route add {{ route.get('destination') }} via {{ route.get('next')}} dev eth0 - down ip -6 route del {{ route.get('destination') }} via {{ route.get('next')}} dev eth0 - {% endif %} - {% if interface.get('mtu', None) != None %} - pre-up /sbin/ifconfig $IFACE mtu {{ interface.get('mtu') }} - {% endif %} - {% if interface.get('mac', None) != None %} - hwaddress {{ interface.get('mac') }} - {% endif %} - {% endif %} - {% endif%} - {% endfor %} - {% else %} - - auto {{ interface.get('ifname') }} - {% if interface.get('iftype') in ['ethernet', 'wireless'] and interface.get('mode') != 'adhoc' %} - iface {{ interface.get('ifname') }} inet manual - {% set route = interface.get('route')%} - {% if interface.get('route') != None and route.get('version') == 4 %} - post-up route add -net {{ route.get('dest') }} netmask {{ route.get('dest_mask') }} gw {{ route.get('next') }} - pre-up route del -net {{ route.get('dest') }} netmask {{ route.get('dest_mask') }} gw {{ route.get('next') }} - {% elif interface.get('route') != None and route.get('version') == 6 %} - up ip -6 route add {{ route.get('destination') }} via {{ route.get('next')}} dev eth0 - down ip -6 route del {{ route.get('destination') }} via {{ route.get('next')}} dev eth0 - {% endif %} - {% endif %} - {% if interface.get('iftype') == 'bridge' %} - bridge_ports {{ interface.get('bridge_members')[0] }} {{ interface.get('bridge_members')[1] }} + auto {{ interface.get('ifname') }} + {% for address in interface.get('address') %} + {% if address.get('proto') == 'static' %} + {% if address.get('family') == 'ipv4' %} + iface {{ interface.get('ifname') }} inet {{ address.get('proto') }} + address {{ address.get('address') }} + netmask {{ address.get('netmask') }} + {% if address.get('gateway', None) != None %} + gateway {{ address.get('gateway')}} + {% endif %} + {% if interface.get('route') != None %} + {% set route = interface.get('route')%} + post-up route add -net {{ route.get('dest') }} netmask {{ route.get('dest_mask') }} gw {{ route.get('next') }} + pre-up route del -net {{ route.get('dest') }} netmask {{ route.get('dest_mask') }} gw {{ route.get('next') }} + {% endif %} + {% if interface.get('mtu', None) != None %} + mtu {{ interface.get('mtu') }} + {% endif %} + {% if interface.get('mac', None) != None %} + hwaddress {{ interface.get('mac') }} + {% endif %} + {% if interface.get('iftype') == 'bridge' %} + bridge_ports {{ interface.get('bridge_members')[0] }} {{ interface.get('bridge_members')[1] }} + {% endif %} + {% elif address.get('family') == 'ipv6' %} + iface {{ interface.get('ifname') }} inet6 {{ address.get('proto') }} + address {{ address.get('address') }} + netmask {{ address.get('netmask') }} + {% if address.get('gateway', None) != None %} + gateway {{ address.get('gateway') }} + {% endif %} + {% if interface.get('route') != None %} + {% set route = interface.get('route')%} + up ip -6 route add {{ route.get('destination') }} via {{ route.get('next')}} dev eth0 + down ip -6 route del {{ route.get('destination') }} via {{ route.get('next')}} dev eth0 + {% endif %} + {% if interface.get('mtu', None) != None %} + mtu {{ interface.get('mtu') }} + {% endif %} + {% if interface.get('mac', None) != None %} + hwaddress {{ interface.get('mac') }} + {% endif %} + {% if interface.get('iftype') == 'bridge' %} + bridge_ports {{ interface.get('bridge_members')[0] }} {{ interface.get('bridge_members')[1] }} + {% endif %} {% endif %} - {% if interface.get('mode') == 'adhoc' %} - iface {{ interface.get('ifname') }} inet static - address 172.128.1.1 - netmask 255.255.255.0 - wireless-channel 1 - wireless-essid {{ interface.get('essid') }} - wireless-mode ad-hoc + {% elif address.get('proto') == 'dhcp' %} + {% if address.get('family') == 'ipv4'%} + iface {{ interface.get('ifname') }} inet {{ address.get('proto') }} + {% if interface.get('route') != None %} + {% set route = interface.get('route')%} + post-up route add -net {{ route.get('dest') }} netmask {{ route.get('dest_mask') }} gw {{ route.get('next') }} + pre-up route del -net {{ route.get('dest') }} netmask {{ route.get('dest_mask') }} gw {{ route.get('next') }} + {% endif %} + {% if interface.get('mtu', None) != None %} + pre-up /sbin/ifconfig $IFACE mtu {{ interface.get('mtu') }} + {% endif %} + {% if interface.get('mac', None) != None %} + hwaddress {{ interface.get('mac') }} + {% endif %} + {% elif address.get('family') == 'ipv6' %} + iface {{ interface.get('ifname') }} inet6 {{ address.get('proto') }} + {% if interface.get('route') != None %} + {% set route = interface.get('route') %} + up ip -6 route add {{ route.get('destination') }} via {{ route.get('next')}} dev eth0 + down ip -6 route del {{ route.get('destination') }} via {{ route.get('next')}} dev eth0 + {% endif %} + {% if interface.get('mtu', None) != None %} + pre-up /sbin/ifconfig $IFACE mtu {{ interface.get('mtu') }} + {% endif %} + {% if interface.get('mac', None) != None %} + hwaddress {{ interface.get('mac') }} + {% endif %} {% endif %} - {% endif %} - {% endif %} + {% endif%} + {% endfor %} + {% else %} - {% endfor %} + auto {{ interface.get('ifname') }} + {% if interface.get('iftype') in ['ethernet', 'wireless'] and interface.get('mode') != 'adhoc' %} + iface {{ interface.get('ifname') }} inet manual + {% set route = interface.get('route')%} + {% if interface.get('route') != None and route.get('version') == 4 %} + post-up route add -net {{ route.get('dest') }} netmask {{ route.get('dest_mask') }} gw {{ route.get('next') }} + pre-up route del -net {{ route.get('dest') }} netmask {{ route.get('dest_mask') }} gw {{ route.get('next') }} + {% elif interface.get('route') != None and route.get('version') == 6 %} + up ip -6 route add {{ route.get('destination') }} via {{ route.get('next')}} dev eth0 + down ip -6 route del {{ route.get('destination') }} via {{ route.get('next')}} dev eth0 + {% endif %} + {% endif %} + {% if interface.get('iftype') == 'bridge' %} + bridge_ports {{ interface.get('bridge_members')[0] }} {{ interface.get('bridge_members')[1] }} + {% endif %} + {% if interface.get('mode') == 'adhoc' %} + iface {{ interface.get('ifname') }} inet static + address 172.128.1.1 + netmask 255.255.255.0 + wireless-channel 1 + wireless-essid {{ interface.get('essid') }} + wireless-mode ad-hoc + {% endif %} + {% endif %} {% endif %} -{% endfor%} + +{% endfor %} diff --git a/netjsonconfig/backends/raspbian/templates/ntp.jinja2 b/netjsonconfig/backends/raspbian/templates/ntp.jinja2 index 491869941..c4af56457 100644 --- a/netjsonconfig/backends/raspbian/templates/ntp.jinja2 +++ b/netjsonconfig/backends/raspbian/templates/ntp.jinja2 @@ -1,9 +1,7 @@ -{% for i, j in data.items() %} - {% if i|string() == 'ntp' %} - # config: /etc/ntp.conf - - {% for server in j %} - server {{ server }} - {% endfor %} - {% endif %} +{% if data.ntp %} +# config: /etc/ntp.conf + +{% endif %} +{% for ntp in data.ntp %} + server {{ ntp }} {% endfor %} diff --git a/netjsonconfig/backends/raspbian/templates/resolv.jinja2 b/netjsonconfig/backends/raspbian/templates/resolv.jinja2 index 68845b800..13d8224ff 100644 --- a/netjsonconfig/backends/raspbian/templates/resolv.jinja2 +++ b/netjsonconfig/backends/raspbian/templates/resolv.jinja2 @@ -1,19 +1,10 @@ -{% set count = [1] %} - {% for i, j in data.items() %} - {% if i|string() in ['dns_servers', 'dns_search'] %} - {% if count == [1] %} - # config: /etc/resolv.conf - - {% if count.append(count.pop() + 1) %}{% endif %} - {% endif %} - {% endif %} - {% if i|string() == 'dns_servers' %} - {% for ip in j %} - nameserver {{ ip }} - {% endfor %} - {% elif i|string() == 'dns_search' %} - {% for domain in j %} - search {{ domain }} - {% endfor %} - {% endif %} -{% endfor%} +{% if data.dns_servers or data.dns_search %} +# config: /etc/resolv.conf + +{% endif %} +{% for ip in data.dns_servers %} + nameserver {{ ip }} +{% endfor %} +{% for domain in data.dns_search %} + search {{ domain }} +{% endfor %} From 2cfdf6e090b5a29e7f738fded82f5e2aeda14b21 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Thu, 20 Jul 2017 13:59:37 +0530 Subject: [PATCH 097/183] [raspbian] Removed extra argument --- netjsonconfig/backends/raspbian/converters/interfaces.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/netjsonconfig/backends/raspbian/converters/interfaces.py b/netjsonconfig/backends/raspbian/converters/interfaces.py index 55ed9f188..27c785551 100644 --- a/netjsonconfig/backends/raspbian/converters/interfaces.py +++ b/netjsonconfig/backends/raspbian/converters/interfaces.py @@ -20,7 +20,7 @@ def to_intermediate(self): 'iftype': iftype }) if iftype in ['ethernet', 'bridge', 'loopback', 'wireless']: - addresses = self._get_address(interface, routes) + addresses = self._get_address(interface) new_interface.update({ 'address': addresses }) @@ -61,7 +61,7 @@ def to_intermediate(self): result.append(new_interface) return (('interfaces', result),) - def _get_address(self, interface, routes): + def _get_address(self, interface): addresses = interface.get('addresses', False) if addresses: for address in addresses: From 6b8b59cd0be1a3cab0f4b4d9754122be31a10fbb Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Thu, 20 Jul 2017 14:04:23 +0530 Subject: [PATCH 098/183] [raspbian] Removed wps test --- tests/raspbian/test_hostapd.py | 36 ---------------------------------- 1 file changed, 36 deletions(-) diff --git a/tests/raspbian/test_hostapd.py b/tests/raspbian/test_hostapd.py index b092911df..d027b94ef 100644 --- a/tests/raspbian/test_hostapd.py +++ b/tests/raspbian/test_hostapd.py @@ -267,39 +267,3 @@ def test_no_encryption(self): ''' self.assertEqual(o.render(), expected) - - @unittest.skip('Test skipping') - def test_wps(self): - o = Raspbian({ - "radios": [ - { - "name": "radio0", - "phy": "phy0", - "driver": "mac80211", - "protocol": "802.11n", - "channel": 3, - "channel_width": 20, - "tx_power": 3 - }, - ], - "interfaces": [ - { - "name": "wlan0", - "type": "wireless", - "wireless": { - "radio": "radio0", - "mode": "access_point", - "ssid": "wps-ssid", - "encryption": { - "protocol": "wps", - "wps_label": False, - "wps_pushbutton": True, - "wps_pin": "" - } - } - } - ] - }) - - expected = '''''' - self.assertEqual(o.render(), expected) From 67a94cadf584043c7069c3136cf300e38866f482 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Thu, 20 Jul 2017 16:12:48 +0530 Subject: [PATCH 099/183] [raspbian] Reduced complexity of Interfaces converter --- .../raspbian/converters/interfaces.py | 101 ++++++++++-------- 1 file changed, 54 insertions(+), 47 deletions(-) diff --git a/netjsonconfig/backends/raspbian/converters/interfaces.py b/netjsonconfig/backends/raspbian/converters/interfaces.py index 27c785551..bf335cfa8 100644 --- a/netjsonconfig/backends/raspbian/converters/interfaces.py +++ b/netjsonconfig/backends/raspbian/converters/interfaces.py @@ -10,56 +10,50 @@ class Interfaces(RaspbianConverter): def to_intermediate(self): result = [] interfaces = get_copy(self.netjson, self.netjson_key) - routes = get_copy(self.netjson, 'routes') for interface in interfaces: - new_interface = {} - ifname = interface.get('name') - iftype = interface.get('type') + result.append(self._get_interface(interface)) + return (('interfaces', result),) + + def _get_interface(self, interface): + new_interface = {} + ifname = interface.get('name') + iftype = interface.get('type') + new_interface.update({ + 'ifname': ifname, + 'iftype': iftype + }) + if iftype in ['ethernet', 'bridge', 'loopback', 'wireless']: + addresses = self._get_address(interface) new_interface.update({ - 'ifname': ifname, - 'iftype': iftype + 'address': addresses }) - if iftype in ['ethernet', 'bridge', 'loopback', 'wireless']: - addresses = self._get_address(interface) - new_interface.update({ - 'address': addresses - }) - if routes: - for route in routes: - if ip_network(route.get('next')).version == 4: - route['version'] = 4 - destination = IPv4Interface(route['destination']).with_netmask - dest, dest_mask = destination.split('/') - route['dest'] = dest - route['dest_mask'] = dest_mask - del route['destination'] - elif ip_network(route.get('next')).version == 6: - route['version'] = 6 - new_interface.update({'route': route}) - mac = interface.get('mac', False) - if mac: - new_interface.update({'mac': mac}) - mtu = interface.get('mtu', False) - if mtu: - new_interface.update({'mtu': mtu}) - txqueuelen = interface.get('txqueuelen', False) - if txqueuelen: - new_interface.update({'txqueuelen': txqueuelen}) - autostart = interface.get('autostart', False) - if autostart: - new_interface.update({'autostart': autostart}) - if iftype == 'wireless' and interface.get('wireless').get('mode') == 'adhoc': - wireless = interface.get('wireless') - new_interface.update({ - 'essid': wireless.get('ssid'), - 'mode': wireless.get('mode') - }) - if iftype == 'bridge': - new_interface.update({ - 'bridge_members': interface.get('bridge_members') - }) - result.append(new_interface) - return (('interfaces', result),) + routes = get_copy(self.netjson, 'routes') + if routes: + route = self._get_route(routes) + new_interface.update({'route': route}) + mac = interface.get('mac', False) + if mac: + new_interface.update({'mac': mac}) + mtu = interface.get('mtu', False) + if mtu: + new_interface.update({'mtu': mtu}) + txqueuelen = interface.get('txqueuelen', False) + if txqueuelen: + new_interface.update({'txqueuelen': txqueuelen}) + autostart = interface.get('autostart', False) + if autostart: + new_interface.update({'autostart': autostart}) + if iftype == 'wireless' and interface.get('wireless').get('mode') == 'adhoc': + wireless = interface.get('wireless') + new_interface.update({ + 'essid': wireless.get('ssid'), + 'mode': wireless.get('mode') + }) + if iftype == 'bridge': + new_interface.update({ + 'bridge_members': interface.get('bridge_members') + }) + return new_interface def _get_address(self, interface): addresses = interface.get('addresses', False) @@ -75,3 +69,16 @@ def _get_address(self, interface): address['netmask'] = address['mask'] del address['mask'] return addresses + + def _get_route(self, routes): + for route in routes: + if ip_network(route.get('next')).version == 4: + route['version'] = 4 + destination = IPv4Interface(route['destination']).with_netmask + dest, dest_mask = destination.split('/') + route['dest'] = dest + route['dest_mask'] = dest_mask + del route['destination'] + elif ip_network(route.get('next')).version == 6: + route['version'] = 6 + return route From 712a0f690740a40cd5a831a1fe0c1e11401c237c Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Thu, 20 Jul 2017 20:56:18 +0530 Subject: [PATCH 100/183] [raspbian] Fixed interfaces jinja2 template --- .../backends/raspbian/templates/interfaces.jinja2 | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/netjsonconfig/backends/raspbian/templates/interfaces.jinja2 b/netjsonconfig/backends/raspbian/templates/interfaces.jinja2 index abda34457..cacdc78ea 100644 --- a/netjsonconfig/backends/raspbian/templates/interfaces.jinja2 +++ b/netjsonconfig/backends/raspbian/templates/interfaces.jinja2 @@ -1,8 +1,10 @@ +{% if data.interfaces %} +# config: /etc/network/interfaces + +{% endif%} {% for interface in data.interfaces %} {% if interface.get('iftype') in ['ethernet', 'bridge', 'loopback', 'wireless'] %} - # config: /etc/network/interfaces {% if interface.get('address') != None %} - auto {{ interface.get('ifname') }} {% for address in interface.get('address') %} {% if address.get('proto') == 'static' %} @@ -80,7 +82,6 @@ {% endif%} {% endfor %} {% else %} - auto {{ interface.get('ifname') }} {% if interface.get('iftype') in ['ethernet', 'wireless'] and interface.get('mode') != 'adhoc' %} iface {{ interface.get('ifname') }} inet manual From 2f3cfda173b511ea7d7fc3a33fe46995f47483a6 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Thu, 20 Jul 2017 20:57:06 +0530 Subject: [PATCH 101/183] [raspbian] Refactored template --- .../backends/raspbian/templates/commands.jinja2 | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/netjsonconfig/backends/raspbian/templates/commands.jinja2 b/netjsonconfig/backends/raspbian/templates/commands.jinja2 index c0df22fb5..e85d6d072 100644 --- a/netjsonconfig/backends/raspbian/templates/commands.jinja2 +++ b/netjsonconfig/backends/raspbian/templates/commands.jinja2 @@ -1,11 +1,7 @@ -{% for i, j in data.items() %} - {% if i|string() == 'general' %} - {% for general in j %} - {% if general.get('timezone') %} - run commands: - $ timedatectl set-timezone {{ general.get('timezone') }} +{% for general in data.general %} + {% if general.get('timezone') %} + run commands: + $ timedatectl set-timezone {{ general.get('timezone') }} - {% endif %} - {% endfor %} {% endif %} {% endfor%} From c7d65226ddeb45ce3ca7a040320e3f1ba558926f Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Thu, 20 Jul 2017 20:57:45 +0530 Subject: [PATCH 102/183] [raspbian] Added multi interfaces tests --- tests/raspbian/test_interfaces.py | 219 +++++++++++++++++++++++++++++- 1 file changed, 214 insertions(+), 5 deletions(-) diff --git a/tests/raspbian/test_interfaces.py b/tests/raspbian/test_interfaces.py index ee9598031..f6a25644c 100644 --- a/tests/raspbian/test_interfaces.py +++ b/tests/raspbian/test_interfaces.py @@ -6,6 +6,51 @@ class TestInterfacesRenderer(unittest.TestCase, _TabsMixin): + def test_no_ip(self): + o = Raspbian({ + "interfaces": [ + { + "name": "eth0", + "type": "ethernet" + } + ] + }) + + expected = """# config: /etc/network/interfaces + +auto eth0 +iface eth0 inet manual + +""" + + self.assertEqual(o.render(), expected) + + def test_multi_no_ip(self): + o = Raspbian({ + "interfaces": [ + { + "name": "eth0", + "type": "ethernet" + }, + { + "name": "eth1", + "type": "ethernet" + } + ] + }) + + expected = """# config: /etc/network/interfaces + +auto eth0 +iface eth0 inet manual + +auto eth1 +iface eth1 inet manual + +""" + + self.assertEqual(o.render(), expected) + def test_ipv4_static(self): o = Raspbian({ "interfaces": [ @@ -31,6 +76,79 @@ def test_ipv4_static(self): address 10.0.0.1 netmask 255.255.255.240 +''' + self.assertEqual(o.render(), expected) + + def test_multi_ipv4_static(self): + o = Raspbian({ + "interfaces": [ + { + "name": "eth0", + "type": "ethernet", + "addresses": [ + { + "family": "ipv4", + "proto": "static", + "address": "10.0.0.1", + "mask": 28 + } + ] + }, + { + "name": "eth1", + "type": "ethernet", + "addresses": [ + { + "family": "ipv4", + "proto": "static", + "address": "10.0.0.2", + "mask": 28 + } + ] + } + ] + }) + + expected = '''# config: /etc/network/interfaces + +auto eth0 +iface eth0 inet static +address 10.0.0.1 +netmask 255.255.255.240 + +auto eth1 +iface eth1 inet static +address 10.0.0.2 +netmask 255.255.255.240 + +''' + self.assertEqual(o.render(), expected) + + def test_ipv6_static(self): + o = Raspbian({ + "interfaces": [ + { + "name": "eth0", + "type": "ethernet", + "addresses": [ + { + "family": "ipv6", + "proto": "static", + "address": "fe80::ba27:ebff:fe1c:5477", + "mask": 64 + } + ] + } + ] + }) + + expected = '''# config: /etc/network/interfaces + +auto eth0 +iface eth0 inet6 static +address fe80::ba27:ebff:fe1c:5477 +netmask 64 + ''' self.assertEqual(o.render(), expected) @@ -48,6 +166,18 @@ def test_ipv6_static(self): "mask": 64 } ] + }, + { + "name": "eth1", + "type": "ethernet", + "addresses": [ + { + "family": "ipv6", + "proto": "static", + "address": "2001:db8:0:0:0:ff00:42:8329", + "mask": 64 + } + ] } ] }) @@ -59,6 +189,11 @@ def test_ipv6_static(self): address fe80::ba27:ebff:fe1c:5477 netmask 64 +auto eth1 +iface eth1 inet6 static +address 2001:db8:0:0:0:ff00:42:8329 +netmask 64 + ''' self.assertEqual(o.render(), expected) @@ -120,6 +255,43 @@ def test_ipv4_dhcp(self): auto eth0 iface eth0 inet dhcp +''' + self.assertEqual(o.render(), expected) + + def test_multi_ipv4_dhcp(self): + o = Raspbian({ + "interfaces": [ + { + "name": "eth0", + "type": "ethernet", + "addresses": [ + { + "proto": "dhcp", + "family": "ipv4" + } + ] + }, + { + "name": "eth1", + "type": "ethernet", + "addresses": [ + { + "proto": "dhcp", + "family": "ipv4" + } + ] + } + ] + }) + + expected = '''# config: /etc/network/interfaces + +auto eth0 +iface eth0 inet dhcp + +auto eth1 +iface eth1 inet dhcp + ''' self.assertEqual(o.render(), expected) @@ -144,6 +316,43 @@ def test_ipv6_dhcp(self): auto eth0 iface eth0 inet6 dhcp +''' + self.assertEqual(o.render(), expected) + + def test_ipv6_dhcp(self): + o = Raspbian({ + "interfaces": [ + { + "name": "eth0", + "type": "ethernet", + "addresses": [ + { + "proto": "dhcp", + "family": "ipv6" + } + ] + }, + { + "name": "eth1", + "type": "ethernet", + "addresses": [ + { + "proto": "dhcp", + "family": "ipv6" + } + ] + } + ] + }) + + expected = '''# config: /etc/network/interfaces + +auto eth0 +iface eth0 inet6 dhcp + +auto eth1 +iface eth1 inet6 dhcp + ''' self.assertEqual(o.render(), expected) @@ -181,7 +390,7 @@ def test_multiple_ip(self): o = Raspbian({ "interfaces": [ { - "name": "eth0.1", + "name": "eth0", "type": "ethernet", "autostart": True, "addresses": [ @@ -210,14 +419,14 @@ def test_multiple_ip(self): expected = '''# config: /etc/network/interfaces -auto eth0.1 -iface eth0.1 inet static +auto eth0 +iface eth0 inet static address 192.168.1.1 netmask 255.255.255.0 -iface eth0.1 inet static +iface eth0 inet static address 192.168.2.1 netmask 255.255.255.0 -iface eth0.1 inet6 static +iface eth0 inet6 static address fd87::1 netmask 128 From fcb45cb3f87a156bfbf5c5e06bb182c1d1aa3335 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Fri, 21 Jul 2017 02:29:21 +0530 Subject: [PATCH 103/183] [raspbian] Improved readability of templates --- .../raspbian/templates/hostapd.jinja2 | 28 +-- .../raspbian/templates/hostname.jinja2 | 12 +- .../raspbian/templates/interfaces.jinja2 | 164 +++++++++--------- 3 files changed, 101 insertions(+), 103 deletions(-) diff --git a/netjsonconfig/backends/raspbian/templates/hostapd.jinja2 b/netjsonconfig/backends/raspbian/templates/hostapd.jinja2 index aca7b6eb2..9f715671f 100644 --- a/netjsonconfig/backends/raspbian/templates/hostapd.jinja2 +++ b/netjsonconfig/backends/raspbian/templates/hostapd.jinja2 @@ -1,26 +1,26 @@ {% for wireless in data.wireless %} # config: /etc/hostapd/hostapd.conf - interface={{ wireless.get('ifname') }} + interface={{ wireless.ifname }} driver=nl80211 - {% if wireless.get('protocol') == 'a' or 'b' or 'g' %} - hw_mode={{ wireless.get('hwmode')}} + {% if wireless.protocol == 'a' or 'b' or 'g' %} + hw_mode={{ wireless.hwmode }} {% endif %} - channel={{ wireless.get('channel')}} - {% if wireless.get('protocol') == '80211n' %} + channel={{ wireless.channel }} + {% if wireless.protocol == '80211n' %} ieee80211n=1 {% endif %} - {% if wireless.get('protocol') == '80211ac' %} + {% if wireless.protocol == '80211ac' %} ieee80211ac=1 {% endif %} - ssid={{ wireless.get('ssid') }} - {% if wireless.get('encryption') != {} %} - auth_algs={{ wireless.get('encryption').get('auth_algs') }} - wpa={{ wireless.get('encryption').get('wpa') }} - wpa_key_mgmt={{ wireless.get('encryption').get('wpa_key_mgmt') }} - wpa_passphrase={{ wireless.get('encryption').get('wpa_passphrase') }} - {% if wireless.get('encryption', None).get('wpa_pairwise') != 'AUTO' %} - wpa_pairwise={{ wireless.get('encryption').get('wpa_pairwise')}} + ssid={{ wireless.ssid }} + {% if wireless.encryption %} + auth_algs={{ wireless.encryption.auth_algs }} + wpa={{ wireless.encryption.wpa }} + wpa_key_mgmt={{ wireless.encryption.wpa_key_mgmt }} + wpa_passphrase={{ wireless.encryption.wpa_passphrase }} + {% if wireless.encryption.wpa_pairwise != 'AUTO' %} + wpa_pairwise={{ wireless.encryption.wpa_pairwise }} {% endif %} {% endif %} {% endfor %} diff --git a/netjsonconfig/backends/raspbian/templates/hostname.jinja2 b/netjsonconfig/backends/raspbian/templates/hostname.jinja2 index 6c1df440f..d7ae654a9 100644 --- a/netjsonconfig/backends/raspbian/templates/hostname.jinja2 +++ b/netjsonconfig/backends/raspbian/templates/hostname.jinja2 @@ -1,8 +1,6 @@ -{% for general in data.general %} - {% if general.get('hostname') %} - # config: /etc/hostname +{% if data.general and data.general[0].hostname %} + # config: /etc/hostname - {{ general.get('hostname') }} - - {% endif %} -{% endfor %} + {{ data.general[0].hostname }} + +{% endif %} \ No newline at end of file diff --git a/netjsonconfig/backends/raspbian/templates/interfaces.jinja2 b/netjsonconfig/backends/raspbian/templates/interfaces.jinja2 index cacdc78ea..c860e9825 100644 --- a/netjsonconfig/backends/raspbian/templates/interfaces.jinja2 +++ b/netjsonconfig/backends/raspbian/templates/interfaces.jinja2 @@ -3,106 +3,106 @@ {% endif%} {% for interface in data.interfaces %} - {% if interface.get('iftype') in ['ethernet', 'bridge', 'loopback', 'wireless'] %} - {% if interface.get('address') != None %} - auto {{ interface.get('ifname') }} - {% for address in interface.get('address') %} - {% if address.get('proto') == 'static' %} - {% if address.get('family') == 'ipv4' %} - iface {{ interface.get('ifname') }} inet {{ address.get('proto') }} - address {{ address.get('address') }} - netmask {{ address.get('netmask') }} - {% if address.get('gateway', None) != None %} - gateway {{ address.get('gateway')}} - {% endif %} - {% if interface.get('route') != None %} - {% set route = interface.get('route')%} - post-up route add -net {{ route.get('dest') }} netmask {{ route.get('dest_mask') }} gw {{ route.get('next') }} - pre-up route del -net {{ route.get('dest') }} netmask {{ route.get('dest_mask') }} gw {{ route.get('next') }} - {% endif %} - {% if interface.get('mtu', None) != None %} - mtu {{ interface.get('mtu') }} - {% endif %} - {% if interface.get('mac', None) != None %} - hwaddress {{ interface.get('mac') }} - {% endif %} - {% if interface.get('iftype') == 'bridge' %} - bridge_ports {{ interface.get('bridge_members')[0] }} {{ interface.get('bridge_members')[1] }} - {% endif %} - {% elif address.get('family') == 'ipv6' %} - iface {{ interface.get('ifname') }} inet6 {{ address.get('proto') }} - address {{ address.get('address') }} - netmask {{ address.get('netmask') }} - {% if address.get('gateway', None) != None %} - gateway {{ address.get('gateway') }} - {% endif %} - {% if interface.get('route') != None %} - {% set route = interface.get('route')%} - up ip -6 route add {{ route.get('destination') }} via {{ route.get('next')}} dev eth0 - down ip -6 route del {{ route.get('destination') }} via {{ route.get('next')}} dev eth0 - {% endif %} - {% if interface.get('mtu', None) != None %} - mtu {{ interface.get('mtu') }} - {% endif %} - {% if interface.get('mac', None) != None %} - hwaddress {{ interface.get('mac') }} - {% endif %} - {% if interface.get('iftype') == 'bridge' %} - bridge_ports {{ interface.get('bridge_members')[0] }} {{ interface.get('bridge_members')[1] }} + {% if interface.iftype in ['ethernet', 'bridge', 'loopback', 'wireless'] %} + {% if interface.address %} + auto {{ interface.ifname }} + {% for address in interface.address %} + {% if address.proto == 'static' %} + {% if address.family == 'ipv4' %} + iface {{ interface.ifname }} inet {{ address.proto }} + address {{ address.address }} + netmask {{ address.netmask }} + {% if address.gateway %} + gateway {{ address.gateway }} + {% endif %} + {% if interface.route %} + {% set route = interface.route %} + post-up route add -net {{ route.dest }} netmask {{ route.dest_mask }} gw {{ route.next }} + pre-up route del -net {{ route.dest }} netmask {{ route.dest_mask }} gw {{ route.next }} + {% endif %} + {% if interface.mtu %} + mtu {{ interface.mtu }} + {% endif %} + {% if interface.mac %} + hwaddress {{ interface.mac }} + {% endif %} + {% if interface.iftype == 'bridge' %} + bridge_ports {{ interface.bridge_members[0] }} {{ interface.bridge_members[1] }} + {% endif %} + {% elif address.family == 'ipv6' %} + iface {{ interface.ifname }} inet6 {{ address.proto }} + address {{ address.address }} + netmask {{ address.netmask }} + {% if address.gateway %} + gateway {{ address.gateway }} + {% endif %} + {% if interface.route %} + {% set route = interface.route %} + up ip -6 route add {{ route.destination }} via {{ route.next }} dev eth0 + down ip -6 route del {{ route.destination }} via {{ route.next }} dev eth0 + {% endif %} + {% if interface.mtu %} + mtu {{ interface.mtu }} + {% endif %} + {% if interface.mac %} + hwaddress {{ interface.mac }} + {% endif %} + {% if interface.iftype == 'bridge' %} + bridge_ports {{ interface.bridge_members[0] }} {{ interface.bridge_members[1] }} {% endif %} {% endif %} - {% elif address.get('proto') == 'dhcp' %} - {% if address.get('family') == 'ipv4'%} - iface {{ interface.get('ifname') }} inet {{ address.get('proto') }} - {% if interface.get('route') != None %} - {% set route = interface.get('route')%} - post-up route add -net {{ route.get('dest') }} netmask {{ route.get('dest_mask') }} gw {{ route.get('next') }} - pre-up route del -net {{ route.get('dest') }} netmask {{ route.get('dest_mask') }} gw {{ route.get('next') }} + {% elif address.proto == 'dhcp' %} + {% if address.family == 'ipv4'%} + iface {{ interface.ifname }} inet {{ address.proto }} + {% if interface.route %} + {% set route = interface.route %} + post-up route add -net {{ route.dest }} netmask {{ route.dest_mask }} gw {{ route.next }} + pre-up route del -net {{ route.dest }} netmask {{ route.dest_mask }} gw {{ route.next }} {% endif %} - {% if interface.get('mtu', None) != None %} - pre-up /sbin/ifconfig $IFACE mtu {{ interface.get('mtu') }} + {% if interface.mtu %} + pre-up /sbin/ifconfig $IFACE mtu {{ interface.mtu }} {% endif %} - {% if interface.get('mac', None) != None %} - hwaddress {{ interface.get('mac') }} + {% if interface.mac %} + hwaddress {{ interface.mac }} {% endif %} - {% elif address.get('family') == 'ipv6' %} - iface {{ interface.get('ifname') }} inet6 {{ address.get('proto') }} - {% if interface.get('route') != None %} - {% set route = interface.get('route') %} - up ip -6 route add {{ route.get('destination') }} via {{ route.get('next')}} dev eth0 - down ip -6 route del {{ route.get('destination') }} via {{ route.get('next')}} dev eth0 + {% elif address.family == 'ipv6' %} + iface {{ interface.ifname }} inet6 {{ address.proto }} + {% if interface.route %} + {% set route = interface.route %} + up ip -6 route add {{ route.destination }} via {{ route.next }} dev eth0 + down ip -6 route del {{ route.destination }} via {{ route.next }} dev eth0 {% endif %} - {% if interface.get('mtu', None) != None %} - pre-up /sbin/ifconfig $IFACE mtu {{ interface.get('mtu') }} + {% if interface.mtu %} + pre-up /sbin/ifconfig $IFACE mtu {{ interface.mtu }} {% endif %} - {% if interface.get('mac', None) != None %} - hwaddress {{ interface.get('mac') }} + {% if interface.mac %} + hwaddress {{ interface.mac }} {% endif %} {% endif %} {% endif%} {% endfor %} {% else %} - auto {{ interface.get('ifname') }} - {% if interface.get('iftype') in ['ethernet', 'wireless'] and interface.get('mode') != 'adhoc' %} - iface {{ interface.get('ifname') }} inet manual - {% set route = interface.get('route')%} - {% if interface.get('route') != None and route.get('version') == 4 %} - post-up route add -net {{ route.get('dest') }} netmask {{ route.get('dest_mask') }} gw {{ route.get('next') }} - pre-up route del -net {{ route.get('dest') }} netmask {{ route.get('dest_mask') }} gw {{ route.get('next') }} - {% elif interface.get('route') != None and route.get('version') == 6 %} - up ip -6 route add {{ route.get('destination') }} via {{ route.get('next')}} dev eth0 - down ip -6 route del {{ route.get('destination') }} via {{ route.get('next')}} dev eth0 + auto {{ interface.ifname }} + {% if interface.iftype in ['ethernet', 'wireless'] and interface.mode != 'adhoc' %} + iface {{ interface.ifname }} inet manual + {% set route = interface.route %} + {% if interface.route and route.version == 4 %} + post-up route add -net {{ route.dest }} netmask {{ route.dest_mask }} gw {{ route.next }} + pre-up route del -net {{ route.dest }} netmask {{ route.dest_mask }} gw {{ route.next }} + {% elif interface.route and route.version == 6 %} + up ip -6 route add {{ route.destination }} via {{ route.next }} dev eth0 + down ip -6 route del {{ route.destination }} via {{ route.next }} dev eth0 {% endif %} {% endif %} - {% if interface.get('iftype') == 'bridge' %} - bridge_ports {{ interface.get('bridge_members')[0] }} {{ interface.get('bridge_members')[1] }} + {% if interface.iftype == 'bridge' %} + bridge_ports {{ interface.bridge_members[0] }} {{ interface.bridge_members[1] }} {% endif %} - {% if interface.get('mode') == 'adhoc' %} - iface {{ interface.get('ifname') }} inet static + {% if interface.mode == 'adhoc' %} + iface {{ interface.ifname }} inet static address 172.128.1.1 netmask 255.255.255.0 wireless-channel 1 - wireless-essid {{ interface.get('essid') }} + wireless-essid {{ interface.essid }} wireless-mode ad-hoc {% endif %} {% endif %} From e9938c42b26d0155aaae9459ef19cf938cb377a5 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Fri, 21 Jul 2017 02:41:29 +0530 Subject: [PATCH 104/183] [raspbian] Fix flake8 error --- tests/raspbian/test_interfaces.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/raspbian/test_interfaces.py b/tests/raspbian/test_interfaces.py index f6a25644c..83ba55f93 100644 --- a/tests/raspbian/test_interfaces.py +++ b/tests/raspbian/test_interfaces.py @@ -152,7 +152,7 @@ def test_ipv6_static(self): ''' self.assertEqual(o.render(), expected) - def test_ipv6_static(self): + def test_multi_ipv6_static(self): o = Raspbian({ "interfaces": [ { @@ -319,7 +319,7 @@ def test_ipv6_dhcp(self): ''' self.assertEqual(o.render(), expected) - def test_ipv6_dhcp(self): + def test_multi_ipv6_dhcp(self): o = Raspbian({ "interfaces": [ { From 9c55b2c1edb01c7c037626905fa6573ccefbedcc Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Fri, 21 Jul 2017 15:15:42 +0530 Subject: [PATCH 105/183] [raspbian] Updated documentation examples --- docs/source/backends/raspbian.rst | 141 ++++++++++++++++-------------- 1 file changed, 75 insertions(+), 66 deletions(-) diff --git a/docs/source/backends/raspbian.rst b/docs/source/backends/raspbian.rst index 92a83a15e..a87d557e8 100644 --- a/docs/source/backends/raspbian.rst +++ b/docs/source/backends/raspbian.rst @@ -11,7 +11,6 @@ Initialization .. automethod:: netjsonconfig.Raspbian.__init__ - Render method ------------- @@ -55,17 +54,18 @@ Code example: Will return the following output:: - config: /etc/network/interfaces + # config: /etc/network/interfaces + auto eth0.1 iface eth0.1 inet static - address 192.168.1.1 - netmask 255.255.255.0 + address 192.168.1.1 + netmask 255.255.255.0 iface eth0.1 inet static - address 192.168.2.1 - netmask 255.255.255.0 + address 192.168.2.1 + netmask 255.255.255.0 iface eth0.1 inet6 static - address fd87::1 - netmask 128 + address fd87::1 + netmask 128 Generate method --------------- @@ -80,18 +80,18 @@ Code example: >>> from netjsonconfig import Raspbian >>> >>> o = Raspbian({ - ... "interfaces": [ - ... { - ... "name": "eth0", - ... "type": "ethernet", - ... "addresses": [ - ... { - ... "proto": "dhcp", - ... "family": "ipv4" - ... } - ... ] - ... } - ... ] + ... "interfaces": [ + ... { + ... "name": "eth0", + ... "type": "ethernet", + ... "addresses": [ + ... { + ... "proto": "dhcp", + ... "family": "ipv4" + ... } + ... ] + ... } + ... ] ... }) >>> stream = o.generate() >>> print(stream) @@ -116,18 +116,18 @@ Example: >>> from netjsonconfig import Raspbian >>> >>> o = Raspbian({ - ... "interfaces": [ - ... { - ... "name": "eth0", - ... "type": "ethernet", - ... "addresses": [ - ... { - ... "proto": "dhcp", - ... "family": "ipv4" - ... } - ... ] - ... } - ... ] + ... "interfaces": [ + ... { + ... "name": "eth0", + ... "type": "ethernet", + ... "addresses": [ + ... { + ... "proto": "dhcp", + ... "family": "ipv4" + ... } + ... ] + ... } + ... ] ... }) >>> o.write('dhcp-router', path='/tmp/') @@ -158,10 +158,12 @@ The following *configuration dictionary*: Will be rendered as follows:: - config: /etc/hostname + # config: /etc/hostname + routerA run commands: + $ timedatectl set-timezone UTC After modifying the config files run the following command to change the @@ -209,11 +211,12 @@ The following *configuration dictionary*: Will be rendered as follows:: - config: /etc/network/interfaces + # config: /etc/network/interfaces + auto lo iface lo inet static - address 127.0.0.1 - netmask 255.0.0.0 + address 127.0.0.1 + netmask 255.0.0.0 Dualstack (IPv4 & IPv6) ~~~~~~~~~~~~~~~~~~~~~~~ @@ -247,14 +250,15 @@ The following *configuration dictionary*: Will be rendered as follows:: - config: /etc/network/interfaces + # config: /etc/network/interfaces + auto eth0 iface eth0 inet static - address 10.27.251.1 - netmask 255.255.255.0 + address 10.27.251.1 + netmask 255.255.255.0 iface eth0 inet6 static - address fdb4:5f35:e8fd::1 - netmask 48 + address fdb4:5f35:e8fd::1 + netmask 48 DNS Servers and Search Domains ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -299,7 +303,8 @@ dynamic ip address configuration won't get the ``dns`` option in the UCI output, Will return the following UCI output:: - config: /etc/network/interfaces + # config: /etc/network/interfaces + auto eth0 iface eth0 inet static address 192.168.1.1 @@ -309,6 +314,7 @@ Will return the following UCI output:: iface eth1 inet dhcp config: /etc/resolv.conf + nameserver 10.11.12.13 nameserver 8.8.8.8 search openwisp.org @@ -338,7 +344,8 @@ The following *configuration dictionary*: Will be rendered as follows:: - config: /etc/network/interfaces + # config: /etc/network/interfaces + auto eth0 iface eth0 inet6 dhcp @@ -361,7 +368,6 @@ You can install it using this command:: $ aptitude install bridge-utils - Bridge Interface Example ~~~~~~~~~~~~~~~~~~~~~~~~ @@ -392,7 +398,8 @@ The following *configuration dictionary*: Will be rendered as follows:: - config: /etc/network/interfaces + # config: /etc/network/interfaces + auto lan_bridge iface lan_bridge inet static address 172.17.0.2 @@ -421,10 +428,10 @@ First we need to setup a static IP for our wireless interface. Edit the auto wlan0 iface wlan0 inet static - address 172.128.1.1 - netmask 255.255.255.0 - network 172.128.1.0 - broadcast 172.128.1.255 + address 172.128.1.1 + netmask 255.255.255.0 + network 172.128.1.0 + broadcast 172.128.1.255 Reload ``wlan0`` interface with ``sudo ifdown wlan0; sudo ifup wlan0`` @@ -539,7 +546,8 @@ common wireless access point configuration: Will be rendered as follows:: - config: /etc/hostapd/hostapd.conf + # config: /etc/hostapd/hostapd.conf + interface=wlan0 driver=nl80211 hw_mode=g @@ -573,14 +581,15 @@ The following example: Will result in:: - config: /etc/network/interfaces + # config: /etc/network/interfaces + auto wireless iface wireless inet static - address 172.128.1.1 - netmask 255.255.255.0 - wireless-channel 1 - wireless-essid freifunk - wireless-mode ad-hoc + address 172.128.1.1 + netmask 255.255.255.0 + wireless-channel 1 + wireless-essid freifunk + wireless-mode ad-hoc WPA2 Personal (Pre-Shared Key) @@ -623,7 +632,8 @@ point using *WPA2 Personal (Pre-Shared Key)* encryption: Will be rendered as follows:: - config: /etc/hostapd/hostapd.conf + # config: /etc/hostapd/hostapd.conf + interface=wlan0 driver=nl80211 hw_mode=g @@ -667,17 +677,16 @@ The following *configuration dictionary* : "enabled": True, "enable_server": False, "server": [ - "0.openwrt.pool.ntp.org", - "1.openwrt.pool.ntp.org", - "2.openwrt.pool.ntp.org", - "3.openwrt.pool.ntp.org" + "0.pool.ntp.org", + "1.pool.ntp.org", + "2.pool.ntp.org" ] } Will be rendered as follows:: - config: /etc/ntp.conf - server 0.openwrt.pool.ntp.org - server 1.openwrt.pool.ntp.org - server 2.openwrt.pool.ntp.org - server 3.openwrt.pool.ntp.org + # config: /etc/ntp.conf + + server 0.pool.ntp.org + server 1.pool.ntp.org + server 2.pool.ntp.org From 8c62ef53843b03938f34a4ff2755f6f8bc127942 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Mon, 24 Jul 2017 04:29:17 +0530 Subject: [PATCH 106/183] [raspbian] Updates documentation - Added docs on radio settings - Added docs on static routes --- docs/source/backends/raspbian.rst | 201 +++++++++++++++++++++++++----- 1 file changed, 173 insertions(+), 28 deletions(-) diff --git a/docs/source/backends/raspbian.rst b/docs/source/backends/raspbian.rst index a87d557e8..b2a543308 100644 --- a/docs/source/backends/raspbian.rst +++ b/docs/source/backends/raspbian.rst @@ -151,8 +151,7 @@ The following *configuration dictionary*: { "general": { "hostname": "routerA", - "timezone": "UTC", - "ula_prefix": "fd8e:f40a:6701::/48" + "timezone": "UTC" } } @@ -162,14 +161,18 @@ Will be rendered as follows:: routerA - run commands: + # script: /scripts/general.sh + + /etc/init.d/hostname.sh start + echo "Hostname of device has been modified" + timedatectl set-timezone UTC + echo "Timezone has changed to UTC" - $ timedatectl set-timezone UTC After modifying the config files run the following command to change the hostname:: - $ /etc/init.d/hostname.sh start + source scripts/general.sh Network interfaces ------------------ @@ -307,13 +310,13 @@ Will return the following UCI output:: auto eth0 iface eth0 inet static - address 192.168.1.1 - netmask 255.255.255.0 + address 192.168.1.1 + netmask 255.255.255.0 auto eth1 iface eth1 inet dhcp - config: /etc/resolv.conf + # config: /etc/resolv.conf nameserver 10.11.12.13 nameserver 8.8.8.8 @@ -402,10 +405,9 @@ Will be rendered as follows:: auto lan_bridge iface lan_bridge inet static - address 172.17.0.2 - netmask 255.255.255.0 - bridge_ports eth0:0 eth0:1 - + address 172.17.0.2 + netmask 255.255.255.0 + bridge_ports eth0:0 eth0:1 Wireless Settings ----------------- @@ -484,23 +486,15 @@ following line:: #net.ipv4.ip_forward=1 -This will enable on the next reboot. Incase you want to activate it immediately:: - - sudo sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward" - -Let us assume we have internet connection on ``eth0``. We will need to configure -a NAT between the ``wlan0`` and ``eth0`` interface. It can be done using the followin -commands:: +After enabling IPv4 Forwarding in ``/etc/sysctl.conf`` you can run the bash script +``/scripts/ipv4_forwarding.sh`` generated in your ``tar.gz`` file:: - sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE - sudo iptables -A FORWARD -i eth0 -o wlan0 -m state --state RELATED,ESTABLISHED -j ACCEPT - sudo iptables -A FORWARD -i wlan0 -o eth0 -j ACCEPT - -These rules need to be applied every time the Raspberry Pi is rebooted. Run :: + source scripts/ipv4_forwarding.sh - sudo sh -c "iptables-save > /etc/iptables.ipv4.nat" - -Now open the `/etc/rc.local` file and just above the line ``exit 0``, add the following line:: +This will enable IPv4 forwarding, setup a NAT between your two interfaces and save the +iptable in ``/etc/iptables.ipv4.nat``. +These rules must be applied everytime the Raspberry Pi is booted up. To do so open the +`/etc/rc.local` file and just above the line ``exit 0``, add the following line:: iptables-restore < /etc/iptables.ipv4.nat @@ -555,6 +549,19 @@ Will be rendered as follows:: ieee80211n=1 ssid=myWiFi + # config: /etc/network/interfaces + + auto wlan0 + iface wlan0 inet manual + + # script: /scripts/ipv4_forwarding.sh + + sudo sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward" + sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE + sudo iptables -A FORWARD -i eth0 -o wlan0 -m state --state RELATED,ESTABLISHED -j ACCEPT + sudo iptables -A FORWARD -i wlan0 -o eth0 -j ACCEPT + sudo sh -c "iptables-save > /etc/iptables.ipv4.nat" + Wireless AdHoc Mode ~~~~~~~~~~~~~~~~~~~ @@ -591,7 +598,6 @@ Will result in:: wireless-essid freifunk wireless-mode ad-hoc - WPA2 Personal (Pre-Shared Key) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -646,6 +652,145 @@ Will be rendered as follows:: wpa_passphrase=passphrase012345 wpa_pairwise=TKIP CCMP + # config: /etc/network/interfaces + + auto wlan0 + iface wlan0 inet manual + + # script: /scripts/ipv4_forwarding.sh + + sudo sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward" + sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE + sudo iptables -A FORWARD -i eth0 -o wlan0 -m state --state RELATED,ESTABLISHED -j ACCEPT + sudo iptables -A FORWARD -i wlan0 -o eth0 -j ACCEPT + sudo sh -c "iptables-save > /etc/iptables.ipv4.nat" + +Radio settings +-------------- + +The radio settings reside in the ``radio`` key of the *configuration dictionary*, +which must contain a list of `NetJSON radio objects `_ +(see the link for the detailed specification). + +Radio object extensions +~~~~~~~~~~~~~~~~~~~~~~~ + +In addition to the default *NetJSON Radio object options*, the ``OpenWrt`` backend +also requires setting the following additional options for each radio in the list: + ++--------------+---------+-----------------------------------------------+ +| key name | type | allowed values | ++==============+=========+===============================================+ +| ``protocol`` | string | 802.11a, 802.11b, 802.11g, 802.11n, 802.11ac | ++--------------+---------+-----------------------------------------------+ + +Radio example +~~~~~~~~~~~~~ + +The following *configuration dictionary*: + +.. code-block:: python + + { + "radios": [ + { + "name": "radio0", + "phy": "phy0", + "driver": "mac80211", + "protocol": "802.11n", + "channel": 11, + "channel_width": 20, + "tx_power": 5, + "country": "IT" + }, + { + "name": "radio1", + "phy": "phy1", + "driver": "mac80211", + "protocol": "802.11n", + "channel": 36, + "channel_width": 20, + "tx_power": 4, + "country": "IT" + } + ], + "interfaces": [ + { + "name": "wlan0", + "type": "wireless", + "wireless": { + "radio": "radio0", + "mode": "access_point", + "ssid": "myWiFi" + } + } + ] + } + +Will be rendered as follows:: + + # config: /etc/hostapd/hostapd.conf + + interface=wlan0 + driver=nl80211 + hw_mode=g + channel=11 + ieee80211n=1 + ssid=myWiFi + + # config: /etc/network/interfaces + + auto wlan0 + iface wlan0 inet manual + + # script: /scripts/ipv4_forwarding.sh + + sudo sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward" + sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE + sudo iptables -A FORWARD -i eth0 -o wlan0 -m state --state RELATED,ESTABLISHED -j ACCEPT + sudo iptables -A FORWARD -i wlan0 -o eth0 -j ACCEPT + sudo sh -c "iptables-save > /etc/iptables.ipv4.nat" + +Static Routes +------------- + +The static routes settings reside in the ``routes`` key of the *configuration dictionary*, +which must contain a list of `NetJSON Static Route objects `_ +(see the link for the detailed specification). +The following *configuration dictionary*: + + +Static route example +~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: python + + { + "interfaces": [ + { + "name": "eth0", + "type": "ethernet" + } + ], + "routes": [ + { + "device": "eth0", + "destination": "192.168.4.1/24", + "next": "192.168.2.2", + "cost": 2, + }, + ] + } + +Will be rendered as follows:: + + # config: /etc/network/interfaces + + auto eth0 + iface eth0 inet manual + post-up route add -net 192.168.4.1 netmask 255.255.255.0 gw 192.168.2.2 + pre-up route del -net 192.168.4.1 netmask 255.255.255.0 gw 192.168.2.2 + NTP settings ------------ From 588bc45b57ddfb248b36d0d626dfbd963654f43f Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Mon, 24 Jul 2017 13:15:29 +0530 Subject: [PATCH 107/183] [raspbian] Updated tests --- .../raspbian/templates/commands.jinja2 | 26 +++++++-- .../raspbian/templates/hostapd.jinja2 | 1 + tests/raspbian/test_hostapd.py | 36 +++++++++++++ tests/raspbian/test_radios.py | 54 +++++++++++++++++++ tests/raspbian/test_system.py | 27 +++++----- 5 files changed, 125 insertions(+), 19 deletions(-) diff --git a/netjsonconfig/backends/raspbian/templates/commands.jinja2 b/netjsonconfig/backends/raspbian/templates/commands.jinja2 index e85d6d072..e4d34c74e 100644 --- a/netjsonconfig/backends/raspbian/templates/commands.jinja2 +++ b/netjsonconfig/backends/raspbian/templates/commands.jinja2 @@ -1,7 +1,23 @@ -{% for general in data.general %} - {% if general.get('timezone') %} - run commands: - $ timedatectl set-timezone {{ general.get('timezone') }} +{% if data.general %} + # script: /scripts/general.sh + {% if 'hostname' in data.general[0]%} + /etc/init.d/hostname.sh start + echo "Hostname of device has been modified" {% endif %} -{% endfor%} + {% if 'timezone' in data.general[0] %} + timedatectl set-timezone {{ data.general[0].timezone }} + echo "Timezone has changed to {{ data.general[0].timezone }}" + {% endif %} + +{% endif %} +{% if data.wireless %} + # script: /scripts/ipv4_forwarding.sh + + sudo sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward" + sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE + sudo iptables -A FORWARD -i eth0 -o {{ data.wireless[0].ifname }} -m state --state RELATED,ESTABLISHED -j ACCEPT + sudo iptables -A FORWARD -i {{ data.wireless[0].ifname }} -o eth0 -j ACCEPT + sudo sh -c "iptables-save > /etc/iptables.ipv4.nat" + +{% endif %} diff --git a/netjsonconfig/backends/raspbian/templates/hostapd.jinja2 b/netjsonconfig/backends/raspbian/templates/hostapd.jinja2 index 9f715671f..45d6c9b51 100644 --- a/netjsonconfig/backends/raspbian/templates/hostapd.jinja2 +++ b/netjsonconfig/backends/raspbian/templates/hostapd.jinja2 @@ -23,4 +23,5 @@ wpa_pairwise={{ wireless.encryption.wpa_pairwise }} {% endif %} {% endif %} + {% endfor %} diff --git a/tests/raspbian/test_hostapd.py b/tests/raspbian/test_hostapd.py index d027b94ef..deffd2415 100644 --- a/tests/raspbian/test_hostapd.py +++ b/tests/raspbian/test_hostapd.py @@ -50,11 +50,20 @@ def test_wpa2_personal(self): wpa_key_mgmt=WPA-PSK wpa_passphrase=passphrase012345 wpa_pairwise=TKIP CCMP + # config: /etc/network/interfaces auto wlan0 iface wlan0 inet manual +# script: /scripts/ipv4_forwarding.sh + +sudo sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward" +sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE +sudo iptables -A FORWARD -i eth0 -o wlan0 -m state --state RELATED,ESTABLISHED -j ACCEPT +sudo iptables -A FORWARD -i wlan0 -o eth0 -j ACCEPT +sudo sh -c "iptables-save > /etc/iptables.ipv4.nat" + ''' self.assertEqual(o.render(), expected) @@ -101,11 +110,20 @@ def test_wpa_personal(self): wpa=1 wpa_key_mgmt=WPA-PSK wpa_passphrase=passphrase012345 + # config: /etc/network/interfaces auto wlan0 iface wlan0 inet manual +# script: /scripts/ipv4_forwarding.sh + +sudo sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward" +sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE +sudo iptables -A FORWARD -i eth0 -o wlan0 -m state --state RELATED,ESTABLISHED -j ACCEPT +sudo iptables -A FORWARD -i wlan0 -o eth0 -j ACCEPT +sudo sh -c "iptables-save > /etc/iptables.ipv4.nat" + ''' self.assertEqual(o.render(), expected) @@ -217,11 +235,20 @@ def test_encryption_disabled(self): channel=3 ieee80211n=1 ssid=MyNetwork + # config: /etc/network/interfaces auto wlan0 iface wlan0 inet manual +# script: /scripts/ipv4_forwarding.sh + +sudo sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward" +sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE +sudo iptables -A FORWARD -i eth0 -o wlan0 -m state --state RELATED,ESTABLISHED -j ACCEPT +sudo iptables -A FORWARD -i wlan0 -o eth0 -j ACCEPT +sudo sh -c "iptables-save > /etc/iptables.ipv4.nat" + ''' self.assertEqual(o.render(), expected) @@ -260,10 +287,19 @@ def test_no_encryption(self): channel=3 ieee80211n=1 ssid=open + # config: /etc/network/interfaces auto wlan0 iface wlan0 inet manual +# script: /scripts/ipv4_forwarding.sh + +sudo sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward" +sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE +sudo iptables -A FORWARD -i eth0 -o wlan0 -m state --state RELATED,ESTABLISHED -j ACCEPT +sudo iptables -A FORWARD -i wlan0 -o eth0 -j ACCEPT +sudo sh -c "iptables-save > /etc/iptables.ipv4.nat" + ''' self.assertEqual(o.render(), expected) diff --git a/tests/raspbian/test_radios.py b/tests/raspbian/test_radios.py index 7587ad8a4..98575c9c3 100644 --- a/tests/raspbian/test_radios.py +++ b/tests/raspbian/test_radios.py @@ -51,11 +51,20 @@ def test_radio_multi(self): channel=11 ieee80211n=1 ssid=myWiFi + # config: /etc/network/interfaces auto wlan0 iface wlan0 inet manual +# script: /scripts/ipv4_forwarding.sh + +sudo sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward" +sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE +sudo iptables -A FORWARD -i eth0 -o wlan0 -m state --state RELATED,ESTABLISHED -j ACCEPT +sudo iptables -A FORWARD -i wlan0 -o eth0 -j ACCEPT +sudo sh -c "iptables-save > /etc/iptables.ipv4.nat" + ''' self.assertEqual(o.render(), expected) @@ -93,11 +102,20 @@ def test_radio_n_24ghz(self): channel=3 ieee80211n=1 ssid=myWiFi + # config: /etc/network/interfaces auto wlan0 iface wlan0 inet manual +# script: /scripts/ipv4_forwarding.sh + +sudo sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward" +sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE +sudo iptables -A FORWARD -i eth0 -o wlan0 -m state --state RELATED,ESTABLISHED -j ACCEPT +sudo iptables -A FORWARD -i wlan0 -o eth0 -j ACCEPT +sudo sh -c "iptables-save > /etc/iptables.ipv4.nat" + ''' self.assertEqual(o.render(), expected) @@ -135,11 +153,20 @@ def test_radio_n_5ghz(self): channel=36 ieee80211n=1 ssid=myWiFi + # config: /etc/network/interfaces auto wlan0 iface wlan0 inet manual +# script: /scripts/ipv4_forwarding.sh + +sudo sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward" +sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE +sudo iptables -A FORWARD -i eth0 -o wlan0 -m state --state RELATED,ESTABLISHED -j ACCEPT +sudo iptables -A FORWARD -i wlan0 -o eth0 -j ACCEPT +sudo sh -c "iptables-save > /etc/iptables.ipv4.nat" + ''' self.assertEqual(o.render(), expected) @@ -176,11 +203,20 @@ def test_radio_ac(self): channel=132 ieee80211ac=1 ssid=myWiFi + # config: /etc/network/interfaces auto wlan0 iface wlan0 inet manual +# script: /scripts/ipv4_forwarding.sh + +sudo sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward" +sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE +sudo iptables -A FORWARD -i eth0 -o wlan0 -m state --state RELATED,ESTABLISHED -j ACCEPT +sudo iptables -A FORWARD -i wlan0 -o eth0 -j ACCEPT +sudo sh -c "iptables-save > /etc/iptables.ipv4.nat" + ''' self.assertEqual(o.render(), expected) @@ -216,11 +252,20 @@ def test_radio_a(self): hw_mode=a channel=0 ssid=myWiFi + # config: /etc/network/interfaces auto wlan0 iface wlan0 inet manual +# script: /scripts/ipv4_forwarding.sh + +sudo sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward" +sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE +sudo iptables -A FORWARD -i eth0 -o wlan0 -m state --state RELATED,ESTABLISHED -j ACCEPT +sudo iptables -A FORWARD -i wlan0 -o eth0 -j ACCEPT +sudo sh -c "iptables-save > /etc/iptables.ipv4.nat" + ''' self.assertEqual(o.render(), expected) @@ -256,10 +301,19 @@ def test_radio_g(self): hw_mode=g channel=0 ssid=myWiFi + # config: /etc/network/interfaces auto wlan0 iface wlan0 inet manual +# script: /scripts/ipv4_forwarding.sh + +sudo sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward" +sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE +sudo iptables -A FORWARD -i eth0 -o wlan0 -m state --state RELATED,ESTABLISHED -j ACCEPT +sudo iptables -A FORWARD -i wlan0 -o eth0 -j ACCEPT +sudo sh -c "iptables-save > /etc/iptables.ipv4.nat" + ''' self.assertEqual(o.render(), expected) diff --git a/tests/raspbian/test_system.py b/tests/raspbian/test_system.py index 399326fd9..4603e84e8 100644 --- a/tests/raspbian/test_system.py +++ b/tests/raspbian/test_system.py @@ -10,10 +10,7 @@ def test_general(self): o = Raspbian({ "general": { "hostname": "test-system", - "timezone": "Europe/Rome", - "custom_setting": True, - "empty_setting1": None, - "empty_setting2": "" + "timezone": "Europe/Rome" } }) @@ -21,8 +18,12 @@ def test_general(self): test-system -run commands: -$ timedatectl set-timezone Europe/Rome +# script: /scripts/general.sh + +/etc/init.d/hostname.sh start +echo "Hostname of device has been modified" +timedatectl set-timezone Europe/Rome +echo "Timezone has changed to Europe/Rome" ''' self.assertEqual(o.render(), expected) @@ -33,19 +34,17 @@ def test_ntp(self): "enabled": True, "enable_server": False, "server": [ - "0.openwrt.pool.ntp.org", - "1.openwrt.pool.ntp.org", - "2.openwrt.pool.ntp.org", - "3.openwrt.pool.ntp.org" + "0.pool.ntp.org", + "1.pool.ntp.org", + "2.pool.ntp.org" ] } }) expected = '''# config: /etc/ntp.conf -server 0.openwrt.pool.ntp.org -server 1.openwrt.pool.ntp.org -server 2.openwrt.pool.ntp.org -server 3.openwrt.pool.ntp.org +server 0.pool.ntp.org +server 1.pool.ntp.org +server 2.pool.ntp.org ''' self.assertEqual(o.render(), expected) From bd988808c18f061355eb5d12a5e052fd44e4e161 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Mon, 24 Jul 2017 13:57:36 +0530 Subject: [PATCH 108/183] [raspbian] Renamed test classname --- tests/raspbian/test_hostapd.py | 2 +- tests/raspbian/test_interfaces.py | 2 +- tests/raspbian/test_resolv.py | 2 +- tests/raspbian/test_routes.py | 2 +- tests/raspbian/test_system.py | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/raspbian/test_hostapd.py b/tests/raspbian/test_hostapd.py index deffd2415..e1e195b71 100644 --- a/tests/raspbian/test_hostapd.py +++ b/tests/raspbian/test_hostapd.py @@ -4,7 +4,7 @@ from netjsonconfig.utils import _TabsMixin -class TestHostapdRenderer(unittest.TestCase, _TabsMixin): +class TestHostapd(unittest.TestCase, _TabsMixin): def test_wpa2_personal(self): o = Raspbian({ diff --git a/tests/raspbian/test_interfaces.py b/tests/raspbian/test_interfaces.py index 83ba55f93..2d7004251 100644 --- a/tests/raspbian/test_interfaces.py +++ b/tests/raspbian/test_interfaces.py @@ -4,7 +4,7 @@ from netjsonconfig.utils import _TabsMixin -class TestInterfacesRenderer(unittest.TestCase, _TabsMixin): +class TestInterfaces(unittest.TestCase, _TabsMixin): def test_no_ip(self): o = Raspbian({ diff --git a/tests/raspbian/test_resolv.py b/tests/raspbian/test_resolv.py index 1f9b19d0d..513bd4835 100644 --- a/tests/raspbian/test_resolv.py +++ b/tests/raspbian/test_resolv.py @@ -4,7 +4,7 @@ from netjsonconfig.utils import _TabsMixin -class TestResovlRenderer(unittest.TestCase, _TabsMixin): +class TestResovl(unittest.TestCase, _TabsMixin): def test_dns_server(self): o = Raspbian({ diff --git a/tests/raspbian/test_routes.py b/tests/raspbian/test_routes.py index f5aa45917..7bc921cd6 100644 --- a/tests/raspbian/test_routes.py +++ b/tests/raspbian/test_routes.py @@ -4,7 +4,7 @@ from netjsonconfig.utils import _TabsMixin -class TestStaticRouteRenderer(unittest.TestCase, _TabsMixin): +class TestStaticRoute.unittest.TestCase, _TabsMixin): def test_ipv4_manual_route(self): o = Raspbian({ diff --git a/tests/raspbian/test_system.py b/tests/raspbian/test_system.py index 4603e84e8..aa998b02e 100644 --- a/tests/raspbian/test_system.py +++ b/tests/raspbian/test_system.py @@ -4,7 +4,7 @@ from netjsonconfig.utils import _TabsMixin -class TestSystemRender(unittest.TestCase, _TabsMixin): +class TestSystem(unittest.TestCase, _TabsMixin): def test_general(self): o = Raspbian({ From e7288fe517e87382950f31f925ab712b49ac1b69 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Mon, 24 Jul 2017 14:00:07 +0530 Subject: [PATCH 109/183] [raspbian] Fixed typo --- tests/raspbian/test_routes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/raspbian/test_routes.py b/tests/raspbian/test_routes.py index 7bc921cd6..67f11eb30 100644 --- a/tests/raspbian/test_routes.py +++ b/tests/raspbian/test_routes.py @@ -4,7 +4,7 @@ from netjsonconfig.utils import _TabsMixin -class TestStaticRoute.unittest.TestCase, _TabsMixin): +class TestStaticRoute(unittest.TestCase, _TabsMixin): def test_ipv4_manual_route(self): o = Raspbian({ From 404db8ac241d23ebba6daceba040fbcb1ebff88c Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Mon, 24 Jul 2017 14:15:12 +0530 Subject: [PATCH 110/183] [raspbian] Updated documentation --- docs/source/backends/raspbian.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/source/backends/raspbian.rst b/docs/source/backends/raspbian.rst index b2a543308..aaf094d2d 100644 --- a/docs/source/backends/raspbian.rst +++ b/docs/source/backends/raspbian.rst @@ -14,13 +14,13 @@ Initialization Render method ------------- -.. automethod:: netjsonconfig.OpenWrt.render +.. automethod:: netjsonconfig.Raspbian.render Code example: .. code-block:: python - from netjsonconfig import OpenWrt + from netjsonconfig import Raspbian o = Raspbian({ "interfaces": [ @@ -106,7 +106,7 @@ The ``generate`` method does not write to disk but instead returns a instance of Write method ------------ -.. automethod:: netjsonconfig.OpenWrt.write +.. automethod:: netjsonconfig.Raspbian.write Example: From 6946ae9e3e78f107b632f93d054f07239fdef01e Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Tue, 25 Jul 2017 02:50:17 +0530 Subject: [PATCH 111/183] [raspbian] Added initial schema for backend --- netjsonconfig/backends/raspbian/schema.py | 87 ++++++++++++++++++++++- 1 file changed, 86 insertions(+), 1 deletion(-) diff --git a/netjsonconfig/backends/raspbian/schema.py b/netjsonconfig/backends/raspbian/schema.py index 7f6033803..6fdf3589c 100644 --- a/netjsonconfig/backends/raspbian/schema.py +++ b/netjsonconfig/backends/raspbian/schema.py @@ -1,4 +1,89 @@ from ...schema import schema as default_schema from ...utils import merge_config +from ..openwrt.timezones import timezones -schema = merge_config(default_schema, {}) +schema = merge_config(default_schema, { + "definitions": { + "radio_hwmode_11g": { + "properties": { + "hwmode": { + "type": "string", + "title": "hardware mode", + "readOnly": True, + "propertyOrder": 8, + "default": "11g", + "enum": ["11g"], + } + } + }, + "radio_hwmode_11a": { + "properties": { + "hwmode": { + "type": "string", + "title": "hardware mode", + "readOnly": True, + "propertyOrder": 8, + "default": "11a", + "enum": ["11a"], + } + } + }, + "radio_80211gn_settings": { + "allOf": [{"$ref": "#/definitions/radio_hwmode_11g"}] + }, + "radio_80211an_settings": { + "allOf": [{"$ref": "#/definitions/radio_hwmode_11a"}] + }, + "radio_80211ac_2ghz_settings": { + "allOf": [{"$ref": "#/definitions/radio_hwmode_11g"}] + }, + "radio_80211ac_5ghz_settings": { + "allOf": [{"$ref": "#/definitions/radio_hwmode_11a"}] + }, + }, + "properties": { + "general": { + "properties": { + "timezone": { + "enum": list(timezones.keys()), + "default": "UTC", + } + } + }, + "ntp": { + "type": "object", + "title": "NTP Settings", + "additionalProperties": True, + "propertyOrder": 8, + "properties": { + "enabled": { + "type": "boolean", + "title": "enable NTP client", + "default": True, + "format": "checkbox", + "propertyOrder": 1, + }, + "enable_server": { + "type": "boolean", + "title": "enable NTP server", + "default": False, + "format": "checkbox", + "propertyOrder": 2, + }, + "server": { + "title": "NTP Servers", + "description": "NTP server candidates", + "type": "array", + "uniqueItems": True, + "additionalItems": True, + "propertyOrder": 3, + "items": { + "title": "NTP server", + "type": "string", + "format": "hostname" + }, + } + } + } + } +}) From 62223e422270f9c3bc647eb1ce5595aba2c415b6 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Tue, 25 Jul 2017 12:31:12 +0530 Subject: [PATCH 112/183] [raspbian] Renamed template --- netjsonconfig/backends/raspbian/raspbian.py | 4 ++-- netjsonconfig/backends/raspbian/renderer.py | 2 +- .../raspbian/templates/{commands.jinja2 => scripts.jinja2} | 0 3 files changed, 3 insertions(+), 3 deletions(-) rename netjsonconfig/backends/raspbian/templates/{commands.jinja2 => scripts.jinja2} (100%) diff --git a/netjsonconfig/backends/raspbian/raspbian.py b/netjsonconfig/backends/raspbian/raspbian.py index ab4320487..0b3a15047 100644 --- a/netjsonconfig/backends/raspbian/raspbian.py +++ b/netjsonconfig/backends/raspbian/raspbian.py @@ -2,7 +2,7 @@ from . import converters from ..base.backend import BaseBackend -from .renderer import Commands, Hostapd, Hostname, Interfaces, Ntp, Resolv +from .renderer import Scripts, Hostapd, Hostname, Interfaces, Ntp, Resolv from .schema import schema @@ -25,7 +25,7 @@ class Raspbian(BaseBackend): Interfaces, Resolv, Ntp, - Commands + Scripts ] def _generate_contents(self, tar): diff --git a/netjsonconfig/backends/raspbian/renderer.py b/netjsonconfig/backends/raspbian/renderer.py index d845cbd9b..9edb1410a 100644 --- a/netjsonconfig/backends/raspbian/renderer.py +++ b/netjsonconfig/backends/raspbian/renderer.py @@ -8,7 +8,7 @@ def cleanup(self, output): pass -class Commands(RaspbianRenderer): +class Scripts(RaspbianRenderer): pass diff --git a/netjsonconfig/backends/raspbian/templates/commands.jinja2 b/netjsonconfig/backends/raspbian/templates/scripts.jinja2 similarity index 100% rename from netjsonconfig/backends/raspbian/templates/commands.jinja2 rename to netjsonconfig/backends/raspbian/templates/scripts.jinja2 From 3906c5f1084eab6e047a6ca9ccc0a3bc1d0da51c Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Tue, 25 Jul 2017 12:55:17 +0530 Subject: [PATCH 113/183] [raspbian] Generate scripts files --- netjsonconfig/backends/raspbian/raspbian.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netjsonconfig/backends/raspbian/raspbian.py b/netjsonconfig/backends/raspbian/raspbian.py index 0b3a15047..2fb91ee5e 100644 --- a/netjsonconfig/backends/raspbian/raspbian.py +++ b/netjsonconfig/backends/raspbian/raspbian.py @@ -30,7 +30,7 @@ class Raspbian(BaseBackend): def _generate_contents(self, tar): text = self.render(files=False) - config_files_pattern = re.compile('^# config:\s', flags=re.MULTILINE) + config_files_pattern = re.compile('^# config:\s|^# script:\s', flags=re.MULTILINE) config_files = config_files_pattern.split(text) if '' in config_files: config_files.remove('') From 387087d5048091a02fd34f5a1d63d95e93ba58ef Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Tue, 25 Jul 2017 12:55:44 +0530 Subject: [PATCH 114/183] [raspbian] Updated tests for recent changes --- tests/raspbian/test_backend.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/raspbian/test_backend.py b/tests/raspbian/test_backend.py index 49ba04364..04e48334a 100644 --- a/tests/raspbian/test_backend.py +++ b/tests/raspbian/test_backend.py @@ -63,6 +63,6 @@ def test_write(self): }) o.write(name='test', path='/tmp') tar = tarfile.open('/tmp/test.tar.gz', mode='r') - self.assertEqual(len(tar.getmembers()), 1) + self.assertEqual(len(tar.getmembers()), 2) tar.close() os.remove('/tmp/test.tar.gz') From 81984255a65b7e288ef33ea61bc564fa54ef27d1 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Tue, 25 Jul 2017 13:08:35 +0530 Subject: [PATCH 115/183] [raspbian] Added tests for scripts --- tests/raspbian/test_backend.py | 64 ++++++++++++++++++++++------------ 1 file changed, 41 insertions(+), 23 deletions(-) diff --git a/tests/raspbian/test_backend.py b/tests/raspbian/test_backend.py index 04e48334a..6aed42f94 100644 --- a/tests/raspbian/test_backend.py +++ b/tests/raspbian/test_backend.py @@ -10,31 +10,41 @@ class TestBackend(unittest.TestCase, _TabsMixin): def test_generate(self): o = Raspbian({ - "interfaces": [ - { - "name": "eth0", - "type": "ethernet", - "addresses": [ - { - "address": "192.168.1.1", - "mask": 24, - "proto": "static", - "family": "ipv4" - } - ] - } - ], - "dns_servers": [ - "10.11.12.13", - "8.8.8.8" - ], - "dns_search": [ - "netjson.org", - "openwisp.org" - ] + "general": { + "hostname": "test" + }, + "interfaces": [ + { + "name": "eth0", + "type": "ethernet", + "addresses": [ + { + "address": "192.168.1.1", + "mask": 24, + "proto": "static", + "family": "ipv4" + } + ] + } + ], + "dns_servers": [ + "10.11.12.13", + "8.8.8.8" + ], + "dns_search": [ + "netjson.org", + "openwisp.org" + ] }) tar = tarfile.open(fileobj=o.generate(), mode='r') - self.assertEqual(len(tar.getmembers()), 2) + self.assertEqual(len(tar.getmembers()), 4) + + general = tar.getmember('/etc/hostname') + contents = tar.extractfile(general).read().decode() + expected = self._tabs('''test + +''') + self.assertEqual(contents, expected) interface = tar.getmember('/etc/network/interfaces') contents = tar.extractfile(interface).read().decode() @@ -52,6 +62,14 @@ def test_generate(self): nameserver 8.8.8.8 search netjson.org search openwisp.org +''') + self.assertEqual(contents, expected) + + script = tar.getmember('/scripts/general.sh') + contents = tar.extractfile(script).read().decode() + expected = self._tabs('''/etc/init.d/hostname.sh start +echo "Hostname of device has been modified" + ''') self.assertEqual(contents, expected) From 71718cff940c70a17492c406b8824d15001d24ec Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Tue, 25 Jul 2017 13:10:35 +0530 Subject: [PATCH 116/183] [raspbian] Changed variable names --- netjsonconfig/backends/raspbian/raspbian.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/netjsonconfig/backends/raspbian/raspbian.py b/netjsonconfig/backends/raspbian/raspbian.py index 2fb91ee5e..1c6b48600 100644 --- a/netjsonconfig/backends/raspbian/raspbian.py +++ b/netjsonconfig/backends/raspbian/raspbian.py @@ -30,12 +30,12 @@ class Raspbian(BaseBackend): def _generate_contents(self, tar): text = self.render(files=False) - config_files_pattern = re.compile('^# config:\s|^# script:\s', flags=re.MULTILINE) - config_files = config_files_pattern.split(text) - if '' in config_files: - config_files.remove('') - for config_file in config_files: - lines = config_file.split('\n') + files_pattern = re.compile('^# config:\s|^# script:\s', flags=re.MULTILINE) + files = files_pattern.split(text) + if '' in files: + files.remove('') + for file in files: + lines = file.split('\n') file_name = lines[0] text_contents = '\n'.join(lines[2:]) self._add_file(tar=tar, From 96c0e881f87983b79a9edbeb2fc9a18f7602bb3f Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Tue, 25 Jul 2017 13:22:50 +0530 Subject: [PATCH 117/183] [raspbian] Fix isort warning --- netjsonconfig/backends/raspbian/raspbian.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netjsonconfig/backends/raspbian/raspbian.py b/netjsonconfig/backends/raspbian/raspbian.py index 1c6b48600..8465b49b7 100644 --- a/netjsonconfig/backends/raspbian/raspbian.py +++ b/netjsonconfig/backends/raspbian/raspbian.py @@ -2,7 +2,7 @@ from . import converters from ..base.backend import BaseBackend -from .renderer import Scripts, Hostapd, Hostname, Interfaces, Ntp, Resolv +from .renderer import Hostapd, Hostname, Interfaces, Ntp, Resolv, Scripts from .schema import schema From 92407fd6b04302796da9f7aa69cde046d1c49398 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Tue, 25 Jul 2017 18:23:38 +0530 Subject: [PATCH 118/183] [raspbian] Added default value to autostart --- netjsonconfig/backends/raspbian/converters/interfaces.py | 2 ++ netjsonconfig/backends/raspbian/templates/interfaces.jinja2 | 2 ++ 2 files changed, 4 insertions(+) diff --git a/netjsonconfig/backends/raspbian/converters/interfaces.py b/netjsonconfig/backends/raspbian/converters/interfaces.py index bf335cfa8..e0353aa51 100644 --- a/netjsonconfig/backends/raspbian/converters/interfaces.py +++ b/netjsonconfig/backends/raspbian/converters/interfaces.py @@ -43,6 +43,8 @@ def _get_interface(self, interface): autostart = interface.get('autostart', False) if autostart: new_interface.update({'autostart': autostart}) + else: + new_interface.update({'autostart': True}) if iftype == 'wireless' and interface.get('wireless').get('mode') == 'adhoc': wireless = interface.get('wireless') new_interface.update({ diff --git a/netjsonconfig/backends/raspbian/templates/interfaces.jinja2 b/netjsonconfig/backends/raspbian/templates/interfaces.jinja2 index c860e9825..083bb3f9d 100644 --- a/netjsonconfig/backends/raspbian/templates/interfaces.jinja2 +++ b/netjsonconfig/backends/raspbian/templates/interfaces.jinja2 @@ -5,7 +5,9 @@ {% for interface in data.interfaces %} {% if interface.iftype in ['ethernet', 'bridge', 'loopback', 'wireless'] %} {% if interface.address %} + {% if interface.autostart %} auto {{ interface.ifname }} + {% endif %} {% for address in interface.address %} {% if address.proto == 'static' %} {% if address.family == 'ipv4' %} From cc2d2e1c4583812d25ea85c5c832f627f9bd2a46 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Wed, 26 Jul 2017 02:12:40 +0530 Subject: [PATCH 119/183] [raspbian] Fixed autostart default value --- netjsonconfig/backends/raspbian/converters/interfaces.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/netjsonconfig/backends/raspbian/converters/interfaces.py b/netjsonconfig/backends/raspbian/converters/interfaces.py index e0353aa51..28a8a3ac1 100644 --- a/netjsonconfig/backends/raspbian/converters/interfaces.py +++ b/netjsonconfig/backends/raspbian/converters/interfaces.py @@ -40,11 +40,11 @@ def _get_interface(self, interface): txqueuelen = interface.get('txqueuelen', False) if txqueuelen: new_interface.update({'txqueuelen': txqueuelen}) - autostart = interface.get('autostart', False) + autostart = interface.get('autostart', True) if autostart: - new_interface.update({'autostart': autostart}) - else: new_interface.update({'autostart': True}) + else: + new_interface.update({'autostart': False}) if iftype == 'wireless' and interface.get('wireless').get('mode') == 'adhoc': wireless = interface.get('wireless') new_interface.update({ From f40e85a4cfc54a97f29ed1270d75a9e7d1c2b041 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Wed, 26 Jul 2017 03:16:14 +0530 Subject: [PATCH 120/183] [raspbian] Updated schema --- netjsonconfig/backends/raspbian/schema.py | 842 ++++++++++++++++++++++ 1 file changed, 842 insertions(+) diff --git a/netjsonconfig/backends/raspbian/schema.py b/netjsonconfig/backends/raspbian/schema.py index 6fdf3589c..fb177fdb3 100644 --- a/netjsonconfig/backends/raspbian/schema.py +++ b/netjsonconfig/backends/raspbian/schema.py @@ -87,3 +87,845 @@ } } }) + +schema = { + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "definitions": { + "base_address": { + "type": "object", + "additionalProperties": True, + "required": [ + "proto", + "family", + ], + "properties": { + "proto": { + "title": "protocol", + "type": "string", + "propertyOrder": 1, + }, + "family": { + "type": "string", + "propertyOrder": 2, + } + } + }, + "static_address": { + "required": [ + "address", + "mask" + ], + "properties": { + "address": { + "type": "string", + "propertyOrder": 3, + }, + "mask": { + "type": "integer", + "propertyOrder": 4, + }, + "gateway": { + "type": "string", + "propertyOrder": 5, + } + } + }, + "ipv4_address": { + "title": "ipv4", + "allOf": [ + {"$ref": "#/definitions/base_address"}, + {"$ref": "#/definitions/static_address"}, + { + "type": "object", + "properties": { + "proto": {"enum": ["static"]}, + "family": {"enum": ["ipv4"]}, + "address": { + "title": "ipv4 address", + "minLength": 7, + "maxLength": 15, + "format": "ipv4", + }, + "mask": { + "minimum": 8, + "maxmium": 32, + "default": 24, + }, + "gateway": { + "title": "ipv4 gateway", + "description": "optional ipv4 gateway", + "maxLength": 16, + } + } + } + ] + }, + "ipv6_address": { + "title": "ipv6", + "allOf": [ + {"$ref": "#/definitions/base_address"}, + {"$ref": "#/definitions/static_address"}, + { + "type": "object", + "required": [ + "address", + "mask" + ], + "properties": { + "proto": {"enum": ["static"]}, + "family": {"enum": ["ipv6"]}, + "address": { + "title": "ipv6 address", + "minLength": 3, + "maxLength": 45, + "format": "ipv6", + "propertyOrder": 3, + }, + "mask": { + "minimum": 4, + "maxmium": 128, + "default": 64, + }, + "gateway": { + "title": "ipv6 gateway", + "description": "optional ipv6 gateway", + "maxLength": 45, + } + } + } + ] + }, + "dhcp_address": { + "title": "DHCP", + "allOf": [ + {"$ref": "#/definitions/base_address"}, + { + "type": "object", + "properties": { + "proto": {"enum": ["dhcp"]}, + "family": {"enum": ["ipv4", "ipv6"]} + } + } + ] + }, + "interface_settings": { + "type": "object", + "title": "Interface settings", + "additionalProperties": True, + "required": [ + "name", + "type" + ], + "properties": { + "name": { + "type": "string", + "minLength": 2, + "maxLength": 15, + "pattern": "^[^\\s]*$", + "propertyOrder": 0, + }, + "mtu": { + "type": "integer", + "title": "Mtu", + "default": 1500, + "minimum": 68, + "propertyOrder": 2, + }, + "mac": { + "type": "string", + "title": "Mac address", + "description": "if specified overrides default macaddress for this interface", + "pattern": "^(([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})|)$", # can be empty + "maxLength": 17, + "propertyOrder": 3, + }, + "autostart": { + "type": "boolean", + "title": "Autostart", + "description": "bring up interface on boot", + "default": True, + "format": "checkbox", + "propertyOrder": 5, + }, + "disabled": { + "type": "boolean", + "description": "disable this interface without deleting its configuration", + "default": False, + "format": "checkbox", + "propertyOrder": 6, + }, + "addresses": { + "type": "array", + "title": "Addresses", + "uniqueItems": True, + "additionalItems": True, + "propertyOrder": 20, + "items": { + "title": "Address", + "oneOf": [ + {"$ref": "#/definitions/dhcp_address"}, + {"$ref": "#/definitions/ipv4_address"}, + {"$ref": "#/definitions/ipv6_address"}, + ] + } + } + } + }, + "network_interface": { + "title": "Network interface", + "allOf": [ + { + "properties": { + "type": { + "type": "string", + "enum": [ + "ethernet", + "virtual", + "loopback" + ], + "propertyOrder": 1, + } + } + }, + {"$ref": "#/definitions/interface_settings"} + ] + }, + "wireless_interface": { + "title": "Wireless interface", + "allOf": [ + { + "properties": { + "type": { + "type": "string", + "enum": ["wireless"], + "default": "wireless", + "propertyOrder": 1, + }, + "wireless": { + "type": "object", + "propertyOrder": 10, + "oneOf": [ + {"$ref": "#/definitions/ap_wireless_settings"}, + {"$ref": "#/definitions/adhoc_wireless_settings"}, + {"$ref": "#/definitions/mesh_wireless_settings"}, + ] + } + } + }, + {"$ref": "#/definitions/interface_settings"}, + ] + }, + "bridge_interface": { + "title": "Bridge interface", + "required": [ + "bridge_members" + ], + "allOf": [ + { + "properties": { + "type": { + "type": "string", + "enum": ["bridge"], + "propertyOrder": 1 + }, + "bridge_members": { + "type": "array", + "title": "Bridge Members", + "uniqueItems": True, + "propertyOrder": 8, + "items": { + "title": "bridged interface", + "type": "string", + "$ref": "#/definitions/interface_settings/properties/name" + } + } + } + }, + {"$ref": "#/definitions/interface_settings"}, + ] + }, + "ssid_wireless_property": { + "required": ["ssid"], + "properties": { + "ssid": { + "type": "string", + "title": "SSID", + "maxLength": 32, + "propertyOrder": 3, + } + } + }, + "hidden_wireless_property": { + "properties": { + "hidden": { + "type": "boolean", + "title": "hide SSID", + "default": False, + "format": "checkbox", + "propertyOrder": 4, + } + } + }, + "bssid_wireless_property": { + "properties": { + "bssid": { + "type": "string", + "title": "BSSID", + "pattern": "^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$", + "minLength": 17, + "maxLength": 17, + "propertyOrder": 4, + }, + } + }, + "encryption_wireless_property_ap": { + "properties": { + "encryption": { + "type": "object", + "title": "Encryption", + "required": ["protocol"], + "propertyOrder": 20, + "oneOf": [ + {"$ref": "#/definitions/encryption_none"}, + {"$ref": "#/definitions/encryption_wpa_personal"}, + {"$ref": "#/definitions/encryption_wpa_enterprise_ap"}, + {"$ref": "#/definitions/encryption_wps"}, + {"$ref": "#/definitions/encryption_wep"}, + ] + } + } + }, + "encryption_none": { + "title": "No encryption", + "properties": { + "protocol": { + "type": "string", + "title": "encryption protocol", + "enum": ["none"], + "options": {"enum_titles": ["No encryption"]} + } + } + }, + "encryption_base_settings": { + "required": ["key"], + "additionalProperties": True, + "properties": { + "protocol": { + "type": "string", + "title": "encryption protocol", + "propertyOrder": 1, + }, + "key": { + "type": "string", + "propertyOrder": 2, + }, + "disabled": { + "type": "boolean", + "default": False, + "format": "checkbox", + "propertyOrder": 20, + }, + } + }, + "encryption_cipher_property": { + "properties": { + "cipher": { + "type": "string", + "enum": [ + "auto", + "ccmp", + "tkip", + "tkip+ccmp" + ], + "options": { + "enum_titles": [ + "auto", + "Force CCMP (AES)", + "Force TKIP", + "FORCE TKIP and CCMP (AES)" + ] + }, + "propertyOrder": 3 + } + } + }, + "encryption_wpa_personal": { + "title": "WPA2/WPA Personal", + "allOf": [ + {"$ref": "#/definitions/encryption_base_settings"}, + {"$ref": "#/definitions/encryption_cipher_property"}, + { + "properties": { + "protocol": { + "enum": [ + "wpa2_personal", + "wpa_personal_mixed", + "wpa_personal", + ], + "options": { + "enum_titles": [ + "WPA2 Personal", + "WPA Personal Mixed Mode", + "WPA Personal", + ] + } + }, + "key": { + "minLength": 8 + } + } + } + ] + }, + "encryption_wpa_enterprise_base_settings": { + "properties": { + "protocol": { + "type": "string", + "title": "encryption protocol", + "enum": [ + "wpa2_enterprise", + "wpa_enterprise_mixed", + "wpa_enterprise", + ], + "options": { + "enum_titles": [ + "WPA2 Enterprise", + "WPA Enterprise Mixed Mode", + "WPA Enterprise", + ] + }, + "propertyOrder": 1 + } + } + }, + "encryption_wpa_enterprise_ap": { + "title": "WPA2/WPA Enterprise (access point)", + "allOf": [ + {"$ref": "#/definitions/encryption_base_settings"}, + {"$ref": "#/definitions/encryption_cipher_property"}, + {"$ref": "#/definitions/encryption_wpa_enterprise_base_settings"}, + { + "required": ["server"], + "properties": { + "server": { + "type": "string", + "minLength": 3, + "title": "radius server", + "propertyOrder": 4, + }, + "key": { + "title": "shared secret", + "minLength": 4, + "propertyOrder": 5, + }, + "port": { + "type": "integer", + "title": "radius port", + "default": 1812, + "propertyOrder": 6, + }, + "acct_server": { + "type": "string", + "title": "accounting server", + "propertyOrder": 7, + }, + "acct_server_port": { + "type": "integer", + "title": "accounting port", + "default": 1813, + "propertyOrder": 8, + }, + } + } + ] + }, + "encryption_wep": { + "title": "WEP (Open System/Shared Key)", + "description": "WEP encryption is insecure and its use is discouraged.", + "allOf": [ + {"$ref": "#/definitions/encryption_base_settings"}, + { + "properties": { + "protocol": { + "enum": [ + "wep_open", + "wep_shared" + ], + "options": { + "enum_titles": [ + "WEP Open System", + "WEP Shared Key" + ] + } + }, + "key": { + "minLength": 5, + "maxLength": 26 + } + } + } + ] + }, + "ap_wireless_settings": { + "title": "Access Point", + "allOf": [ + { + "properties": { + "mode": { + "enum": ["access_point"], + "options": {"enum_titles": ["access point"]} + } + } + }, + {"$ref": "#/definitions/base_wireless_settings"}, + {"$ref": "#/definitions/ssid_wireless_property"}, + {"$ref": "#/definitions/hidden_wireless_property"}, + {"$ref": "#/definitions/encryption_wireless_property_ap"}, + ] + }, + "adhoc_wireless_settings": { + "title": "Adhoc", + "allOf": [ + {"properties": {"mode": {"enum": ["adhoc"]}}}, + {"$ref": "#/definitions/base_wireless_settings"}, + {"$ref": "#/definitions/ssid_wireless_property"}, + {"$ref": "#/definitions/bssid_wireless_property"}, + {"$ref": "#/definitions/encryption_wireless_property_mesh"}, + ] + }, + "base_radio_settings": { + "type": "object", + "additionalProperties": True, + "required": [ + "protocol", + "name", + "channel", + "channel_width", + ], + "properties": { + "name": { + "type": "string", + "propertyOrder": 1, + "minLength": 3 + }, + "protocol": { + "type": "string", + "propertyOrder": 2, + }, + "phy": { + "type": "string", + "propertyOrder": 3, + }, + "channel": { + "type": "integer", + "propertyOrder": 4, + }, + "channel_width": { + "type": "integer", + "title": "channel width (mhz)", + "propertyOrder": 5, + }, + "tx_power": { + "type": "integer", + "title": "transmit power (dbm)", + "propertyOrder": 6, + }, + "country": { + "type": "string", + "maxLength": 2, + "default": "00", + "enum": list(countries.values()), + "options": {"enum_titles": list(countries.keys())}, + "propertyOrder": 7, + }, + "disabled": { + "type": "boolean", + "default": False, + "format": "checkbox", + "propertyOrder": 9, + } + } + }, + "radio_2ghz_channels": { + "properties": { + "channel": { + "enum": channels_2ghz, + "options": {"enum_titles": ['auto']} + } + } + }, + "radio_5ghz_channels": { + "properties": { + "channel": { + "enum": channels_5ghz, + "options": {"enum_titles": ['auto']} + } + } + }, + "radio_2and5_channels": { + "properties": { + "channel": { + "enum": channels_2and5, + "options": {"enum_titles": ['auto']} + } + } + }, + "radio_legacy_channel_width": { + "properties": {"channel_width": {"enum": [20]}} + }, + "radio_n_channel_width": { + "properties": {"channel_width": {"enum": [20, 40]}} + }, + "radio_ac_channel_width": { + "properties": {"channel_width": {"enum": [20, 40, 80, 160]}} + }, + "radio_80211bg_settings": { + "title": "802.11b/g (2.4 GHz legacy)", + "allOf": [ + {"properties": {"protocol": {"enum": ["802.11b", "802.11g"]}}}, + {"$ref": "#/definitions/base_radio_settings"}, + {"$ref": "#/definitions/radio_2ghz_channels"}, + {"$ref": "#/definitions/radio_legacy_channel_width"} + ] + }, + "radio_80211a_settings": { + "title": "802.11a (5 GHz legacy)", + "allOf": [ + {"properties": {"protocol": {"enum": ["802.11a"]}}}, + {"$ref": "#/definitions/base_radio_settings"}, + {"$ref": "#/definitions/radio_5ghz_channels"}, + {"$ref": "#/definitions/radio_legacy_channel_width"} + ] + }, + "radio_80211gn_settings": { + "title": "802.11n (2.4 GHz N)", + "allOf": [ + {"properties": {"protocol": {"enum": ["802.11n"]}}}, + {"$ref": "#/definitions/base_radio_settings"}, + {"$ref": "#/definitions/radio_2ghz_channels"}, + {"$ref": "#/definitions/radio_n_channel_width"}, + ] + }, + "radio_80211an_settings": { + "title": "802.11n (5 GHz N)", + "allOf": [ + {"properties": {"protocol": {"enum": ["802.11n"]}}}, + {"$ref": "#/definitions/base_radio_settings"}, + {"$ref": "#/definitions/radio_5ghz_channels"}, + {"$ref": "#/definitions/radio_n_channel_width"}, + ] + }, + "radio_80211ac_2ghz_settings": { + "title": "802.11ac (2.4 GHz AC)", + "allOf": [ + {"properties": {"protocol": {"enum": ["802.11ac"]}}}, + {"$ref": "#/definitions/base_radio_settings"}, + {"$ref": "#/definitions/radio_2ghz_channels"}, + {"$ref": "#/definitions/radio_ac_channel_width"}, + ] + }, + "radio_80211ac_5ghz_settings": { + "title": "802.11ac (5 GHz AC)", + "allOf": [ + {"properties": {"protocol": {"enum": ["802.11ac"]}}}, + {"$ref": "#/definitions/base_radio_settings"}, + {"$ref": "#/definitions/radio_5ghz_channels"}, + {"$ref": "#/definitions/radio_ac_channel_width"}, + ] + }, + "radio_hwmode_11g": { + "properties": { + "hwmode": { + "type": "string", + "title": "hardware mode", + "readOnly": True, + "propertyOrder": 8, + "default": "11g", + "enum": ["11g"], + } + } + }, + "radio_hwmode_11a": { + "properties": { + "hwmode": { + "type": "string", + "title": "hardware mode", + "readOnly": True, + "propertyOrder": 8, + "default": "11a", + "enum": ["11a"], + } + } + }, + "radio_80211gn_settings": { + "allOf": [{"$ref": "#/definitions/radio_hwmode_11g"}] + }, + "radio_80211an_settings": { + "allOf": [{"$ref": "#/definitions/radio_hwmode_11a"}] + }, + "radio_80211ac_2ghz_settings": { + "allOf": [{"$ref": "#/definitions/radio_hwmode_11g"}] + }, + "radio_80211ac_5ghz_settings": { + "allOf": [{"$ref": "#/definitions/radio_hwmode_11a"}] + }, + }, + "properties": { + "general": { + "type": "object", + "title": "General", + "additionalProperties": True, + "propertyOrder": 1, + "properties": { + "hostname": { + "type": "string", + "maxLength": 63, + "minLength": 1, + "format": "hostname", + "propertyOrder": 1, + }, + "timezone": { + "enum": list(timezones.keys()), + "default": "UTC", + } + } + }, + "interfaces": { + "type": "array", + "title": "Interfaces", + "uniqueItems": True, + "additionalItems": True, + "propertyOrder": 2, + "items": { + "title": "Interface", + "oneOf": [ + {"$ref": "#/definitions/network_interface"}, + {"$ref": "#/definitions/wireless_interface"}, + {"$ref": "#/definitions/bridge_interface"} + ] + } + }, + "radios": { + "type": "array", + "title": "Radios", + "uniqueItems": True, + "additionalItems": True, + "propertyOrder": 3, + "items": { + "title": "Radio", + "oneOf": [ + {"$ref": "#/definitions/radio_80211gn_settings"}, + {"$ref": "#/definitions/radio_80211an_settings"}, + {"$ref": "#/definitions/radio_80211ac_2ghz_settings"}, + {"$ref": "#/definitions/radio_80211ac_5ghz_settings"}, + {"$ref": "#/definitions/radio_80211bg_settings"}, + {"$ref": "#/definitions/radio_80211a_settings"}, + ] + } + }, + "dns_servers": { + "title": "DNS Configuration", + "type": "array", + "uniqueItems": True, + "additionalItems": True, + "propertyOrder": 4, + "items": { + "title": "DNS Server", + "type": "string" + } + }, + "dns_search": { + "title": "DNS Search Domains", + "type": "array", + "uniqueItems": True, + "additionalItems": True, + "propertyOrder": 5, + "items": { + "title": "Domain", + "type": "string", + "format": "hostname" + } + }, + "routes": { + "type": "array", + "title": "Static routes", + "uniqueItems": True, + "additionalItems": True, + "propertyOrder": 6, + "items": { + "type": "object", + "title": "Route", + "additionalProperties": True, + "required": [ + "device", + "destination", + "next", + "cost" + ], + "properties": { + "device": { + "type": "string", + "description": "interface name of the to which the static route should apply", + "propertyOrder": 1, + }, + "destination": { + "type": "string", + "propertyOrder": 2, + }, + "next": { + "title": "next hop", + "type": "string", + "propertyOrder": 2, + }, + "cost": { + "type": "integer", + "propertyOrder": 4, + "default": 0, + }, + "source": { + "type": "string", + "description": "the preferred source address when sending to destinations " + "covered by the target (optional)", + "propertyOrder": 5, + } + } + } + }, + "ntp": { + "type": "object", + "title": "NTP Settings", + "additionalProperties": True, + "propertyOrder": 8, + "properties": { + "enabled": { + "type": "boolean", + "title": "enable NTP client", + "default": True, + "format": "checkbox", + "propertyOrder": 1, + }, + "enable_server": { + "type": "boolean", + "title": "enable NTP server", + "default": False, + "format": "checkbox", + "propertyOrder": 2, + }, + "server": { + "title": "NTP Servers", + "description": "NTP server candidates", + "type": "array", + "uniqueItems": True, + "additionalItems": True, + "propertyOrder": 3, + "items": { + "title": "NTP server", + "type": "string", + "format": "hostname" + }, + } + } + } + } +} From 450da4b4a3b4e27af6131e3fd5e449cb9c69c507 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Wed, 26 Jul 2017 03:28:55 +0530 Subject: [PATCH 121/183] [raspbian] Updated schema --- netjsonconfig/backends/raspbian/schema.py | 174 +++++++++++----------- 1 file changed, 89 insertions(+), 85 deletions(-) diff --git a/netjsonconfig/backends/raspbian/schema.py b/netjsonconfig/backends/raspbian/schema.py index fb177fdb3..9e2e6f451 100644 --- a/netjsonconfig/backends/raspbian/schema.py +++ b/netjsonconfig/backends/raspbian/schema.py @@ -1,92 +1,94 @@ +from ...channels import channels_2and5, channels_2ghz, channels_5ghz +from ...countries import countries from ...schema import schema as default_schema from ...utils import merge_config from ..openwrt.timezones import timezones -schema = merge_config(default_schema, { - "definitions": { - "radio_hwmode_11g": { - "properties": { - "hwmode": { - "type": "string", - "title": "hardware mode", - "readOnly": True, - "propertyOrder": 8, - "default": "11g", - "enum": ["11g"], - } - } - }, - "radio_hwmode_11a": { - "properties": { - "hwmode": { - "type": "string", - "title": "hardware mode", - "readOnly": True, - "propertyOrder": 8, - "default": "11a", - "enum": ["11a"], - } - } - }, - "radio_80211gn_settings": { - "allOf": [{"$ref": "#/definitions/radio_hwmode_11g"}] - }, - "radio_80211an_settings": { - "allOf": [{"$ref": "#/definitions/radio_hwmode_11a"}] - }, - "radio_80211ac_2ghz_settings": { - "allOf": [{"$ref": "#/definitions/radio_hwmode_11g"}] - }, - "radio_80211ac_5ghz_settings": { - "allOf": [{"$ref": "#/definitions/radio_hwmode_11a"}] - }, - }, - "properties": { - "general": { - "properties": { - "timezone": { - "enum": list(timezones.keys()), - "default": "UTC", - } - } - }, - "ntp": { - "type": "object", - "title": "NTP Settings", - "additionalProperties": True, - "propertyOrder": 8, - "properties": { - "enabled": { - "type": "boolean", - "title": "enable NTP client", - "default": True, - "format": "checkbox", - "propertyOrder": 1, - }, - "enable_server": { - "type": "boolean", - "title": "enable NTP server", - "default": False, - "format": "checkbox", - "propertyOrder": 2, - }, - "server": { - "title": "NTP Servers", - "description": "NTP server candidates", - "type": "array", - "uniqueItems": True, - "additionalItems": True, - "propertyOrder": 3, - "items": { - "title": "NTP server", - "type": "string", - "format": "hostname" - }, - } - } - } - } -}) +# schema = merge_config(default_schema, { +# "definitions": { +# "radio_hwmode_11g": { +# "properties": { +# "hwmode": { +# "type": "string", +# "title": "hardware mode", +# "readOnly": True, +# "propertyOrder": 8, +# "default": "11g", +# "enum": ["11g"], +# } +# } +# }, +# "radio_hwmode_11a": { +# "properties": { +# "hwmode": { +# "type": "string", +# "title": "hardware mode", +# "readOnly": True, +# "propertyOrder": 8, +# "default": "11a", +# "enum": ["11a"], +# } +# } +# }, +# "radio_80211gn_settings": { +# "allOf": [{"$ref": "#/definitions/radio_hwmode_11g"}] +# }, +# "radio_80211an_settings": { +# "allOf": [{"$ref": "#/definitions/radio_hwmode_11a"}] +# }, +# "radio_80211ac_2ghz_settings": { +# "allOf": [{"$ref": "#/definitions/radio_hwmode_11g"}] +# }, +# "radio_80211ac_5ghz_settings": { +# "allOf": [{"$ref": "#/definitions/radio_hwmode_11a"}] +# }, +# }, +# "properties": { +# "general": { +# "properties": { +# "timezone": { +# "enum": list(timezones.keys()), +# "default": "UTC", +# } +# } +# }, +# "ntp": { +# "type": "object", +# "title": "NTP Settings", +# "additionalProperties": True, +# "propertyOrder": 8, +# "properties": { +# "enabled": { +# "type": "boolean", +# "title": "enable NTP client", +# "default": True, +# "format": "checkbox", +# "propertyOrder": 1, +# }, +# "enable_server": { +# "type": "boolean", +# "title": "enable NTP server", +# "default": False, +# "format": "checkbox", +# "propertyOrder": 2, +# }, +# "server": { +# "title": "NTP Servers", +# "description": "NTP server candidates", +# "type": "array", +# "uniqueItems": True, +# "additionalItems": True, +# "propertyOrder": 3, +# "items": { +# "title": "NTP server", +# "type": "string", +# "format": "hostname" +# }, +# } +# } +# } +# } +# }) schema = { "$schema": "http://json-schema.org/draft-04/schema#", @@ -786,6 +788,8 @@ "propertyOrder": 1, }, "timezone": { + "type": "string", + "propertyOrder": 1, "enum": list(timezones.keys()), "default": "UTC", } From cf579b822f33a96dd329bbec783ce34355d87f64 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Wed, 26 Jul 2017 13:56:42 +0530 Subject: [PATCH 122/183] [raspbian] Updated schema --- netjsonconfig/backends/raspbian/schema.py | 830 +--------------------- 1 file changed, 3 insertions(+), 827 deletions(-) diff --git a/netjsonconfig/backends/raspbian/schema.py b/netjsonconfig/backends/raspbian/schema.py index 9e2e6f451..21179cf85 100644 --- a/netjsonconfig/backends/raspbian/schema.py +++ b/netjsonconfig/backends/raspbian/schema.py @@ -4,275 +4,10 @@ from ...utils import merge_config from ..openwrt.timezones import timezones -# schema = merge_config(default_schema, { -# "definitions": { -# "radio_hwmode_11g": { -# "properties": { -# "hwmode": { -# "type": "string", -# "title": "hardware mode", -# "readOnly": True, -# "propertyOrder": 8, -# "default": "11g", -# "enum": ["11g"], -# } -# } -# }, -# "radio_hwmode_11a": { -# "properties": { -# "hwmode": { -# "type": "string", -# "title": "hardware mode", -# "readOnly": True, -# "propertyOrder": 8, -# "default": "11a", -# "enum": ["11a"], -# } -# } -# }, -# "radio_80211gn_settings": { -# "allOf": [{"$ref": "#/definitions/radio_hwmode_11g"}] -# }, -# "radio_80211an_settings": { -# "allOf": [{"$ref": "#/definitions/radio_hwmode_11a"}] -# }, -# "radio_80211ac_2ghz_settings": { -# "allOf": [{"$ref": "#/definitions/radio_hwmode_11g"}] -# }, -# "radio_80211ac_5ghz_settings": { -# "allOf": [{"$ref": "#/definitions/radio_hwmode_11a"}] -# }, -# }, -# "properties": { -# "general": { -# "properties": { -# "timezone": { -# "enum": list(timezones.keys()), -# "default": "UTC", -# } -# } -# }, -# "ntp": { -# "type": "object", -# "title": "NTP Settings", -# "additionalProperties": True, -# "propertyOrder": 8, -# "properties": { -# "enabled": { -# "type": "boolean", -# "title": "enable NTP client", -# "default": True, -# "format": "checkbox", -# "propertyOrder": 1, -# }, -# "enable_server": { -# "type": "boolean", -# "title": "enable NTP server", -# "default": False, -# "format": "checkbox", -# "propertyOrder": 2, -# }, -# "server": { -# "title": "NTP Servers", -# "description": "NTP server candidates", -# "type": "array", -# "uniqueItems": True, -# "additionalItems": True, -# "propertyOrder": 3, -# "items": { -# "title": "NTP server", -# "type": "string", -# "format": "hostname" -# }, -# } -# } -# } -# } -# }) - -schema = { - "$schema": "http://json-schema.org/draft-04/schema#", - "type": "object", +schema = merge_config(default_schema, { "definitions": { - "base_address": { - "type": "object", - "additionalProperties": True, - "required": [ - "proto", - "family", - ], - "properties": { - "proto": { - "title": "protocol", - "type": "string", - "propertyOrder": 1, - }, - "family": { - "type": "string", - "propertyOrder": 2, - } - } - }, - "static_address": { - "required": [ - "address", - "mask" - ], - "properties": { - "address": { - "type": "string", - "propertyOrder": 3, - }, - "mask": { - "type": "integer", - "propertyOrder": 4, - }, - "gateway": { - "type": "string", - "propertyOrder": 5, - } - } - }, - "ipv4_address": { - "title": "ipv4", - "allOf": [ - {"$ref": "#/definitions/base_address"}, - {"$ref": "#/definitions/static_address"}, - { - "type": "object", - "properties": { - "proto": {"enum": ["static"]}, - "family": {"enum": ["ipv4"]}, - "address": { - "title": "ipv4 address", - "minLength": 7, - "maxLength": 15, - "format": "ipv4", - }, - "mask": { - "minimum": 8, - "maxmium": 32, - "default": 24, - }, - "gateway": { - "title": "ipv4 gateway", - "description": "optional ipv4 gateway", - "maxLength": 16, - } - } - } - ] - }, - "ipv6_address": { - "title": "ipv6", - "allOf": [ - {"$ref": "#/definitions/base_address"}, - {"$ref": "#/definitions/static_address"}, - { - "type": "object", - "required": [ - "address", - "mask" - ], - "properties": { - "proto": {"enum": ["static"]}, - "family": {"enum": ["ipv6"]}, - "address": { - "title": "ipv6 address", - "minLength": 3, - "maxLength": 45, - "format": "ipv6", - "propertyOrder": 3, - }, - "mask": { - "minimum": 4, - "maxmium": 128, - "default": 64, - }, - "gateway": { - "title": "ipv6 gateway", - "description": "optional ipv6 gateway", - "maxLength": 45, - } - } - } - ] - }, - "dhcp_address": { - "title": "DHCP", - "allOf": [ - {"$ref": "#/definitions/base_address"}, - { - "type": "object", - "properties": { - "proto": {"enum": ["dhcp"]}, - "family": {"enum": ["ipv4", "ipv6"]} - } - } - ] - }, "interface_settings": { - "type": "object", - "title": "Interface settings", - "additionalProperties": True, - "required": [ - "name", - "type" - ], - "properties": { - "name": { - "type": "string", - "minLength": 2, - "maxLength": 15, - "pattern": "^[^\\s]*$", - "propertyOrder": 0, - }, - "mtu": { - "type": "integer", - "title": "Mtu", - "default": 1500, - "minimum": 68, - "propertyOrder": 2, - }, - "mac": { - "type": "string", - "title": "Mac address", - "description": "if specified overrides default macaddress for this interface", - "pattern": "^(([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})|)$", # can be empty - "maxLength": 17, - "propertyOrder": 3, - }, - "autostart": { - "type": "boolean", - "title": "Autostart", - "description": "bring up interface on boot", - "default": True, - "format": "checkbox", - "propertyOrder": 5, - }, - "disabled": { - "type": "boolean", - "description": "disable this interface without deleting its configuration", - "default": False, - "format": "checkbox", - "propertyOrder": 6, - }, - "addresses": { - "type": "array", - "title": "Addresses", - "uniqueItems": True, - "additionalItems": True, - "propertyOrder": 20, - "items": { - "title": "Address", - "oneOf": [ - {"$ref": "#/definitions/dhcp_address"}, - {"$ref": "#/definitions/ipv4_address"}, - {"$ref": "#/definitions/ipv6_address"}, - ] - } - } - } + "additionalProperties": False, }, "network_interface": { "title": "Network interface", @@ -280,462 +15,17 @@ { "properties": { "type": { - "type": "string", "enum": [ "ethernet", "virtual", "loopback" ], - "propertyOrder": 1, } } }, {"$ref": "#/definitions/interface_settings"} ] }, - "wireless_interface": { - "title": "Wireless interface", - "allOf": [ - { - "properties": { - "type": { - "type": "string", - "enum": ["wireless"], - "default": "wireless", - "propertyOrder": 1, - }, - "wireless": { - "type": "object", - "propertyOrder": 10, - "oneOf": [ - {"$ref": "#/definitions/ap_wireless_settings"}, - {"$ref": "#/definitions/adhoc_wireless_settings"}, - {"$ref": "#/definitions/mesh_wireless_settings"}, - ] - } - } - }, - {"$ref": "#/definitions/interface_settings"}, - ] - }, - "bridge_interface": { - "title": "Bridge interface", - "required": [ - "bridge_members" - ], - "allOf": [ - { - "properties": { - "type": { - "type": "string", - "enum": ["bridge"], - "propertyOrder": 1 - }, - "bridge_members": { - "type": "array", - "title": "Bridge Members", - "uniqueItems": True, - "propertyOrder": 8, - "items": { - "title": "bridged interface", - "type": "string", - "$ref": "#/definitions/interface_settings/properties/name" - } - } - } - }, - {"$ref": "#/definitions/interface_settings"}, - ] - }, - "ssid_wireless_property": { - "required": ["ssid"], - "properties": { - "ssid": { - "type": "string", - "title": "SSID", - "maxLength": 32, - "propertyOrder": 3, - } - } - }, - "hidden_wireless_property": { - "properties": { - "hidden": { - "type": "boolean", - "title": "hide SSID", - "default": False, - "format": "checkbox", - "propertyOrder": 4, - } - } - }, - "bssid_wireless_property": { - "properties": { - "bssid": { - "type": "string", - "title": "BSSID", - "pattern": "^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$", - "minLength": 17, - "maxLength": 17, - "propertyOrder": 4, - }, - } - }, - "encryption_wireless_property_ap": { - "properties": { - "encryption": { - "type": "object", - "title": "Encryption", - "required": ["protocol"], - "propertyOrder": 20, - "oneOf": [ - {"$ref": "#/definitions/encryption_none"}, - {"$ref": "#/definitions/encryption_wpa_personal"}, - {"$ref": "#/definitions/encryption_wpa_enterprise_ap"}, - {"$ref": "#/definitions/encryption_wps"}, - {"$ref": "#/definitions/encryption_wep"}, - ] - } - } - }, - "encryption_none": { - "title": "No encryption", - "properties": { - "protocol": { - "type": "string", - "title": "encryption protocol", - "enum": ["none"], - "options": {"enum_titles": ["No encryption"]} - } - } - }, - "encryption_base_settings": { - "required": ["key"], - "additionalProperties": True, - "properties": { - "protocol": { - "type": "string", - "title": "encryption protocol", - "propertyOrder": 1, - }, - "key": { - "type": "string", - "propertyOrder": 2, - }, - "disabled": { - "type": "boolean", - "default": False, - "format": "checkbox", - "propertyOrder": 20, - }, - } - }, - "encryption_cipher_property": { - "properties": { - "cipher": { - "type": "string", - "enum": [ - "auto", - "ccmp", - "tkip", - "tkip+ccmp" - ], - "options": { - "enum_titles": [ - "auto", - "Force CCMP (AES)", - "Force TKIP", - "FORCE TKIP and CCMP (AES)" - ] - }, - "propertyOrder": 3 - } - } - }, - "encryption_wpa_personal": { - "title": "WPA2/WPA Personal", - "allOf": [ - {"$ref": "#/definitions/encryption_base_settings"}, - {"$ref": "#/definitions/encryption_cipher_property"}, - { - "properties": { - "protocol": { - "enum": [ - "wpa2_personal", - "wpa_personal_mixed", - "wpa_personal", - ], - "options": { - "enum_titles": [ - "WPA2 Personal", - "WPA Personal Mixed Mode", - "WPA Personal", - ] - } - }, - "key": { - "minLength": 8 - } - } - } - ] - }, - "encryption_wpa_enterprise_base_settings": { - "properties": { - "protocol": { - "type": "string", - "title": "encryption protocol", - "enum": [ - "wpa2_enterprise", - "wpa_enterprise_mixed", - "wpa_enterprise", - ], - "options": { - "enum_titles": [ - "WPA2 Enterprise", - "WPA Enterprise Mixed Mode", - "WPA Enterprise", - ] - }, - "propertyOrder": 1 - } - } - }, - "encryption_wpa_enterprise_ap": { - "title": "WPA2/WPA Enterprise (access point)", - "allOf": [ - {"$ref": "#/definitions/encryption_base_settings"}, - {"$ref": "#/definitions/encryption_cipher_property"}, - {"$ref": "#/definitions/encryption_wpa_enterprise_base_settings"}, - { - "required": ["server"], - "properties": { - "server": { - "type": "string", - "minLength": 3, - "title": "radius server", - "propertyOrder": 4, - }, - "key": { - "title": "shared secret", - "minLength": 4, - "propertyOrder": 5, - }, - "port": { - "type": "integer", - "title": "radius port", - "default": 1812, - "propertyOrder": 6, - }, - "acct_server": { - "type": "string", - "title": "accounting server", - "propertyOrder": 7, - }, - "acct_server_port": { - "type": "integer", - "title": "accounting port", - "default": 1813, - "propertyOrder": 8, - }, - } - } - ] - }, - "encryption_wep": { - "title": "WEP (Open System/Shared Key)", - "description": "WEP encryption is insecure and its use is discouraged.", - "allOf": [ - {"$ref": "#/definitions/encryption_base_settings"}, - { - "properties": { - "protocol": { - "enum": [ - "wep_open", - "wep_shared" - ], - "options": { - "enum_titles": [ - "WEP Open System", - "WEP Shared Key" - ] - } - }, - "key": { - "minLength": 5, - "maxLength": 26 - } - } - } - ] - }, - "ap_wireless_settings": { - "title": "Access Point", - "allOf": [ - { - "properties": { - "mode": { - "enum": ["access_point"], - "options": {"enum_titles": ["access point"]} - } - } - }, - {"$ref": "#/definitions/base_wireless_settings"}, - {"$ref": "#/definitions/ssid_wireless_property"}, - {"$ref": "#/definitions/hidden_wireless_property"}, - {"$ref": "#/definitions/encryption_wireless_property_ap"}, - ] - }, - "adhoc_wireless_settings": { - "title": "Adhoc", - "allOf": [ - {"properties": {"mode": {"enum": ["adhoc"]}}}, - {"$ref": "#/definitions/base_wireless_settings"}, - {"$ref": "#/definitions/ssid_wireless_property"}, - {"$ref": "#/definitions/bssid_wireless_property"}, - {"$ref": "#/definitions/encryption_wireless_property_mesh"}, - ] - }, - "base_radio_settings": { - "type": "object", - "additionalProperties": True, - "required": [ - "protocol", - "name", - "channel", - "channel_width", - ], - "properties": { - "name": { - "type": "string", - "propertyOrder": 1, - "minLength": 3 - }, - "protocol": { - "type": "string", - "propertyOrder": 2, - }, - "phy": { - "type": "string", - "propertyOrder": 3, - }, - "channel": { - "type": "integer", - "propertyOrder": 4, - }, - "channel_width": { - "type": "integer", - "title": "channel width (mhz)", - "propertyOrder": 5, - }, - "tx_power": { - "type": "integer", - "title": "transmit power (dbm)", - "propertyOrder": 6, - }, - "country": { - "type": "string", - "maxLength": 2, - "default": "00", - "enum": list(countries.values()), - "options": {"enum_titles": list(countries.keys())}, - "propertyOrder": 7, - }, - "disabled": { - "type": "boolean", - "default": False, - "format": "checkbox", - "propertyOrder": 9, - } - } - }, - "radio_2ghz_channels": { - "properties": { - "channel": { - "enum": channels_2ghz, - "options": {"enum_titles": ['auto']} - } - } - }, - "radio_5ghz_channels": { - "properties": { - "channel": { - "enum": channels_5ghz, - "options": {"enum_titles": ['auto']} - } - } - }, - "radio_2and5_channels": { - "properties": { - "channel": { - "enum": channels_2and5, - "options": {"enum_titles": ['auto']} - } - } - }, - "radio_legacy_channel_width": { - "properties": {"channel_width": {"enum": [20]}} - }, - "radio_n_channel_width": { - "properties": {"channel_width": {"enum": [20, 40]}} - }, - "radio_ac_channel_width": { - "properties": {"channel_width": {"enum": [20, 40, 80, 160]}} - }, - "radio_80211bg_settings": { - "title": "802.11b/g (2.4 GHz legacy)", - "allOf": [ - {"properties": {"protocol": {"enum": ["802.11b", "802.11g"]}}}, - {"$ref": "#/definitions/base_radio_settings"}, - {"$ref": "#/definitions/radio_2ghz_channels"}, - {"$ref": "#/definitions/radio_legacy_channel_width"} - ] - }, - "radio_80211a_settings": { - "title": "802.11a (5 GHz legacy)", - "allOf": [ - {"properties": {"protocol": {"enum": ["802.11a"]}}}, - {"$ref": "#/definitions/base_radio_settings"}, - {"$ref": "#/definitions/radio_5ghz_channels"}, - {"$ref": "#/definitions/radio_legacy_channel_width"} - ] - }, - "radio_80211gn_settings": { - "title": "802.11n (2.4 GHz N)", - "allOf": [ - {"properties": {"protocol": {"enum": ["802.11n"]}}}, - {"$ref": "#/definitions/base_radio_settings"}, - {"$ref": "#/definitions/radio_2ghz_channels"}, - {"$ref": "#/definitions/radio_n_channel_width"}, - ] - }, - "radio_80211an_settings": { - "title": "802.11n (5 GHz N)", - "allOf": [ - {"properties": {"protocol": {"enum": ["802.11n"]}}}, - {"$ref": "#/definitions/base_radio_settings"}, - {"$ref": "#/definitions/radio_5ghz_channels"}, - {"$ref": "#/definitions/radio_n_channel_width"}, - ] - }, - "radio_80211ac_2ghz_settings": { - "title": "802.11ac (2.4 GHz AC)", - "allOf": [ - {"properties": {"protocol": {"enum": ["802.11ac"]}}}, - {"$ref": "#/definitions/base_radio_settings"}, - {"$ref": "#/definitions/radio_2ghz_channels"}, - {"$ref": "#/definitions/radio_ac_channel_width"}, - ] - }, - "radio_80211ac_5ghz_settings": { - "title": "802.11ac (5 GHz AC)", - "allOf": [ - {"properties": {"protocol": {"enum": ["802.11ac"]}}}, - {"$ref": "#/definitions/base_radio_settings"}, - {"$ref": "#/definitions/radio_5ghz_channels"}, - {"$ref": "#/definitions/radio_ac_channel_width"}, - ] - }, "radio_hwmode_11g": { "properties": { "hwmode": { @@ -775,127 +65,13 @@ }, "properties": { "general": { - "type": "object", - "title": "General", - "additionalProperties": True, - "propertyOrder": 1, "properties": { - "hostname": { - "type": "string", - "maxLength": 63, - "minLength": 1, - "format": "hostname", - "propertyOrder": 1, - }, "timezone": { - "type": "string", - "propertyOrder": 1, "enum": list(timezones.keys()), "default": "UTC", } } }, - "interfaces": { - "type": "array", - "title": "Interfaces", - "uniqueItems": True, - "additionalItems": True, - "propertyOrder": 2, - "items": { - "title": "Interface", - "oneOf": [ - {"$ref": "#/definitions/network_interface"}, - {"$ref": "#/definitions/wireless_interface"}, - {"$ref": "#/definitions/bridge_interface"} - ] - } - }, - "radios": { - "type": "array", - "title": "Radios", - "uniqueItems": True, - "additionalItems": True, - "propertyOrder": 3, - "items": { - "title": "Radio", - "oneOf": [ - {"$ref": "#/definitions/radio_80211gn_settings"}, - {"$ref": "#/definitions/radio_80211an_settings"}, - {"$ref": "#/definitions/radio_80211ac_2ghz_settings"}, - {"$ref": "#/definitions/radio_80211ac_5ghz_settings"}, - {"$ref": "#/definitions/radio_80211bg_settings"}, - {"$ref": "#/definitions/radio_80211a_settings"}, - ] - } - }, - "dns_servers": { - "title": "DNS Configuration", - "type": "array", - "uniqueItems": True, - "additionalItems": True, - "propertyOrder": 4, - "items": { - "title": "DNS Server", - "type": "string" - } - }, - "dns_search": { - "title": "DNS Search Domains", - "type": "array", - "uniqueItems": True, - "additionalItems": True, - "propertyOrder": 5, - "items": { - "title": "Domain", - "type": "string", - "format": "hostname" - } - }, - "routes": { - "type": "array", - "title": "Static routes", - "uniqueItems": True, - "additionalItems": True, - "propertyOrder": 6, - "items": { - "type": "object", - "title": "Route", - "additionalProperties": True, - "required": [ - "device", - "destination", - "next", - "cost" - ], - "properties": { - "device": { - "type": "string", - "description": "interface name of the to which the static route should apply", - "propertyOrder": 1, - }, - "destination": { - "type": "string", - "propertyOrder": 2, - }, - "next": { - "title": "next hop", - "type": "string", - "propertyOrder": 2, - }, - "cost": { - "type": "integer", - "propertyOrder": 4, - "default": 0, - }, - "source": { - "type": "string", - "description": "the preferred source address when sending to destinations " - "covered by the target (optional)", - "propertyOrder": 5, - } - } - } - }, "ntp": { "type": "object", "title": "NTP Settings", @@ -932,4 +108,4 @@ } } } -} +}) From b8cb824194723a9ab0301f2883f2c0464994eb34 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Wed, 26 Jul 2017 14:37:02 +0530 Subject: [PATCH 123/183] [raspbian] Added rts_threshold, frag_threshhold and hidden wireless settings --- .../backends/raspbian/converters/wireless.py | 6 ++++++ .../backends/raspbian/templates/hostapd.jinja2 | 11 ++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/netjsonconfig/backends/raspbian/converters/wireless.py b/netjsonconfig/backends/raspbian/converters/wireless.py index 3d1e791ff..52f0a5225 100644 --- a/netjsonconfig/backends/raspbian/converters/wireless.py +++ b/netjsonconfig/backends/raspbian/converters/wireless.py @@ -28,6 +28,12 @@ def to_intermediate(self): 'channel': channel, 'protocol': protocol }) + hidden = wireless.get('hidden', False) + new_interface.update({'hidden': hidden}) + rts_threshold = wireless.get('rts_threshold', -1) + new_interface.update({'rts_threshold': rts_threshold}) + frag_threshold = wireless.get('frag_threshold', -1) + new_interface.update({'frag_threshold': frag_threshold}) new_interface.update({'encryption': self._get_encryption(wireless)}) result.append(new_interface) return (('wireless', result),) diff --git a/netjsonconfig/backends/raspbian/templates/hostapd.jinja2 b/netjsonconfig/backends/raspbian/templates/hostapd.jinja2 index 45d6c9b51..72d887963 100644 --- a/netjsonconfig/backends/raspbian/templates/hostapd.jinja2 +++ b/netjsonconfig/backends/raspbian/templates/hostapd.jinja2 @@ -14,6 +14,15 @@ ieee80211ac=1 {% endif %} ssid={{ wireless.ssid }} + {% if wireless.hidden %} + ignore_broadcast_ssid=1 + {% endif %} + {% if wireless.rts_threshold > 0 %} + rts_threshold={{ wireless.rts_threshold }} + {% endif %} + {% if wireless.frag_threshold > 0 %} + frag_threshold={{ wireless.frag_threshold }} + {% endif %} {% if wireless.encryption %} auth_algs={{ wireless.encryption.auth_algs }} wpa={{ wireless.encryption.wpa }} @@ -23,5 +32,5 @@ wpa_pairwise={{ wireless.encryption.wpa_pairwise }} {% endif %} {% endif %} - + {% endfor %} From bda6e72a560c7965a5a026413b1713167f927eaa Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Wed, 26 Jul 2017 14:44:08 +0530 Subject: [PATCH 124/183] [raspbian] Set additionalProperties back to default --- netjsonconfig/backends/raspbian/schema.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/netjsonconfig/backends/raspbian/schema.py b/netjsonconfig/backends/raspbian/schema.py index 21179cf85..3067d87fd 100644 --- a/netjsonconfig/backends/raspbian/schema.py +++ b/netjsonconfig/backends/raspbian/schema.py @@ -6,9 +6,6 @@ schema = merge_config(default_schema, { "definitions": { - "interface_settings": { - "additionalProperties": False, - }, "network_interface": { "title": "Network interface", "allOf": [ From 9c0eee71f57f0d0ea7831ae6b6329bd930d57487 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Wed, 26 Jul 2017 14:49:59 +0530 Subject: [PATCH 125/183] [raspbian] Fix flake8 warnings --- netjsonconfig/backends/raspbian/schema.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/netjsonconfig/backends/raspbian/schema.py b/netjsonconfig/backends/raspbian/schema.py index 3067d87fd..00c673424 100644 --- a/netjsonconfig/backends/raspbian/schema.py +++ b/netjsonconfig/backends/raspbian/schema.py @@ -1,5 +1,3 @@ -from ...channels import channels_2and5, channels_2ghz, channels_5ghz -from ...countries import countries from ...schema import schema as default_schema from ...utils import merge_config from ..openwrt.timezones import timezones From a13b9828c4f0fa495469f0fc3c84c64817c4ec8c Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Wed, 26 Jul 2017 18:52:51 +0530 Subject: [PATCH 126/183] [raspbian] Added stp setting in bridge interface --- .../backends/raspbian/converters/interfaces.py | 3 ++- .../backends/raspbian/templates/interfaces.jinja2 | 10 ++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/netjsonconfig/backends/raspbian/converters/interfaces.py b/netjsonconfig/backends/raspbian/converters/interfaces.py index 28a8a3ac1..7243939a1 100644 --- a/netjsonconfig/backends/raspbian/converters/interfaces.py +++ b/netjsonconfig/backends/raspbian/converters/interfaces.py @@ -53,7 +53,8 @@ def _get_interface(self, interface): }) if iftype == 'bridge': new_interface.update({ - 'bridge_members': interface.get('bridge_members') + 'bridge_members': interface.get('bridge_members'), + 'stp': interface.get('stp', False) }) return new_interface diff --git a/netjsonconfig/backends/raspbian/templates/interfaces.jinja2 b/netjsonconfig/backends/raspbian/templates/interfaces.jinja2 index 083bb3f9d..a3501756f 100644 --- a/netjsonconfig/backends/raspbian/templates/interfaces.jinja2 +++ b/netjsonconfig/backends/raspbian/templates/interfaces.jinja2 @@ -30,6 +30,10 @@ {% endif %} {% if interface.iftype == 'bridge' %} bridge_ports {{ interface.bridge_members[0] }} {{ interface.bridge_members[1] }} + {{ interface }} + {% if interface.stp %} + bridge_stp {{ interface.stp }} + {% endif %} {% endif %} {% elif address.family == 'ipv6' %} iface {{ interface.ifname }} inet6 {{ address.proto }} @@ -52,6 +56,9 @@ {% if interface.iftype == 'bridge' %} bridge_ports {{ interface.bridge_members[0] }} {{ interface.bridge_members[1] }} {% endif %} + {% if interface.stp %} + bridge_stp {{ interface.stp }} + {% endif %} {% endif %} {% elif address.proto == 'dhcp' %} {% if address.family == 'ipv4'%} @@ -99,6 +106,9 @@ {% if interface.iftype == 'bridge' %} bridge_ports {{ interface.bridge_members[0] }} {{ interface.bridge_members[1] }} {% endif %} + {% if interface.stp %} + bridge_stp {{ interface.stp }} + {% endif %} {% if interface.mode == 'adhoc' %} iface {{ interface.ifname }} inet static address 172.128.1.1 From 0e403a9ea99390fdef050e601c197c569dec4f54 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Wed, 26 Jul 2017 19:38:36 +0530 Subject: [PATCH 127/183] [raspbian] Added country in radio settings --- netjsonconfig/backends/raspbian/converters/wireless.py | 3 +++ netjsonconfig/backends/raspbian/templates/hostapd.jinja2 | 3 +++ 2 files changed, 6 insertions(+) diff --git a/netjsonconfig/backends/raspbian/converters/wireless.py b/netjsonconfig/backends/raspbian/converters/wireless.py index 52f0a5225..2fffe3f6a 100644 --- a/netjsonconfig/backends/raspbian/converters/wireless.py +++ b/netjsonconfig/backends/raspbian/converters/wireless.py @@ -28,6 +28,9 @@ def to_intermediate(self): 'channel': channel, 'protocol': protocol }) + if req_radio['country']: + country = req_radio['country'] + new_interface.update({'country': country}) hidden = wireless.get('hidden', False) new_interface.update({'hidden': hidden}) rts_threshold = wireless.get('rts_threshold', -1) diff --git a/netjsonconfig/backends/raspbian/templates/hostapd.jinja2 b/netjsonconfig/backends/raspbian/templates/hostapd.jinja2 index 72d887963..32aaaa322 100644 --- a/netjsonconfig/backends/raspbian/templates/hostapd.jinja2 +++ b/netjsonconfig/backends/raspbian/templates/hostapd.jinja2 @@ -3,6 +3,9 @@ interface={{ wireless.ifname }} driver=nl80211 + {% if wireless.country %} + country={{ wireless.country }} + {% endif %} {% if wireless.protocol == 'a' or 'b' or 'g' %} hw_mode={{ wireless.hwmode }} {% endif %} From 7a63ab1ee0f67b9af225094adeb69ee0b385e6c7 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Thu, 27 Jul 2017 01:38:26 +0530 Subject: [PATCH 128/183] [raspbian] Updated test --- netjsonconfig/backends/raspbian/converters/wireless.py | 2 +- tests/raspbian/test_radios.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/netjsonconfig/backends/raspbian/converters/wireless.py b/netjsonconfig/backends/raspbian/converters/wireless.py index 2fffe3f6a..a3bc37724 100644 --- a/netjsonconfig/backends/raspbian/converters/wireless.py +++ b/netjsonconfig/backends/raspbian/converters/wireless.py @@ -28,7 +28,7 @@ def to_intermediate(self): 'channel': channel, 'protocol': protocol }) - if req_radio['country']: + if 'country' in req_radio: country = req_radio['country'] new_interface.update({'country': country}) hidden = wireless.get('hidden', False) diff --git a/tests/raspbian/test_radios.py b/tests/raspbian/test_radios.py index 98575c9c3..9d8e3f542 100644 --- a/tests/raspbian/test_radios.py +++ b/tests/raspbian/test_radios.py @@ -47,6 +47,7 @@ def test_radio_multi(self): interface=wlan0 driver=nl80211 +country=IT hw_mode=g channel=11 ieee80211n=1 From 1b7edd41ee3eba04a94075983052a4bfb6d487f2 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Thu, 27 Jul 2017 03:44:39 +0530 Subject: [PATCH 129/183] [raspbian] Added wpa_supplicant template --- netjsonconfig/backends/raspbian/raspbian.py | 5 +++-- netjsonconfig/backends/raspbian/renderer.py | 4 ++++ .../raspbian/templates/wpasupplicant.jinja2 | 18 ++++++++++++++++++ 3 files changed, 25 insertions(+), 2 deletions(-) create mode 100644 netjsonconfig/backends/raspbian/templates/wpasupplicant.jinja2 diff --git a/netjsonconfig/backends/raspbian/raspbian.py b/netjsonconfig/backends/raspbian/raspbian.py index 8465b49b7..f66cac9b5 100644 --- a/netjsonconfig/backends/raspbian/raspbian.py +++ b/netjsonconfig/backends/raspbian/raspbian.py @@ -2,7 +2,7 @@ from . import converters from ..base.backend import BaseBackend -from .renderer import Hostapd, Hostname, Interfaces, Ntp, Resolv, Scripts +from .renderer import Hostapd, Hostname, Interfaces, Ntp, Resolv, Scripts, WpaSupplicant from .schema import schema @@ -22,10 +22,11 @@ class Raspbian(BaseBackend): renderers = [ Hostname, Hostapd, + WpaSupplicant, Interfaces, Resolv, Ntp, - Scripts + Scripts, ] def _generate_contents(self, tar): diff --git a/netjsonconfig/backends/raspbian/renderer.py b/netjsonconfig/backends/raspbian/renderer.py index 9edb1410a..febf2db59 100644 --- a/netjsonconfig/backends/raspbian/renderer.py +++ b/netjsonconfig/backends/raspbian/renderer.py @@ -8,6 +8,10 @@ def cleanup(self, output): pass +class WpaSupplicant(RaspbianRenderer): + pass + + class Scripts(RaspbianRenderer): pass diff --git a/netjsonconfig/backends/raspbian/templates/wpasupplicant.jinja2 b/netjsonconfig/backends/raspbian/templates/wpasupplicant.jinja2 new file mode 100644 index 000000000..9a236da2f --- /dev/null +++ b/netjsonconfig/backends/raspbian/templates/wpasupplicant.jinja2 @@ -0,0 +1,18 @@ +{% if data.wireless and data.wireless[0].mode == 'station' %} + {% for wireless in data.wireless %} + # config: /etc/wpa_supplicant/wpa_supplicant.conf + + network={ + ssid="{{ wireless.ssid }}" + {% if 'wpa' in wireless.encryption %} + {% if wireless.encryption %} + key="{{ wireless.encryption.wpa_passphrase }}" + {% endif %} + {% if wireless.encryption.wpa_key_mgmt %} + key_mgtmt={{ wireless.encryption.wpa_key_mgmt }} + {% endif %} + {% endif %} + } + + {% endfor %} +{% endif %} From 89f88099bbb602299d2245fca56f4f6a7773ff07 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Thu, 27 Jul 2017 03:45:26 +0530 Subject: [PATCH 130/183] [raspbian] Added support for station mode --- .../backends/raspbian/converters/wireless.py | 3 +- .../raspbian/templates/hostapd.jinja2 | 76 ++++++++++--------- 2 files changed, 41 insertions(+), 38 deletions(-) diff --git a/netjsonconfig/backends/raspbian/converters/wireless.py b/netjsonconfig/backends/raspbian/converters/wireless.py index a3bc37724..5709bede5 100644 --- a/netjsonconfig/backends/raspbian/converters/wireless.py +++ b/netjsonconfig/backends/raspbian/converters/wireless.py @@ -16,6 +16,7 @@ def to_intermediate(self): 'ssid': interface['wireless'].get('ssid') } wireless = interface.get('wireless') + new_interface.update({'mode': wireless.get('mode')}) radio_num = interface['wireless'].get('radio') radios = get_copy(self.netjson, 'radios') if radios is not None: @@ -69,7 +70,7 @@ def _get_encryption(self, wireless): 'wpa_key_mgmt': wpa_key_mgmt, 'wpa_passphrase': wpa_passphrase }) - if encryption.get('cipher', None) is not None or 'auto': + if encryption.get('cipher', None) is not None: wpa_pairwise = str(encryption.get('cipher').replace('+', ' ')).upper() new_encryption.update({'wpa_pairwise': wpa_pairwise}) return new_encryption diff --git a/netjsonconfig/backends/raspbian/templates/hostapd.jinja2 b/netjsonconfig/backends/raspbian/templates/hostapd.jinja2 index 32aaaa322..9d96df42a 100644 --- a/netjsonconfig/backends/raspbian/templates/hostapd.jinja2 +++ b/netjsonconfig/backends/raspbian/templates/hostapd.jinja2 @@ -1,39 +1,41 @@ -{% for wireless in data.wireless %} - # config: /etc/hostapd/hostapd.conf +{% if data.wireless and data.wireless[0].mode == 'access_point' %} + {% for wireless in data.wireless %} + # config: /etc/hostapd/hostapd.conf - interface={{ wireless.ifname }} - driver=nl80211 - {% if wireless.country %} - country={{ wireless.country }} - {% endif %} - {% if wireless.protocol == 'a' or 'b' or 'g' %} - hw_mode={{ wireless.hwmode }} - {% endif %} - channel={{ wireless.channel }} - {% if wireless.protocol == '80211n' %} - ieee80211n=1 - {% endif %} - {% if wireless.protocol == '80211ac' %} - ieee80211ac=1 - {% endif %} - ssid={{ wireless.ssid }} - {% if wireless.hidden %} - ignore_broadcast_ssid=1 - {% endif %} - {% if wireless.rts_threshold > 0 %} - rts_threshold={{ wireless.rts_threshold }} - {% endif %} - {% if wireless.frag_threshold > 0 %} - frag_threshold={{ wireless.frag_threshold }} - {% endif %} - {% if wireless.encryption %} - auth_algs={{ wireless.encryption.auth_algs }} - wpa={{ wireless.encryption.wpa }} - wpa_key_mgmt={{ wireless.encryption.wpa_key_mgmt }} - wpa_passphrase={{ wireless.encryption.wpa_passphrase }} - {% if wireless.encryption.wpa_pairwise != 'AUTO' %} - wpa_pairwise={{ wireless.encryption.wpa_pairwise }} - {% endif %} - {% endif %} + interface={{ wireless.ifname }} + driver=nl80211 + {% if wireless.country %} + country={{ wireless.country }} + {% endif %} + {% if wireless.protocol == 'a' or 'b' or 'g' %} + hw_mode={{ wireless.hwmode }} + {% endif %} + channel={{ wireless.channel }} + {% if wireless.protocol == '80211n' %} + ieee80211n=1 + {% endif %} + {% if wireless.protocol == '80211ac' %} + ieee80211ac=1 + {% endif %} + ssid={{ wireless.ssid }} + {% if wireless.hidden %} + ignore_broadcast_ssid=1 + {% endif %} + {% if wireless.rts_threshold > 0 %} + rts_threshold={{ wireless.rts_threshold }} + {% endif %} + {% if wireless.frag_threshold > 0 %} + frag_threshold={{ wireless.frag_threshold }} + {% endif %} + {% if wireless.encryption %} + auth_algs={{ wireless.encryption.auth_algs }} + wpa={{ wireless.encryption.wpa }} + wpa_key_mgmt={{ wireless.encryption.wpa_key_mgmt }} + wpa_passphrase={{ wireless.encryption.wpa_passphrase }} + {% if wireless.encryption.wpa_pairwise != 'AUTO' %} + wpa_pairwise={{ wireless.encryption.wpa_pairwise }} + {% endif %} + {% endif %} -{% endfor %} + {% endfor %} +{% endif %} From 4d18eb0246b004f846fe425846521505cbd7a652 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Thu, 27 Jul 2017 03:45:55 +0530 Subject: [PATCH 131/183] [raspbian] Added tests for wpasupplicant --- tests/raspbian/test_wpasupplicant.py | 111 +++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 tests/raspbian/test_wpasupplicant.py diff --git a/tests/raspbian/test_wpasupplicant.py b/tests/raspbian/test_wpasupplicant.py new file mode 100644 index 000000000..178c0c88c --- /dev/null +++ b/tests/raspbian/test_wpasupplicant.py @@ -0,0 +1,111 @@ +import unittest + +from netjsonconfig import Raspbian +from netjsonconfig.utils import _TabsMixin + + +class TestWpaSupplicant(unittest.TestCase, _TabsMixin): + + def test_wpa2_personal_sta(self): + o = Raspbian({ + "radios": [ + { + "name": "radio0", + "phy": "phy0", + "driver": "mac80211", + "protocol": "802.11n", + "channel": 3, + "channel_width": 20, + "tx_power": 3 + } + ], + "interfaces": [ + { + "type": "wireless", + "name": "wlan0", + "wireless": { + "radio": "radio0", + "mode": "station", + "ssid": "ap-ssid-example", + "bssid": "00:11:22:33:44:55", + "encryption": { + "protocol": "wpa2_personal", + "key": "cucumber", + }, + }, + } + ] + }) + + expected = '''# config: /etc/wpa_supplicant/wpa_supplicant.conf + +network={ +ssid="ap-ssid-example" +key="cucumber" +key_mgtmt=WPA-PSK +} + +# config: /etc/network/interfaces + +auto wlan0 +iface wlan0 inet manual + +# script: /scripts/ipv4_forwarding.sh + +sudo sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward" +sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE +sudo iptables -A FORWARD -i eth0 -o wlan0 -m state --state RELATED,ESTABLISHED -j ACCEPT +sudo iptables -A FORWARD -i wlan0 -o eth0 -j ACCEPT +sudo sh -c "iptables-save > /etc/iptables.ipv4.nat" + +''' + self.assertEqual(o.render(), expected) + + def test_no_encryption(self): + o = Raspbian({ + "radios": [ + { + "name": "radio0", + "phy": "phy0", + "driver": "mac80211", + "protocol": "802.11n", + "channel": 3, + "channel_width": 20, + "tx_power": 3 + } + ], + "interfaces": [ + { + "type": "wireless", + "name": "wlan0", + "wireless": { + "radio": "radio0", + "mode": "station", + "ssid": "ap-ssid-example", + "bssid": "00:11:22:33:44:55", + }, + } + ] + }) + + expected = '''# config: /etc/wpa_supplicant/wpa_supplicant.conf + +network={ +ssid="ap-ssid-example" +} + +# config: /etc/network/interfaces + +auto wlan0 +iface wlan0 inet manual + +# script: /scripts/ipv4_forwarding.sh + +sudo sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward" +sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE +sudo iptables -A FORWARD -i eth0 -o wlan0 -m state --state RELATED,ESTABLISHED -j ACCEPT +sudo iptables -A FORWARD -i wlan0 -o eth0 -j ACCEPT +sudo sh -c "iptables-save > /etc/iptables.ipv4.nat" + +''' + self.assertEqual(o.render(), expected) From 5fa829de88cb8eee5b52ae1f89f317869705af6b Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Thu, 27 Jul 2017 03:46:30 +0530 Subject: [PATCH 132/183] [raspbian] Updated schema --- netjsonconfig/backends/raspbian/schema.py | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/netjsonconfig/backends/raspbian/schema.py b/netjsonconfig/backends/raspbian/schema.py index 00c673424..5a6648ba6 100644 --- a/netjsonconfig/backends/raspbian/schema.py +++ b/netjsonconfig/backends/raspbian/schema.py @@ -73,20 +73,6 @@ "additionalProperties": True, "propertyOrder": 8, "properties": { - "enabled": { - "type": "boolean", - "title": "enable NTP client", - "default": True, - "format": "checkbox", - "propertyOrder": 1, - }, - "enable_server": { - "type": "boolean", - "title": "enable NTP server", - "default": False, - "format": "checkbox", - "propertyOrder": 2, - }, "server": { "title": "NTP Servers", "description": "NTP server candidates", @@ -104,3 +90,8 @@ } } }) + +del schema['properties']['general']['properties']['ula_prefix'] +del schema['properties']['general']['properties']['description'] +del schema['properties']['general']['properties']['maintainer'] +del schema['definitions']['base_wireless_settings']['properties']['ack_distance'] From 09736ea584cee553b8c32d3c1ef6124729ee5e40 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Fri, 28 Jul 2017 00:27:49 +0530 Subject: [PATCH 133/183] [raspbian] Refactored wireless converter --- .../backends/raspbian/converters/wireless.py | 77 +++++++++---------- 1 file changed, 37 insertions(+), 40 deletions(-) diff --git a/netjsonconfig/backends/raspbian/converters/wireless.py b/netjsonconfig/backends/raspbian/converters/wireless.py index 5709bede5..b499f296a 100644 --- a/netjsonconfig/backends/raspbian/converters/wireless.py +++ b/netjsonconfig/backends/raspbian/converters/wireless.py @@ -8,69 +8,66 @@ class Wireless(RaspbianConverter): def to_intermediate(self): result = [] interfaces = get_copy(self.netjson, self.netjson_key) + new_interface = {} for interface in interfaces: - if interface['type'] == 'wireless' and interface.get('wireless').get('mode') is not 'adhoc': - new_interface = { + if interface.get('type') == 'wireless' and interface.get('wireless').get('mode') is not 'adhoc': + new_interface.update({ 'ifname': interface.get('name'), 'iftype': interface.get('type'), - 'ssid': interface['wireless'].get('ssid') - } + }) wireless = interface.get('wireless') - new_interface.update({'mode': wireless.get('mode')}) - radio_num = interface['wireless'].get('radio') + new_interface.update({ + 'ssid': wireless.get('ssid'), + 'radio': wireless.get('radio'), + 'mode': wireless.get('mode'), + 'hidden': wireless.get('hidden', False), + 'rts_threshold': wireless.get('rts_threshold', -1), + 'frag_threshold': wireless.get('frag_threshold', -1), + 'encryption': self._get_encryption(wireless) + }) radios = get_copy(self.netjson, 'radios') - if radios is not None: - req_radio = [radio for radio in radios if radio['name'] == radio_num][0] - hwmode = self._get_hwmode(req_radio) - channel = req_radio['channel'] - protocol = req_radio['protocol'].replace(".", "") + if radios: + req_radio = [radio for radio in radios if radio['name'] == wireless.get('radio')][0] new_interface.update({ - 'hwmode': hwmode, - 'channel': channel, - 'protocol': protocol + 'protocol': req_radio.get('protocol').replace(".", ""), + 'hwmode': self._get_hwmode(req_radio), + 'channel': req_radio.get('channel'), + 'channel_width': req_radio.get('channel_width') }) if 'country' in req_radio: - country = req_radio['country'] - new_interface.update({'country': country}) - hidden = wireless.get('hidden', False) - new_interface.update({'hidden': hidden}) - rts_threshold = wireless.get('rts_threshold', -1) - new_interface.update({'rts_threshold': rts_threshold}) - frag_threshold = wireless.get('frag_threshold', -1) - new_interface.update({'frag_threshold': frag_threshold}) - new_interface.update({'encryption': self._get_encryption(wireless)}) + new_interface.update({'country': req_radio.get('country')}) result.append(new_interface) return (('wireless', result),) def _get_hwmode(self, radio): - protocol = radio['protocol'] + protocol = radio.get('protocol') if protocol in ['802.11a', '802.11b', '802.11g']: return protocol[-1:] - elif radio['channel'] <= 13: + elif radio.get('channel') <= 13: return 'g' else: return 'a' def _get_encryption(self, wireless): encryption = wireless.get('encryption', None) + new_encryption = {} if encryption is None: - return {} + return new_encryption disabled = encryption.get('disabled', False) - new_encryption = {} - if encryption.get('protocol') is not 'none' and disabled is not True: - protocol, method = encryption.get('protocol').split("_") - if protocol in ['wpa', 'wpa2']: - auth_algs = '1' - wpa = '1' if protocol == 'wpa' else '2' - wpa_key_mgmt = 'WPA-PSK' if method == 'personal' else 'WPA-EAP' - wpa_passphrase = encryption.get('key') + protocol = encryption.get('protocol') + if disabled or protocol == 'none': + return new_encryption + protocol, method = protocol.split("_") + print(protocol, method) + if 'wpa' in protocol: + if 'personal' in method: new_encryption.update({ - 'auth_algs': auth_algs, - 'wpa': wpa, - 'wpa_key_mgmt': wpa_key_mgmt, - 'wpa_passphrase': wpa_passphrase - }) - if encryption.get('cipher', None) is not None: + 'auth_algs': '1', + 'wpa': '1' if protocol == 'wpa' else '2', + 'wpa_key_mgmt': 'WPA-PSK', + 'wpa_passphrase': encryption.get('key'), + }) + if encryption.get('cipher'): wpa_pairwise = str(encryption.get('cipher').replace('+', ' ')).upper() new_encryption.update({'wpa_pairwise': wpa_pairwise}) return new_encryption From 528ff71c5d5a72c6512774e657b8f245b8d697c1 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Fri, 28 Jul 2017 12:19:56 +0530 Subject: [PATCH 134/183] [raspbian] Fixed isort warning --- netjsonconfig/backends/raspbian/raspbian.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/netjsonconfig/backends/raspbian/raspbian.py b/netjsonconfig/backends/raspbian/raspbian.py index f66cac9b5..06c63ef55 100644 --- a/netjsonconfig/backends/raspbian/raspbian.py +++ b/netjsonconfig/backends/raspbian/raspbian.py @@ -2,7 +2,8 @@ from . import converters from ..base.backend import BaseBackend -from .renderer import Hostapd, Hostname, Interfaces, Ntp, Resolv, Scripts, WpaSupplicant +from .renderer import (Hostapd, Hostname, Interfaces, Ntp, Resolv, Scripts, + WpaSupplicant) from .schema import schema From 0545fe1afb4d8cc22a0795dcfaec5531cdab2764 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Fri, 28 Jul 2017 12:20:34 +0530 Subject: [PATCH 135/183] [raspbian] Removed unsupported values from schema --- netjsonconfig/backends/raspbian/schema.py | 30 +++++++++-------------- 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/netjsonconfig/backends/raspbian/schema.py b/netjsonconfig/backends/raspbian/schema.py index 5a6648ba6..be9841126 100644 --- a/netjsonconfig/backends/raspbian/schema.py +++ b/netjsonconfig/backends/raspbian/schema.py @@ -4,23 +4,6 @@ schema = merge_config(default_schema, { "definitions": { - "network_interface": { - "title": "Network interface", - "allOf": [ - { - "properties": { - "type": { - "enum": [ - "ethernet", - "virtual", - "loopback" - ], - } - } - }, - {"$ref": "#/definitions/interface_settings"} - ] - }, "radio_hwmode_11g": { "properties": { "hwmode": { @@ -92,6 +75,17 @@ }) del schema['properties']['general']['properties']['ula_prefix'] -del schema['properties']['general']['properties']['description'] del schema['properties']['general']['properties']['maintainer'] +del schema['properties']['general']['properties']['description'] +del schema['properties']['routes']['items']['required'][3] +del schema['properties']['routes']['items']['properties']['cost'] +del schema['properties']['routes']['items']['properties']['source'] +del schema['properties']['files'] + +del schema['definitions']['wireless_interface']['allOf'][0]['properties']['wireless']['oneOf'][4] +del schema['definitions']['wireless_interface']['allOf'][0]['properties']['wireless']['oneOf'][3] del schema['definitions']['base_wireless_settings']['properties']['ack_distance'] +del schema['definitions']['ap_wireless_settings']['allOf'][4] +del schema['definitions']['sta_wireless_settings']['allOf'][4] +del schema['definitions']['base_radio_settings']['properties']['phy'] +del schema['definitions']['base_radio_settings']['properties']['tx_power'] From 168d792b061a60fcc80aa74b0c7746bf3db149c9 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Fri, 28 Jul 2017 12:55:51 +0530 Subject: [PATCH 136/183] [raspbian] Created a deepcopy of schema before modification --- netjsonconfig/backends/raspbian/schema.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/netjsonconfig/backends/raspbian/schema.py b/netjsonconfig/backends/raspbian/schema.py index be9841126..a91f65527 100644 --- a/netjsonconfig/backends/raspbian/schema.py +++ b/netjsonconfig/backends/raspbian/schema.py @@ -1,3 +1,5 @@ +from copy import deepcopy + from ...schema import schema as default_schema from ...utils import merge_config from ..openwrt.timezones import timezones @@ -73,7 +75,7 @@ } } }) - +schema = deepcopy(schema) del schema['properties']['general']['properties']['ula_prefix'] del schema['properties']['general']['properties']['maintainer'] del schema['properties']['general']['properties']['description'] From 37e14fb4872000e07305a48adffc3efeea5e92af Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Mon, 31 Jul 2017 17:50:02 +0530 Subject: [PATCH 137/183] [raspbian] Added NONE value to key_mgmt --- .../backends/raspbian/templates/wpasupplicant.jinja2 | 9 ++++++--- tests/raspbian/test_wpasupplicant.py | 3 ++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/netjsonconfig/backends/raspbian/templates/wpasupplicant.jinja2 b/netjsonconfig/backends/raspbian/templates/wpasupplicant.jinja2 index 9a236da2f..5de5ea83a 100644 --- a/netjsonconfig/backends/raspbian/templates/wpasupplicant.jinja2 +++ b/netjsonconfig/backends/raspbian/templates/wpasupplicant.jinja2 @@ -5,12 +5,15 @@ network={ ssid="{{ wireless.ssid }}" {% if 'wpa' in wireless.encryption %} - {% if wireless.encryption %} key="{{ wireless.encryption.wpa_passphrase }}" - {% endif %} {% if wireless.encryption.wpa_key_mgmt %} - key_mgtmt={{ wireless.encryption.wpa_key_mgmt }} + key_mgmt={{ wireless.encryption.wpa_key_mgmt }} {% endif %} + {% else %} + key_mgmt=NONE + {% endif %} + {% if 'wep' in wireless.encryption %} + {# WEP Config Here#} {% endif %} } diff --git a/tests/raspbian/test_wpasupplicant.py b/tests/raspbian/test_wpasupplicant.py index 178c0c88c..340fb7a90 100644 --- a/tests/raspbian/test_wpasupplicant.py +++ b/tests/raspbian/test_wpasupplicant.py @@ -42,7 +42,7 @@ def test_wpa2_personal_sta(self): network={ ssid="ap-ssid-example" key="cucumber" -key_mgtmt=WPA-PSK +key_mgmt=WPA-PSK } # config: /etc/network/interfaces @@ -92,6 +92,7 @@ def test_no_encryption(self): network={ ssid="ap-ssid-example" +key_mgmt=NONE } # config: /etc/network/interfaces From 43d4b82ccffc731f73588331919422dd3ecb85c4 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Mon, 31 Jul 2017 22:45:31 +0530 Subject: [PATCH 138/183] [raspbian] Added support WPA2 Enterprise Mode (Client) --- .../backends/raspbian/converters/wireless.py | 20 +++++- .../raspbian/templates/wpasupplicant.jinja2 | 35 ++++++++-- tests/raspbian/test_wpasupplicant.py | 68 +++++++++++++++++-- 3 files changed, 113 insertions(+), 10 deletions(-) diff --git a/netjsonconfig/backends/raspbian/converters/wireless.py b/netjsonconfig/backends/raspbian/converters/wireless.py index b499f296a..7405b7f0b 100644 --- a/netjsonconfig/backends/raspbian/converters/wireless.py +++ b/netjsonconfig/backends/raspbian/converters/wireless.py @@ -58,10 +58,11 @@ def _get_encryption(self, wireless): if disabled or protocol == 'none': return new_encryption protocol, method = protocol.split("_") - print(protocol, method) if 'wpa' in protocol: if 'personal' in method: new_encryption.update({ + 'protocol': 'wpa', + 'method': 'personal', 'auth_algs': '1', 'wpa': '1' if protocol == 'wpa' else '2', 'wpa_key_mgmt': 'WPA-PSK', @@ -70,4 +71,21 @@ def _get_encryption(self, wireless): if encryption.get('cipher'): wpa_pairwise = str(encryption.get('cipher').replace('+', ' ')).upper() new_encryption.update({'wpa_pairwise': wpa_pairwise}) + elif 'enterprise' in method: + if encryption.get('cipher'): + cipher = str(encryption.get('cipher').replace('+', ' ').upper()) + new_encryption.update({'cipher': cipher}) + if encryption.get('eap_type'): + eap_type = encryption.get('eap_type').upper() + new_encryption.update({'eap_type': eap_type}) + new_encryption.update({ + 'protocol': 'wpa', + 'method': 'enterprise', + 'identity': encryption.get('identity', None), + 'password': encryption.get('password', None), + 'ca_cert': encryption.get('ca_cert', None), + 'client_cert': encryption.get('client_cert', None), + 'priv_key': encryption.get('priv_key', None), + 'priv_key_pwd': encryption.get('priv_key_pwd', None) + }) return new_encryption diff --git a/netjsonconfig/backends/raspbian/templates/wpasupplicant.jinja2 b/netjsonconfig/backends/raspbian/templates/wpasupplicant.jinja2 index 5de5ea83a..2082c7285 100644 --- a/netjsonconfig/backends/raspbian/templates/wpasupplicant.jinja2 +++ b/netjsonconfig/backends/raspbian/templates/wpasupplicant.jinja2 @@ -4,11 +4,36 @@ network={ ssid="{{ wireless.ssid }}" - {% if 'wpa' in wireless.encryption %} - key="{{ wireless.encryption.wpa_passphrase }}" - {% if wireless.encryption.wpa_key_mgmt %} - key_mgmt={{ wireless.encryption.wpa_key_mgmt }} - {% endif %} + {% if 'wpa' in wireless.encryption.protocol %} + {% set encryption = wireless.encryption %} + {% if encryption.method == 'personal' %} + key="{{ encryption.wpa_passphrase }}" + {% if encryption.wpa_key_mgmt %} + key_mgmt={{ encryption.wpa_key_mgmt }} + {% endif %} + {% elif wireless.encryption.method == 'enterprise' %} + {% if encryption.eap_type %} + eap={{ encryption.eap_type }} + {% endif %} + {% if encryption.identity %} + identity="{{ encryption.identity }}" + {% endif %} + {% if encryption.password %} + password="{{ encryption.password }}" + {% endif %} + {% if encryption.ca_cert %} + ca_cert="{{ encryption.ca_cert }}" + {% endif %} + {% if encryption.client_cert %} + client_cert="{{ encryption.client_cert }}" + {% endif %} + {% if encryption.priv_key %} + priv_key="{{ encryption.priv_key }}" + {% endif %} + {% if encryption.priv_key_pwd %} + priv_key_pwd="{{ encryption.priv_key_pwd }}" + {% endif %} + {% endif%} {% else %} key_mgmt=NONE {% endif %} diff --git a/tests/raspbian/test_wpasupplicant.py b/tests/raspbian/test_wpasupplicant.py index 340fb7a90..8617d7fb3 100644 --- a/tests/raspbian/test_wpasupplicant.py +++ b/tests/raspbian/test_wpasupplicant.py @@ -26,11 +26,11 @@ def test_wpa2_personal_sta(self): "wireless": { "radio": "radio0", "mode": "station", - "ssid": "ap-ssid-example", + "ssid": "Test", "bssid": "00:11:22:33:44:55", "encryption": { "protocol": "wpa2_personal", - "key": "cucumber", + "key": "changeme", }, }, } @@ -40,8 +40,8 @@ def test_wpa2_personal_sta(self): expected = '''# config: /etc/wpa_supplicant/wpa_supplicant.conf network={ -ssid="ap-ssid-example" -key="cucumber" +ssid="Test" +key="changeme" key_mgmt=WPA-PSK } @@ -61,6 +61,66 @@ def test_wpa2_personal_sta(self): ''' self.assertEqual(o.render(), expected) + def test_wpa2_enterprise_client(self): + o = Raspbian({ + "radios": [ + { + "name": "radio0", + "phy": "phy0", + "driver": "mac80211", + "protocol": "802.11n", + "channel": 36, + "channel_width": 20, + "tx_power": 3 + } + ], + "interfaces": [ + { + "name": "wlan0", + "type": "wireless", + "wireless": { + "radio": "radio0", + "mode": "station", + "ssid": "enterprise-client", + "bssid": "00:26:b9:20:5f:09", + "encryption": { + "protocol": "wpa2_enterprise", + "cipher": "auto", + "eap_type": "tls", + "identity": "test-identity", + "password": "test-password", + } + } + } + ] + }) + + expected = '''# config: /etc/wpa_supplicant/wpa_supplicant.conf + +network={ +ssid="enterprise-client" +eap=TLS +identity="test-identity" +password="test-password" +} + +# config: /etc/network/interfaces + +auto wlan0 +iface wlan0 inet manual + +# script: /scripts/ipv4_forwarding.sh + +sudo sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward" +sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE +sudo iptables -A FORWARD -i eth0 -o wlan0 -m state --state RELATED,ESTABLISHED -j ACCEPT +sudo iptables -A FORWARD -i wlan0 -o eth0 -j ACCEPT +sudo sh -c "iptables-save > /etc/iptables.ipv4.nat" + +''' + + self.assertEqual(o.render(), expected) + def test_no_encryption(self): o = Raspbian({ "radios": [ From 55ff9dcc39baf11ac524e9386d3ff275dbee0358 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Tue, 1 Aug 2017 16:09:07 +0530 Subject: [PATCH 139/183] [raspbian] Updated render methods example --- docs/source/backends/raspbian.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/source/backends/raspbian.rst b/docs/source/backends/raspbian.rst index aaf094d2d..955840c78 100644 --- a/docs/source/backends/raspbian.rst +++ b/docs/source/backends/raspbian.rst @@ -25,7 +25,7 @@ Code example: o = Raspbian({ "interfaces": [ { - "name": "eth0.1", + "name": "eth0", "type": "ethernet", "addresses": [ { @@ -56,14 +56,14 @@ Will return the following output:: # config: /etc/network/interfaces - auto eth0.1 - iface eth0.1 inet static + auto eth0 + iface eth0 inet static address 192.168.1.1 netmask 255.255.255.0 - iface eth0.1 inet static + iface eth0 inet static address 192.168.2.1 netmask 255.255.255.0 - iface eth0.1 inet6 static + iface eth0 inet6 static address fd87::1 netmask 128 From 1aef4d805c6955a5ac1baab661cd429266159e5e Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Tue, 1 Aug 2017 20:49:46 +0530 Subject: [PATCH 140/183] [raspbian] Updated loopback interface output --- netjsonconfig/backends/raspbian/converters/interfaces.py | 2 +- netjsonconfig/backends/raspbian/templates/interfaces.jinja2 | 5 ++++- tests/raspbian/test_interfaces.py | 4 +--- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/netjsonconfig/backends/raspbian/converters/interfaces.py b/netjsonconfig/backends/raspbian/converters/interfaces.py index 7243939a1..aa2124e8e 100644 --- a/netjsonconfig/backends/raspbian/converters/interfaces.py +++ b/netjsonconfig/backends/raspbian/converters/interfaces.py @@ -22,7 +22,7 @@ def _get_interface(self, interface): 'ifname': ifname, 'iftype': iftype }) - if iftype in ['ethernet', 'bridge', 'loopback', 'wireless']: + if iftype in ['ethernet', 'bridge', 'wireless']: addresses = self._get_address(interface) new_interface.update({ 'address': addresses diff --git a/netjsonconfig/backends/raspbian/templates/interfaces.jinja2 b/netjsonconfig/backends/raspbian/templates/interfaces.jinja2 index a3501756f..e25487357 100644 --- a/netjsonconfig/backends/raspbian/templates/interfaces.jinja2 +++ b/netjsonconfig/backends/raspbian/templates/interfaces.jinja2 @@ -3,7 +3,7 @@ {% endif%} {% for interface in data.interfaces %} - {% if interface.iftype in ['ethernet', 'bridge', 'loopback', 'wireless'] %} + {% if interface.iftype in ['ethernet', 'bridge', 'wireless'] %} {% if interface.address %} {% if interface.autostart %} auto {{ interface.ifname }} @@ -118,6 +118,9 @@ wireless-mode ad-hoc {% endif %} {% endif %} + {% elif interface.iftype == 'loopback'%} + auto {{ interface.ifname }} + iface {{ interface.ifname }} inet loopback {% endif %} {% endfor %} diff --git a/tests/raspbian/test_interfaces.py b/tests/raspbian/test_interfaces.py index 2d7004251..96a6d6b23 100644 --- a/tests/raspbian/test_interfaces.py +++ b/tests/raspbian/test_interfaces.py @@ -585,9 +585,7 @@ def test_loopback(self): expected = '''# config: /etc/network/interfaces auto lo -iface lo inet static -address 127.0.0.1 -netmask 255.0.0.0 +iface lo inet loopback ''' self.assertEqual(o.render(), expected) From 067c2e193303b9d390336f8b12a9032378b14829 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Tue, 1 Aug 2017 20:50:29 +0530 Subject: [PATCH 141/183] [raspbian] Removed loopback section from docs --- docs/source/backends/raspbian.rst | 33 ------------------------------- 1 file changed, 33 deletions(-) diff --git a/docs/source/backends/raspbian.rst b/docs/source/backends/raspbian.rst index 955840c78..8b4618b98 100644 --- a/docs/source/backends/raspbian.rst +++ b/docs/source/backends/raspbian.rst @@ -188,39 +188,6 @@ There are 3 main type of interfaces: * **wireless interfaces**: must be of type ``wireless`` * **bridge interfaces**: must be of type ``bridge`` -Loopback Interface -~~~~~~~~~~~~~~~~~~ - -The following *configuration dictionary*: - -.. code-block:: python - - { - "interfaces": [ - { - "name": "lo", - "type": "loopback", - "addresses": [ - { - "address": "127.0.0.1", - "mask": 8, - "proto": "static", - "family": "ipv4" - } - ] - } - ] - } - -Will be rendered as follows:: - - # config: /etc/network/interfaces - - auto lo - iface lo inet static - address 127.0.0.1 - netmask 255.0.0.0 - Dualstack (IPv4 & IPv6) ~~~~~~~~~~~~~~~~~~~~~~~ From 836d44a58883a26e5f51eb43f14c7450f4ce42ec Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Wed, 2 Aug 2017 13:37:05 +0530 Subject: [PATCH 142/183] [raspbian] Fixed autostart output --- .../raspbian/converters/interfaces.py | 34 +++++++++++-------- .../raspbian/templates/interfaces.jinja2 | 2 ++ 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/netjsonconfig/backends/raspbian/converters/interfaces.py b/netjsonconfig/backends/raspbian/converters/interfaces.py index aa2124e8e..df75e3917 100644 --- a/netjsonconfig/backends/raspbian/converters/interfaces.py +++ b/netjsonconfig/backends/raspbian/converters/interfaces.py @@ -28,23 +28,29 @@ def _get_interface(self, interface): 'address': addresses }) routes = get_copy(self.netjson, 'routes') + new_interface.update({ + 'mac': interface.get('mac', None), + 'mtu': interface.get('mtu', None), + 'txqueuelen': interface.get('txqueuelen', None), + 'autostart': interface.get('autostart', True), + }) if routes: route = self._get_route(routes) new_interface.update({'route': route}) - mac = interface.get('mac', False) - if mac: - new_interface.update({'mac': mac}) - mtu = interface.get('mtu', False) - if mtu: - new_interface.update({'mtu': mtu}) - txqueuelen = interface.get('txqueuelen', False) - if txqueuelen: - new_interface.update({'txqueuelen': txqueuelen}) - autostart = interface.get('autostart', True) - if autostart: - new_interface.update({'autostart': True}) - else: - new_interface.update({'autostart': False}) + # mac = interface.get('mac', False) + # if mac: + # new_interface.update({'mac': mac}) + # mtu = interface.get('mtu', False) + # if mtu: + # new_interface.update({'mtu': mtu}) + # txqueuelen = interface.get('txqueuelen', False) + # if txqueuelen: + # new_interface.update({'txqueuelen': txqueuelen}) + # autostart = interface.get('autostart', True) + # if autostart: + # new_interface.update({'autostart': True}) + # else: + # new_interface.update({'autostart': False}) if iftype == 'wireless' and interface.get('wireless').get('mode') == 'adhoc': wireless = interface.get('wireless') new_interface.update({ diff --git a/netjsonconfig/backends/raspbian/templates/interfaces.jinja2 b/netjsonconfig/backends/raspbian/templates/interfaces.jinja2 index e25487357..31c3e398b 100644 --- a/netjsonconfig/backends/raspbian/templates/interfaces.jinja2 +++ b/netjsonconfig/backends/raspbian/templates/interfaces.jinja2 @@ -91,7 +91,9 @@ {% endif%} {% endfor %} {% else %} + {% if interface.autostart %} auto {{ interface.ifname }} + {% endif %} {% if interface.iftype in ['ethernet', 'wireless'] and interface.mode != 'adhoc' %} iface {{ interface.ifname }} inet manual {% set route = interface.route %} From 7b4ba065620f0dcd36190eb3a05d4706f2a9217d Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Wed, 2 Aug 2017 13:37:38 +0530 Subject: [PATCH 143/183] [raspbian] Added test for autostart --- tests/raspbian/test_interfaces.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/tests/raspbian/test_interfaces.py b/tests/raspbian/test_interfaces.py index 96a6d6b23..068afd809 100644 --- a/tests/raspbian/test_interfaces.py +++ b/tests/raspbian/test_interfaces.py @@ -433,6 +433,25 @@ def test_multiple_ip(self): ''' self.assertEqual(o.render(), expected) + def test_autostart_false(self): + o = Raspbian({ + "interfaces": [ + { + "name": "eth0", + "type": "ethernet", + "autostart": False + } + ] + }) + + expected = '''# config: /etc/network/interfaces + +iface eth0 inet manual + +''' + + self.assertEqual(o.render(), expected) + def test_mtu(self): o = Raspbian({ "interfaces": [ From 52d706097c2915730cf5365f08d7c1927075ed8b Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Wed, 2 Aug 2017 14:42:29 +0530 Subject: [PATCH 144/183] [raspbian] Remove old commented code --- .../backends/raspbian/converters/interfaces.py | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/netjsonconfig/backends/raspbian/converters/interfaces.py b/netjsonconfig/backends/raspbian/converters/interfaces.py index df75e3917..352b504fe 100644 --- a/netjsonconfig/backends/raspbian/converters/interfaces.py +++ b/netjsonconfig/backends/raspbian/converters/interfaces.py @@ -37,20 +37,6 @@ def _get_interface(self, interface): if routes: route = self._get_route(routes) new_interface.update({'route': route}) - # mac = interface.get('mac', False) - # if mac: - # new_interface.update({'mac': mac}) - # mtu = interface.get('mtu', False) - # if mtu: - # new_interface.update({'mtu': mtu}) - # txqueuelen = interface.get('txqueuelen', False) - # if txqueuelen: - # new_interface.update({'txqueuelen': txqueuelen}) - # autostart = interface.get('autostart', True) - # if autostart: - # new_interface.update({'autostart': True}) - # else: - # new_interface.update({'autostart': False}) if iftype == 'wireless' and interface.get('wireless').get('mode') == 'adhoc': wireless = interface.get('wireless') new_interface.update({ From 51eef5268456e3fcafc782ced156cc746615ea0b Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Sat, 5 Aug 2017 01:00:24 +0530 Subject: [PATCH 145/183] [raspbian] Added support for WEP Station mode --- netjsonconfig/backends/raspbian/converters/wireless.py | 7 +++++++ .../backends/raspbian/templates/wpasupplicant.jinja2 | 9 ++++++--- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/netjsonconfig/backends/raspbian/converters/wireless.py b/netjsonconfig/backends/raspbian/converters/wireless.py index 7405b7f0b..081b0449b 100644 --- a/netjsonconfig/backends/raspbian/converters/wireless.py +++ b/netjsonconfig/backends/raspbian/converters/wireless.py @@ -88,4 +88,11 @@ def _get_encryption(self, wireless): 'priv_key': encryption.get('priv_key', None), 'priv_key_pwd': encryption.get('priv_key_pwd', None) }) + elif 'wep' in protocol: + new_encryption.update({ + 'protocol': 'wep', + 'method': method, + 'option': encryption.get('options', None).split('_')[1], + 'key': encryption.get('key', None) + }) return new_encryption diff --git a/netjsonconfig/backends/raspbian/templates/wpasupplicant.jinja2 b/netjsonconfig/backends/raspbian/templates/wpasupplicant.jinja2 index 2082c7285..6153364f9 100644 --- a/netjsonconfig/backends/raspbian/templates/wpasupplicant.jinja2 +++ b/netjsonconfig/backends/raspbian/templates/wpasupplicant.jinja2 @@ -34,11 +34,14 @@ priv_key_pwd="{{ encryption.priv_key_pwd }}" {% endif %} {% endif%} - {% else %} + {% elif 'wep' in wireless.encryption.protocol %} key_mgmt=NONE + wep_key0="{{ wireless.encryption.key }}" + {% if wireless.encryption.option == 'shared' %} + auth_algs=shared {% endif %} - {% if 'wep' in wireless.encryption %} - {# WEP Config Here#} + {% else %} + key_mgmt=NONE {% endif %} } From f6dbdf40e58429cc6dd490f5b094712477f49e58 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Sat, 5 Aug 2017 02:10:20 +0530 Subject: [PATCH 146/183] [raspbian] Updated wep station mode --- netjsonconfig/backends/raspbian/converters/wireless.py | 1 - netjsonconfig/backends/raspbian/templates/wpasupplicant.jinja2 | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/netjsonconfig/backends/raspbian/converters/wireless.py b/netjsonconfig/backends/raspbian/converters/wireless.py index 081b0449b..dfc2d6b8d 100644 --- a/netjsonconfig/backends/raspbian/converters/wireless.py +++ b/netjsonconfig/backends/raspbian/converters/wireless.py @@ -92,7 +92,6 @@ def _get_encryption(self, wireless): new_encryption.update({ 'protocol': 'wep', 'method': method, - 'option': encryption.get('options', None).split('_')[1], 'key': encryption.get('key', None) }) return new_encryption diff --git a/netjsonconfig/backends/raspbian/templates/wpasupplicant.jinja2 b/netjsonconfig/backends/raspbian/templates/wpasupplicant.jinja2 index 6153364f9..c9a7af6ee 100644 --- a/netjsonconfig/backends/raspbian/templates/wpasupplicant.jinja2 +++ b/netjsonconfig/backends/raspbian/templates/wpasupplicant.jinja2 @@ -37,7 +37,7 @@ {% elif 'wep' in wireless.encryption.protocol %} key_mgmt=NONE wep_key0="{{ wireless.encryption.key }}" - {% if wireless.encryption.option == 'shared' %} + {% if wireless.encryption.method == 'shared' %} auth_algs=shared {% endif %} {% else %} From 879a0e78a8cf92a446c5d106b3e83af7311800fa Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Sat, 5 Aug 2017 02:10:45 +0530 Subject: [PATCH 147/183] [raspbian] Added tests for wep station mode --- tests/raspbian/test_wpasupplicant.py | 91 ++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) diff --git a/tests/raspbian/test_wpasupplicant.py b/tests/raspbian/test_wpasupplicant.py index 8617d7fb3..c9dd5da57 100644 --- a/tests/raspbian/test_wpasupplicant.py +++ b/tests/raspbian/test_wpasupplicant.py @@ -6,6 +6,97 @@ class TestWpaSupplicant(unittest.TestCase, _TabsMixin): + def test_wep_open(self): + o = Raspbian({ + "interfaces": [ + { + "name": "wlan0", + "type": "wireless", + "wireless": { + "mode": "station", + "radio": "radio0", + "ssid": "wep-test", + "bssid": "01:23:45:67:89:ab", + "encryption": { + "protocol": "wep_open", + "key": "12345" + } + }, + } + ] + }) + + expected = '''# config: /etc/wpa_supplicant/wpa_supplicant.conf + +network={ +ssid="wep-test" +key_mgmt=NONE +wep_key0="12345" +} + +# config: /etc/network/interfaces + +auto wlan0 +iface wlan0 inet manual + +# script: /scripts/ipv4_forwarding.sh + +sudo sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward" +sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE +sudo iptables -A FORWARD -i eth0 -o wlan0 -m state --state RELATED,ESTABLISHED -j ACCEPT +sudo iptables -A FORWARD -i wlan0 -o eth0 -j ACCEPT +sudo sh -c "iptables-save > /etc/iptables.ipv4.nat" + +''' + + self.assertEqual(o.render(), expected) + + def test_wep_shared(self): + o = Raspbian({ + "interfaces": [ + { + "name": "wlan0", + "type": "wireless", + "wireless": { + "mode": "station", + "radio": "radio0", + "ssid": "wep-test", + "bssid": "01:23:45:67:89:ab", + "encryption": { + "protocol": "wep_shared", + "key": "12345" + } + }, + } + ] + }) + + expected = '''# config: /etc/wpa_supplicant/wpa_supplicant.conf + +network={ +ssid="wep-test" +key_mgmt=NONE +wep_key0="12345" +auth_algs=shared +} + +# config: /etc/network/interfaces + +auto wlan0 +iface wlan0 inet manual + +# script: /scripts/ipv4_forwarding.sh + +sudo sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward" +sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE +sudo iptables -A FORWARD -i eth0 -o wlan0 -m state --state RELATED,ESTABLISHED -j ACCEPT +sudo iptables -A FORWARD -i wlan0 -o eth0 -j ACCEPT +sudo sh -c "iptables-save > /etc/iptables.ipv4.nat" + +''' + + self.assertEqual(o.render(), expected) + def test_wpa2_personal_sta(self): o = Raspbian({ "radios": [ From 450840379bbbe328a8a2f993cd7628080bd2466c Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Mon, 7 Aug 2017 13:36:50 +0530 Subject: [PATCH 148/183] [raspbian] Reduce _get_encryption complexity --- netjsonconfig/backends/raspbian/converters/wireless.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netjsonconfig/backends/raspbian/converters/wireless.py b/netjsonconfig/backends/raspbian/converters/wireless.py index dfc2d6b8d..f14ee1223 100644 --- a/netjsonconfig/backends/raspbian/converters/wireless.py +++ b/netjsonconfig/backends/raspbian/converters/wireless.py @@ -71,7 +71,7 @@ def _get_encryption(self, wireless): if encryption.get('cipher'): wpa_pairwise = str(encryption.get('cipher').replace('+', ' ')).upper() new_encryption.update({'wpa_pairwise': wpa_pairwise}) - elif 'enterprise' in method: + else: if encryption.get('cipher'): cipher = str(encryption.get('cipher').replace('+', ' ').upper()) new_encryption.update({'cipher': cipher}) From e0e82fbd8ebaeb46f5f25d3d971e3ab170e9600e Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Mon, 7 Aug 2017 14:43:56 +0530 Subject: [PATCH 149/183] [raspbian] Updated converter and template for multiple static routes --- .../raspbian/converters/interfaces.py | 4 +- .../raspbian/templates/interfaces.jinja2 | 51 +++++++++++-------- 2 files changed, 34 insertions(+), 21 deletions(-) diff --git a/netjsonconfig/backends/raspbian/converters/interfaces.py b/netjsonconfig/backends/raspbian/converters/interfaces.py index 352b504fe..7d79a24be 100644 --- a/netjsonconfig/backends/raspbian/converters/interfaces.py +++ b/netjsonconfig/backends/raspbian/converters/interfaces.py @@ -66,6 +66,7 @@ def _get_address(self, interface): return addresses def _get_route(self, routes): + result = [] for route in routes: if ip_network(route.get('next')).version == 4: route['version'] = 4 @@ -76,4 +77,5 @@ def _get_route(self, routes): del route['destination'] elif ip_network(route.get('next')).version == 6: route['version'] = 6 - return route + result.append(route) + return routes diff --git a/netjsonconfig/backends/raspbian/templates/interfaces.jinja2 b/netjsonconfig/backends/raspbian/templates/interfaces.jinja2 index 31c3e398b..c1afa2027 100644 --- a/netjsonconfig/backends/raspbian/templates/interfaces.jinja2 +++ b/netjsonconfig/backends/raspbian/templates/interfaces.jinja2 @@ -18,9 +18,11 @@ gateway {{ address.gateway }} {% endif %} {% if interface.route %} - {% set route = interface.route %} - post-up route add -net {{ route.dest }} netmask {{ route.dest_mask }} gw {{ route.next }} - pre-up route del -net {{ route.dest }} netmask {{ route.dest_mask }} gw {{ route.next }} + {% set routes = interface.route %} + {% for route in routes %} + post-up route add -net {{ route.dest }} netmask {{ route.dest_mask }} gw {{ route.next }} + pre-up route del -net {{ route.dest }} netmask {{ route.dest_mask }} gw {{ route.next }} + {% endfor %} {% endif %} {% if interface.mtu %} mtu {{ interface.mtu }} @@ -43,9 +45,11 @@ gateway {{ address.gateway }} {% endif %} {% if interface.route %} - {% set route = interface.route %} - up ip -6 route add {{ route.destination }} via {{ route.next }} dev eth0 - down ip -6 route del {{ route.destination }} via {{ route.next }} dev eth0 + {% set routes = interface.route %} + {% for route in routes %} + up ip -6 route add {{ route.destination }} via {{ route.next }} dev eth0 + down ip -6 route del {{ route.destination }} via {{ route.next }} dev eth0 + {% endfor %} {% endif %} {% if interface.mtu %} mtu {{ interface.mtu }} @@ -64,9 +68,11 @@ {% if address.family == 'ipv4'%} iface {{ interface.ifname }} inet {{ address.proto }} {% if interface.route %} - {% set route = interface.route %} - post-up route add -net {{ route.dest }} netmask {{ route.dest_mask }} gw {{ route.next }} - pre-up route del -net {{ route.dest }} netmask {{ route.dest_mask }} gw {{ route.next }} + {% set routes = interface.route %} + {% for route in routes %} + post-up route add -net {{ route.dest }} netmask {{ route.dest_mask }} gw {{ route.next }} + pre-up route del -net {{ route.dest }} netmask {{ route.dest_mask }} gw {{ route.next }} + {% endfor %} {% endif %} {% if interface.mtu %} pre-up /sbin/ifconfig $IFACE mtu {{ interface.mtu }} @@ -77,9 +83,11 @@ {% elif address.family == 'ipv6' %} iface {{ interface.ifname }} inet6 {{ address.proto }} {% if interface.route %} - {% set route = interface.route %} - up ip -6 route add {{ route.destination }} via {{ route.next }} dev eth0 - down ip -6 route del {{ route.destination }} via {{ route.next }} dev eth0 + {% set routes = interface.route %} + {% for route in routes %} + up ip -6 route add {{ route.destination }} via {{ route.next }} dev eth0 + down ip -6 route del {{ route.destination }} via {{ route.next }} dev eth0 + {% endfor %} {% endif %} {% if interface.mtu %} pre-up /sbin/ifconfig $IFACE mtu {{ interface.mtu }} @@ -96,14 +104,17 @@ {% endif %} {% if interface.iftype in ['ethernet', 'wireless'] and interface.mode != 'adhoc' %} iface {{ interface.ifname }} inet manual - {% set route = interface.route %} - {% if interface.route and route.version == 4 %} - post-up route add -net {{ route.dest }} netmask {{ route.dest_mask }} gw {{ route.next }} - pre-up route del -net {{ route.dest }} netmask {{ route.dest_mask }} gw {{ route.next }} - {% elif interface.route and route.version == 6 %} - up ip -6 route add {{ route.destination }} via {{ route.next }} dev eth0 - down ip -6 route del {{ route.destination }} via {{ route.next }} dev eth0 - {% endif %} + {% set routes = interface.route %} + {% for route in routes %} + {% if interface.route and route.version == 4 %} + post-up route add -net {{ route.dest }} netmask {{ route.dest_mask }} gw {{ route.next }} + pre-up route del -net {{ route.dest }} netmask {{ route.dest_mask }} gw {{ route.next }} + {% endif %} + {% if interface.route and route.version == 6 %} + up ip -6 route add {{ route.destination }} via {{ route.next }} dev eth0 + down ip -6 route del {{ route.destination }} via {{ route.next }} dev eth0 + {% endif %} + {% endfor %} {% endif %} {% if interface.iftype == 'bridge' %} bridge_ports {{ interface.bridge_members[0] }} {{ interface.bridge_members[1] }} From e5a2acd3df9c677dc448f8f1cdd4b52341ec9310 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Mon, 7 Aug 2017 14:44:30 +0530 Subject: [PATCH 150/183] [raspbian] Added tests for multiple static routes --- tests/raspbian/test_routes.py | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/tests/raspbian/test_routes.py b/tests/raspbian/test_routes.py index 67f11eb30..b66f844c6 100644 --- a/tests/raspbian/test_routes.py +++ b/tests/raspbian/test_routes.py @@ -136,5 +136,39 @@ def test_ipv6_static_route(self): up ip -6 route add fd89::1/128 via fd88::1 dev eth0 down ip -6 route del fd89::1/128 via fd88::1 dev eth0 +''' + self.assertEqual(o.render(), expected) + + def test_multiple_routes(self): + o = Raspbian({ + "routes": [ + { + "destination": "192.168.4.1/24", + "next": "192.168.2.2", + "device": "eth1" + }, + { + "destination": "fd89::1/128", + "next": "fd88::1", + "device": "eth1" + } + ], + "interfaces": [ + { + "type": "ethernet", + "name": "eth1" + } + ] + }) + + expected = '''# config: /etc/network/interfaces + +auto eth1 +iface eth1 inet manual +post-up route add -net 192.168.4.1 netmask 255.255.255.0 gw 192.168.2.2 +pre-up route del -net 192.168.4.1 netmask 255.255.255.0 gw 192.168.2.2 +up ip -6 route add fd89::1/128 via fd88::1 dev eth0 +down ip -6 route del fd89::1/128 via fd88::1 dev eth0 + ''' self.assertEqual(o.render(), expected) From 65f4a9b990e1862ded1593c851ad9f9ee7e341c4 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Mon, 7 Aug 2017 17:02:50 +0530 Subject: [PATCH 151/183] [raspbian] Fixed multiple static routes output --- .../backends/raspbian/templates/interfaces.jinja2 | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/netjsonconfig/backends/raspbian/templates/interfaces.jinja2 b/netjsonconfig/backends/raspbian/templates/interfaces.jinja2 index c1afa2027..02e373b5f 100644 --- a/netjsonconfig/backends/raspbian/templates/interfaces.jinja2 +++ b/netjsonconfig/backends/raspbian/templates/interfaces.jinja2 @@ -20,8 +20,10 @@ {% if interface.route %} {% set routes = interface.route %} {% for route in routes %} + {% if route.version == 4%} post-up route add -net {{ route.dest }} netmask {{ route.dest_mask }} gw {{ route.next }} pre-up route del -net {{ route.dest }} netmask {{ route.dest_mask }} gw {{ route.next }} + {% endif %} {% endfor %} {% endif %} {% if interface.mtu %} @@ -47,8 +49,10 @@ {% if interface.route %} {% set routes = interface.route %} {% for route in routes %} + {% if route.version == 6 %} up ip -6 route add {{ route.destination }} via {{ route.next }} dev eth0 down ip -6 route del {{ route.destination }} via {{ route.next }} dev eth0 + {% endif %} {% endfor %} {% endif %} {% if interface.mtu %} @@ -70,8 +74,10 @@ {% if interface.route %} {% set routes = interface.route %} {% for route in routes %} + {% if route.version == 4 %} post-up route add -net {{ route.dest }} netmask {{ route.dest_mask }} gw {{ route.next }} pre-up route del -net {{ route.dest }} netmask {{ route.dest_mask }} gw {{ route.next }} + {% endif %} {% endfor %} {% endif %} {% if interface.mtu %} @@ -85,8 +91,10 @@ {% if interface.route %} {% set routes = interface.route %} {% for route in routes %} + {% if route.version == 6 %} up ip -6 route add {{ route.destination }} via {{ route.next }} dev eth0 down ip -6 route del {{ route.destination }} via {{ route.next }} dev eth0 + {% endif %} {% endfor %} {% endif %} {% if interface.mtu %} @@ -104,18 +112,20 @@ {% endif %} {% if interface.iftype in ['ethernet', 'wireless'] and interface.mode != 'adhoc' %} iface {{ interface.ifname }} inet manual + {% if interface.route %} {% set routes = interface.route %} {% for route in routes %} - {% if interface.route and route.version == 4 %} + {% if route.version == 4 %} post-up route add -net {{ route.dest }} netmask {{ route.dest_mask }} gw {{ route.next }} pre-up route del -net {{ route.dest }} netmask {{ route.dest_mask }} gw {{ route.next }} {% endif %} - {% if interface.route and route.version == 6 %} + {% if route.version == 6 %} up ip -6 route add {{ route.destination }} via {{ route.next }} dev eth0 down ip -6 route del {{ route.destination }} via {{ route.next }} dev eth0 {% endif %} {% endfor %} {% endif %} + {% endif %} {% if interface.iftype == 'bridge' %} bridge_ports {{ interface.bridge_members[0] }} {{ interface.bridge_members[1] }} {% endif %} From 7c07e9db3ea5a1db49173a17cd13b0dea3fc8615 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Mon, 7 Aug 2017 17:03:15 +0530 Subject: [PATCH 152/183] [raspbian] Added tests for dhcp interface static routes --- tests/raspbian/test_routes.py | 72 +++++++++++++++++++++++++++++++++-- 1 file changed, 68 insertions(+), 4 deletions(-) diff --git a/tests/raspbian/test_routes.py b/tests/raspbian/test_routes.py index b66f844c6..00000e2da 100644 --- a/tests/raspbian/test_routes.py +++ b/tests/raspbian/test_routes.py @@ -18,8 +18,7 @@ def test_ipv4_manual_route(self): { "device": "eth0", "destination": "192.168.4.1/24", - "next": "192.168.2.2", - "cost": 2, + "next": "192.168.2.2" }, ] }) @@ -54,8 +53,7 @@ def test_ipv4_static_route(self): { "device": "eth0", "destination": "192.168.4.1/24", - "next": "192.168.2.2", - "cost": 2, + "next": "192.168.2.2" }, ] }) @@ -69,6 +67,39 @@ def test_ipv4_static_route(self): post-up route add -net 192.168.4.1 netmask 255.255.255.0 gw 192.168.2.2 pre-up route del -net 192.168.4.1 netmask 255.255.255.0 gw 192.168.2.2 +''' + self.assertEqual(o.render(), expected) + + def test_ipv4_dchp_route(self): + o = Raspbian({ + "interfaces": [ + { + "name": "eth0", + "type": "ethernet", + "addresses": [ + { + "family": "ipv4", + "proto": "dhcp" + } + ] + } + ], + "routes": [ + { + "device": "eth0", + "destination": "192.168.4.1/24", + "next": "192.168.2.2" + }, + ] + }) + + expected = '''# config: /etc/network/interfaces + +auto eth0 +iface eth0 inet dhcp +post-up route add -net 192.168.4.1 netmask 255.255.255.0 gw 192.168.2.2 +pre-up route del -net 192.168.4.1 netmask 255.255.255.0 gw 192.168.2.2 + ''' self.assertEqual(o.render(), expected) @@ -136,6 +167,39 @@ def test_ipv6_static_route(self): up ip -6 route add fd89::1/128 via fd88::1 dev eth0 down ip -6 route del fd89::1/128 via fd88::1 dev eth0 +''' + self.assertEqual(o.render(), expected) + + def test_ipv6_dhcp_route(self): + o = Raspbian({ + "interfaces": [ + { + "name": "eth0", + "type": "ethernet", + "addresses": [ + { + "family": "ipv6", + "proto": "dhcp" + } + ] + } + ], + "routes": [ + { + "device": "eth0", + "destination": "fd89::1/128", + "next": "fd88::1" + } + ] + }) + + expected = '''# config: /etc/network/interfaces + +auto eth0 +iface eth0 inet6 dhcp +up ip -6 route add fd89::1/128 via fd88::1 dev eth0 +down ip -6 route del fd89::1/128 via fd88::1 dev eth0 + ''' self.assertEqual(o.render(), expected) From 6165704dec1634a26ebda8d00777e722c890536c Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Wed, 9 Aug 2017 21:51:16 +0530 Subject: [PATCH 153/183] [raspbian] Remove unnecessary output from template --- netjsonconfig/backends/raspbian/templates/interfaces.jinja2 | 1 - 1 file changed, 1 deletion(-) diff --git a/netjsonconfig/backends/raspbian/templates/interfaces.jinja2 b/netjsonconfig/backends/raspbian/templates/interfaces.jinja2 index 02e373b5f..bbbdae212 100644 --- a/netjsonconfig/backends/raspbian/templates/interfaces.jinja2 +++ b/netjsonconfig/backends/raspbian/templates/interfaces.jinja2 @@ -34,7 +34,6 @@ {% endif %} {% if interface.iftype == 'bridge' %} bridge_ports {{ interface.bridge_members[0] }} {{ interface.bridge_members[1] }} - {{ interface }} {% if interface.stp %} bridge_stp {{ interface.stp }} {% endif %} From a3ad9b68f185e41cdab27cdc9c38395b4edaf7e0 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Thu, 10 Aug 2017 02:03:20 +0530 Subject: [PATCH 154/183] [raspbian] Added support for macaddr acl in wireless settings --- netjsonconfig/backends/raspbian/converters/wireless.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/netjsonconfig/backends/raspbian/converters/wireless.py b/netjsonconfig/backends/raspbian/converters/wireless.py index f14ee1223..4e5b7a4e4 100644 --- a/netjsonconfig/backends/raspbian/converters/wireless.py +++ b/netjsonconfig/backends/raspbian/converters/wireless.py @@ -23,6 +23,8 @@ def to_intermediate(self): 'hidden': wireless.get('hidden', False), 'rts_threshold': wireless.get('rts_threshold', -1), 'frag_threshold': wireless.get('frag_threshold', -1), + 'macfilter': wireless.get('macfilter', None), + 'maclist': wireless.get('maclist', None), 'encryption': self._get_encryption(wireless) }) radios = get_copy(self.netjson, 'radios') From 49a48ab45ce6c46e1be542833027c84cf26fbad2 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Thu, 10 Aug 2017 02:04:26 +0530 Subject: [PATCH 155/183] [raspbian] Generate mac list config file --- netjsonconfig/backends/raspbian/raspbian.py | 5 +++-- netjsonconfig/backends/raspbian/renderer.py | 4 ++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/netjsonconfig/backends/raspbian/raspbian.py b/netjsonconfig/backends/raspbian/raspbian.py index 06c63ef55..95e012c48 100644 --- a/netjsonconfig/backends/raspbian/raspbian.py +++ b/netjsonconfig/backends/raspbian/raspbian.py @@ -2,8 +2,8 @@ from . import converters from ..base.backend import BaseBackend -from .renderer import (Hostapd, Hostname, Interfaces, Ntp, Resolv, Scripts, - WpaSupplicant) +from .renderer import (Hostapd, MacAddrList, Hostname, Interfaces, Ntp, Resolv, + Scripts, WpaSupplicant) from .schema import schema @@ -23,6 +23,7 @@ class Raspbian(BaseBackend): renderers = [ Hostname, Hostapd, + MacAddrList, WpaSupplicant, Interfaces, Resolv, diff --git a/netjsonconfig/backends/raspbian/renderer.py b/netjsonconfig/backends/raspbian/renderer.py index febf2db59..9844ef520 100644 --- a/netjsonconfig/backends/raspbian/renderer.py +++ b/netjsonconfig/backends/raspbian/renderer.py @@ -24,6 +24,10 @@ class Hostapd(RaspbianRenderer): pass +class MacAddrList(RaspbianRenderer): + pass + + class Interfaces(RaspbianRenderer): pass From d9961e89bc65c6b863b4f4139172472590d6924d Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Thu, 10 Aug 2017 02:05:35 +0530 Subject: [PATCH 156/183] [raspbian] Updated hostapd template and created new template for macaddr list --- .../backends/raspbian/templates/hostapd.jinja2 | 9 +++++++++ .../backends/raspbian/templates/macaddrlist.jinja2 | 12 ++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 netjsonconfig/backends/raspbian/templates/macaddrlist.jinja2 diff --git a/netjsonconfig/backends/raspbian/templates/hostapd.jinja2 b/netjsonconfig/backends/raspbian/templates/hostapd.jinja2 index 9d96df42a..72adc4da1 100644 --- a/netjsonconfig/backends/raspbian/templates/hostapd.jinja2 +++ b/netjsonconfig/backends/raspbian/templates/hostapd.jinja2 @@ -27,6 +27,15 @@ {% if wireless.frag_threshold > 0 %} frag_threshold={{ wireless.frag_threshold }} {% endif %} + {% if wireless.macfilter %} + {% if wireless.macfilter == 'deny'%} + macaddr_acl=0 + deny_mac_file=/etc/hostapd.deny + {% elif wireless.macfilter == 'accept' %} + macaddr_acl=1 + accept_mac_file=/etc/hostapd.accept + {% endif %} + {% endif %} {% if wireless.encryption %} auth_algs={{ wireless.encryption.auth_algs }} wpa={{ wireless.encryption.wpa }} diff --git a/netjsonconfig/backends/raspbian/templates/macaddrlist.jinja2 b/netjsonconfig/backends/raspbian/templates/macaddrlist.jinja2 new file mode 100644 index 000000000..0dcd6fc58 --- /dev/null +++ b/netjsonconfig/backends/raspbian/templates/macaddrlist.jinja2 @@ -0,0 +1,12 @@ +{% if data.wireless and data.wireless[0].mode == 'access_point' %} + {% for wireless in data.wireless %} + {% if wireless.macfilter %} + # config: /etc/hostapd.{{ wireless.macfilter }} + + {% for mac in wireless.maclist %} + {{ mac }} + {% endfor %} + + {% endif %} + {% endfor %} +{% endif %} From ae16a603abb3b17114fbdd59fd95558f4920afaf Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Thu, 10 Aug 2017 02:06:00 +0530 Subject: [PATCH 157/183] [raspbian] Addded tests for macaddr acl --- tests/raspbian/test_hostapd.py | 126 +++++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) diff --git a/tests/raspbian/test_hostapd.py b/tests/raspbian/test_hostapd.py index e1e195b71..722d61b9f 100644 --- a/tests/raspbian/test_hostapd.py +++ b/tests/raspbian/test_hostapd.py @@ -301,5 +301,131 @@ def test_no_encryption(self): sudo iptables -A FORWARD -i wlan0 -o eth0 -j ACCEPT sudo sh -c "iptables-save > /etc/iptables.ipv4.nat" +''' + self.assertEqual(o.render(), expected) + + def test_macaddracl_accept(self): + o = Raspbian({ + "radios": [ + { + "name": "radio0", + "phy": "phy0", + "driver": "mac80211", + "protocol": "802.11n", + "channel": 3, + "channel_width": 20, + "tx_power": 3 + }, + ], + "interfaces": [ + { + "name": "wlan0", + "type": "wireless", + "wireless": { + "radio": "radio0", + "mode": "access_point", + "ssid": "MyWifiAP", + "macfilter": "accept", + "maclist": [ + "E8:94:F6:33:8C:1D", + "42:6c:8f:95:0f:00" + ] + } + } + ] + }) + + expected = '''# config: /etc/hostapd/hostapd.conf + +interface=wlan0 +driver=nl80211 +hw_mode=g +channel=3 +ieee80211n=1 +ssid=MyWifiAP +macaddr_acl=1 +accept_mac_file=/etc/hostapd.accept + +# config: /etc/hostapd.accept + +E8:94:F6:33:8C:1D +42:6c:8f:95:0f:00 + +# config: /etc/network/interfaces + +auto wlan0 +iface wlan0 inet manual + +# script: /scripts/ipv4_forwarding.sh + +sudo sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward" +sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE +sudo iptables -A FORWARD -i eth0 -o wlan0 -m state --state RELATED,ESTABLISHED -j ACCEPT +sudo iptables -A FORWARD -i wlan0 -o eth0 -j ACCEPT +sudo sh -c "iptables-save > /etc/iptables.ipv4.nat" + +''' + self.assertEqual(o.render(), expected) + + def test_macaddracl_deny(self): + o = Raspbian({ + "radios": [ + { + "name": "radio0", + "phy": "phy0", + "driver": "mac80211", + "protocol": "802.11n", + "channel": 3, + "channel_width": 20, + "tx_power": 3 + }, + ], + "interfaces": [ + { + "name": "wlan0", + "type": "wireless", + "wireless": { + "radio": "radio0", + "mode": "access_point", + "ssid": "MyWifiAP", + "macfilter": "deny", + "maclist": [ + "E8:94:F6:33:8C:1D", + "42:6c:8f:95:0f:00" + ] + } + } + ] + }) + + expected = '''# config: /etc/hostapd/hostapd.conf + +interface=wlan0 +driver=nl80211 +hw_mode=g +channel=3 +ieee80211n=1 +ssid=MyWifiAP +macaddr_acl=0 +deny_mac_file=/etc/hostapd.deny + +# config: /etc/hostapd.deny + +E8:94:F6:33:8C:1D +42:6c:8f:95:0f:00 + +# config: /etc/network/interfaces + +auto wlan0 +iface wlan0 inet manual + +# script: /scripts/ipv4_forwarding.sh + +sudo sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward" +sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE +sudo iptables -A FORWARD -i eth0 -o wlan0 -m state --state RELATED,ESTABLISHED -j ACCEPT +sudo iptables -A FORWARD -i wlan0 -o eth0 -j ACCEPT +sudo sh -c "iptables-save > /etc/iptables.ipv4.nat" + ''' self.assertEqual(o.render(), expected) From 98c919ec0812e33aec1fbdd0a25f88254c135fcf Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Thu, 10 Aug 2017 10:56:39 +0530 Subject: [PATCH 158/183] [raspbian] Added macfilter and maclist to schema --- netjsonconfig/backends/raspbian/schema.py | 43 +++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/netjsonconfig/backends/raspbian/schema.py b/netjsonconfig/backends/raspbian/schema.py index a91f65527..907d2977c 100644 --- a/netjsonconfig/backends/raspbian/schema.py +++ b/netjsonconfig/backends/raspbian/schema.py @@ -6,6 +6,49 @@ schema = merge_config(default_schema, { "definitions": { + "ap_wireless_settings": { + "allOf": [ + { + "properties": { + "macfilter": { + "type": "string", + "title": "MAC Filter", + "description": "specifies the mac filter policy, \"disable\" to disable " + "the filter, \"allow\" to treat it as whitelist or " + "\"deny\" to treat it as blacklist", + "enum": [ + None, + "accept", + "deny", + ], + "options": { + "enum_titles": [ + "disabled", + "accept", + "deny" + ] + }, + "default": "disable", + "propertyOrder": 15, + }, + "maclist": { + "type": "array", + "title": "MAC List", + "description": "mac addresses that will be filtered according to the policy " + "specified in the \"macfilter\" option", + "propertyOrder": 16, + "items": { + "type": "string", + "title": "MAC address", + "pattern": "^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$", + "minLength": 17, + "maxLength": 17, + } + } + } + } + ] + }, "radio_hwmode_11g": { "properties": { "hwmode": { From fdc7a15ce9a14c64b4ab16d865f59d8d28ca48bf Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Thu, 10 Aug 2017 17:02:51 +0530 Subject: [PATCH 159/183] [raspbian] Fixed isort warning --- netjsonconfig/backends/raspbian/raspbian.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netjsonconfig/backends/raspbian/raspbian.py b/netjsonconfig/backends/raspbian/raspbian.py index 95e012c48..1fc24e488 100644 --- a/netjsonconfig/backends/raspbian/raspbian.py +++ b/netjsonconfig/backends/raspbian/raspbian.py @@ -2,7 +2,7 @@ from . import converters from ..base.backend import BaseBackend -from .renderer import (Hostapd, MacAddrList, Hostname, Interfaces, Ntp, Resolv, +from .renderer import (Hostapd, Hostname, Interfaces, MacAddrList, Ntp, Resolv, Scripts, WpaSupplicant) from .schema import schema From 418f20d8c6a6a43ef56d490a5bfc56933283fd64 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Fri, 11 Aug 2017 00:03:33 +0530 Subject: [PATCH 160/183] [raspbian] Added support for wmm and isolate in wireless settings --- netjsonconfig/backends/raspbian/converters/wireless.py | 2 ++ netjsonconfig/backends/raspbian/templates/hostapd.jinja2 | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/netjsonconfig/backends/raspbian/converters/wireless.py b/netjsonconfig/backends/raspbian/converters/wireless.py index 4e5b7a4e4..141c06e39 100644 --- a/netjsonconfig/backends/raspbian/converters/wireless.py +++ b/netjsonconfig/backends/raspbian/converters/wireless.py @@ -23,6 +23,8 @@ def to_intermediate(self): 'hidden': wireless.get('hidden', False), 'rts_threshold': wireless.get('rts_threshold', -1), 'frag_threshold': wireless.get('frag_threshold', -1), + 'wmm': wireless.get('wmm', False), + 'isolate': wireless.get('isolate', False), 'macfilter': wireless.get('macfilter', None), 'maclist': wireless.get('maclist', None), 'encryption': self._get_encryption(wireless) diff --git a/netjsonconfig/backends/raspbian/templates/hostapd.jinja2 b/netjsonconfig/backends/raspbian/templates/hostapd.jinja2 index 72adc4da1..9d3584ddf 100644 --- a/netjsonconfig/backends/raspbian/templates/hostapd.jinja2 +++ b/netjsonconfig/backends/raspbian/templates/hostapd.jinja2 @@ -27,6 +27,12 @@ {% if wireless.frag_threshold > 0 %} frag_threshold={{ wireless.frag_threshold }} {% endif %} + {% if wireless.wmm %} + wmm_enabled=1 + {% endif %} + {% if wireless.isolate %} + ap_isolate=1 + {% endif %} {% if wireless.macfilter %} {% if wireless.macfilter == 'deny'%} macaddr_acl=0 From 884aa4cbfd75fa1e4b11a9a6acb33db5c29f64fc Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Fri, 11 Aug 2017 20:32:30 +0530 Subject: [PATCH 161/183] [raspbian] Added wmm and isolate to schema --- netjsonconfig/backends/raspbian/schema.py | 28 +++++++++++++++-------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/netjsonconfig/backends/raspbian/schema.py b/netjsonconfig/backends/raspbian/schema.py index 907d2977c..feb19255b 100644 --- a/netjsonconfig/backends/raspbian/schema.py +++ b/netjsonconfig/backends/raspbian/schema.py @@ -10,6 +10,23 @@ "allOf": [ { "properties": { + "wmm": { + "type": "boolean", + "title": "WMM (802.11e)", + "description": "enables WMM (802.11e) support; " + "required for 802.11n support", + "default": True, + "format": "checkbox", + "propertyOrder": 8, + }, + "isolate": { + "type": "boolean", + "title": "isolate clients", + "description": "isolate wireless clients from one another", + "default": False, + "format": "checkbox", + "propertyOrder": 9, + }, "macfilter": { "type": "string", "title": "MAC Filter", @@ -17,17 +34,10 @@ "the filter, \"allow\" to treat it as whitelist or " "\"deny\" to treat it as blacklist", "enum": [ - None, - "accept", + "disable", + "allow", "deny", ], - "options": { - "enum_titles": [ - "disabled", - "accept", - "deny" - ] - }, "default": "disable", "propertyOrder": 15, }, From c20333ab60dd852bd01965f6c3ba03b0641ca667 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Fri, 11 Aug 2017 20:37:06 +0530 Subject: [PATCH 162/183] [raspbian] Changed macfilter value --- netjsonconfig/backends/raspbian/schema.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netjsonconfig/backends/raspbian/schema.py b/netjsonconfig/backends/raspbian/schema.py index feb19255b..0a4cee967 100644 --- a/netjsonconfig/backends/raspbian/schema.py +++ b/netjsonconfig/backends/raspbian/schema.py @@ -35,7 +35,7 @@ "\"deny\" to treat it as blacklist", "enum": [ "disable", - "allow", + "accept", "deny", ], "default": "disable", From ea3d408cbcf77cdbcf358e0b2b1f0d5fd087bbbc Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Fri, 11 Aug 2017 20:51:51 +0530 Subject: [PATCH 163/183] [raspbian] Added additional files to schema --- netjsonconfig/backends/raspbian/schema.py | 1 - 1 file changed, 1 deletion(-) diff --git a/netjsonconfig/backends/raspbian/schema.py b/netjsonconfig/backends/raspbian/schema.py index 0a4cee967..8c246d74d 100644 --- a/netjsonconfig/backends/raspbian/schema.py +++ b/netjsonconfig/backends/raspbian/schema.py @@ -135,7 +135,6 @@ del schema['properties']['routes']['items']['required'][3] del schema['properties']['routes']['items']['properties']['cost'] del schema['properties']['routes']['items']['properties']['source'] -del schema['properties']['files'] del schema['definitions']['wireless_interface']['allOf'][0]['properties']['wireless']['oneOf'][4] del schema['definitions']['wireless_interface']['allOf'][0]['properties']['wireless']['oneOf'][3] From e32da726dcde94bcf2b709e6a6ef35b853487b61 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Sun, 13 Aug 2017 21:52:07 +0530 Subject: [PATCH 164/183] [raspbian] Updated documentations examples --- docs/source/backends/raspbian.rst | 42 +++++++++++++------------------ 1 file changed, 17 insertions(+), 25 deletions(-) diff --git a/docs/source/backends/raspbian.rst b/docs/source/backends/raspbian.rst index 8b4618b98..19a9c1e3f 100644 --- a/docs/source/backends/raspbian.rst +++ b/docs/source/backends/raspbian.rst @@ -34,12 +34,6 @@ Code example: "proto": "static", "family": "ipv4" }, - { - "address": "192.168.2.1", - "mask": 24, - "proto": "static", - "family": "ipv4" - }, { "address": "fd87::1", "mask": 128, @@ -60,9 +54,6 @@ Will return the following output:: iface eth0 inet static address 192.168.1.1 netmask 255.255.255.0 - iface eth0 inet static - address 192.168.2.1 - netmask 255.255.255.0 iface eth0 inet6 static address fd87::1 netmask 128 @@ -150,7 +141,7 @@ The following *configuration dictionary*: { "general": { - "hostname": "routerA", + "hostname": "RaspberryPi", "timezone": "UTC" } } @@ -159,7 +150,7 @@ Will be rendered as follows:: # config: /etc/hostname - routerA + RaspberryPi # script: /scripts/general.sh @@ -236,15 +227,9 @@ DNS Servers and Search Domains DNS servers can be set using ``dns_servers``, while search domains can be set using ``dns_search``. -If specified, these values will be automatically added in every interface which has -at least one static ip address; interfaces which have no ip address configured or are using -dynamic ip address configuration won't get the ``dns`` option in the UCI output, eg: - .. code-block:: python { - "dns_servers": ["10.11.12.13", "8.8.8.8"], - "dns_search": ["openwisp.org", "netjson.org"], "interfaces": [ { "name": "eth0", @@ -268,10 +253,17 @@ dynamic ip address configuration won't get the ``dns`` option in the UCI output, } ] } - ] + ], + "dns_servers": [ + "10.11.12.13", + "8.8.8.8" + ], + "dns_search": [ + "openwisp.org", + "netjson.org"], } -Will return the following UCI output:: +Will return the following output:: # config: /etc/network/interfaces @@ -348,11 +340,11 @@ The following *configuration dictionary*: { "interfaces": [ { - "name": "lan_bridge", + "name": "lan", "type": "bridge", "bridge_members": [ - "eth0:0", - "eth0:1" + "eth0", + "eth1" ], "addresses": [ { @@ -370,11 +362,11 @@ Will be rendered as follows:: # config: /etc/network/interfaces - auto lan_bridge - iface lan_bridge inet static + auto lan + iface lan inet static address 172.17.0.2 netmask 255.255.255.0 - bridge_ports eth0:0 eth0:1 + bridge_ports eth0 eth1 Wireless Settings ----------------- From 660cfba1a731d764e88f99baf887926dd3aae9dc Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Sun, 13 Aug 2017 22:17:11 +0530 Subject: [PATCH 165/183] [raspbian] Renamed reserved variable --- netjsonconfig/backends/raspbian/raspbian.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/netjsonconfig/backends/raspbian/raspbian.py b/netjsonconfig/backends/raspbian/raspbian.py index 1fc24e488..19b546394 100644 --- a/netjsonconfig/backends/raspbian/raspbian.py +++ b/netjsonconfig/backends/raspbian/raspbian.py @@ -37,8 +37,8 @@ def _generate_contents(self, tar): files = files_pattern.split(text) if '' in files: files.remove('') - for file in files: - lines = file.split('\n') + for file_ in files: + lines = file_.split('\n') file_name = lines[0] text_contents = '\n'.join(lines[2:]) self._add_file(tar=tar, From 33ec6dc64a71d9610c70cfba33d2c23e8ccefc45 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Tue, 15 Aug 2017 01:12:44 +0530 Subject: [PATCH 166/183] [raspbian] Added support for WPA-EAP mode --- .../backends/raspbian/converters/wireless.py | 46 ++++++++++++------- .../raspbian/templates/hostapd.jinja2 | 21 +++++++-- 2 files changed, 47 insertions(+), 20 deletions(-) diff --git a/netjsonconfig/backends/raspbian/converters/wireless.py b/netjsonconfig/backends/raspbian/converters/wireless.py index 141c06e39..d2d7d5a2b 100644 --- a/netjsonconfig/backends/raspbian/converters/wireless.py +++ b/netjsonconfig/backends/raspbian/converters/wireless.py @@ -75,23 +75,35 @@ def _get_encryption(self, wireless): if encryption.get('cipher'): wpa_pairwise = str(encryption.get('cipher').replace('+', ' ')).upper() new_encryption.update({'wpa_pairwise': wpa_pairwise}) - else: - if encryption.get('cipher'): - cipher = str(encryption.get('cipher').replace('+', ' ').upper()) - new_encryption.update({'cipher': cipher}) - if encryption.get('eap_type'): - eap_type = encryption.get('eap_type').upper() - new_encryption.update({'eap_type': eap_type}) - new_encryption.update({ - 'protocol': 'wpa', - 'method': 'enterprise', - 'identity': encryption.get('identity', None), - 'password': encryption.get('password', None), - 'ca_cert': encryption.get('ca_cert', None), - 'client_cert': encryption.get('client_cert', None), - 'priv_key': encryption.get('priv_key', None), - 'priv_key_pwd': encryption.get('priv_key_pwd', None) - }) + elif method == 'enterprise': + if wireless.get('mode') == 'access_point': + new_encryption.update({ + 'protocol': 'wpa', + 'method': 'enterprise', + 'auth_algs': '1', + 'wpa': '1' if protocol == 'wpa' else '2', + 'wpa_key_mgmt': 'WPA-EAP', + 'auth_server_addr': encryption.get('server'), + 'auth_server_port': encryption.get('port', 1812), + 'auth_server_shared_secret': encryption.get('key', None), + }) + elif wireless.get('mode') == 'station': + if encryption.get('cipher'): + cipher = str(encryption.get('cipher').replace('+', ' ').upper()) + new_encryption.update({'cipher': cipher}) + if encryption.get('eap_type'): + eap_type = encryption.get('eap_type').upper() + new_encryption.update({'eap_type': eap_type}) + new_encryption.update({ + 'protocol': 'wpa', + 'method': 'enterprise', + 'identity': encryption.get('identity', None), + 'password': encryption.get('password', None), + 'ca_cert': encryption.get('ca_cert', None), + 'client_cert': encryption.get('client_cert', None), + 'priv_key': encryption.get('priv_key', None), + 'priv_key_pwd': encryption.get('priv_key_pwd', None) + }) elif 'wep' in protocol: new_encryption.update({ 'protocol': 'wep', diff --git a/netjsonconfig/backends/raspbian/templates/hostapd.jinja2 b/netjsonconfig/backends/raspbian/templates/hostapd.jinja2 index 9d3584ddf..d59917c63 100644 --- a/netjsonconfig/backends/raspbian/templates/hostapd.jinja2 +++ b/netjsonconfig/backends/raspbian/templates/hostapd.jinja2 @@ -46,9 +46,24 @@ auth_algs={{ wireless.encryption.auth_algs }} wpa={{ wireless.encryption.wpa }} wpa_key_mgmt={{ wireless.encryption.wpa_key_mgmt }} - wpa_passphrase={{ wireless.encryption.wpa_passphrase }} - {% if wireless.encryption.wpa_pairwise != 'AUTO' %} - wpa_pairwise={{ wireless.encryption.wpa_pairwise }} + {% if wireless.encryption.method == 'personal' %} + wpa_passphrase={{ wireless.encryption.wpa_passphrase }} + {% if wireless.encryption.wpa_pairwise != 'AUTO' %} + wpa_pairwise={{ wireless.encryption.wpa_pairwise }} + {% endif %} + {% elif wireless.encryption.method == 'enterprise'%} + ieee8021x=1 + eap_server=1 + eapol_version=1 + {% if wireless.encryption.auth_server_addr %} + auth_server_addr={{ wireless.encryption.auth_server_addr }} + {% endif %} + {% if wireless.encryption.auth_server_port %} + auth_server_port={{ wireless.encryption.auth_server_port }} + {% endif %} + {% if wireless.encryption.auth_server_shared_secret %} + auth_server_shared_secret={{ wireless.encryption.auth_server_shared_secret }} + {% endif %} {% endif %} {% endif %} From 05159342415ced150ac3c3cb0d755f7ba4ac8e37 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Tue, 15 Aug 2017 01:13:20 +0530 Subject: [PATCH 167/183] [raspbian] Added tests for WPA Enterprise --- tests/raspbian/test_hostapd.py | 66 ++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/tests/raspbian/test_hostapd.py b/tests/raspbian/test_hostapd.py index 722d61b9f..9728f022c 100644 --- a/tests/raspbian/test_hostapd.py +++ b/tests/raspbian/test_hostapd.py @@ -127,6 +127,72 @@ def test_wpa_personal(self): ''' self.assertEqual(o.render(), expected) + def test_wpa2_enterprise_ap(self): + o = Raspbian({ + "radios": [ + { + "name": "radio0", + "phy": "phy0", + "driver": "mac80211", + "protocol": "802.11n", + "channel": 3, + "channel_width": 20, + }, + ], + "interfaces": [ + { + "type": "wireless", + "name": "wlan0", + "mac": "de:9f:db:30:c9:c5", + "wireless": { + "radio": "radio0", + "mode": "access_point", + "ssid": "ap-ssid-example", + "encryption": { + "protocol": "wpa2_enterprise", + "server": "radius.example.com", + "key": "the-shared-key", + }, + }, + } + ] + }) + + expected = '''# config: /etc/hostapd/hostapd.conf + +interface=wlan0 +driver=nl80211 +hw_mode=g +channel=3 +ieee80211n=1 +ssid=ap-ssid-example +auth_algs=1 +wpa=2 +wpa_key_mgmt=WPA-EAP +ieee8021x=1 +eap_server=1 +eapol_version=1 +auth_server_addr=radius.example.com +auth_server_port=1812 +auth_server_shared_secret=the-shared-key + +# config: /etc/network/interfaces + +auto wlan0 +iface wlan0 inet manual + +# script: /scripts/ipv4_forwarding.sh + +sudo sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward" +sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE +sudo iptables -A FORWARD -i eth0 -o wlan0 -m state --state RELATED,ESTABLISHED -j ACCEPT +sudo iptables -A FORWARD -i wlan0 -o eth0 -j ACCEPT +sudo sh -c "iptables-save > /etc/iptables.ipv4.nat" + +''' + + self.assertEqual(o.render(), expected) + @unittest.skip('Test skipping') def test_wep_open(self): o = Raspbian({ From 4b878e57ebd5fdf696b237e2e24ccb92b43c879f Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Tue, 15 Aug 2017 19:50:40 +0530 Subject: [PATCH 168/183] [raspbian] Added experimental warning --- docs/source/backends/raspbian.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/source/backends/raspbian.rst b/docs/source/backends/raspbian.rst index 19a9c1e3f..d79d27ba6 100644 --- a/docs/source/backends/raspbian.rst +++ b/docs/source/backends/raspbian.rst @@ -6,6 +6,10 @@ Raspbian Backend The ``Raspbian`` backend allows to Raspbian compatible configuration files. +.. warning:: + The backend is in experimental stage and may have bugs, check for updates on + a regular basis + Initialization -------------- From 94b3d3f255aedcf95c8dad0cec02f997fccbbf60 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Tue, 15 Aug 2017 20:54:56 +0530 Subject: [PATCH 169/183] [raspbian] Reduce _get_encryption complexity --- .../backends/raspbian/converters/wireless.py | 26 ++++++++----------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/netjsonconfig/backends/raspbian/converters/wireless.py b/netjsonconfig/backends/raspbian/converters/wireless.py index d2d7d5a2b..cad12d502 100644 --- a/netjsonconfig/backends/raspbian/converters/wireless.py +++ b/netjsonconfig/backends/raspbian/converters/wireless.py @@ -11,12 +11,10 @@ def to_intermediate(self): new_interface = {} for interface in interfaces: if interface.get('type') == 'wireless' and interface.get('wireless').get('mode') is not 'adhoc': + wireless = interface.get('wireless') new_interface.update({ 'ifname': interface.get('name'), 'iftype': interface.get('type'), - }) - wireless = interface.get('wireless') - new_interface.update({ 'ssid': wireless.get('ssid'), 'radio': wireless.get('radio'), 'mode': wireless.get('mode'), @@ -55,13 +53,9 @@ def _get_hwmode(self, radio): def _get_encryption(self, wireless): encryption = wireless.get('encryption', None) new_encryption = {} - if encryption is None: + if encryption is None or encryption.get('disabled', False) or encryption.get('protocol') == 'none': return new_encryption - disabled = encryption.get('disabled', False) - protocol = encryption.get('protocol') - if disabled or protocol == 'none': - return new_encryption - protocol, method = protocol.split("_") + protocol, method = encryption.get('protocol').split("_") if 'wpa' in protocol: if 'personal' in method: new_encryption.update({ @@ -71,10 +65,8 @@ def _get_encryption(self, wireless): 'wpa': '1' if protocol == 'wpa' else '2', 'wpa_key_mgmt': 'WPA-PSK', 'wpa_passphrase': encryption.get('key'), + 'wpa_pairwise': self._get_cipher(encryption), }) - if encryption.get('cipher'): - wpa_pairwise = str(encryption.get('cipher').replace('+', ' ')).upper() - new_encryption.update({'wpa_pairwise': wpa_pairwise}) elif method == 'enterprise': if wireless.get('mode') == 'access_point': new_encryption.update({ @@ -88,15 +80,13 @@ def _get_encryption(self, wireless): 'auth_server_shared_secret': encryption.get('key', None), }) elif wireless.get('mode') == 'station': - if encryption.get('cipher'): - cipher = str(encryption.get('cipher').replace('+', ' ').upper()) - new_encryption.update({'cipher': cipher}) if encryption.get('eap_type'): eap_type = encryption.get('eap_type').upper() new_encryption.update({'eap_type': eap_type}) new_encryption.update({ 'protocol': 'wpa', 'method': 'enterprise', + 'wpa_pairwise': self._get_cipher(encryption), 'identity': encryption.get('identity', None), 'password': encryption.get('password', None), 'ca_cert': encryption.get('ca_cert', None), @@ -111,3 +101,9 @@ def _get_encryption(self, wireless): 'key': encryption.get('key', None) }) return new_encryption + + def _get_cipher(self, encryption): + if encryption.get('cipher'): + return str(encryption.get('cipher').replace('+', ' ')).upper() + else: + return None From 8c117b85c9bb21f0f63236f77603af5024c7a851 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Tue, 15 Aug 2017 22:10:36 +0530 Subject: [PATCH 170/183] [raspbian] Added _get_cipher and _update_radio definitions --- .../backends/raspbian/converters/wireless.py | 25 +++++++++++-------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/netjsonconfig/backends/raspbian/converters/wireless.py b/netjsonconfig/backends/raspbian/converters/wireless.py index cad12d502..305f93027 100644 --- a/netjsonconfig/backends/raspbian/converters/wireless.py +++ b/netjsonconfig/backends/raspbian/converters/wireless.py @@ -27,17 +27,7 @@ def to_intermediate(self): 'maclist': wireless.get('maclist', None), 'encryption': self._get_encryption(wireless) }) - radios = get_copy(self.netjson, 'radios') - if radios: - req_radio = [radio for radio in radios if radio['name'] == wireless.get('radio')][0] - new_interface.update({ - 'protocol': req_radio.get('protocol').replace(".", ""), - 'hwmode': self._get_hwmode(req_radio), - 'channel': req_radio.get('channel'), - 'channel_width': req_radio.get('channel_width') - }) - if 'country' in req_radio: - new_interface.update({'country': req_radio.get('country')}) + self._update_radio(wireless, new_interface) result.append(new_interface) return (('wireless', result),) @@ -50,6 +40,19 @@ def _get_hwmode(self, radio): else: return 'a' + def _update_radio(self, wireless, interface): + radios = get_copy(self.netjson, 'radios') + if radios: + req_radio = [radio for radio in radios if radio['name'] == wireless.get('radio')][0] + interface.update({ + 'protocol': req_radio.get('protocol').replace(".", ""), + 'hwmode': self._get_hwmode(req_radio), + 'channel': req_radio.get('channel'), + 'channel_width': req_radio.get('channel_width') + }) + if 'country' in req_radio: + interface.update({'country': req_radio.get('country')}) + def _get_encryption(self, wireless): encryption = wireless.get('encryption', None) new_encryption = {} From f89e2cf24840d7ad654935af1026a247bc3b649a Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Sat, 19 Aug 2017 22:30:45 +0530 Subject: [PATCH 171/183] [raspbian] Updated experimental warning --- docs/source/backends/raspbian.rst | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/source/backends/raspbian.rst b/docs/source/backends/raspbian.rst index d79d27ba6..eec18355e 100644 --- a/docs/source/backends/raspbian.rst +++ b/docs/source/backends/raspbian.rst @@ -7,8 +7,11 @@ Raspbian Backend The ``Raspbian`` backend allows to Raspbian compatible configuration files. .. warning:: - The backend is in experimental stage and may have bugs, check for updates on - a regular basis + This backend is in experimental stage: it may have bugs and it will + receive backward incompatible updates in during the first 6 months + of development (starting from September 2017). + Early feedback and contributions are very welcome and will help + to stabilize the backend faster. Initialization -------------- From 5f3e6755534bd3a9c291fcccbd9125e3340c3872 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Sat, 19 Aug 2017 22:46:11 +0530 Subject: [PATCH 172/183] [raspbian] Removed wps ap mode from schema --- netjsonconfig/backends/raspbian/schema.py | 1 + 1 file changed, 1 insertion(+) diff --git a/netjsonconfig/backends/raspbian/schema.py b/netjsonconfig/backends/raspbian/schema.py index 8c246d74d..83d259661 100644 --- a/netjsonconfig/backends/raspbian/schema.py +++ b/netjsonconfig/backends/raspbian/schema.py @@ -139,6 +139,7 @@ del schema['definitions']['wireless_interface']['allOf'][0]['properties']['wireless']['oneOf'][4] del schema['definitions']['wireless_interface']['allOf'][0]['properties']['wireless']['oneOf'][3] del schema['definitions']['base_wireless_settings']['properties']['ack_distance'] +del schema['definitions']['encryption_wireless_property_ap']['properties']['encryption']['oneOf'][3] del schema['definitions']['ap_wireless_settings']['allOf'][4] del schema['definitions']['sta_wireless_settings']['allOf'][4] del schema['definitions']['base_radio_settings']['properties']['phy'] From f4c33282205718ea614a83aa35ad4370261622ce Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Mon, 21 Aug 2017 16:26:18 +0400 Subject: [PATCH 173/183] [raspbian] Updated tests for wep --- tests/raspbian/test_hostapd.py | 58 +++++++++++++++++++++++++++++++--- 1 file changed, 53 insertions(+), 5 deletions(-) diff --git a/tests/raspbian/test_hostapd.py b/tests/raspbian/test_hostapd.py index 9728f022c..e34033c12 100644 --- a/tests/raspbian/test_hostapd.py +++ b/tests/raspbian/test_hostapd.py @@ -49,7 +49,7 @@ def test_wpa2_personal(self): wpa=2 wpa_key_mgmt=WPA-PSK wpa_passphrase=passphrase012345 -wpa_pairwise=TKIP CCMP +rsn_pairwise=TKIP CCMP # config: /etc/network/interfaces @@ -193,7 +193,6 @@ def test_wpa2_enterprise_ap(self): self.assertEqual(o.render(), expected) - @unittest.skip('Test skipping') def test_wep_open(self): o = Raspbian({ "radios": [ @@ -224,10 +223,34 @@ def test_wep_open(self): ] }) - expected = '''''' + expected = '''# config: /etc/hostapd/hostapd.conf + +interface=wlan0 +driver=nl80211 +hw_mode=g +channel=3 +ieee80211n=1 +ssid=wep +auth_algs=1 +wep_default_key=0 +wep_key0=wepkey1234567 + +# config: /etc/network/interfaces + +auto wlan0 +iface wlan0 inet manual + +# script: /scripts/ipv4_forwarding.sh + +sudo sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward" +sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE +sudo iptables -A FORWARD -i eth0 -o wlan0 -m state --state RELATED,ESTABLISHED -j ACCEPT +sudo iptables -A FORWARD -i wlan0 -o eth0 -j ACCEPT +sudo sh -c "iptables-save > /etc/iptables.ipv4.nat" + +''' self.assertEqual(o.render(), expected) - @unittest.skip('Test skipping') def test_wep_shared(self): o = Raspbian({ "radios": [ @@ -258,7 +281,32 @@ def test_wep_shared(self): ] }) - expected = '''''' + expected = '''# config: /etc/hostapd/hostapd.conf + +interface=wlan0 +driver=nl80211 +hw_mode=g +channel=3 +ieee80211n=1 +ssid=wep +auth_algs=2 +wep_default_key=0 +wep_key0=wepkey1234567 + +# config: /etc/network/interfaces + +auto wlan0 +iface wlan0 inet manual + +# script: /scripts/ipv4_forwarding.sh + +sudo sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward" +sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE +sudo iptables -A FORWARD -i eth0 -o wlan0 -m state --state RELATED,ESTABLISHED -j ACCEPT +sudo iptables -A FORWARD -i wlan0 -o eth0 -j ACCEPT +sudo sh -c "iptables-save > /etc/iptables.ipv4.nat" + +''' self.assertEqual(o.render(), expected) def test_encryption_disabled(self): From 01264b645e4969ef96d2ea5eb4520f1d7eddc272 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Mon, 21 Aug 2017 16:28:26 +0400 Subject: [PATCH 174/183] [raspbian] Added support for wep mode --- .../backends/raspbian/converters/wireless.py | 3 +- .../raspbian/templates/hostapd.jinja2 | 48 +++++++++++-------- 2 files changed, 31 insertions(+), 20 deletions(-) diff --git a/netjsonconfig/backends/raspbian/converters/wireless.py b/netjsonconfig/backends/raspbian/converters/wireless.py index 305f93027..921deeb85 100644 --- a/netjsonconfig/backends/raspbian/converters/wireless.py +++ b/netjsonconfig/backends/raspbian/converters/wireless.py @@ -68,7 +68,7 @@ def _get_encryption(self, wireless): 'wpa': '1' if protocol == 'wpa' else '2', 'wpa_key_mgmt': 'WPA-PSK', 'wpa_passphrase': encryption.get('key'), - 'wpa_pairwise': self._get_cipher(encryption), + 'cipher': self._get_cipher(encryption), }) elif method == 'enterprise': if wireless.get('mode') == 'access_point': @@ -99,6 +99,7 @@ def _get_encryption(self, wireless): }) elif 'wep' in protocol: new_encryption.update({ + 'auth_algs': 1 if method == 'open' else 2, 'protocol': 'wep', 'method': method, 'key': encryption.get('key', None) diff --git a/netjsonconfig/backends/raspbian/templates/hostapd.jinja2 b/netjsonconfig/backends/raspbian/templates/hostapd.jinja2 index d59917c63..1e2491574 100644 --- a/netjsonconfig/backends/raspbian/templates/hostapd.jinja2 +++ b/netjsonconfig/backends/raspbian/templates/hostapd.jinja2 @@ -44,26 +44,36 @@ {% endif %} {% if wireless.encryption %} auth_algs={{ wireless.encryption.auth_algs }} - wpa={{ wireless.encryption.wpa }} - wpa_key_mgmt={{ wireless.encryption.wpa_key_mgmt }} - {% if wireless.encryption.method == 'personal' %} - wpa_passphrase={{ wireless.encryption.wpa_passphrase }} - {% if wireless.encryption.wpa_pairwise != 'AUTO' %} - wpa_pairwise={{ wireless.encryption.wpa_pairwise }} - {% endif %} - {% elif wireless.encryption.method == 'enterprise'%} - ieee8021x=1 - eap_server=1 - eapol_version=1 - {% if wireless.encryption.auth_server_addr %} - auth_server_addr={{ wireless.encryption.auth_server_addr }} - {% endif %} - {% if wireless.encryption.auth_server_port %} - auth_server_port={{ wireless.encryption.auth_server_port }} - {% endif %} - {% if wireless.encryption.auth_server_shared_secret %} - auth_server_shared_secret={{ wireless.encryption.auth_server_shared_secret }} + {% if wireless.encryption.protocol == 'wpa' %} + wpa={{ wireless.encryption.wpa }} + wpa_key_mgmt={{ wireless.encryption.wpa_key_mgmt }} + {% if wireless.encryption.method == 'personal' %} + wpa_passphrase={{ wireless.encryption.wpa_passphrase }} + {% if wireless.encryption.cipher != 'AUTO' %} + {% if wireless.encryption.wpa == '1' %} + wpa_pairwise={{ wireless.encryption.cipher }} + {% endif %} + {% if wireless.encryption.wpa == '2' %} + rsn_pairwise={{ wireless.encryption.cipher }} + {% endif %} + {% endif %} + {% elif wireless.encryption.method == 'enterprise'%} + ieee8021x=1 + eap_server=1 + eapol_version=1 + {% if wireless.encryption.auth_server_addr %} + auth_server_addr={{ wireless.encryption.auth_server_addr }} + {% endif %} + {% if wireless.encryption.auth_server_port %} + auth_server_port={{ wireless.encryption.auth_server_port }} + {% endif %} + {% if wireless.encryption.auth_server_shared_secret %} + auth_server_shared_secret={{ wireless.encryption.auth_server_shared_secret }} + {% endif %} {% endif %} + {% elif wireless.encryption.protocol == 'wep' %} + wep_default_key=0 + wep_key0={{ wireless.encryption.key}} {% endif %} {% endif %} From fa3f9f98082e26ea8f179a1159d13c1f930b1029 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Thu, 24 Aug 2017 10:53:59 +0400 Subject: [PATCH 175/183] [raspbian] Consistency with other backends --- tests/raspbian/test_backend.py | 16 +++--- tests/raspbian/test_hostapd.py | 36 ++++++------- tests/raspbian/test_interfaces.py | 80 ++++++++++++++-------------- tests/raspbian/test_radios.py | 24 ++++----- tests/raspbian/test_resolv.py | 14 ++--- tests/raspbian/test_routes.py | 28 +++++----- tests/raspbian/test_system.py | 8 +-- tests/raspbian/test_wpasupplicant.py | 20 +++---- 8 files changed, 113 insertions(+), 113 deletions(-) diff --git a/tests/raspbian/test_backend.py b/tests/raspbian/test_backend.py index 6aed42f94..a1c80293b 100644 --- a/tests/raspbian/test_backend.py +++ b/tests/raspbian/test_backend.py @@ -41,36 +41,36 @@ def test_generate(self): general = tar.getmember('/etc/hostname') contents = tar.extractfile(general).read().decode() - expected = self._tabs('''test + expected = self._tabs("""test -''') +""") self.assertEqual(contents, expected) interface = tar.getmember('/etc/network/interfaces') contents = tar.extractfile(interface).read().decode() - expected = self._tabs('''auto eth0 + expected = self._tabs("""auto eth0 iface eth0 inet static address 192.168.1.1 netmask 255.255.255.0 -''') +""") self.assertEqual(contents, expected) resolv = tar.getmember('/etc/resolv.conf') contents = tar.extractfile(resolv).read().decode() - expected = self._tabs('''nameserver 10.11.12.13 + expected = self._tabs("""nameserver 10.11.12.13 nameserver 8.8.8.8 search netjson.org search openwisp.org -''') +""") self.assertEqual(contents, expected) script = tar.getmember('/scripts/general.sh') contents = tar.extractfile(script).read().decode() - expected = self._tabs('''/etc/init.d/hostname.sh start + expected = self._tabs("""/etc/init.d/hostname.sh start echo "Hostname of device has been modified" -''') +""") self.assertEqual(contents, expected) def test_write(self): diff --git a/tests/raspbian/test_hostapd.py b/tests/raspbian/test_hostapd.py index e34033c12..d6874a0e2 100644 --- a/tests/raspbian/test_hostapd.py +++ b/tests/raspbian/test_hostapd.py @@ -37,7 +37,7 @@ def test_wpa2_personal(self): ] }) - expected = '''# config: /etc/hostapd/hostapd.conf + expected = """# config: /etc/hostapd/hostapd.conf interface=wlan0 driver=nl80211 @@ -64,7 +64,7 @@ def test_wpa2_personal(self): sudo iptables -A FORWARD -i wlan0 -o eth0 -j ACCEPT sudo sh -c "iptables-save > /etc/iptables.ipv4.nat" -''' +""" self.assertEqual(o.render(), expected) def test_wpa_personal(self): @@ -98,7 +98,7 @@ def test_wpa_personal(self): ] }) - expected = '''# config: /etc/hostapd/hostapd.conf + expected = """# config: /etc/hostapd/hostapd.conf interface=wlan0 driver=nl80211 @@ -124,7 +124,7 @@ def test_wpa_personal(self): sudo iptables -A FORWARD -i wlan0 -o eth0 -j ACCEPT sudo sh -c "iptables-save > /etc/iptables.ipv4.nat" -''' +""" self.assertEqual(o.render(), expected) def test_wpa2_enterprise_ap(self): @@ -158,7 +158,7 @@ def test_wpa2_enterprise_ap(self): ] }) - expected = '''# config: /etc/hostapd/hostapd.conf + expected = """# config: /etc/hostapd/hostapd.conf interface=wlan0 driver=nl80211 @@ -189,7 +189,7 @@ def test_wpa2_enterprise_ap(self): sudo iptables -A FORWARD -i wlan0 -o eth0 -j ACCEPT sudo sh -c "iptables-save > /etc/iptables.ipv4.nat" -''' +""" self.assertEqual(o.render(), expected) @@ -223,7 +223,7 @@ def test_wep_open(self): ] }) - expected = '''# config: /etc/hostapd/hostapd.conf + expected = """# config: /etc/hostapd/hostapd.conf interface=wlan0 driver=nl80211 @@ -248,7 +248,7 @@ def test_wep_open(self): sudo iptables -A FORWARD -i wlan0 -o eth0 -j ACCEPT sudo sh -c "iptables-save > /etc/iptables.ipv4.nat" -''' +""" self.assertEqual(o.render(), expected) def test_wep_shared(self): @@ -281,7 +281,7 @@ def test_wep_shared(self): ] }) - expected = '''# config: /etc/hostapd/hostapd.conf + expected = """# config: /etc/hostapd/hostapd.conf interface=wlan0 driver=nl80211 @@ -306,7 +306,7 @@ def test_wep_shared(self): sudo iptables -A FORWARD -i wlan0 -o eth0 -j ACCEPT sudo sh -c "iptables-save > /etc/iptables.ipv4.nat" -''' +""" self.assertEqual(o.render(), expected) def test_encryption_disabled(self): @@ -341,7 +341,7 @@ def test_encryption_disabled(self): ] }) - expected = '''# config: /etc/hostapd/hostapd.conf + expected = """# config: /etc/hostapd/hostapd.conf interface=wlan0 driver=nl80211 @@ -363,7 +363,7 @@ def test_encryption_disabled(self): sudo iptables -A FORWARD -i wlan0 -o eth0 -j ACCEPT sudo sh -c "iptables-save > /etc/iptables.ipv4.nat" -''' +""" self.assertEqual(o.render(), expected) def test_no_encryption(self): @@ -393,7 +393,7 @@ def test_no_encryption(self): ] }) - expected = '''# config: /etc/hostapd/hostapd.conf + expected = """# config: /etc/hostapd/hostapd.conf interface=wlan0 driver=nl80211 @@ -415,7 +415,7 @@ def test_no_encryption(self): sudo iptables -A FORWARD -i wlan0 -o eth0 -j ACCEPT sudo sh -c "iptables-save > /etc/iptables.ipv4.nat" -''' +""" self.assertEqual(o.render(), expected) def test_macaddracl_accept(self): @@ -449,7 +449,7 @@ def test_macaddracl_accept(self): ] }) - expected = '''# config: /etc/hostapd/hostapd.conf + expected = """# config: /etc/hostapd/hostapd.conf interface=wlan0 driver=nl80211 @@ -478,7 +478,7 @@ def test_macaddracl_accept(self): sudo iptables -A FORWARD -i wlan0 -o eth0 -j ACCEPT sudo sh -c "iptables-save > /etc/iptables.ipv4.nat" -''' +""" self.assertEqual(o.render(), expected) def test_macaddracl_deny(self): @@ -512,7 +512,7 @@ def test_macaddracl_deny(self): ] }) - expected = '''# config: /etc/hostapd/hostapd.conf + expected = """# config: /etc/hostapd/hostapd.conf interface=wlan0 driver=nl80211 @@ -541,5 +541,5 @@ def test_macaddracl_deny(self): sudo iptables -A FORWARD -i wlan0 -o eth0 -j ACCEPT sudo sh -c "iptables-save > /etc/iptables.ipv4.nat" -''' +""" self.assertEqual(o.render(), expected) diff --git a/tests/raspbian/test_interfaces.py b/tests/raspbian/test_interfaces.py index 068afd809..613e6c45a 100644 --- a/tests/raspbian/test_interfaces.py +++ b/tests/raspbian/test_interfaces.py @@ -69,14 +69,14 @@ def test_ipv4_static(self): ] }) - expected = '''# config: /etc/network/interfaces + expected = """# config: /etc/network/interfaces auto eth0 iface eth0 inet static address 10.0.0.1 netmask 255.255.255.240 -''' +""" self.assertEqual(o.render(), expected) def test_multi_ipv4_static(self): @@ -109,7 +109,7 @@ def test_multi_ipv4_static(self): ] }) - expected = '''# config: /etc/network/interfaces + expected = """# config: /etc/network/interfaces auto eth0 iface eth0 inet static @@ -121,7 +121,7 @@ def test_multi_ipv4_static(self): address 10.0.0.2 netmask 255.255.255.240 -''' +""" self.assertEqual(o.render(), expected) def test_ipv6_static(self): @@ -142,14 +142,14 @@ def test_ipv6_static(self): ] }) - expected = '''# config: /etc/network/interfaces + expected = """# config: /etc/network/interfaces auto eth0 iface eth0 inet6 static address fe80::ba27:ebff:fe1c:5477 netmask 64 -''' +""" self.assertEqual(o.render(), expected) def test_multi_ipv6_static(self): @@ -182,7 +182,7 @@ def test_multi_ipv6_static(self): ] }) - expected = '''# config: /etc/network/interfaces + expected = """# config: /etc/network/interfaces auto eth0 iface eth0 inet6 static @@ -194,7 +194,7 @@ def test_multi_ipv6_static(self): address 2001:db8:0:0:0:ff00:42:8329 netmask 64 -''' +""" self.assertEqual(o.render(), expected) def test_multiple_static(self): @@ -221,7 +221,7 @@ def test_multiple_static(self): ] }) - expected = '''# config: /etc/network/interfaces + expected = """# config: /etc/network/interfaces auto eth0 iface eth0 inet static @@ -231,7 +231,7 @@ def test_multiple_static(self): address fe80::ba27:ebff:fe1c:5477 netmask 64 -''' +""" self.assertEqual(o.render(), expected) def test_ipv4_dhcp(self): @@ -250,12 +250,12 @@ def test_ipv4_dhcp(self): ] }) - expected = '''# config: /etc/network/interfaces + expected = """# config: /etc/network/interfaces auto eth0 iface eth0 inet dhcp -''' +""" self.assertEqual(o.render(), expected) def test_multi_ipv4_dhcp(self): @@ -284,7 +284,7 @@ def test_multi_ipv4_dhcp(self): ] }) - expected = '''# config: /etc/network/interfaces + expected = """# config: /etc/network/interfaces auto eth0 iface eth0 inet dhcp @@ -292,7 +292,7 @@ def test_multi_ipv4_dhcp(self): auto eth1 iface eth1 inet dhcp -''' +""" self.assertEqual(o.render(), expected) def test_ipv6_dhcp(self): @@ -311,12 +311,12 @@ def test_ipv6_dhcp(self): ] }) - expected = '''# config: /etc/network/interfaces + expected = """# config: /etc/network/interfaces auto eth0 iface eth0 inet6 dhcp -''' +""" self.assertEqual(o.render(), expected) def test_multi_ipv6_dhcp(self): @@ -345,7 +345,7 @@ def test_multi_ipv6_dhcp(self): ] }) - expected = '''# config: /etc/network/interfaces + expected = """# config: /etc/network/interfaces auto eth0 iface eth0 inet6 dhcp @@ -353,7 +353,7 @@ def test_multi_ipv6_dhcp(self): auto eth1 iface eth1 inet6 dhcp -''' +""" self.assertEqual(o.render(), expected) def test_multiple_dhcp(self): @@ -377,13 +377,13 @@ def test_multiple_dhcp(self): ] }) - expected = '''# config: /etc/network/interfaces + expected = """# config: /etc/network/interfaces auto eth0 iface eth0 inet dhcp iface eth0 inet6 dhcp -''' +""" self.assertEqual(o.render(), expected) def test_multiple_ip(self): @@ -417,7 +417,7 @@ def test_multiple_ip(self): ] }) - expected = '''# config: /etc/network/interfaces + expected = """# config: /etc/network/interfaces auto eth0 iface eth0 inet static @@ -430,7 +430,7 @@ def test_multiple_ip(self): address fd87::1 netmask 128 -''' +""" self.assertEqual(o.render(), expected) def test_autostart_false(self): @@ -444,11 +444,11 @@ def test_autostart_false(self): ] }) - expected = '''# config: /etc/network/interfaces + expected = """# config: /etc/network/interfaces iface eth0 inet manual -''' +""" self.assertEqual(o.render(), expected) @@ -469,13 +469,13 @@ def test_mtu(self): ], }) - expected = '''# config: /etc/network/interfaces + expected = """# config: /etc/network/interfaces auto eth1 iface eth1 inet dhcp pre-up /sbin/ifconfig $IFACE mtu 1500 -''' +""" self.assertEqual(o.render(), expected) def test_mac(self): @@ -495,13 +495,13 @@ def test_mac(self): ], }) - expected = '''# config: /etc/network/interfaces + expected = """# config: /etc/network/interfaces auto eth1 iface eth1 inet dhcp hwaddress 52:54:00:56:46:c0 -''' +""" self.assertEqual(o.render(), expected) @@ -533,7 +533,7 @@ def test_multiple_ip_and_dhcp(self): ] }) - expected = '''# config: /etc/network/interfaces + expected = """# config: /etc/network/interfaces auto eth0 iface eth0 inet dhcp @@ -544,7 +544,7 @@ def test_multiple_ip_and_dhcp(self): address 192.168.2.1 netmask 255.255.255.0 -''' +""" self.assertEqual(o.render(), expected) def test_interface_with_resolv(self): @@ -567,7 +567,7 @@ def test_interface_with_resolv(self): "dns_search": ["netjson.org", "openwisp.org"], }) - expected = '''# config: /etc/network/interfaces + expected = """# config: /etc/network/interfaces auto eth0 iface eth0 inet static @@ -580,7 +580,7 @@ def test_interface_with_resolv(self): nameserver 8.8.8.8 search netjson.org search openwisp.org -''' +""" self.assertEqual(o.render(), expected) def test_loopback(self): @@ -601,12 +601,12 @@ def test_loopback(self): ] }) - expected = '''# config: /etc/network/interfaces + expected = """# config: /etc/network/interfaces auto lo iface lo inet loopback -''' +""" self.assertEqual(o.render(), expected) def test_adhoc_wireless(self): @@ -625,7 +625,7 @@ def test_adhoc_wireless(self): ] }) - expected = '''# config: /etc/network/interfaces + expected = """# config: /etc/network/interfaces auto wlan0 iface wlan0 inet static @@ -635,7 +635,7 @@ def test_adhoc_wireless(self): wireless-essid freifunk wireless-mode ad-hoc -''' +""" self.assertEqual(o.render(), expected) def test_simple_bridge(self): @@ -653,12 +653,12 @@ def test_simple_bridge(self): ] }) - expected = '''# config: /etc/network/interfaces + expected = """# config: /etc/network/interfaces auto br-lan bridge_ports eth0 eth1 -''' +""" self.assertEqual(o.render(), expected) def test_complex_bridge(self): @@ -684,7 +684,7 @@ def test_complex_bridge(self): ] }) - expected = '''# config: /etc/network/interfaces + expected = """# config: /etc/network/interfaces auto brwifi iface brwifi inet6 static @@ -693,5 +693,5 @@ def test_complex_bridge(self): mtu 1500 bridge_ports wlan0 vpn.40 -''' +""" self.assertEqual(o.render(), expected) diff --git a/tests/raspbian/test_radios.py b/tests/raspbian/test_radios.py index 9d8e3f542..caa3131da 100644 --- a/tests/raspbian/test_radios.py +++ b/tests/raspbian/test_radios.py @@ -43,7 +43,7 @@ def test_radio_multi(self): ] }) - expected = '''# config: /etc/hostapd/hostapd.conf + expected = """# config: /etc/hostapd/hostapd.conf interface=wlan0 driver=nl80211 @@ -66,7 +66,7 @@ def test_radio_multi(self): sudo iptables -A FORWARD -i wlan0 -o eth0 -j ACCEPT sudo sh -c "iptables-save > /etc/iptables.ipv4.nat" -''' +""" self.assertEqual(o.render(), expected) def test_radio_n_24ghz(self): @@ -95,7 +95,7 @@ def test_radio_n_24ghz(self): ] }) - expected = '''# config: /etc/hostapd/hostapd.conf + expected = """# config: /etc/hostapd/hostapd.conf interface=wlan0 driver=nl80211 @@ -117,7 +117,7 @@ def test_radio_n_24ghz(self): sudo iptables -A FORWARD -i wlan0 -o eth0 -j ACCEPT sudo sh -c "iptables-save > /etc/iptables.ipv4.nat" -''' +""" self.assertEqual(o.render(), expected) def test_radio_n_5ghz(self): @@ -146,7 +146,7 @@ def test_radio_n_5ghz(self): ] }) - expected = '''# config: /etc/hostapd/hostapd.conf + expected = """# config: /etc/hostapd/hostapd.conf interface=wlan0 driver=nl80211 @@ -168,7 +168,7 @@ def test_radio_n_5ghz(self): sudo iptables -A FORWARD -i wlan0 -o eth0 -j ACCEPT sudo sh -c "iptables-save > /etc/iptables.ipv4.nat" -''' +""" self.assertEqual(o.render(), expected) def test_radio_ac(self): @@ -196,7 +196,7 @@ def test_radio_ac(self): ] }) - expected = '''# config: /etc/hostapd/hostapd.conf + expected = """# config: /etc/hostapd/hostapd.conf interface=wlan0 driver=nl80211 @@ -218,7 +218,7 @@ def test_radio_ac(self): sudo iptables -A FORWARD -i wlan0 -o eth0 -j ACCEPT sudo sh -c "iptables-save > /etc/iptables.ipv4.nat" -''' +""" self.assertEqual(o.render(), expected) def test_radio_a(self): @@ -246,7 +246,7 @@ def test_radio_a(self): ] }) - expected = '''# config: /etc/hostapd/hostapd.conf + expected = """# config: /etc/hostapd/hostapd.conf interface=wlan0 driver=nl80211 @@ -267,7 +267,7 @@ def test_radio_a(self): sudo iptables -A FORWARD -i wlan0 -o eth0 -j ACCEPT sudo sh -c "iptables-save > /etc/iptables.ipv4.nat" -''' +""" self.assertEqual(o.render(), expected) def test_radio_g(self): @@ -295,7 +295,7 @@ def test_radio_g(self): ] }) - expected = '''# config: /etc/hostapd/hostapd.conf + expected = """# config: /etc/hostapd/hostapd.conf interface=wlan0 driver=nl80211 @@ -316,5 +316,5 @@ def test_radio_g(self): sudo iptables -A FORWARD -i wlan0 -o eth0 -j ACCEPT sudo sh -c "iptables-save > /etc/iptables.ipv4.nat" -''' +""" self.assertEqual(o.render(), expected) diff --git a/tests/raspbian/test_resolv.py b/tests/raspbian/test_resolv.py index 513bd4835..e50757cb7 100644 --- a/tests/raspbian/test_resolv.py +++ b/tests/raspbian/test_resolv.py @@ -14,11 +14,11 @@ def test_dns_server(self): ], }) - expected = '''# config: /etc/resolv.conf + expected = """# config: /etc/resolv.conf nameserver 10.254.0.1 nameserver 10.254.0.2 -''' +""" self.assertEqual(o.render(), expected) def test_dns_search(self): @@ -28,10 +28,10 @@ def test_dns_search(self): ], }) - expected = '''# config: /etc/resolv.conf + expected = """# config: /etc/resolv.conf search domain.com -''' +""" self.assertEqual(o.render(), expected) def test_dns_server_and_dns_search(self): @@ -45,18 +45,18 @@ def test_dns_server_and_dns_search(self): ], }) - expected = '''# config: /etc/resolv.conf + expected = """# config: /etc/resolv.conf nameserver 10.11.12.13 nameserver 8.8.8.8 search netjson.org search openwisp.org -''' +""" self.assertEqual(o.render(), expected) def test_no_dns_server_and_dns_search(self): o = Raspbian({ }) - expected = '''''' + expected = """""" self.assertEqual(o.render(), expected) diff --git a/tests/raspbian/test_routes.py b/tests/raspbian/test_routes.py index 00000e2da..9d5e91afc 100644 --- a/tests/raspbian/test_routes.py +++ b/tests/raspbian/test_routes.py @@ -23,14 +23,14 @@ def test_ipv4_manual_route(self): ] }) - expected = '''# config: /etc/network/interfaces + expected = """# config: /etc/network/interfaces auto eth0 iface eth0 inet manual post-up route add -net 192.168.4.1 netmask 255.255.255.0 gw 192.168.2.2 pre-up route del -net 192.168.4.1 netmask 255.255.255.0 gw 192.168.2.2 -''' +""" self.assertEqual(o.render(), expected) def test_ipv4_static_route(self): @@ -58,7 +58,7 @@ def test_ipv4_static_route(self): ] }) - expected = '''# config: /etc/network/interfaces + expected = """# config: /etc/network/interfaces auto eth0 iface eth0 inet static @@ -67,7 +67,7 @@ def test_ipv4_static_route(self): post-up route add -net 192.168.4.1 netmask 255.255.255.0 gw 192.168.2.2 pre-up route del -net 192.168.4.1 netmask 255.255.255.0 gw 192.168.2.2 -''' +""" self.assertEqual(o.render(), expected) def test_ipv4_dchp_route(self): @@ -93,14 +93,14 @@ def test_ipv4_dchp_route(self): ] }) - expected = '''# config: /etc/network/interfaces + expected = """# config: /etc/network/interfaces auto eth0 iface eth0 inet dhcp post-up route add -net 192.168.4.1 netmask 255.255.255.0 gw 192.168.2.2 pre-up route del -net 192.168.4.1 netmask 255.255.255.0 gw 192.168.2.2 -''' +""" self.assertEqual(o.render(), expected) def test_ipv6_manual_route(self): @@ -121,14 +121,14 @@ def test_ipv6_manual_route(self): ] }) - expected = '''# config: /etc/network/interfaces + expected = """# config: /etc/network/interfaces auto eth0 iface eth0 inet manual up ip -6 route add fd89::1/128 via fd88::1 dev eth0 down ip -6 route del fd89::1/128 via fd88::1 dev eth0 -''' +""" self.assertEqual(o.render(), expected) @@ -158,7 +158,7 @@ def test_ipv6_static_route(self): ] }) - expected = '''# config: /etc/network/interfaces + expected = """# config: /etc/network/interfaces auto eth0 iface eth0 inet6 static @@ -167,7 +167,7 @@ def test_ipv6_static_route(self): up ip -6 route add fd89::1/128 via fd88::1 dev eth0 down ip -6 route del fd89::1/128 via fd88::1 dev eth0 -''' +""" self.assertEqual(o.render(), expected) def test_ipv6_dhcp_route(self): @@ -193,14 +193,14 @@ def test_ipv6_dhcp_route(self): ] }) - expected = '''# config: /etc/network/interfaces + expected = """# config: /etc/network/interfaces auto eth0 iface eth0 inet6 dhcp up ip -6 route add fd89::1/128 via fd88::1 dev eth0 down ip -6 route del fd89::1/128 via fd88::1 dev eth0 -''' +""" self.assertEqual(o.render(), expected) def test_multiple_routes(self): @@ -225,7 +225,7 @@ def test_multiple_routes(self): ] }) - expected = '''# config: /etc/network/interfaces + expected = """# config: /etc/network/interfaces auto eth1 iface eth1 inet manual @@ -234,5 +234,5 @@ def test_multiple_routes(self): up ip -6 route add fd89::1/128 via fd88::1 dev eth0 down ip -6 route del fd89::1/128 via fd88::1 dev eth0 -''' +""" self.assertEqual(o.render(), expected) diff --git a/tests/raspbian/test_system.py b/tests/raspbian/test_system.py index aa998b02e..09688daaf 100644 --- a/tests/raspbian/test_system.py +++ b/tests/raspbian/test_system.py @@ -14,7 +14,7 @@ def test_general(self): } }) - expected = '''# config: /etc/hostname + expected = """# config: /etc/hostname test-system @@ -25,7 +25,7 @@ def test_general(self): timedatectl set-timezone Europe/Rome echo "Timezone has changed to Europe/Rome" -''' +""" self.assertEqual(o.render(), expected) def test_ntp(self): @@ -41,10 +41,10 @@ def test_ntp(self): } }) - expected = '''# config: /etc/ntp.conf + expected = """# config: /etc/ntp.conf server 0.pool.ntp.org server 1.pool.ntp.org server 2.pool.ntp.org -''' +""" self.assertEqual(o.render(), expected) diff --git a/tests/raspbian/test_wpasupplicant.py b/tests/raspbian/test_wpasupplicant.py index c9dd5da57..76d83bb18 100644 --- a/tests/raspbian/test_wpasupplicant.py +++ b/tests/raspbian/test_wpasupplicant.py @@ -26,7 +26,7 @@ def test_wep_open(self): ] }) - expected = '''# config: /etc/wpa_supplicant/wpa_supplicant.conf + expected = """# config: /etc/wpa_supplicant/wpa_supplicant.conf network={ ssid="wep-test" @@ -47,7 +47,7 @@ def test_wep_open(self): sudo iptables -A FORWARD -i wlan0 -o eth0 -j ACCEPT sudo sh -c "iptables-save > /etc/iptables.ipv4.nat" -''' +""" self.assertEqual(o.render(), expected) @@ -71,7 +71,7 @@ def test_wep_shared(self): ] }) - expected = '''# config: /etc/wpa_supplicant/wpa_supplicant.conf + expected = """# config: /etc/wpa_supplicant/wpa_supplicant.conf network={ ssid="wep-test" @@ -93,7 +93,7 @@ def test_wep_shared(self): sudo iptables -A FORWARD -i wlan0 -o eth0 -j ACCEPT sudo sh -c "iptables-save > /etc/iptables.ipv4.nat" -''' +""" self.assertEqual(o.render(), expected) @@ -128,7 +128,7 @@ def test_wpa2_personal_sta(self): ] }) - expected = '''# config: /etc/wpa_supplicant/wpa_supplicant.conf + expected = """# config: /etc/wpa_supplicant/wpa_supplicant.conf network={ ssid="Test" @@ -149,7 +149,7 @@ def test_wpa2_personal_sta(self): sudo iptables -A FORWARD -i wlan0 -o eth0 -j ACCEPT sudo sh -c "iptables-save > /etc/iptables.ipv4.nat" -''' +""" self.assertEqual(o.render(), expected) def test_wpa2_enterprise_client(self): @@ -186,7 +186,7 @@ def test_wpa2_enterprise_client(self): ] }) - expected = '''# config: /etc/wpa_supplicant/wpa_supplicant.conf + expected = """# config: /etc/wpa_supplicant/wpa_supplicant.conf network={ ssid="enterprise-client" @@ -208,7 +208,7 @@ def test_wpa2_enterprise_client(self): sudo iptables -A FORWARD -i wlan0 -o eth0 -j ACCEPT sudo sh -c "iptables-save > /etc/iptables.ipv4.nat" -''' +""" self.assertEqual(o.render(), expected) @@ -239,7 +239,7 @@ def test_no_encryption(self): ] }) - expected = '''# config: /etc/wpa_supplicant/wpa_supplicant.conf + expected = """# config: /etc/wpa_supplicant/wpa_supplicant.conf network={ ssid="ap-ssid-example" @@ -259,5 +259,5 @@ def test_no_encryption(self): sudo iptables -A FORWARD -i wlan0 -o eth0 -j ACCEPT sudo sh -c "iptables-save > /etc/iptables.ipv4.nat" -''' +""" self.assertEqual(o.render(), expected) From 8040a51b41838f63ddf71610d9a8e4c574f7a756 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Thu, 24 Aug 2017 10:55:46 +0400 Subject: [PATCH 176/183] [raspbian] Updated experimental warning --- docs/source/backends/raspbian.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/backends/raspbian.rst b/docs/source/backends/raspbian.rst index eec18355e..7ed07c5e5 100644 --- a/docs/source/backends/raspbian.rst +++ b/docs/source/backends/raspbian.rst @@ -8,7 +8,7 @@ The ``Raspbian`` backend allows to Raspbian compatible configuration files. .. warning:: This backend is in experimental stage: it may have bugs and it will - receive backward incompatible updates in during the first 6 months + receive backward incompatible updates during the first 6 months of development (starting from September 2017). Early feedback and contributions are very welcome and will help to stabilize the backend faster. From 89066bf4ed65bdeef21e00eb3ee11e5d6a828ddc Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Thu, 24 Aug 2017 10:57:47 +0400 Subject: [PATCH 177/183] [raspbian] Remove unnecessary pass statement --- netjsonconfig/backends/raspbian/renderer.py | 1 - 1 file changed, 1 deletion(-) diff --git a/netjsonconfig/backends/raspbian/renderer.py b/netjsonconfig/backends/raspbian/renderer.py index 9844ef520..4468032ac 100644 --- a/netjsonconfig/backends/raspbian/renderer.py +++ b/netjsonconfig/backends/raspbian/renderer.py @@ -5,7 +5,6 @@ class RaspbianRenderer(BaseRenderer): def cleanup(self, output): output = output.replace(' ', '') return output - pass class WpaSupplicant(RaspbianRenderer): From 3bdfdfcbb493723f83a4ac4e3e05c7704867f223 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Sat, 26 Aug 2017 04:41:15 +0400 Subject: [PATCH 178/183] [raspbian] Update documentations --- docs/source/backends/raspbian.rst | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/docs/source/backends/raspbian.rst b/docs/source/backends/raspbian.rst index 7ed07c5e5..dddf0c1a9 100644 --- a/docs/source/backends/raspbian.rst +++ b/docs/source/backends/raspbian.rst @@ -387,27 +387,36 @@ You can install it using this command:: modes * **dnsmasq** - The package converts the Raspberry Pi into a DHCP and DNS server +Since the configuration files are not ready yet, turn the new softwares off as follows:: + + $ sudo systemctl stop dnsmasq + $ sudo systemctl stop hostapd + Configure your interface ~~~~~~~~~~~~~~~~~~~~~~~~ Let us say that ``wlan0`` is our wireless interface which we will be using. -First we need to setup a static IP for our wireless interface. Edit the -``wlan0`` section in interface configuration file ``/etc/network/interfaces``:: +First the standard interface handling for ``wlan0`` needs to be disabled. +Normally the dhcpcd daemon (DHCP client) will search the network for a DHCP server +to assign a IP address to ``wlan0`` This is disabled by editing the configuration +file ``/etc/dhcpcd.conf``. +Add ``denyinterfaces wlan0`` to the end of the line (but above any other added +``interface`` lines) and save the file. - auto wlan0 - iface wlan0 inet static - address 172.128.1.1 - netmask 255.255.255.0 - network 172.128.1.0 - broadcast 172.128.1.255 -Reload ``wlan0`` interface with ``sudo ifdown wlan0; sudo ifup wlan0`` +To configure the static IP address, create a backup of the original +``/etc/network/interfaces``. Then replace the the file with the one generated +by the backend. Now restart the dhcpcd daemon and setup the new ``wlan0`` configuration:: + + sudo service dhcpcd restart + sudo ifdown wlan0 + sudo ifup wlan0 Configure hostapd ~~~~~~~~~~~~~~~~~ Create a new configuration file ``/etc/hostapd/hostapd.conf``. The contents of this -configuration will be generated by the render method using NetJSON DeviceConfiguration. +configuration will be generated by the backend. You can check if your wireless service is working by running ``/usr/sbin/hostapd /etc/hostapd/hostapd.conf``. At this point you should be able to see your wireless network. If you try to connect From 6be241298c43397658754608fa8a7ab9503d79e8 Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Sun, 27 Aug 2017 10:02:14 +0400 Subject: [PATCH 179/183] [raspbian] Simplify dnsmasq configuration in docs --- docs/source/backends/raspbian.rst | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/docs/source/backends/raspbian.rst b/docs/source/backends/raspbian.rst index dddf0c1a9..a93ff87fe 100644 --- a/docs/source/backends/raspbian.rst +++ b/docs/source/backends/raspbian.rst @@ -438,18 +438,8 @@ file needs to be used. It is advisable to create a copy of the original ``dnsmas After creating the backup, delete the original file and create a new file ``/etc/dnsmasq.conf`` Setup your DNS and DHCP server. Below is an example configuration file:: - # User interface wlan0 + # Use interface wlan0 interface=wlan0 - # Specify the address to listen on - listen-address=172.128.1.1 - # Bind only the interfaces it is listening on - bind-interfaces - # Forward DNS requests to Google DNS - server=8.8.8.8 - # Never forward plain names (without a dot or domain part) - domain-needed - # Never forward addresses in the non-routed address spaces - bogus-priv # Assign IP addresses between 172.128.1.50 and 172.128.1.150 with a 12 hour lease time dhcp-range=172.128.1.50,172.128.1.150,12h From e5822483f3a72c563aa5027e510c27296668c6fd Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Wed, 30 Aug 2017 02:38:08 +0400 Subject: [PATCH 180/183] [raspbian] Updated documentations --- docs/source/backends/raspbian.rst | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/docs/source/backends/raspbian.rst b/docs/source/backends/raspbian.rst index a93ff87fe..4b0811198 100644 --- a/docs/source/backends/raspbian.rst +++ b/docs/source/backends/raspbian.rst @@ -487,7 +487,6 @@ common wireless access point configuration: "protocol": "802.11n", "channel": 3, "channel_width": 20, - "tx_power": 3 }, ], "interfaces": [ @@ -580,7 +579,6 @@ point using *WPA2 Personal (Pre-Shared Key)* encryption: "protocol": "802.11n", "channel": 3, "channel_width": 20, - "tx_power": 3 } ], "interfaces": [ @@ -640,7 +638,7 @@ which must contain a list of `NetJSON radio objects Date: Wed, 30 Aug 2017 03:37:44 +0400 Subject: [PATCH 181/183] [raspbian] Fix py2-ipaddress related unicode bug --- .../backends/raspbian/converters/interfaces.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/netjsonconfig/backends/raspbian/converters/interfaces.py b/netjsonconfig/backends/raspbian/converters/interfaces.py index 7d79a24be..e7636f07c 100644 --- a/netjsonconfig/backends/raspbian/converters/interfaces.py +++ b/netjsonconfig/backends/raspbian/converters/interfaces.py @@ -1,5 +1,7 @@ from ipaddress import IPv4Interface, ip_network +import six + from ....utils import get_copy from .base import RaspbianConverter @@ -58,7 +60,7 @@ def _get_address(self, interface): if address.get('family') == 'ipv4': address_mask = str(address.get('address')) + '/' + str(address.get('mask')) - address['netmask'] = IPv4Interface(address_mask).with_netmask.split('/')[1] + address['netmask'] = IPv4Interface(six.text_type(address_mask)).with_netmask.split('/')[1] del address['mask'] if address.get('family') == 'ipv6': address['netmask'] = address['mask'] @@ -68,14 +70,14 @@ def _get_address(self, interface): def _get_route(self, routes): result = [] for route in routes: - if ip_network(route.get('next')).version == 4: + if ip_network(six.text_type(route.get('next'))).version == 4: route['version'] = 4 - destination = IPv4Interface(route['destination']).with_netmask + destination = IPv4Interface(six.text_type(route['destination'])).with_netmask dest, dest_mask = destination.split('/') route['dest'] = dest route['dest_mask'] = dest_mask del route['destination'] - elif ip_network(route.get('next')).version == 6: + elif ip_network(six.text_type(route.get('next'))).version == 6: route['version'] = 6 result.append(route) return routes From 6247cd7a19608ce0f75de7a69fc4cb241b82fbcb Mon Sep 17 00:00:00 2001 From: Ritwick DSouza Date: Wed, 30 Aug 2017 03:39:15 +0400 Subject: [PATCH 182/183] [raspbian] Fix flake8 warning --- netjsonconfig/backends/raspbian/converters/interfaces.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/netjsonconfig/backends/raspbian/converters/interfaces.py b/netjsonconfig/backends/raspbian/converters/interfaces.py index e7636f07c..cbc31c6d6 100644 --- a/netjsonconfig/backends/raspbian/converters/interfaces.py +++ b/netjsonconfig/backends/raspbian/converters/interfaces.py @@ -60,7 +60,8 @@ def _get_address(self, interface): if address.get('family') == 'ipv4': address_mask = str(address.get('address')) + '/' + str(address.get('mask')) - address['netmask'] = IPv4Interface(six.text_type(address_mask)).with_netmask.split('/')[1] + netmask = IPv4Interface(six.text_type(address_mask)) + address['netmask'] = netmask.with_netmask.split('/')[1] del address['mask'] if address.get('family') == 'ipv6': address['netmask'] = address['mask'] From 26a4087866d9fcbfee1fbd59683ecce356f70a29 Mon Sep 17 00:00:00 2001 From: Federico Capoano Date: Thu, 21 May 2020 20:37:30 -0500 Subject: [PATCH 183/183] [docs] Updated github stars and fork buttons #154 Related to #154 --- docs/source/_github.rst | 6 ------ docs/source/backends/openvpn.rst | 2 +- docs/source/backends/openwisp.rst | 2 +- docs/source/backends/openwrt.rst | 2 +- docs/source/backends/raspbian.rst | 2 +- docs/source/general/basics.rst | 2 +- docs/source/general/commandline_utility.rst | 2 +- docs/source/general/contributing.rst | 2 +- docs/source/general/goals.rst | 2 +- docs/source/general/running_tests.rst | 2 +- docs/source/general/setup.rst | 2 +- docs/source/index.rst | 2 +- 12 files changed, 11 insertions(+), 17 deletions(-) delete mode 100644 docs/source/_github.rst diff --git a/docs/source/_github.rst b/docs/source/_github.rst deleted file mode 100644 index 3f8f505bb..000000000 --- a/docs/source/_github.rst +++ /dev/null @@ -1,6 +0,0 @@ -.. raw:: html - -

- - -

diff --git a/docs/source/backends/openvpn.rst b/docs/source/backends/openvpn.rst index 67fc83cab..2d529b76c 100644 --- a/docs/source/backends/openvpn.rst +++ b/docs/source/backends/openvpn.rst @@ -2,7 +2,7 @@ OpenVPN 2.3 Backend =================== -.. include:: ../_github.rst + The ``OpenVpn`` backend allows to generate OpenVPN 2.3.x compatible configurations. diff --git a/docs/source/backends/openwisp.rst b/docs/source/backends/openwisp.rst index 33ba5805a..9726ff82b 100644 --- a/docs/source/backends/openwisp.rst +++ b/docs/source/backends/openwisp.rst @@ -2,7 +2,7 @@ OpenWISP 1.x Backend ==================== -.. include:: ../_github.rst + The OpenWISP 1.x Backend is based on the OpenWRT backend, therefore it inherits all its features with some differences that are explained in this page. diff --git a/docs/source/backends/openwrt.rst b/docs/source/backends/openwrt.rst index 3ddfacbde..cb1447903 100644 --- a/docs/source/backends/openwrt.rst +++ b/docs/source/backends/openwrt.rst @@ -2,7 +2,7 @@ OpenWRT Backend =============== -.. include:: ../_github.rst + The ``OpenWrt`` backend allows to generate OpenWRT compatible configurations. diff --git a/docs/source/backends/raspbian.rst b/docs/source/backends/raspbian.rst index 4b0811198..40f2831b3 100644 --- a/docs/source/backends/raspbian.rst +++ b/docs/source/backends/raspbian.rst @@ -2,7 +2,7 @@ Raspbian Backend ================ -.. include:: ../_github.rst + The ``Raspbian`` backend allows to Raspbian compatible configuration files. diff --git a/docs/source/general/basics.rst b/docs/source/general/basics.rst index 902102f59..f403cf3e8 100644 --- a/docs/source/general/basics.rst +++ b/docs/source/general/basics.rst @@ -2,7 +2,7 @@ Basic concepts ============== -.. include:: ../_github.rst + Before starting, let's quickly introduce the main concepts used in netjsonconfig: diff --git a/docs/source/general/commandline_utility.rst b/docs/source/general/commandline_utility.rst index 9e2a9cc08..55e07b98d 100644 --- a/docs/source/general/commandline_utility.rst +++ b/docs/source/general/commandline_utility.rst @@ -2,7 +2,7 @@ Command line utility ==================== -.. include:: ../_github.rst + netjsonconfig ships a command line utility that can be used from the interactive shell, bash scripts or other programming diff --git a/docs/source/general/contributing.rst b/docs/source/general/contributing.rst index 64d5c45c7..fa3461de8 100644 --- a/docs/source/general/contributing.rst +++ b/docs/source/general/contributing.rst @@ -2,7 +2,7 @@ Contributing ============ -.. include:: ../_github.rst + Thank you for taking the time to contribute to netjsonconfig. diff --git a/docs/source/general/goals.rst b/docs/source/general/goals.rst index b75c8caf5..39ba6b8d9 100644 --- a/docs/source/general/goals.rst +++ b/docs/source/general/goals.rst @@ -1,7 +1,7 @@ Motivations and Goals ===================== -.. include:: ../_github.rst + In this page we explain the goals of this project and the motivations that led us on this path. diff --git a/docs/source/general/running_tests.rst b/docs/source/general/running_tests.rst index 5b77e5d46..e2eca8c38 100644 --- a/docs/source/general/running_tests.rst +++ b/docs/source/general/running_tests.rst @@ -2,7 +2,7 @@ Running tests ============= -.. include:: ../_github.rst + Running the test suite is really straightforward! diff --git a/docs/source/general/setup.rst b/docs/source/general/setup.rst index a57caf594..1e046a9e5 100644 --- a/docs/source/general/setup.rst +++ b/docs/source/general/setup.rst @@ -2,7 +2,7 @@ Setup ===== -.. include:: ../_github.rst + Install stable version from pypi -------------------------------- diff --git a/docs/source/index.rst b/docs/source/index.rst index 6b65d36da..08583963b 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -20,7 +20,7 @@ Netjsonconfig is part of the `OpenWISP project `_. .. image:: ./images/openwisp.org.svg :target: http://openwisp.org -.. include:: _github.rst + **netjsonconfig** is a python library that converts `NetJSON `_ *DeviceConfiguration* objects into real router configurations that can be installed