Fix AXFR loop when updating secondary zone
When a secondary zone is created or updated we trigger an AXFR,
this AXFR then goes ahead and updates the zone. This then causes
the AXFR code to get triggered again as it thinks the masters
has changed.
We fix this by ensuring that when we update the zone from the AXFR
code that we always reset the masters field.
Partial-Bug: #1856442
Change-Id: Ifc2efb5a6d1091ff16373f3cbe3846f5e4371272
(cherry picked from commit ecaff9e6d3
)
This commit is contained in:
parent
0577a1df72
commit
b1ecf814a8
@ -819,9 +819,7 @@ class Service(service.RPCService):
|
||||
self.worker_api.create_zone(context, zone)
|
||||
|
||||
if zone.type == constants.ZONE_SECONDARY:
|
||||
xfr_zone = copy.deepcopy(zone)
|
||||
xfr_zone.obj_reset_changes(recursive=True)
|
||||
self.worker_api.perform_zone_xfr(context, xfr_zone)
|
||||
self.worker_api.perform_zone_xfr(context, zone)
|
||||
|
||||
# If zone is a superzone, update subzones
|
||||
# with new parent IDs
|
||||
|
@ -1622,42 +1622,6 @@ class CentralZoneTestCase(CentralBasic):
|
||||
refresh_time = central_service._generate_soa_refresh_interval()
|
||||
self.assertEqual(3563, refresh_time)
|
||||
|
||||
@patch.object(objects.Zone, 'obj_reset_changes')
|
||||
def test_create_secondary_zone(self, mock_obj_reset_changes):
|
||||
self.service._enforce_zone_quota = mock.Mock()
|
||||
self.service._create_zone_in_storage = mock.Mock(
|
||||
return_value=objects.Zone(name='example.com.', type='SECONDARY'))
|
||||
self.service._is_valid_zone_name = mock.Mock()
|
||||
self.service._is_valid_ttl = mock.Mock()
|
||||
self.service._is_subzone = mock.Mock(return_value=False)
|
||||
self.service._is_superzone = mock.Mock(return_value=[])
|
||||
self.service.storage.get_pool.return_value = RoObject(
|
||||
ns_records=[RoObject()])
|
||||
self.useFixture(
|
||||
fixtures.MockPatchObject(
|
||||
self.service.storage,
|
||||
'find_pools',
|
||||
return_value=objects.PoolList.from_list(
|
||||
[
|
||||
{'id': '94ccc2c1-d751-44fe-b57f-8894c9f5c842'}
|
||||
]
|
||||
)
|
||||
)
|
||||
)
|
||||
output = self.service.create_zone(
|
||||
self.context,
|
||||
objects.Zone(
|
||||
tenant_id='1',
|
||||
name='example.com.',
|
||||
ttl=60,
|
||||
pool_id=CentralZoneTestCase.pool__id,
|
||||
refresh=0,
|
||||
type='SECONDARY'
|
||||
)
|
||||
)
|
||||
self.assertEqual('example.com.', output.name)
|
||||
mock_obj_reset_changes.assert_called_once_with(recursive=True)
|
||||
|
||||
|
||||
class IsSubzoneTestCase(CentralBasic):
|
||||
def setUp(self):
|
||||
|
@ -60,6 +60,38 @@ class TestXfr(oslotest.base.BaseTestCase):
|
||||
self.assertIn('transferred_at', zone.obj_what_changed())
|
||||
self.assertNotIn('name', zone.obj_what_changed())
|
||||
|
||||
@mock.patch.object(dnsutils, 'do_axfr', mock.Mock())
|
||||
def test_zone_sync_not_change_masters(self):
|
||||
recordset = objects.RecordSet(
|
||||
name='www.example.test.', type='TXT',
|
||||
records=objects.RecordList(objects=[
|
||||
objects.Record(data='foo bar'),
|
||||
])
|
||||
)
|
||||
zone = objects.Zone(
|
||||
id='7592878e-4ade-40de-8b8d-699b871ee6fa',
|
||||
name='example.com.',
|
||||
serial=1,
|
||||
masters=objects.ZoneMasterList.from_list(
|
||||
[{'host': '127.0.0.1', 'port': 53}, ]
|
||||
),
|
||||
type=constants.ZONE_SECONDARY,
|
||||
recordsets=objects.RecordSetList(objects=[]),
|
||||
)
|
||||
|
||||
self.xfr = worker_zone.ZoneXfr(mock.Mock(), self.context, zone)
|
||||
self.xfr._central_api = mock.Mock()
|
||||
|
||||
with mock.patch.object(dnsutils, 'from_dnspython_zone') as mock_dns:
|
||||
zone.recordsets = objects.RecordSetList(objects=[recordset])
|
||||
zone.masters = objects.ZoneMasterList()
|
||||
mock_dns.return_value = zone
|
||||
|
||||
self.xfr()
|
||||
|
||||
self.assertIn('transferred_at', zone.obj_what_changed())
|
||||
self.assertNotIn('masters', zone.obj_what_changed())
|
||||
|
||||
@mock.patch.object(dnsutils, 'do_axfr', mock.Mock())
|
||||
def test_zone_sync_using_list_of_servers(self):
|
||||
zone = objects.Zone(
|
||||
|
@ -183,7 +183,7 @@ class ZoneXfr(base.Task):
|
||||
|
||||
self.zone.update(dnsutils.from_dnspython_zone(dnspython_zone))
|
||||
self.zone.transferred_at = timeutils.utcnow()
|
||||
self.zone.obj_reset_changes(['name'])
|
||||
self.zone.obj_reset_changes(['name', 'masters'], recursive=True)
|
||||
self.central_api.update_zone(
|
||||
self.context, self.zone, increment_serial=False
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user