From 4d95543eea56eab8b3e3751bf05085fd6ebeb38e Mon Sep 17 00:00:00 2001 From: anagha-infoblox Date: Sun, 26 Jun 2022 23:45:53 +0530 Subject: [PATCH 1/5] Fix to create txt record with an equals sign in the text field and update the text field --- plugins/module_utils/api.py | 45 ++++++++++++++++++++++++++++++++----- 1 file changed, 40 insertions(+), 5 deletions(-) diff --git a/plugins/module_utils/api.py b/plugins/module_utils/api.py index ced9de6f..737a0229 100644 --- a/plugins/module_utils/api.py +++ b/plugins/module_utils/api.py @@ -35,7 +35,8 @@ from ansible.module_utils.six import iteritems from ansible.module_utils._text import to_text from ansible.module_utils.basic import env_fallback -from ansible.module_utils.common.validation import check_type_dict +from ansible.module_utils.common.validation import check_type_dict, safe_eval +from ansible.module_utils.six import string_types try: from infoblox_client.connector import Connector @@ -313,6 +314,20 @@ def run(self, ib_obj_type, ib_spec): if (ib_obj_type == NIOS_MEMBER): proposed_object = member_normalize(proposed_object) + # checks if the 'text' field has to be updated for the TXT Record + if (ib_obj_type == NIOS_TXT_RECORD): + text_obj = proposed_object["text"] + if text_obj.startswith("{"): + try: + text_obj = json.loads(text_obj) + txt = text_obj['old_text'] + except Exception: + (result, exc) = safe_eval(text_obj, dict(), include_exceptions=True) + if exc is not None: + raise TypeError('unable to evaluate string as dictionary') + txt = result['old_text'] + proposed_object['text'] = txt + # checks if the name's field has been updated if update and new_name: proposed_object['name'] = new_name @@ -560,8 +575,18 @@ def get_object_ref(self, module, ib_obj_type, obj_filter, ib_spec): # resolves issue where multiple txt_records with same name and different text test_obj_filter = obj_filter try: - text_obj = check_type_dict(obj_filter['text']) - txt = text_obj['old_text'] + text_obj = obj_filter['text'] + if text_obj.startswith("{"): + try: + text_obj = json.loads(text_obj) + txt = text_obj['old_text'] + except Exception: + (result, exc) = safe_eval(text_obj, dict(), include_exceptions=True) + if exc is not None: + raise TypeError('unable to evaluate string as dictionary') + txt = result['old_text'] + else: + txt = text_obj except TypeError: txt = obj_filter['text'] test_obj_filter['text'] = txt @@ -583,8 +608,18 @@ def get_object_ref(self, module, ib_obj_type, obj_filter, ib_spec): # resolves issue where multiple txt_records with same name and different text test_obj_filter = obj_filter try: - text_obj = check_type_dict(obj_filter['text']) - txt = text_obj['old_text'] + text_obj = obj_filter(['text']) + if text_obj.startswith("{"): + try: + text_obj = json.loads(text_obj) + txt = text_obj['old_text'] + except Exception: + (result, exc) = safe_eval(text_obj, dict(), include_exceptions=True) + if exc is not None: + raise TypeError('unable to evaluate string as dictionary') + txt = result['old_text'] + else: + txt = text_obj except TypeError: txt = obj_filter['text'] test_obj_filter['text'] = txt From 5a6f864fcdfdee63e0a3db735aa943badc1ffe7a Mon Sep 17 00:00:00 2001 From: Anagha K H <70952486+anagha-infoblox@users.noreply.github.com> Date: Mon, 27 Jun 2022 00:10:20 +0530 Subject: [PATCH 2/5] Added the missing import --- plugins/module_utils/api.py | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/module_utils/api.py b/plugins/module_utils/api.py index 737a0229..86733954 100644 --- a/plugins/module_utils/api.py +++ b/plugins/module_utils/api.py @@ -29,6 +29,7 @@ # +import json import os from functools import partial from ansible.module_utils._text import to_native From f5d7d4f4c7532a78ccc0f4a4c7d5bfc35cb6ecde Mon Sep 17 00:00:00 2001 From: anagha-infoblox Date: Mon, 27 Jun 2022 10:40:25 +0530 Subject: [PATCH 3/5] Corrected a typo --- plugins/module_utils/api.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/module_utils/api.py b/plugins/module_utils/api.py index 737a0229..87b19b05 100644 --- a/plugins/module_utils/api.py +++ b/plugins/module_utils/api.py @@ -320,12 +320,12 @@ def run(self, ib_obj_type, ib_spec): if text_obj.startswith("{"): try: text_obj = json.loads(text_obj) - txt = text_obj['old_text'] + txt = text_obj['new_text'] except Exception: (result, exc) = safe_eval(text_obj, dict(), include_exceptions=True) if exc is not None: raise TypeError('unable to evaluate string as dictionary') - txt = result['old_text'] + txt = result['new_text'] proposed_object['text'] = txt # checks if the name's field has been updated From b76ecf090ebab7be01b04898bac554b633b311ce Mon Sep 17 00:00:00 2001 From: anagha-infoblox Date: Tue, 28 Jun 2022 11:24:47 +0530 Subject: [PATCH 4/5] Converted record names to lower case --- plugins/module_utils/api.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/module_utils/api.py b/plugins/module_utils/api.py index 025ad3dd..63c2d463 100644 --- a/plugins/module_utils/api.py +++ b/plugins/module_utils/api.py @@ -530,8 +530,8 @@ def get_object_ref(self, module, ib_obj_type, obj_filter, ib_spec): # gets and returns the current object based on name/old_name passed try: name_obj = check_type_dict(obj_filter['name']) - old_name = name_obj['old_name'] - new_name = name_obj['new_name'] + old_name = name_obj['old_name'].lower() + new_name = name_obj['new_name'].lower() except TypeError: name = obj_filter['name'] From b80d6bdf5ccec08f66034badfd72a4d9e31e9e4c Mon Sep 17 00:00:00 2001 From: anagha-infoblox Date: Tue, 28 Jun 2022 11:51:43 +0530 Subject: [PATCH 5/5] Fixed unit test failures --- tests/unit/plugins/module_utils/test_api.py | 10 +++++----- tests/unit/plugins/modules/test_nios_a_record.py | 2 +- tests/unit/plugins/modules/test_nios_aaaa_record.py | 2 +- tests/unit/plugins/modules/test_nios_cname_record.py | 2 +- tests/unit/plugins/modules/test_nios_dns_view.py | 2 +- tests/unit/plugins/modules/test_nios_host_record.py | 2 +- tests/unit/plugins/modules/test_nios_mx_record.py | 2 +- tests/unit/plugins/modules/test_nios_naptr_record.py | 2 +- tests/unit/plugins/modules/test_nios_network_view.py | 2 +- tests/unit/plugins/modules/test_nios_nsgroup.py | 2 +- tests/unit/plugins/modules/test_nios_srv_record.py | 2 +- 11 files changed, 15 insertions(+), 15 deletions(-) diff --git a/tests/unit/plugins/module_utils/test_api.py b/tests/unit/plugins/module_utils/test_api.py index f43c8da6..ab0554c7 100644 --- a/tests/unit/plugins/module_utils/test_api.py +++ b/tests/unit/plugins/module_utils/test_api.py @@ -58,7 +58,7 @@ def test_wapi_no_change(self): { "comment": "test comment", "_ref": "networkview/ZG5zLm5ldHdvcmtfdmlldyQw:default/true", - "name": self.mock_check_type_dict_obj().__getitem__(), + "name": self.mock_check_type_dict_obj().__getitem__().lower(), "extattrs": {} } ] @@ -146,7 +146,7 @@ def test_wapi_extattrs_change(self): kwargs = copy.deepcopy(test_object[0]) kwargs['extattrs']['Site']['value'] = 'update' - kwargs['name'] = self.mock_check_type_dict_obj().__getitem__() + kwargs['name'] = self.mock_check_type_dict_obj().__getitem__().lower() del kwargs['_ref'] wapi = self._get_wapi(test_object) @@ -162,7 +162,7 @@ def test_wapi_extattrs_nochange(self): test_object = [{ "comment": "test comment", "_ref": "networkview/ZG5zLm5ldHdvcmtfdmlldyQw:default/true", - "name": self.mock_check_type_dict_obj().__getitem__(), + "name": self.mock_check_type_dict_obj().__getitem__().lower(), "extattrs": {'Site': {'value': 'test'}} }] @@ -193,7 +193,7 @@ def test_wapi_create(self): res = wapi.run('testobject', test_spec) self.assertTrue(res['changed']) - wapi.create_object.assert_called_once_with('testobject', {'name': self.mock_check_type_dict_obj().__getitem__()}) + wapi.create_object.assert_called_once_with('testobject', {'name': self.mock_check_type_dict_obj().__getitem__().lower()}) def test_wapi_delete(self): self.module.params = {'provider': None, 'state': 'absent', 'name': 'ansible', @@ -243,7 +243,7 @@ def test_wapi_strip_network_view(self): kwargs = test_object[0].copy() ref = kwargs.pop('_ref') kwargs['comment'] = 'updated comment' - kwargs['name'] = self.mock_check_type_dict_obj().__getitem__() + kwargs['name'] = self.mock_check_type_dict_obj().__getitem__().lower() del kwargs['network_view'] del kwargs['extattrs'] diff --git a/tests/unit/plugins/modules/test_nios_a_record.py b/tests/unit/plugins/modules/test_nios_a_record.py index 6921d967..a5bec396 100644 --- a/tests/unit/plugins/modules/test_nios_a_record.py +++ b/tests/unit/plugins/modules/test_nios_a_record.py @@ -79,7 +79,7 @@ def test_nios_a_record_create(self): res = wapi.run('testobject', test_spec) self.assertTrue(res['changed']) - wapi.create_object.assert_called_once_with('testobject', {'name': self.mock_check_type_dict_obj().__getitem__(), + wapi.create_object.assert_called_once_with('testobject', {'name': self.mock_check_type_dict_obj().__getitem__().lower(), 'ipv4': '192.168.10.1'}) def test_nios_a_record_update_comment(self): diff --git a/tests/unit/plugins/modules/test_nios_aaaa_record.py b/tests/unit/plugins/modules/test_nios_aaaa_record.py index d9dce970..6027c7fc 100644 --- a/tests/unit/plugins/modules/test_nios_aaaa_record.py +++ b/tests/unit/plugins/modules/test_nios_aaaa_record.py @@ -79,7 +79,7 @@ def test_nios_aaaa_record_create(self): res = wapi.run('testobject', test_spec) self.assertTrue(res['changed']) - wapi.create_object.assert_called_once_with('testobject', {'name': self.mock_check_type_dict_obj().__getitem__(), + wapi.create_object.assert_called_once_with('testobject', {'name': self.mock_check_type_dict_obj().__getitem__().lower(), 'ipv6': '2001:0db8:85a3:0000:0000:8a2e:0370:7334'}) def test_nios_aaaa_record_update_comment(self): diff --git a/tests/unit/plugins/modules/test_nios_cname_record.py b/tests/unit/plugins/modules/test_nios_cname_record.py index bbf56172..61f09d27 100644 --- a/tests/unit/plugins/modules/test_nios_cname_record.py +++ b/tests/unit/plugins/modules/test_nios_cname_record.py @@ -79,7 +79,7 @@ def test_nios_a_record_create(self): res = wapi.run('testobject', test_spec) self.assertTrue(res['changed']) - wapi.create_object.assert_called_once_with('testobject', {'name': self.mock_check_type_dict_obj().__getitem__(), + wapi.create_object.assert_called_once_with('testobject', {'name': self.mock_check_type_dict_obj().__getitem__().lower(), 'canonical': 'realhost.ansible.com'}) def test_nios_a_record_update_comment(self): diff --git a/tests/unit/plugins/modules/test_nios_dns_view.py b/tests/unit/plugins/modules/test_nios_dns_view.py index cc874611..e552748a 100644 --- a/tests/unit/plugins/modules/test_nios_dns_view.py +++ b/tests/unit/plugins/modules/test_nios_dns_view.py @@ -78,7 +78,7 @@ def test_nios_dns_view_create(self): res = wapi.run('testobject', test_spec) self.assertTrue(res['changed']) - wapi.create_object.assert_called_once_with('testobject', {'name': self.mock_check_type_dict_obj().__getitem__()}) + wapi.create_object.assert_called_once_with('testobject', {'name': self.mock_check_type_dict_obj().__getitem__().lower()}) def test_nios_dns_view_update_comment(self): self.module.params = {'provider': None, 'state': 'present', 'name': 'ansible-dns', diff --git a/tests/unit/plugins/modules/test_nios_host_record.py b/tests/unit/plugins/modules/test_nios_host_record.py index ddb8a265..ae0eaa16 100644 --- a/tests/unit/plugins/modules/test_nios_host_record.py +++ b/tests/unit/plugins/modules/test_nios_host_record.py @@ -77,7 +77,7 @@ def test_nios_host_record_create(self): res = wapi.run('testobject', test_spec) self.assertTrue(res['changed']) - wapi.create_object.assert_called_once_with('testobject', {'name': self.mock_check_type_dict_obj().__getitem__()}) + wapi.create_object.assert_called_once_with('testobject', {'name': self.mock_check_type_dict_obj().__getitem__().lower()}) def test_nios_host_record_remove(self): self.module.params = {'provider': None, 'state': 'absent', 'name': 'ansible', diff --git a/tests/unit/plugins/modules/test_nios_mx_record.py b/tests/unit/plugins/modules/test_nios_mx_record.py index 5b3eeb77..33a2f299 100644 --- a/tests/unit/plugins/modules/test_nios_mx_record.py +++ b/tests/unit/plugins/modules/test_nios_mx_record.py @@ -80,7 +80,7 @@ def test_nios_mx_record_create(self): res = wapi.run('testobject', test_spec) self.assertTrue(res['changed']) - wapi.create_object.assert_called_once_with('testobject', {'name': self.mock_check_type_dict_obj().__getitem__(), + wapi.create_object.assert_called_once_with('testobject', {'name': self.mock_check_type_dict_obj().__getitem__().lower(), 'mx': 'mailhost.ansible.com', 'preference': 0}) def test_nios_mx_record_update_comment(self): diff --git a/tests/unit/plugins/modules/test_nios_naptr_record.py b/tests/unit/plugins/modules/test_nios_naptr_record.py index 10469bdf..82596f78 100644 --- a/tests/unit/plugins/modules/test_nios_naptr_record.py +++ b/tests/unit/plugins/modules/test_nios_naptr_record.py @@ -82,7 +82,7 @@ def test_nios_naptr_record_create(self): res = wapi.run('testobject', test_spec) self.assertTrue(res['changed']) - wapi.create_object.assert_called_once_with('testobject', {'name': self.mock_check_type_dict_obj().__getitem__(), + wapi.create_object.assert_called_once_with('testobject', {'name': self.mock_check_type_dict_obj().__getitem__().lower(), 'order': '1000', 'preference': '10', 'replacement': 'replacement1.network.ansiblezone.com'}) diff --git a/tests/unit/plugins/modules/test_nios_network_view.py b/tests/unit/plugins/modules/test_nios_network_view.py index 4d0f0a3d..4a2f7f10 100644 --- a/tests/unit/plugins/modules/test_nios_network_view.py +++ b/tests/unit/plugins/modules/test_nios_network_view.py @@ -78,7 +78,7 @@ def test_nios_network_view_create(self): res = wapi.run('testobject', test_spec) self.assertTrue(res['changed']) - wapi.create_object.assert_called_once_with('testobject', {'name': self.mock_check_type_dict_obj().__getitem__()}) + wapi.create_object.assert_called_once_with('testobject', {'name': self.mock_check_type_dict_obj().__getitem__().lower()}) def test_nios_network_view_update_comment(self): self.module.params = {'provider': None, 'state': 'present', 'name': 'default', diff --git a/tests/unit/plugins/modules/test_nios_nsgroup.py b/tests/unit/plugins/modules/test_nios_nsgroup.py index 315e3ba8..f57fc73c 100644 --- a/tests/unit/plugins/modules/test_nios_nsgroup.py +++ b/tests/unit/plugins/modules/test_nios_nsgroup.py @@ -77,7 +77,7 @@ def test_nios_nsgroup_create(self): res = wapi.run('testobject', test_spec) self.assertTrue(res['changed']) - wapi.create_object.assert_called_once_with('testobject', {'name': self.mock_check_type_dict_obj().__getitem__()}) + wapi.create_object.assert_called_once_with('testobject', {'name': self.mock_check_type_dict_obj().__getitem__().lower()}) def test_nios_nsgroup_remove(self): self.module.params = {'provider': None, 'state': 'absent', 'name': 'my-simple-group', diff --git a/tests/unit/plugins/modules/test_nios_srv_record.py b/tests/unit/plugins/modules/test_nios_srv_record.py index 5d36d4cc..f680be9f 100644 --- a/tests/unit/plugins/modules/test_nios_srv_record.py +++ b/tests/unit/plugins/modules/test_nios_srv_record.py @@ -83,7 +83,7 @@ def test_nios_srv_record_create(self): res = wapi.run('testobject', test_spec) self.assertTrue(res['changed']) - wapi.create_object.assert_called_once_with('testobject', {'name': self.mock_check_type_dict_obj().__getitem__(), + wapi.create_object.assert_called_once_with('testobject', {'name': self.mock_check_type_dict_obj().__getitem__().lower(), 'port': 5080, 'target': 'service1.ansible.com', 'priority': 10, 'weight': 10}) def test_nios_srv_record_update_comment(self):