From d0e1bb18721352007c1c0356658ee73d0bed8c06 Mon Sep 17 00:00:00 2001 From: Scott Solkhon Date: Thu, 30 Jul 2020 17:28:18 +0100 Subject: Reload Infoblox config after deleting zone If you delete a zone using the Infoblox backend the zone will be deleted from Infoblox but the zone within OpenStack will go into an ERROR state unless an operator manually logs into Infoblox and issues a reload of the running configuration. This commit fixes this bug by issuing a 'restart if needed' after deleting the zone. This does not happen when creating zones as 'restart if needed' can be passed through as a param into that API call. Co-Authored-By: Jay Faulkner Change-Id: I296c5f085cce27033461be81ca58c85f095df89a Closes-Bug: #1840253 --- designate/backend/impl_infoblox/connector.py | 5 ++++- .../backend/impl_infoblox/object_manipulator.py | 26 +++++++++++++++++++++- designate/tests/unit/backend/test_infoblox.py | 5 +++++ 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/designate/backend/impl_infoblox/connector.py b/designate/backend/impl_infoblox/connector.py index fab9d784..aaf1456f 100644 --- a/designate/backend/impl_infoblox/connector.py +++ b/designate/backend/impl_infoblox/connector.py @@ -131,7 +131,10 @@ class Infoblox(object): headers = {'Content-type': 'application/json'} - data = jsonutils.dump_as_bytes(payload) + # NOTE (scottsol): This can trigger an internal error in Infoblox if + # jsonutils sets it to 'null' (a string with quotes). Setting to None + # works around this and returns a valid response from Infoblox + data = jsonutils.dump_as_bytes(payload) if payload else None url = self._construct_url(objtype, query_params, extattrs) r = self.session.get(url, diff --git a/designate/backend/impl_infoblox/object_manipulator.py b/designate/backend/impl_infoblox/object_manipulator.py index a2d4fdf5..dbbb431d 100644 --- a/designate/backend/impl_infoblox/object_manipulator.py +++ b/designate/backend/impl_infoblox/object_manipulator.py @@ -122,14 +122,16 @@ class InfobloxObjectManipulator(object): 'zone_auth', {'fqdn': fqdn, 'view': dns_view}, {'ns_group': self.connector.ns_group, - 'restart_if_needed': True, 'zone_format': zone_format}, + 'zone_format': zone_format}, check_if_exists=True) + self._restart_if_needed() except exc.InfobloxCannotCreateObject as e: LOG.warning(e) def delete_zone_auth(self, fqdn): self._delete_infoblox_object( 'zone_auth', {'fqdn': fqdn}) + self._restart_if_needed() def _create_infoblox_object(self, obj_type, payload, additional_create_kwargs=None, @@ -205,3 +207,25 @@ class InfobloxObjectManipulator(object): if ib_object_ref: self.connector.delete_object(ib_object_ref) LOG.info('Infoblox object was deleted: %s', ib_object_ref) + + def _restart_if_needed(self): + ib_object_ref = None + obj_type = 'grid' + warn_msg = ('Infoblox %(obj_type)s will not be restarted because' + ' the API object reference cannot be found') + try: + ib_object_ref = self._get_infoblox_object_or_none(obj_type) + if not ib_object_ref: + LOG.warning(warn_msg, {'obj_type': obj_type}) + except exc.InfobloxSearchError as e: + LOG.warning(warn_msg, {'obj_type': obj_type}) + LOG.info(e) + + if ib_object_ref: + payload = { + "restart_option": "RESTART_IF_NEEDED", + "mode": "GROUPED", + "services": ["DNS"], + } + self.connector.call_func( + 'restartservices', ib_object_ref, payload) diff --git a/designate/tests/unit/backend/test_infoblox.py b/designate/tests/unit/backend/test_infoblox.py index 81c8351b..731757c4 100644 --- a/designate/tests/unit/backend/test_infoblox.py +++ b/designate/tests/unit/backend/test_infoblox.py @@ -88,6 +88,11 @@ class InfobloxBackendTestCase(oslotest.base.BaseTestCase): json={}, ) + req_mock.get( + '%s/v2.0/grid' % self.base_address, + json={}, + ) + self.backend.create_zone(self.context, self.zone) self.backend.delete_zone(self.context, self.zone) -- cgit v1.2.1