Open edoput opened 7 years ago
@EdoPut could you add an example of how to replicate the error please?
Using the schema and tests from https://github.com/openwisp/netjsonconfig/commit/7c8e27bb34476e1b4cc70b398345cb8df33d3728 you can reproduce this with the command
nosetest tests/airos/test_aaa.py
Paying attention to the logs from the failing tests we can see that it raises a validation error because of two different schema that validate the same instance under a OneOf
constraint
As an example
======================================================================
ERROR: test_sta_psk_authentication (tests.airos.test_aaa.TestResolvConverter)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/edoput/repo/netjsonconfig/netjsonconfig/backends/base/backend.py", line 113, in validate
validate(self.config, self.schema, format_checker=FormatChecker())
File "/home/edoput/.virtualenvs/netjsonconfig3/local/lib/python3.5/site-packages/jsonschema/validators.py", line 541, in validate
cls(schema, *args, **kwargs).validate(instance)
File "/home/edoput/.virtualenvs/netjsonconfig3/local/lib/python3.5/site-packages/jsonschema/validators.py", line 130, in validate
raise error
jsonschema.exceptions.ValidationError: {'type': 'wireless', 'name': 'wlan0', 'wireless': {'bssid': '00:11:22:33:44:55', 'mode': 'station', 'radio': 'ath0', 'encryption': {'protocol': 'wpa2_personal', 'key': 'and-pizza-too'}, 'ssid': 'i-like-pasta'}} is not valid under any of the given schemas
Failed validating 'oneOf' in schema['properties']['interfaces']['items']:
{'oneOf': [{'$ref': '#/definitions/network_interface'},
{'$ref': '#/definitions/wireless_interface'},
{'$ref': '#/definitions/bridge_interface'}],
'title': 'Interface'}
On instance['interfaces'][0]:
{'name': 'wlan0',
'type': 'wireless',
'wireless': {'bssid': '00:11:22:33:44:55',
'encryption': {'key': 'and-pizza-too',
'protocol': 'wpa2_personal'},
'mode': 'station',
'radio': 'ath0',
'ssid': 'i-like-pasta'}}
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/edoput/repo/netjsonconfig/tests/airos/test_aaa.py", line 142, in test_sta_psk_authentication
o.to_intermediate()
File "/home/edoput/repo/netjsonconfig/netjsonconfig/backends/airos/airos.py", line 54, in to_intermediate
super(AirOs, self).to_intermediate()
File "/home/edoput/repo/netjsonconfig/netjsonconfig/backends/base/backend.py", line 252, in to_intermediate
self.validate()
File "/home/edoput/repo/netjsonconfig/netjsonconfig/backends/base/backend.py", line 115, in validate
raise ValidationError(e)
netjsonconfig.exceptions.ValidationError: ValidationError {'type': 'wireless', 'name': 'wlan0', 'wireless': {'bssid': '00:11:22:33:44:55', 'mode': 'station', 'radio': 'ath0', 'encryption': {'protocol': 'wpa2_personal', 'key': 'and-pizza-too'}, 'ssid': 'i-like-pasta'}} is not valid under any of the given schemas
Failed validating 'oneOf' in schema['properties']['interfaces']['items']:
{'oneOf': [{'$ref': '#/definitions/network_interface'},
{'$ref': '#/definitions/wireless_interface'},
{'$ref': '#/definitions/bridge_interface'}],
'title': 'Interface'}
On instance['interfaces'][0]:
{'name': 'wlan0',
'type': 'wireless',
'wireless': {'bssid': '00:11:22:33:44:55',
'encryption': {'key': 'and-pizza-too',
'protocol': 'wpa2_personal'},
'mode': 'station',
'radio': 'ath0',
'ssid': 'i-like-pasta'}}
Against schema {'$ref': '#/definitions/network_interface'}
'wireless' is not one of ['ethernet', 'virtual', 'loopback', 'other']
Against schema {'$ref': '#/definitions/wireless_interface'}
{'bssid': '00:11:22:33:44:55', 'mode': 'station', 'radio': 'ath0', 'encryption': {'protocol': 'wpa2_personal', 'key': 'and-pizza-too'}, 'ssid': 'i-like-pasta'} is not valid under any of the given schemas
Against schema {'$ref': '#/definitions/ap_wireless_settings'}
'station' is not one of ['access_point']
Against schema {'$ref': '#/definitions/sta_wireless_settings'}
{'protocol': 'wpa2_personal', 'key': 'and-pizza-too'} is valid under each of OrderedDict([('$ref', '#/definitions/encryption_wpa_personal')]), {'$ref': '#/definitions/encryption_wpa_personal'}
Against schema {'$ref': '#/definitions/adhoc_wireless_settings'}
{'protocol': 'wpa2_personal', 'key': 'and-pizza-too'} is valid under each of OrderedDict([('$ref', '#/definitions/encryption_wpa_personal')]), {'$ref': '#/definitions/encryption_wpa_personal'}
Against schema {'$ref': '#/definitions/monitor_wireless_settings'}
'station' is not one of ['adhoc']
Against schema {'$ref': '#/definitions/mesh_wireless_settings'}
'station' is not one of ['monitor']
Against schema {'$ref': '#/definitions/bridge_interface'}
'wireless' is not one of ['bridge']
where the interesting part is
Against schema {'$ref': '#/definitions/sta_wireless_settings'}
{'protocol': 'wpa2_personal', 'key': 'and-pizza-too'} is valid under each of OrderedDict([('$ref', '#/definitions/encryption_wpa_personal')]), {'$ref': '#/definitions/encryption_wpa_personal'}
Obviously there are two because the airos branch has an override for the available authentication encryption here
Spent some time to analyze the issue, but unfortunately it is not a bug but the intended mechanism.
Read more about this here: http://netjsonconfig.openwisp.org/en/stable/general/basics.html#implementation-details
Pay attention to these two passages:
I will suggest a workaround for your issue on PR #91
Let's say that we have a custom schema like in airos and that we print the schema, like it happens on a validation error report.
The interesting part is that redefined
definitions
do not override the default one as it can be read from the logIt seems that
merge_config
can merge a json-schema andOrderedDict
but it treat the same definition as different elements.