diff --git a/neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/ovn_client.py b/neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/ovn_client.py index 96c4457d190..1aa18dbf121 100644 --- a/neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/ovn_client.py +++ b/neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/ovn_client.py @@ -2240,6 +2240,10 @@ class OVNClient(object): port_dns_records[fqdn] = dns_assignment['ip_address'] else: port_dns_records[fqdn] += " " + dns_assignment['ip_address'] + # Add reverse DNS enteries for port only for fqdn + for ip in port_dns_records[fqdn].split(" "): + ptr_record = netaddr.IPAddress(ip).reverse_dns.rstrip(".") + port_dns_records[ptr_record] = fqdn return port_dns_records @@ -2288,14 +2292,18 @@ class OVNClient(object): net_dns_domain = net.get('dns_domain', '').rstrip('.') hostnames = [] + ips = [] for dns_assignment in port['dns_assignment']: hostname = dns_assignment['hostname'] fqdn = dns_assignment['fqdn'].rstrip('.') + ip = dns_assignment['ip_address'] if hostname not in hostnames: hostnames.append(hostname) net_dns_fqdn = hostname + '.' + net_dns_domain if net_dns_domain and net_dns_fqdn != fqdn: hostnames.append(net_dns_fqdn) + if ip not in ips: + ips.append(ip) if fqdn not in hostnames: hostnames.append(fqdn) @@ -2304,3 +2312,8 @@ class OVNClient(object): if ls_dns_record.records.get(hostname): txn.add(self._nb_idl.dns_remove_record( ls_dns_record.uuid, hostname, if_exists=True)) + for ip in ips: + ptr_record = netaddr.IPAddress(ip).reverse_dns.rstrip(".") + if ls_dns_record.records.get(ptr_record): + txn.add(self._nb_idl.dns_remove_record( + ls_dns_record.uuid, ptr_record, if_exists=True)) diff --git a/neutron/tests/functional/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_ovn_db_resources.py b/neutron/tests/functional/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_ovn_db_resources.py index e8a9fdafa8c..558a11ac849 100644 --- a/neutron/tests/functional/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_ovn_db_resources.py +++ b/neutron/tests/functional/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_ovn_db_resources.py @@ -965,6 +965,9 @@ class TestDNSRecords(base.TestOVNFunctionalBase): 'records': {'n1p1': port_ips, 'n1p1.ovn.test': port_ips, 'n1p1.net-n1': port_ips}} ] + for ip in port_ips.split(" "): + p_record = netaddr.IPAddress(ip).reverse_dns.rstrip(".") + expected_dns_records[0]['records'][p_record] = 'n1p1.ovn.test' self._validate_dns_records(expected_dns_records) self._validate_ls_dns_records(n1_lswitch_name, @@ -990,6 +993,9 @@ class TestDNSRecords(base.TestOVNFunctionalBase): expected_dns_records.append( {'external_ids': {'ls_name': n2_lswitch_name}, 'records': {'n2p1': port_ips, 'n2p1.ovn.test': port_ips}}) + for ip in port_ips.split(" "): + p_record = netaddr.IPAddress(ip).reverse_dns.rstrip(".") + expected_dns_records[1]['records'][p_record] = 'n2p1.ovn.test' self._validate_dns_records(expected_dns_records) self._validate_ls_dns_records(n1_lswitch_name, [expected_dns_records[0]]) @@ -1007,6 +1013,9 @@ class TestDNSRecords(base.TestOVNFunctionalBase): expected_dns_records[0]['records']['n1p2'] = port_ips expected_dns_records[0]['records']['n1p2.ovn.test'] = port_ips expected_dns_records[0]['records']['n1p2.net-n1'] = port_ips + for ip in port_ips.split(" "): + p_record = netaddr.IPAddress(ip).reverse_dns.rstrip(".") + expected_dns_records[0]['records'][p_record] = 'n1p2.ovn.test' self._validate_dns_records(expected_dns_records) self._validate_ls_dns_records(n1_lswitch_name, [expected_dns_records[0]]) @@ -1020,6 +1029,11 @@ class TestDNSRecords(base.TestOVNFunctionalBase): res = req.get_response(self.api) self.assertEqual(200, res.status_int) expected_dns_records[0]['records'].pop('n1p1') + port_ips = " ".join([f['ip_address'] + for f in n1p1['port']['fixed_ips']]) + for ip in port_ips.split(" "): + p_record = netaddr.IPAddress(ip).reverse_dns.rstrip(".") + expected_dns_records[0]['records'].pop(p_record) expected_dns_records[0]['records'].pop('n1p1.ovn.test') expected_dns_records[0]['records'].pop('n1p1.net-n1') self._validate_dns_records(expected_dns_records) diff --git a/neutron/tests/functional/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_ovn_db_sync.py b/neutron/tests/functional/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_ovn_db_sync.py index 7678367ff1f..e9103536ecb 100644 --- a/neutron/tests/functional/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_ovn_db_sync.py +++ b/neutron/tests/functional/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_ovn_db_sync.py @@ -12,6 +12,7 @@ # License for the specific language governing permissions and limitations # under the License. +import netaddr from neutron.common.ovn import acl as acl_utils from neutron.common.ovn import constants as ovn_const from neutron.common.ovn import utils @@ -162,6 +163,9 @@ class TestOvnNbSync(base.TestOVNFunctionalBase): self.expected_dns_records[0]['records'][hname] = port_ips hname = 'n1-' + p + '.ovn.test' self.expected_dns_records[0]['records'][hname] = port_ips + for ip in port_ips.split(" "): + p_record = netaddr.IPAddress(ip).reverse_dns.rstrip(".") + self.expected_dns_records[0]['records'][p_record] = hname self.expected_ports_with_unknown_addr.append(lport_name) if p == 'p1': @@ -512,6 +516,9 @@ class TestOvnNbSync(base.TestOVNFunctionalBase): self.expected_dns_records[1]['records'][hname] = port_ips hname = 'n4-' + p + '.ovn.test' self.expected_dns_records[1]['records'][hname] = port_ips + for ip in port_ips.split(" "): + p_record = netaddr.IPAddress(ip).reverse_dns.rstrip(".") + self.expected_dns_records[1]['records'][p_record] = hname n4_port_dict[p] = port['port']['id'] self.lport_dhcp_ignored.append(port['port']['id'])