diff options
author | Scott Solkhon <scottsolkhon@gmail.com> | 2020-07-30 17:28:18 +0100 |
---|---|---|
committer | Jay Faulkner <jay@jvf.cc> | 2022-11-11 08:03:20 -0800 |
commit | d0e1bb18721352007c1c0356658ee73d0bed8c06 (patch) | |
tree | 39037e99b92f5701d76b6379c3b145d7288dacfe | |
parent | f4999fdfcb1211bf343d04ccd28cfc0e1bc87129 (diff) | |
download | designate-d0e1bb18721352007c1c0356658ee73d0bed8c06.tar.gz |
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 <jay@jvf.cc>
Change-Id: I296c5f085cce27033461be81ca58c85f095df89a
Closes-Bug: #1840253
-rw-r--r-- | designate/backend/impl_infoblox/connector.py | 5 | ||||
-rw-r--r-- | designate/backend/impl_infoblox/object_manipulator.py | 26 | ||||
-rw-r--r-- | 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) |