Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Overriding json-schema from backend does not override definitions #93

Open
edoput opened this issue Jul 20, 2017 · 3 comments
Open

Overriding json-schema from backend does not override definitions #93

edoput opened this issue Jul 20, 2017 · 3 comments
Labels

Comments

@edoput
Copy link
Contributor

edoput commented Jul 20, 2017

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 log

Against schema {'$ref': '#/definitions/ap_wireless_settings'}
{'proto': 'wpa2_personal', 'key': 'and-pizza-too'} is valid under each of
{'$ref': '#/definitions/encryption_wpa_personal'},
{'$ref': '#/definitions/encryption_wps'},
{'$ref': '#/definitions/encryption_wep'},
OrderedDict([('$ref', '#/definitions/encryption_none')]),
OrderedDict([('$ref', '#/definitions/encryption_wpa_personal')]),
OrderedDict([('$ref', '#/definitions/encryption_wpa_enterprise_sta')]),
{'$ref': '#/definitions/encryption_none'}

It seems that merge_config can merge a json-schema and OrderedDict but it treat the same definition as different elements.

@nemesifier
Copy link
Member

@edoput could you add an example of how to replicate the error please?

@edoput
Copy link
Contributor Author

edoput commented Jul 21, 2017

Using the schema and tests from 7c8e27b 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

@nemesifier nemesifier added the bug label Jul 21, 2017
@nemesifier
Copy link
Member

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:

  1. values of type list in both config and template will be merged using to the merge_list function
  2. The remaining elements will be summed in order to create a list which contains elements of both lists.

I will suggest a workaround for your issue on PR #91

edoput pushed a commit to edoput/netjsonconfig that referenced this issue Aug 7, 2017
edoput pushed a commit to edoput/netjsonconfig that referenced this issue Aug 22, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants