From b7f815ba898fcff7ffb4722f0e917a47755b589f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Claes=20N=C3=A4st=C3=A9n?= Date: Wed, 24 Jan 2018 12:21:05 +0100 Subject: [PATCH] nso_config handle data.not_found in exists for nested lists (#35267) Recent NSO can return data.not_found error on exists when parent list entries does not exist. Handle this and return as false. Fixes: #35264 --- lib/ansible/module_utils/network/nso/nso.py | 12 ++++++-- .../module_utils/network/nso/test_nso.py | 28 +++++++++++++++++++ 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/lib/ansible/module_utils/network/nso/nso.py b/lib/ansible/module_utils/network/nso/nso.py index ab13f2ea02..f4267b8cab 100644 --- a/lib/ansible/module_utils/network/nso/nso.py +++ b/lib/ansible/module_utils/network/nso/nso.py @@ -140,8 +140,16 @@ class JsonRpc(object): def exists(self, path): payload = {'method': 'exists', 'params': {'path': path}} - resp, resp_json = self._read_call(payload) - return resp_json['result']['exists'] + try: + resp, resp_json = self._read_call(payload) + return resp_json['result']['exists'] + except NsoException as ex: + # calling exists on a sub-list when the parent list does + # not exists will cause data.not_found errors on recent + # NSO + if 'type' in ex.error and ex.error['type'] == 'data.not_found': + return False + raise def create(self, th, path): payload = {'method': 'create', 'params': {'th': th, 'path': path}} diff --git a/test/units/module_utils/network/nso/test_nso.py b/test/units/module_utils/network/nso/test_nso.py index e41e8c2594..38fed66b23 100644 --- a/test/units/module_utils/network/nso/test_nso.py +++ b/test/units/module_utils/network/nso/test_nso.py @@ -256,6 +256,34 @@ def get_schema_response(path): SCHEMA_DATA[path])) +class TestJsonRpc(unittest.TestCase): + @patch('ansible.module_utils.network.nso.nso.open_url') + def test_exists(self, open_url_mock): + calls = [ + MockResponse('new_trans', {}, 200, '{"result": {"th": 1}}'), + MockResponse('exists', {'path': '/exists'}, 200, '{"result": {"exists": true}}'), + MockResponse('exists', {'path': '/not-exists'}, 200, '{"result": {"exists": false}}') + ] + open_url_mock.side_effect = lambda *args, **kwargs: mock_call(calls, *args, **kwargs) + client = nso.JsonRpc('http://localhost:8080/jsonrpc') + self.assertEquals(True, client.exists('/exists')) + self.assertEquals(False, client.exists('/not-exists')) + + self.assertEqual(0, len(calls)) + + @patch('ansible.module_utils.network.nso.nso.open_url') + def test_exists_data_not_found(self, open_url_mock): + calls = [ + MockResponse('new_trans', {}, 200, '{"result": {"th": 1}}'), + MockResponse('exists', {'path': '/list{missing-parent}/list{child}'}, 200, '{"error":{"type":"data.not_found"}}') + ] + open_url_mock.side_effect = lambda *args, **kwargs: mock_call(calls, *args, **kwargs) + client = nso.JsonRpc('http://localhost:8080/jsonrpc') + self.assertEquals(False, client.exists('/list{missing-parent}/list{child}')) + + self.assertEqual(0, len(calls)) + + class TestValueBuilder(unittest.TestCase): @patch('ansible.module_utils.network.nso.nso.open_url') def test_identityref_leaf(self, open_url_mock):