[OVN] Add option to allow configuring dns ovn-owned
Added a configuration option '[ovn]dns_records_ovn_owned' to allow setting 'ovn-owned' DNS option added as part of [1]. The Default is False so no change in the current behavior. If this option is set to True for OVN version 24.03 and above, DNS records will be treated local to the OVN controller and it will respond to the queries for the records and record types known to it else it will forward them to the configured DNS Server(s). Also added a maintenance task to update the option in all the DNS records as per the config option with neutron restart. [1] https://github.com/ovn-org/ovn/commit/1622526ff Depends-On: https://review.opendev.org/c/openstack/requirements/+/942797 Depends-On: https://review.opendev.org/c/openstack/ovsdbapp/+/942367 Related-Issue: https://issues.redhat.com/browse/OSPRH-10758 Related-Bug: #2059405 Change-Id: Ia645e8539753c03eb6ead9a868ba5bf194e9a724
This commit is contained in:
@@ -67,6 +67,7 @@ OVN_GATEWAY_NAT_ADDRESSES_KEY = 'nat-addresses'
|
||||
OVN_ROUTER_PORT_EXCLUDE_LB_VIPS_GARP = 'exclude-lb-vips-from-garp'
|
||||
OVN_DROP_PORT_GROUP_NAME = 'neutron_pg_drop'
|
||||
OVN_ROUTER_PORT_GW_MTU_OPTION = 'gateway_mtu'
|
||||
OVN_OWNED = 'ovn-owned'
|
||||
|
||||
OVN_PROVNET_PORT_NAME_PREFIX = 'provnet-'
|
||||
OVN_NAME_PREFIX = 'neutron-'
|
||||
|
@@ -154,6 +154,14 @@ ovn_opts = [
|
||||
"field is empty. If both subnet's dns_nameservers and "
|
||||
"this option are empty, then the DNS resolvers on the "
|
||||
"host running the neutron server will be used.")),
|
||||
cfg.BoolOpt('dns_records_ovn_owned',
|
||||
default=False,
|
||||
help=_("Whether to consider DNS records local to OVN or not. "
|
||||
"For OVN version 24.03 and above if this option is set "
|
||||
"to True, DNS records will be treated local to the OVN "
|
||||
"controller and it will respond to the queries for the "
|
||||
"records and record types known to it, else it will "
|
||||
"forward them to the configured DNS server(s).")),
|
||||
cfg.DictOpt('ovn_dhcp4_global_options',
|
||||
default={},
|
||||
help=_("Dictionary of global DHCPv4 options which will be "
|
||||
@@ -369,6 +377,10 @@ def get_dns_servers():
|
||||
return cfg.CONF.ovn.dns_servers
|
||||
|
||||
|
||||
def is_dns_records_ovn_owned():
|
||||
return cfg.CONF.ovn.dns_records_ovn_owned
|
||||
|
||||
|
||||
def get_global_dhcpv4_opts():
|
||||
return cfg.CONF.ovn.ovn_dhcp4_global_options
|
||||
|
||||
|
@@ -1111,6 +1111,29 @@ class DBInconsistenciesPeriodics(SchemaAwarePeriodicsBase):
|
||||
check_error=True)
|
||||
raise periodics.NeverAgain()
|
||||
|
||||
@has_lock_periodic(
|
||||
periodic_run_limit=ovn_const.MAINTENANCE_TASK_RETRY_LIMIT,
|
||||
spacing=ovn_const.MAINTENANCE_ONE_RUN_TASK_SPACING,
|
||||
run_immediately=True)
|
||||
def set_ovn_owned_dns_option(self):
|
||||
"""Set the ovn_owned option as configured for the DNS records"""
|
||||
cmds = []
|
||||
ovn_owned = ('true' if ovn_conf.is_dns_records_ovn_owned()
|
||||
else 'false')
|
||||
dns_options = {ovn_const.OVN_OWNED: ovn_owned}
|
||||
for dns in self._nb_idl.dns_list().execute(check_error=True):
|
||||
if ('ls_name' in dns.external_ids and
|
||||
dns.options.get(ovn_const.OVN_OWNED) != ovn_owned):
|
||||
cmds.append(self._nb_idl.dns_set_options(
|
||||
dns.uuid, **dns_options))
|
||||
|
||||
if cmds:
|
||||
with self._nb_idl.transaction(check_error=True) as txn:
|
||||
for cmd in cmds:
|
||||
txn.add(cmd)
|
||||
|
||||
raise periodics.NeverAgain()
|
||||
|
||||
|
||||
class HashRingHealthCheckPeriodics:
|
||||
|
||||
|
@@ -2891,6 +2891,14 @@ class OVNClient:
|
||||
txn.add(self._nb_idl.ls_set_dns_records(ls.uuid, dns_add_txn))
|
||||
return
|
||||
|
||||
# Only run when options column is available
|
||||
if hasattr(ls_dns_record, 'options'):
|
||||
ovn_owned = ('true' if ovn_conf.is_dns_records_ovn_owned()
|
||||
else 'false')
|
||||
dns_options = {ovn_const.OVN_OWNED: ovn_owned}
|
||||
txn.add(self._nb_idl.dns_set_options(ls_dns_record.uuid,
|
||||
**dns_options))
|
||||
|
||||
if original_port:
|
||||
old_records = self.get_port_dns_records(original_port)
|
||||
|
||||
|
@@ -1425,6 +1425,34 @@ class TestMaintenance(_TestMaintenanceHelper):
|
||||
original_value=True,
|
||||
config_value=True)
|
||||
|
||||
def test_set_ovn_owned_dns_option(self):
|
||||
neutron_net = self._create_network('network1')
|
||||
ls_name = utils.ovn_name(neutron_net['id'])
|
||||
with mock.patch.object(
|
||||
self._ovn_client, 'is_dns_required_for_port',
|
||||
return_value=True):
|
||||
self._create_port('portdns', neutron_net['id'])
|
||||
|
||||
ls, ls_dns_record = self.nb_api.get_ls_and_dns_record(ls_name)
|
||||
|
||||
# Assert that option is not set
|
||||
self.assertNotEqual(
|
||||
ls_dns_record.options.get('ovn-owned'), 'true')
|
||||
|
||||
# Override config
|
||||
cfg.CONF.set_override(
|
||||
'dns_records_ovn_owned', True, group='ovn')
|
||||
|
||||
# Call the maintenance task and check that the option has been
|
||||
# updated in the DNS record
|
||||
self.assertRaises(
|
||||
periodics.NeverAgain,
|
||||
self.maint.set_ovn_owned_dns_option)
|
||||
|
||||
# Assert that option is not set
|
||||
self.assertEqual(
|
||||
ls_dns_record.options.get('ovn-owned'), 'true')
|
||||
|
||||
|
||||
class TestLogMaintenance(_TestMaintenanceHelper,
|
||||
test_log_driver.LogApiTestCaseBase):
|
||||
|
@@ -978,3 +978,50 @@ class TestDBInconsistenciesPeriodics(testlib_api.SqlTestCaseLight,
|
||||
mock.call(sroute_a, external_ids=external_ids),
|
||||
mock.call(sroute_b, external_ids=external_ids),
|
||||
])
|
||||
|
||||
def _test_set_ovn_owned_dns_option(self, dns):
|
||||
nb_idl = self.fake_ovn_client._nb_idl
|
||||
nb_idl.dns_list.return_value.execute.return_value = [dns]
|
||||
|
||||
self.assertRaises(
|
||||
periodics.NeverAgain,
|
||||
self.periodic.set_ovn_owned_dns_option)
|
||||
|
||||
def test_set_ovn_owned_dns_option(self):
|
||||
cfg.CONF.set_override('dns_records_ovn_owned', 'true',
|
||||
group='ovn')
|
||||
dns = fakes.FakeOvsdbRow.create_one_ovsdb_row(
|
||||
attrs={'external_ids': {'ls_name': 'neutron-foo'},
|
||||
'options': {constants.OVN_OWNED: 'false'}})
|
||||
|
||||
self._test_set_ovn_owned_dns_option(dns)
|
||||
|
||||
ovn_owned = ('true' if ovn_conf.is_dns_records_ovn_owned()
|
||||
else 'false')
|
||||
dns_options = {constants.OVN_OWNED: ovn_owned}
|
||||
|
||||
self.fake_ovn_client._nb_idl.dns_set_options.assert_called_once_with(
|
||||
dns.uuid, **dns_options)
|
||||
|
||||
def test_set_ovn_owned_dns_option_already_set(self):
|
||||
cfg.CONF.set_override('dns_records_ovn_owned', 'true',
|
||||
group='ovn')
|
||||
dns = fakes.FakeOvsdbRow.create_one_ovsdb_row(
|
||||
attrs={'external_ids': {'ls_name': 'neutron-foo'},
|
||||
'options': {constants.OVN_OWNED: 'true'}})
|
||||
|
||||
self._test_set_ovn_owned_dns_option(dns)
|
||||
|
||||
# Assert there was no transactions because the value was already set
|
||||
self.fake_ovn_client._nb_idl.dns_set_options.assert_not_called()
|
||||
|
||||
def test_set_ovn_owned_dns_option_ovn_direct_record(self):
|
||||
dns = fakes.FakeOvsdbRow.create_one_ovsdb_row(
|
||||
attrs={'external_ids': {'ovn_direct': 'ovn-foo'},
|
||||
'options': {constants.OVN_OWNED: 'true'}})
|
||||
|
||||
self._test_set_ovn_owned_dns_option(dns)
|
||||
|
||||
# Assert there was no transactions because the record directly
|
||||
# created in ovn i.e not created by neutron
|
||||
self.fake_ovn_client._nb_idl.dns_set_options.assert_not_called()
|
||||
|
@@ -0,0 +1,12 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
For OVN version 24.03 and above you can now configure DNS records to be
|
||||
local to OVN by setting the new configuration option
|
||||
``[ovn]dns_records_ovn_owned``.
|
||||
If this option is set to True, DNS records will be treated local to the OVN
|
||||
controller and it will respond to the queries for the records and record
|
||||
types known to it, else it will forward them to the configured DNS server(s).
|
||||
For more information, see bug
|
||||
`2059405 <https://bugs.launchpad.net/neutron/+bug/2059405>`_.
|
||||
Default is False.
|
@@ -45,7 +45,7 @@ osprofiler>=2.3.0 # Apache-2.0
|
||||
os-ken>=2.11.2 # Apache-2.0
|
||||
os-resource-classes>=1.1.0 # Apache-2.0
|
||||
ovs>=2.12.0 # Apache-2.0
|
||||
ovsdbapp>=2.7.1 # Apache-2.0
|
||||
ovsdbapp>=2.11.0 # Apache-2.0
|
||||
psutil>=6.1.0 # BSD
|
||||
pyroute2>=0.7.3;sys_platform!='win32' # Apache-2.0 (+ dual licensed GPL2)
|
||||
pyOpenSSL>=17.1.0 # Apache-2.0
|
||||
|
Reference in New Issue
Block a user