Merge "Emit notification on update_status() on a zone"
This commit is contained in:
commit
62f578174b
@ -2265,6 +2265,8 @@ class Service(service.RPCService, service.Service):
|
||||
return pool
|
||||
|
||||
# Pool Manager Integration
|
||||
@notification('dns.domain.update')
|
||||
@notification('dns.zone.update')
|
||||
@transaction
|
||||
def update_status(self, context, zone_id, status, serial):
|
||||
"""
|
||||
@ -2272,14 +2274,19 @@ class Service(service.RPCService, service.Service):
|
||||
:param zone_id: The ID of the designate zone.
|
||||
:param status: The status, 'SUCCESS' or 'ERROR'.
|
||||
:param serial: The consensus serial number for the zone.
|
||||
:return: None
|
||||
:return: updated zone
|
||||
"""
|
||||
# TODO(kiall): If the status is SUCCESS and the zone is already ACTIVE,
|
||||
# we likely don't need to do anything.
|
||||
self._update_record_status(context, zone_id, status, serial)
|
||||
self._update_zone_status(context, zone_id, status, serial)
|
||||
zone = self._update_zone_status(context, zone_id, status, serial)
|
||||
return zone
|
||||
|
||||
def _update_zone_status(self, context, zone_id, status, serial):
|
||||
"""Update zone status in storage
|
||||
|
||||
:return: updated zone
|
||||
"""
|
||||
zone = self.storage.get_zone(context, zone_id)
|
||||
|
||||
zone, deleted = self._update_zone_or_record_status(
|
||||
@ -2298,7 +2305,12 @@ class Service(service.RPCService, service.Service):
|
||||
# that the action, status and serial are updated correctly.
|
||||
self.storage.delete_zone(context, zone.id)
|
||||
|
||||
return zone
|
||||
|
||||
def _update_record_status(self, context, zone_id, status, serial):
|
||||
"""Update status on every record in a zone based on `serial`
|
||||
:returns: updated records
|
||||
"""
|
||||
criterion = {
|
||||
'zone_id': zone_id
|
||||
}
|
||||
@ -2347,6 +2359,8 @@ class Service(service.RPCService, service.Service):
|
||||
if len(recordset.records) == 0:
|
||||
self.storage.delete_recordset(context, recordset.id)
|
||||
|
||||
return records
|
||||
|
||||
@staticmethod
|
||||
def _update_zone_or_record_status(zone_or_record, status, serial):
|
||||
deleted = False
|
||||
|
@ -66,7 +66,9 @@ class NotifyEndpoint(base.BaseEndpoint):
|
||||
|
||||
def poll_for_serial_number(self, context, zone, nameserver, timeout,
|
||||
retry_interval, max_retries, delay):
|
||||
"""
|
||||
"""Get the serial number of a zone on a resolver, then call update_status
|
||||
on Pool Manager to update the zone status.
|
||||
|
||||
:param context: The user context.
|
||||
:param zone: The designate zone object. This contains the zone
|
||||
name. zone.serial = expected_serial
|
||||
@ -78,7 +80,7 @@ class NotifyEndpoint(base.BaseEndpoint):
|
||||
an expected serial number. After this many retries, mindns returns
|
||||
an ERROR.
|
||||
:param delay: The time to wait before sending the first request.
|
||||
:return: The pool manager is informed of the status with update_status.
|
||||
:return: None
|
||||
"""
|
||||
(status, actual_serial, retries) = self.get_serial_number(
|
||||
context, zone, nameserver.host, nameserver.port, timeout,
|
||||
|
@ -247,7 +247,11 @@ class Service(service.RPCService, coordination.CoordinationMixin,
|
||||
# Standard Create/Update/Delete Methods
|
||||
|
||||
def create_zone(self, context, zone):
|
||||
"""
|
||||
"""Called by Central or by periodic_recovery, instruct the backends to
|
||||
create a zone, then poll for consensus.
|
||||
On success, send NOTIFY to also_notifies and nameservers
|
||||
Finally, poll for zone serial number on nameservers.
|
||||
|
||||
:param context: Security context information.
|
||||
:param zone: Zone to be created
|
||||
:return: None
|
||||
@ -291,7 +295,8 @@ class Service(service.RPCService, coordination.CoordinationMixin,
|
||||
self.retry_interval, self.max_retries, self.delay)
|
||||
|
||||
def _create_zone_on_target(self, context, target, zone):
|
||||
"""
|
||||
"""Called by create_zone, run create_zone on backends
|
||||
|
||||
:param context: Security context information.
|
||||
:param target: Target to create Zone on
|
||||
:param zone: Zone to be created
|
||||
@ -354,8 +359,8 @@ class Service(service.RPCService, coordination.CoordinationMixin,
|
||||
for nameserver in self.pool.nameservers:
|
||||
# See if there is already another update in progress
|
||||
try:
|
||||
update_status = self.cache.retrieve(
|
||||
context, nameserver.id, zone.id, UPDATE_ACTION)
|
||||
self.cache.retrieve(context, nameserver.id, zone.id,
|
||||
UPDATE_ACTION)
|
||||
except exceptions.PoolManagerStatusNotFound:
|
||||
update_status = self._build_status_object(
|
||||
nameserver, zone, UPDATE_ACTION)
|
||||
|
@ -3006,6 +3006,41 @@ class CentralServiceTest(CentralTestCase):
|
||||
self.admin_context, zone['id'], recordset['id'],
|
||||
record['id'])
|
||||
|
||||
@mock.patch.object(notifier.Notifier, "info")
|
||||
def test_update_status_send_notification(self, mock_notifier):
|
||||
|
||||
# Create zone and ensure that two zone/domain create notifications
|
||||
# have been sent - status is PENDING
|
||||
zone = self.create_zone(email='info@example.org')
|
||||
self.assertEqual(2, mock_notifier.call_count)
|
||||
|
||||
notify_string, notified_zone = mock_notifier.call_args_list[0][0][1:]
|
||||
self.assertEqual('dns.domain.create', notify_string)
|
||||
self.assertEqual('example.com.', notified_zone.name)
|
||||
self.assertEqual('PENDING', notified_zone.status)
|
||||
|
||||
notify_string, notified_zone = mock_notifier.call_args_list[1][0][1:]
|
||||
self.assertEqual('dns.zone.create', notify_string)
|
||||
self.assertEqual('example.com.', notified_zone.name)
|
||||
self.assertEqual('PENDING', notified_zone.status)
|
||||
|
||||
# Perform an update; ensure that zone/domain update notifications
|
||||
# have been sent and the zone is now in ACTIVE status
|
||||
mock_notifier.reset_mock()
|
||||
self.central_service.update_status(
|
||||
self.admin_context, zone['id'], "SUCCESS", zone.serial)
|
||||
|
||||
self.assertEqual(2, mock_notifier.call_count)
|
||||
notify_string, notified_zone = mock_notifier.call_args_list[0][0][1:]
|
||||
self.assertEqual('dns.domain.update', notify_string)
|
||||
self.assertEqual('example.com.', notified_zone.name)
|
||||
self.assertEqual('ACTIVE', notified_zone.status)
|
||||
|
||||
notify_string, notified_zone = mock_notifier.call_args_list[1][0][1:]
|
||||
self.assertEqual('dns.zone.update', notify_string)
|
||||
self.assertEqual('example.com.', notified_zone.name)
|
||||
self.assertEqual('ACTIVE', notified_zone.status)
|
||||
|
||||
def test_update_status_delete_last_record_without_incrementing_serial(
|
||||
self):
|
||||
zone = self.create_zone()
|
||||
|
Loading…
Reference in New Issue
Block a user