Repository: openwisp/netjsonconfig

Issue:
error on netjsonconfig: 1.1.1.post1 convert config.tar.gz to json for zerotier
Hi,
I tried uploading the original zerotier config to my router without changing anything.
I saved the backup and ran the conversion instructions.

`netjsonconfig --native config.tar.gz --backend openwrt --method json -a indent="    "`

I get this error:
```
$ netjsonconfig --native backup-ReginaMargherita116-AP-2025-02-26.tar.gz --backend openwrt --method json -a indent="    "
Traceback (most recent call last):
  File "/home/michele/.local/pipx/venvs/netjsonconfig/lib/python3.11/site-packages/netjsonconfig/backends/base/backend.py", line 157, in validate
    Draft4Validator(self.schema, format_checker=draft4_format_checker).validate(
  File "/home/michele/.local/pipx/venvs/netjsonconfig/lib/python3.11/site-packages/jsonschema/validators.py", line 451, in validate
    raise error
jsonschema.exceptions.ValidationError: '0' is not of type 'boolean'

Failed validating 'type' in schema['properties']['zerotier']['items']['properties']['networks']['items']['properties']['allow_global']:
    OrderedDict([('type', 'boolean'),
                 ('title', 'Allow Global'),
                 ('default', False),
                 ('format', 'checkbox'),
                 ('description',
                  'Allow ZeroTier to set Global/Public/Not-Private range '
                  'IPs and Routes')])

On instance['zerotier'][0]['networks'][0]['allow_global']:
    '0'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/michele/.local/bin/netjsonconfig", line 174, in <module>
    instance = backend_class(**options)
               ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/michele/.local/pipx/venvs/netjsonconfig/lib/python3.11/site-packages/netjsonconfig/backends/openwrt/openwrt.py", line 56, in __init__
    super().__init__(config, native, templates, context)
  File "/home/michele/.local/pipx/venvs/netjsonconfig/lib/python3.11/site-packages/netjsonconfig/backends/base/backend.py", line 51, in __init__
    self.parse(native)
  File "/home/michele/.local/pipx/venvs/netjsonconfig/lib/python3.11/site-packages/netjsonconfig/backends/base/backend.py", line 329, in parse
    self.to_netjson()
  File "/home/michele/.local/pipx/venvs/netjsonconfig/lib/python3.11/site-packages/netjsonconfig/backends/base/backend.py", line 348, in to_netjson
    self.validate()
  File "/home/michele/.local/pipx/venvs/netjsonconfig/lib/python3.11/site-packages/netjsonconfig/backends/openwrt/openwrt.py", line 60, in validate
    super().validate()
  File "/home/michele/.local/pipx/venvs/netjsonconfig/lib/python3.11/site-packages/netjsonconfig/backends/base/backend.py", line 161, in validate
    raise ValidationError(e)
netjsonconfig.exceptions.ValidationError: ValidationError '0' is not of type 'boolean'

Failed validating 'type' in schema['properties']['zerotier']['items']['properties']['networks']['items']['properties']['allow_global']:
    OrderedDict([('type', 'boolean'),
                 ('title', 'Allow Global'),
                 ('default', False),
                 ('format', 'checkbox'),
                 ('description',
                  'Allow ZeroTier to set Global/Public/Not-Private range '
                  'IPs and Routes')])

On instance['zerotier'][0]['networks'][0]['allow_global']:
    '0'

```
What am I doing wrong?

I have a need to have a template for the new version of zerotier.
Openwisp even though it has been updated continues to generate the old format.

Discussion:
@pandafy: @mikysal78 can you share the your zerotier config (/etc/config/zerotier), assuming this is the expected configuration. Please remove any personal identifiable information (e.g. network id and client secret).@mikysal78: Hi @pandafy,
I tried using the defaults configuration.
I updated openwisp but it doesn't generate the template for the new zerotier format (I don't understand why).
To fix the template I wanted to generate the json code from the original file.

```
config zerotier 'global'
	# Sets whether ZeroTier is enabled or not
	option enabled '0'
	# Sets the ZeroTier listening port (default 9993; set to 0 for random)
	#option port '9993'
	# Client secret (leave blank to generate a secret on first run)
	option secret ''
	# Path of the optional file local.conf (see documentation at
	# https://docs.zerotier.com/config#local-configuration-options)
	#option local_conf_path '/etc/zerotier.conf'
	# Persistent configuration directory (to perform other configurations such
	# as controller mode or moons, etc.)
	#option config_path '/etc/zerotier'
	# Copy the contents of the persistent configuration directory to memory
	# instead of linking it, this avoids writing to flash
	#option copy_config_path '1'

# Network configuration, you can have as many configurations as networks you
# want to join (the network name is optional)
config network 'earth'
	# Identifier of the network you wish to join
	option id '8056c2e21c000001'
	# Sets whether this network is enabled or disabled. If it is not
	# enabled ZeroTier will not join it.
	option enabled '1'
	# Network configuration parameters (all are optional, if not indicated the
	# default values are set, see documentation at
	# https://docs.zerotier.com/config/#network-specific-configuration)
	option allow_managed '1'
	option allow_global '0'
	option allow_default '0'
	option allow_dns '0'

# Example of a second network (unnamed as it is optional)
#config network
#	option id '1234567890123456'
#	option enabled '0'
#	option allow_managed '1'
#	option allow_global '0'
#	option allow_default '0'
#	option allow_dns '0'
```

If you can explain how to generate the new template from openwisp directly I will solve all the problems.
My Openwisp is:

OpenWISP Version: 24.11.1
Installed OpenWISP Modules
openwisp-controller: 1.1.1
openwisp-firmware-upgrader: 1.1.1
openwisp-ipam: 1.1
openwisp-monitoring: 1.1.2
openwisp-network-topology: 1.1.1
openwisp-notifications: 1.1
openwisp-radius: 1.1.1
openwisp-users: 1.1.0
openwisp-utils: 1.1.1
netdiff: 1.1
netjsonconfig: 1.1.1.post1
OS Information
OS version: #1 SMP PREEMPT_DYNAMIC Debian 6.1.128-1 (2025-02-07)
Kernel version: 6.1.0-31-amd64
Hardware platform: x86_64

Solution patch:
diff --git a/docs/source/backends/zerotier.rst b/docs/source/backends/zerotier.rst
index cb7afdd..b48e21f 100644
--- a/docs/source/backends/zerotier.rst
+++ b/docs/source/backends/zerotier.rst
@@ -85,9 +85,9 @@ See an example of initialization and rendering below:
                     "remoteTraceLevel": 1,
                     "client_options": {
                         "allow_managed": True,
-                        "allowed_global": False,
-                        "allowed_default": False,
-                        "allowed_dns": False,
+                        "allow_global": False,
+                        "allow_default": False,
+                        "allow_dns": False,
                     },
                 }
             ]
@@ -276,18 +276,17 @@ key name              type    default     description
 ``remoteTraceLevel``  integer             level of network tracing
 ``client_options``    dict    ``{}``      These options are only used for client configurations
 
-                                          =================== ======= ==========================================
-                                          key name            type    description
-                                          =================== ======= ==========================================
-                                          ``allow_managed``   boolean allow ZeroTier to set IP addresses and
-                                                                      routes
-                                          ``allowed_global``  boolean allow ZeroTier to set
-                                                                      global/public/not-private range IPs and
-                                                                      routes
-                                          ``allowed_default`` boolean allow ZeroTier to set the default route on
-                                                                      the system
-                                          ``allowed_dns``     boolean allow ZeroTier to set DNS servers
-                                          =================== ======= ==========================================
+                                          ================= ======= =============================================
+                                          key name          type    description
+                                          ================= ======= =============================================
+                                          ``allow_managed`` boolean allow ZeroTier to set IP addresses and routes
+                                          ``allow_global``  boolean allow ZeroTier to set
+                                                                    global/public/not-private range IPs and
+                                                                    routes
+                                          ``allow_default`` boolean allow ZeroTier to set the default route on
+                                                                    the system
+                                          ``allow_dns``     boolean allow ZeroTier to set DNS servers
+                                          ================= ======= =============================================
 ===================== ======= =========== =======================================================================
 
 Client specific settings
diff --git a/netjsonconfig/backends/openwrt/converters/zerotier.py b/netjsonconfig/backends/openwrt/converters/zerotier.py
index 78e1b5d..e347558 100644
--- a/netjsonconfig/backends/openwrt/converters/zerotier.py
+++ b/netjsonconfig/backends/openwrt/converters/zerotier.py
@@ -79,12 +79,12 @@ class ZeroTier(OpenWrtConverter, BaseZeroTier):
             network.pop(key)
         network['ifname'] = self._get_ifname_from_id(network['id'])
         # Handle boolean fields
-        if 'allowed_global' in network:
-            network['allowed_global'] = network['allowed_global'] == '1'
-        if 'allowed_default' in network:
-            network['allowed_default'] = network['allowed_default'] == '1'
-        if 'allowed_dns' in network:
-            network['allowed_dns'] = network['allowed_dns'] == '1'
+        if 'allow_global' in network:
+            network['allow_global'] = network['allow_global'] == '1'
+        if 'allow_default' in network:
+            network['allow_default'] = network['allow_default'] == '1'
+        if 'allow_dns' in network:
+            network['allow_dns'] = network['allow_dns'] == '1'
         if 'allow_managed' in network:
             network['allow_managed'] = network['allow_managed'] == '1'
         return network


Test patch:
diff --git a/tests/openwrt/test_zerotier.py b/tests/openwrt/test_zerotier.py
index 90e1adb..a6f4ab3 100644
--- a/tests/openwrt/test_zerotier.py
+++ b/tests/openwrt/test_zerotier.py
@@ -18,17 +18,17 @@ class TestZeroTier(unittest.TestCase, _TabsMixin):
                         "id": "9536600adf654321",
                         "ifname": "owzt654321",
                         "allow_managed": True,
-                        "allowed_global": False,
-                        "allowed_default": False,
-                        "allowed_dns": False,
+                        "allow_global": False,
+                        "allow_default": False,
+                        "allow_dns": False,
                     },
                     {
                         "id": "9536600adf654322",
                         "ifname": "owzt654322",
                         "allow_managed": True,
-                        "allowed_global": False,
-                        "allowed_default": False,
-                        "allowed_dns": False,
+                        "allow_global": False,
+                        "allow_default": False,
+                        "allow_dns": False,
                     },
                 ],
             },
@@ -46,17 +46,17 @@ config zerotier 'ow_zt'
     option local_conf_path '/etc/openwisp/zerotier/zerotier.conf'
 
 config network 'owzt654321'
+    option allow_default '0'
+    option allow_dns '0'
+    option allow_global '0'
     option allow_managed '1'
-    option allowed_default '0'
-    option allowed_dns '0'
-    option allowed_global '0'
     option id '9536600adf654321'
 
 config network 'owzt654322'
+    option allow_default '0'
+    option allow_dns '0'
+    option allow_global '0'
     option allow_managed '1'
-    option allowed_default '0'
-    option allowed_dns '0'
-    option allowed_global '0'
     option id '9536600adf654322'
 
 # ---------- files ---------- #
@@ -132,10 +132,10 @@ config network
 
 config network
     option id '9536600adf654322'
+    option allow_default '0'
+    option allow_dns '0'
+    option allow_global '0'
     option allow_managed '1'
-    option allowed_default '0'
-    option allowed_dns '0'
-    option allowed_global '0'
 """
         )
         expected = {
@@ -148,9 +148,9 @@ config network
                             "id": "9536600adf654322",
                             "ifname": "owzt654322",
                             "allow_managed": True,
-                            "allowed_global": False,
-                            "allowed_default": False,
-                            "allowed_dns": False,
+                            "allow_global": False,
+                            "allow_default": False,
+                            "allow_dns": False,
                         },
                     ],
                     "name": "ow_zt",
diff --git a/tests/zerotier/test_backend.py b/tests/zerotier/test_backend.py
index a8158df..b9f4ab5 100644
--- a/tests/zerotier/test_backend.py
+++ b/tests/zerotier/test_backend.py
@@ -62,9 +62,9 @@ class TestBackend(unittest.TestCase):
                 "remoteTraceLevel": 1,
                 "client_options": {
                     "allow_managed": True,
-                    "allowed_global": False,
-                    "allowed_default": False,
-                    "allowed_dns": False,
+                    "allow_global": False,
+                    "allow_default": False,
+                    "allow_dns": False,
                 },
             }
         ]