Skip to content

Commit

Permalink
[req-changes] Reverted schema properties change and improved docs
Browse files Browse the repository at this point in the history
I changed the example in 'Advanced Configuration' because ZeroTier port configuration
can be done using the UCI option 'port' without the need for a `local.conf` file.

Instead, I have updated the example to demonstrate
how to blacklist a specific physical network path.
  • Loading branch information
Aryamanz29 committed Aug 29, 2023
1 parent a8a0e1e commit 5091014
Show file tree
Hide file tree
Showing 7 changed files with 94 additions and 73 deletions.
89 changes: 44 additions & 45 deletions docs/source/backends/zerotier.rst
Expand Up @@ -275,27 +275,31 @@ Client specific settings
Required properties:

* name
* nwid_ifname

+------------------------+---------+----------------------------+------------------------------------------------------------------------------------------------------+
| key name | type | default | description |
+========================+=========+============================+======================================================================================================+
| ``name`` | string | ``ow_zt`` | name of the zerotier network |
+------------------------+---------+----------------------------+------------------------------------------------------------------------------------------------------+
| ``nwid_ifname`` | list | ``[{}]`` | list of dictionaries containing strings with **16-digit** hexadecimal network IDs for joining, |
| | | | |
| | | | along with a corresponding custom **10-digit** ZeroTier interface name for each network |
| | | | |
| | | | **note:** ensure that the list includes at least one such dictionary |
+------------------------+---------+----------------------------+------------------------------------------------------------------------------------------------------+
| ``config_path`` | string | ``/etc/openwisp/zerotier`` | path to the persistent configuration directory |
+------------------------+---------+----------------------------+------------------------------------------------------------------------------------------------------+
| ``copy_config_path`` | string | ``'1'`` | specifies whether to copy the configuration file to RAM |
| | | | |
| | | | ``'0'`` - No, ``'1'`` - Yes, this prevents writing to flash in zerotier controller mode |
+------------------------+---------+----------------------------+------------------------------------------------------------------------------------------------------+
| ``secret`` | string | ``{{secret}}`` | secret key of the zerotier client (network member), leave it default to be automatically determined |
+------------------------+---------+----------------------------+------------------------------------------------------------------------------------------------------+
* networks

+------------------------+---------+----------------------------+-----------------------------------------------------------------------------------------------------------+
| key name | type | default | description |
+========================+=========+============================+===========================================================================================================+
| ``name`` | string | ``ow_zt`` | name of the zerotier network |
+------------------------+---------+----------------------------+-----------------------------------------------------------------------------------------------------------+
| ``networks`` | list | ``[{}]`` | list of dictionaries containing strings with **16-digit** hexadecimal network IDs for joining, |
| | | | |
| | | | along with a corresponding custom **10-digit** ZeroTier interface name for each network |
| | | | |
| | | | **note:** ensure that the list includes at least one such dictionary |
+------------------------+---------+----------------------------+-----------------------------------------------------------------------------------------------------------+
| ``config_path`` | string | ``/etc/openwisp/zerotier`` | path to the persistent configuration directory |
+------------------------+---------+----------------------------+-----------------------------------------------------------------------------------------------------------+
| ``copy_config_path`` | string | ``'1'`` | specifies whether to copy the configuration file to RAM |
| | | | |
| | | | ``'0'`` - No, ``'1'`` - Yes, this prevents writing to flash in zerotier controller mode |
+------------------------+---------+----------------------------+-----------------------------------------------------------------------------------------------------------+
| ``secret`` | string | ``{{secret}}`` | identity secret of the zerotier client (network member), leave it default to be automatically determined |
+------------------------+---------+----------------------------+-----------------------------------------------------------------------------------------------------------+
| ``port`` | integer | ``9993`` | port number of the zerotier service |
+------------------------+---------+----------------------------+-----------------------------------------------------------------------------------------------------------+
| ``local_conf`` | string | | path of the local zerotier configuration |
+------------------------+---------+----------------------------+-----------------------------------------------------------------------------------------------------------+

Working around schema limitations
---------------------------------
Expand All @@ -313,15 +317,15 @@ Automatic generation of clients

.. automethod:: netjsonconfig.OpenWrt.zerotier_auto_client

**Example (with custom ``zerotier interface name``)**:
Example (with custom zerotier interface name):

.. code-block:: python
from netjsonconfig import OpenWrt
client_config = OpenWrt.zerotier_auto_client(
name='ow_zt',
nwid_ifname=[{"id": "9536600adf654321", "ifname": "owzt654321"}],
networks=[{"id": "9536600adf654321", "ifname": "owzt654321"}],
)
print(OpenWrt(client_config).render())
Expand All @@ -340,7 +344,7 @@ Will be rendered as:
# ---------- files ---------- #
# path: /etc/ow_zerotier/devicemap
# path: /etc/openwisp/zerotier/devicemap
# mode: 0644
# network_id=interface_name
Expand Down Expand Up @@ -372,42 +376,37 @@ configuration settings, please refer to the following OpenAPI API specifications
Advanced configuration
~~~~~~~~~~~~~~~~~~~~~~

The OpenWRT ZeroTier service can be configured to run on multiple ports,
for example, **9993 (default)** and **9994**. This can be achieved by creating
a file named ``zt_local.conf`` in a persistent filesystem location, such as
``/etc/config/zt_local.conf``, and then adding the option ``local_conf``
to the ZeroTier UCI configuration.
If you want to use advanced configuration options that
apply to your OpenWrt device, such as setting up trusted paths,
blacklisting physical paths, setting up physical path hints for certain nodes,
and defining trusted upstream devices, this can be achieved by creating a file named
``local.conf`` in a persistent filesystem location, such as ``/etc/config/local.conf``
and then adding the ``local_conf`` option to the ZeroTier UCI configuration.

``/etc/config/zt_local.conf``
For example, let's create a local configuration file at ``/etc/config/local.conf`` (JSON)
to blacklist a specific physical network path **(10.0.0.0/24)** from all ZeroTier traffic.

.. code-block:: json
{
"settings": {
"primaryPort": 9994
"physical": {
"10.0.0.0/24": {
"blacklist": true
}
}
}
``/etc/config/zerotier``
Now add ``local_conf`` option to ``/etc/config/zerotier``:

.. code-block:: text
package zerotier
# This config utilizes port 9993 (default)
config zerotier 'ow_zt1'
option enabled '1'
list join '9536600adf654321'
option secret '{{zt_identity_secret}}'
# This config utilizes port 9994
config zerotier 'ow_zt2' (new)
config zerotier 'ow_zt'
option enabled '1'
list join '9536600adf654322'
option secret '{{zt_identity_secret}}'
option local_conf '/etc/config/zerotier.local.conf'
option secret '{{secret}}'
option local_conf '/etc/config/local.conf'
**More information**
Expand Down
18 changes: 8 additions & 10 deletions netjsonconfig/backends/openwrt/converters/zerotier.py
Expand Up @@ -8,7 +8,7 @@ class ZeroTier(OpenWrtConverter, BaseZeroTier):
_schema = schema['properties']['zerotier']['items']

def __intermediate_vpn(self, vpn):
nwid_ifnames = vpn.get('nwid_ifname', [])
nwid_ifnames = vpn.get('networks', [])
files = self.netjson.get('files', [])
self.netjson['files'] = self.__get_zt_ifname_files(vpn, files)
vpn.update(
Expand All @@ -17,32 +17,30 @@ def __intermediate_vpn(self, vpn):
'.type': 'zerotier',
'config_path': vpn.get('config_path', '/etc/openwisp/zerotier'),
'copy_config_path': vpn.get('copy_config_path', '1'),
'join': [nwid_ifname.get('id', '') for nwid_ifname in nwid_ifnames],
'join': [networks.get('id', '') for networks in nwid_ifnames],
'enabled': not vpn.pop('disabled', False),
}
)
del vpn['nwid_ifname']
del vpn['networks']
return super().__intermediate_vpn(vpn, remove=[''])

def __netjson_vpn(self, vpn):
nwids = vpn.pop('join')
vpn['name'] = vpn.pop('.name')
vpn['nwid_ifname'] = [
{"id": nwid, "ifname": f"owzt{nwid[-6:]}"} for nwid in nwids
]
vpn['networks'] = [{"id": nwid, "ifname": f"owzt{nwid[-6:]}"} for nwid in nwids]
# 'disabled' defaults to False in OpenWRT
vpn['disabled'] = vpn.pop('enabled', '0') == '0'
del vpn['.type']
return super().__netjson_vpn(vpn)

def __get_zt_ifname_files(self, vpn, files):
config_path = vpn.get('config_path', '/etc/openwisp/zerotier')
nwid_ifnames = vpn.get('nwid_ifname', [])
nwid_ifnames = vpn.get('networks', [])
zt_file_contents = '# network_id=interface_name\n'

for nwid_ifname in nwid_ifnames:
nwid = nwid_ifname.get('id', '')
ifname = nwid_ifname.get('ifname', f'owzt{nwid[-6:]}')
for networks in nwid_ifnames:
nwid = networks.get('id', '')
ifname = networks.get('ifname', f'owzt{nwid[-6:]}')
zt_file_contents += f"{nwid}={ifname}\n"

zt_interface_map = {
Expand Down
32 changes: 28 additions & 4 deletions netjsonconfig/backends/openwrt/schema.py
Expand Up @@ -1010,7 +1010,7 @@
"type": "object",
"title": "Network Member Configuration",
"additionalProperties": True,
"required": ["name", "nwid_ifname"],
"required": ["name", "networks"],
"properties": {
# ZeroTier customization (disabled) for OpenWRT
"disabled": {
Expand All @@ -1028,7 +1028,7 @@
"minLength": 1,
"description": "Name of the zerotier network member configuration",
},
"nwid_ifname": {
"networks": {
"type": "array",
"title": "Network ID and Interface name",
"minItems": 1,
Expand Down Expand Up @@ -1062,11 +1062,11 @@
"propertyOrder": 4,
"default": "{{secret}}",
"description": (
"Secret key of the zerotier client (network member), "
"Identity secret of the zerotier client (network member), "
"You can leave it as the default and OpenWISP will automatically determine it"
),
},
# Hidden property
# Hidden properties
"config_path": {
"type": "string",
"propertyOrder": 5,
Expand All @@ -1077,6 +1077,30 @@
"directory (for zerotier controller mode)"
),
},
"copy_config_path": {
"type": "string",
"propertyOrder": 6,
"options": {"hidden": True},
"enum": ["0", "1"],
"description": (
"Specifies whether to copy the configuration "
"file to RAM ('0' - No, '1' - Yes), this prevents "
"writing to flash in zerotier controller mode"
),
},
"port": {
"type": "integer",
"minimum": 1,
"maximum": 65535,
"default": 9993,
"propertyOrder": 7,
"description": "Port number of the zerotier service",
},
"local_conf": {
"type": "string",
"propertyOrder": 8,
"description": "Path of the local zerotier configuration",
},
},
},
},
Expand Down
6 changes: 3 additions & 3 deletions netjsonconfig/backends/zerotier/zerotier.py
Expand Up @@ -18,15 +18,15 @@ class ZeroTier(BaseVpnBackend):
def auto_client(
cls,
name='ow_zt',
nwid_ifname=None,
networks=None,
identity_secret='{{secret}}',
config_path='/etc/openwisp/zerotier',
disabled=False,
):
nwid_ifname = nwid_ifname or []
networks = networks or []
return {
'name': name,
'nwid_ifname': nwid_ifname,
'networks': networks,
'secret': identity_secret,
'config_path': config_path,
'disabled': disabled,
Expand Down
6 changes: 3 additions & 3 deletions tests/openwrt/test_backend.py
Expand Up @@ -552,7 +552,7 @@ def test_zerotier_auto_client(self):
'zerotier': [
{
'name': 'ow_zt',
'nwid_ifname': [],
'networks': [],
'secret': '{{secret}}',
'config_path': '/etc/openwisp/zerotier',
'disabled': False,
Expand All @@ -565,7 +565,7 @@ def test_zerotier_auto_client(self):
'zerotier': [
{
'name': 'ow_zt',
'nwid_ifname': [
'networks': [
{'id': '9536600adf654321', 'ifname': 'owzt654321'}
],
'secret': '{{secret}}',
Expand All @@ -579,7 +579,7 @@ def test_zerotier_auto_client(self):
OpenWrt.zerotier_auto_client(
# Test it is possible to change default `config_path`
config_path='/etc/ow_zerotier_test',
nwid_ifname=[{'id': nw_id, 'ifname': f'owzt{nw_id[-6:]}'}],
networks=[{'id': nw_id, 'ifname': f'owzt{nw_id[-6:]}'}],
),
expected,
)
12 changes: 6 additions & 6 deletions tests/openwrt/test_zerotier.py
Expand Up @@ -12,7 +12,7 @@ class TestZeroTier(unittest.TestCase, _TabsMixin):
"zerotier": [
{
"name": "ow_zt",
"nwid_ifname": [
"networks": [
{"id": "9536600adf654321", "ifname": "owzt654321"},
{"id": "9536600adf654322", "ifname": "owzt654322"},
],
Expand All @@ -27,11 +27,11 @@ class TestZeroTier(unittest.TestCase, _TabsMixin):
"zerotier": [
{
"name": "ow_zt1",
"nwid_ifname": [{"id": "9536600adf654321", "ifname": "owzt654321"}],
"networks": [{"id": "9536600adf654321", "ifname": "owzt654321"}],
},
{
"name": "ow_zt2",
"nwid_ifname": [{"id": "9536600adf654322", "ifname": "owzt654322"}],
"networks": [{"id": "9536600adf654322", "ifname": "owzt654322"}],
},
]
}
Expand Down Expand Up @@ -86,12 +86,12 @@ def test_zt_mutiple_parse_diff_name(self):
{
"name": "ow_zt1",
"disabled": False,
"nwid_ifname": [{"id": "9536600adf654321", "ifname": "owzt654321"}],
"networks": [{"id": "9536600adf654321", "ifname": "owzt654321"}],
},
{
"name": "ow_zt2",
"disabled": False,
"nwid_ifname": [{"id": "9536600adf654322", "ifname": "owzt654322"}],
"networks": [{"id": "9536600adf654322", "ifname": "owzt654322"}],
},
]
}
Expand Down Expand Up @@ -136,7 +136,7 @@ def test_zt_mutiple_parse_same_name(self):
expected = {
"zerotier": [
{
"nwid_ifname": [
"networks": [
{"id": "9536600adf654321", "ifname": "owzt654321"},
{"id": "9536600adf654322", "ifname": "owzt654322"},
],
Expand Down
4 changes: 2 additions & 2 deletions tests/zerotier/test_backend.py
Expand Up @@ -388,15 +388,15 @@ def test_auto_client(self):
nw_id = test_config['id']
expected = {
'name': 'ow_zt',
'nwid_ifname': [{'id': '9536600adf654321', 'ifname': 'owzt654321'}],
'networks': [{'id': '9536600adf654321', 'ifname': 'owzt654321'}],
'secret': 'test_secret',
'config_path': '/etc/openwisp/zerotier',
'disabled': False,
}
self.assertEqual(
ZeroTier.auto_client(
name="ow_zt",
nwid_ifname=[
networks=[
{
'id': nw_id,
'ifname': f'owzt{nw_id[-6:]}',
Expand Down

0 comments on commit 5091014

Please sign in to comment.