From 0dd12f3746e52dba2e6cc78984525845c473e836 Mon Sep 17 00:00:00 2001 From: Andrew Bogott Date: Mon, 1 Jun 2020 10:04:12 -0500 Subject: [PATCH] pdns4 backend: check if zone exists before attempting delete This should prevent us from obsessing over zones that are in the designate DB but not in the pdns backend due to races/incomplete transactions/etc. Bug: 1880230 Change-Id: I00ae6227edf21007c39a7d55221898ae5c10dda2 (cherry picked from commit 5acba9443e2fc1f6e78f9a32cd85eb168d2a7cb2) --- designate/backend/impl_pdns4.py | 21 +++++++++++------ designate/tests/unit/backend/test_pdns4.py | 26 ++++++++++++++++++++++ 2 files changed, 40 insertions(+), 7 deletions(-) diff --git a/designate/backend/impl_pdns4.py b/designate/backend/impl_pdns4.py index 576dddd5c..7149beba7 100644 --- a/designate/backend/impl_pdns4.py +++ b/designate/backend/impl_pdns4.py @@ -106,10 +106,17 @@ class PDNS4Backend(base.Backend): def delete_zone(self, context, zone): """Delete a DNS zone""" - try: - requests.delete( - self._build_url(zone.name), - headers=self.headers - ).raise_for_status() - except requests.HTTPError as e: - raise exceptions.Backend(e) + # First verify that the zone exists -- If it's not present + # in the backend then we can just declare victory. + if self._check_zone_exists(zone): + try: + requests.delete( + self._build_url(zone.name), + headers=self.headers + ).raise_for_status() + except requests.HTTPError as e: + raise exceptions.Backend(e) + else: + LOG.warning("Trying to delete zone %s but that zone is not " + "present in the pdns backend. Assuming success.", + zone) diff --git a/designate/tests/unit/backend/test_pdns4.py b/designate/tests/unit/backend/test_pdns4.py index 2439d7f22..a04a28c80 100644 --- a/designate/tests/unit/backend/test_pdns4.py +++ b/designate/tests/unit/backend/test_pdns4.py @@ -285,6 +285,28 @@ class PDNS4BackendTestCase(designate.tests.TestCase): req_mock.delete( '%s/localhost/zones/example.com.' % self.base_address, ) + req_mock.get( + '%s/localhost/zones/%s' % (self.base_address, self.zone.name), + status_code=200, + ) + + self.backend.delete_zone(self.context, self.zone) + + self.assertEqual( + req_mock.last_request.headers.get('X-API-Key'), 'api_key' + ) + + @requests_mock.mock() + def test_delete_zone_missing(self, req_mock): + req_mock.delete( + '%s/localhost/zones/example.com.' % self.base_address, + ) + + # pdns returns 422 if asked about a zone that doesn't exist. + req_mock.get( + '%s/localhost/zones/%s' % (self.base_address, self.zone.name), + status_code=422, + ) self.backend.delete_zone(self.context, self.zone) @@ -298,6 +320,10 @@ class PDNS4BackendTestCase(designate.tests.TestCase): '%s/localhost/zones/example.com.' % self.base_address, status_code=500, ) + req_mock.get( + '%s/localhost/zones/%s' % (self.base_address, self.zone.name), + status_code=200, + ) self.assertRaisesRegexp( exceptions.Backend,