nm: Find interfaces with default gateway for DNS configuration

Find interfaces with IPv4/IPv6 default gateway for desired DNS
configuration via `nm.dns.find_interfaces_for_dns_conf()`.

Introduce `nm.dns.DNS_PRIORITY_STATIC_BASE` for the DNS priority
on the first name server, the dns priority for remaining name server
could be increase 1 from it.

Signed-off-by: Gris Ge <fge@redhat.com>
This commit is contained in:
Gris Ge 2019-06-13 15:34:42 +08:00
parent 665ed8bf18
commit 4f11dccd4f
3 changed files with 126 additions and 1 deletions

View File

@ -21,7 +21,9 @@ from libnmstate import iplib
from libnmstate.error import NmstateInternalError
from libnmstate.nm import nmclient
from libnmstate.nm import active_connection as nm_ac
from libnmstate.nm import route as nm_route
from libnmstate.schema import DNS
from libnmstate.schema import Interface
DNS_DEFAULT_PRIORITY_VPN = 50
@ -29,6 +31,9 @@ DNS_DEFAULT_PRIORITY_OTHER = 100
DNS_METADATA = '_dns'
DNS_METADATA_PRIORITY = '_priority'
DEFAULT_DNS_PRIORITY = 0
# The 40 is chose as default DHCP DNS priority is 100, and VPN DNS priority is
# 50, the static DNS configuration should be list before them.
DNS_PRIORITY_STATIC_BASE = 40
IPV6_ADDRESS_LENGTH = 128
@ -118,3 +123,14 @@ def get_dns_config_iface_names(acs_and_ipv4_profiles, acs_and_ipv6_profiles):
if ip_profile.props.dns or ip_profile.props.dns_search:
iface_names.append(nm_ac.ActiveConnection(ac).devname)
return iface_names
def find_interfaces_for_name_servers(iface_routes):
"""
Find interfaces to store the DNS configurations:
* Interface with static gateway configured.
Return two interface names for IPv4 and IPv6 name servers.
The interface name will be None if failed to find proper interface.
"""
return (nm_route.get_static_gateway_iface(Interface.IPV4, iface_routes),
nm_route.get_static_gateway_iface(Interface.IPV6, iface_routes))

View File

@ -18,11 +18,14 @@
from operator import itemgetter
import socket
import six
from libnmstate import iplib
from libnmstate.error import NmstateInternalError
from libnmstate.error import NmstateNotImplementedError
from libnmstate.nm import nmclient
from libnmstate.nm import active_connection as nm_ac
from libnmstate.schema import Interface
from libnmstate.schema import Route
NM_ROUTE_TABLE_ATTRIBUTE = 'table'
@ -178,3 +181,18 @@ def _add_route_gateway(setting_ip, route):
Route.USE_DEFAULT_ROUTE_TABLE)
setting_ip.props.route_metric = route.get(Route.METRIC,
Route.USE_DEFAULT_METRIC)
def get_static_gateway_iface(family, iface_routes):
"""
Return one interface with gateway for given IP family.
Return None if not found.
"""
destination = (IPV6_DEFAULT_GATEWAY_DESTINATION
if family == Interface.IPV6
else IPV4_DEFAULT_GATEWAY_DESTINATION)
for iface_name, routes in six.viewitems(iface_routes):
for route in routes:
if route[Route.DESTINATION] == destination:
return iface_name
return None

View File

@ -17,11 +17,17 @@
import pytest
from libnmstate.schema import DNS
import libnmstate.nm.connection as nm_connection
import libnmstate.nm.dns as nm_dns
import libnmstate.nm.ipv4 as nm_ipv4
import libnmstate.nm.ipv6 as nm_ipv6
from libnmstate.schema import DNS
from libnmstate.schema import Route
TEST_IPV4_GATEWAY_IFACE = 'eth1'
TEST_IPV6_GATEWAY_IFACE = 'eth2'
TEST_STATIC_ROUTE_IFACE = 'eth3'
def _get_test_dns_v4():
@ -124,3 +130,88 @@ def _assert_dns(setting_ip, dns_conf):
priority = dns_conf.get(nm_dns.DNS_METADATA_PRIORITY,
nm_dns.DEFAULT_DNS_PRIORITY)
assert setting_ip.props.dns_priority == priority
def test_find_interfaces_for_dns_with_ipv6_and_ipv4_static_gateways():
iface_routes = _get_test_iface_routes()
assert ((TEST_IPV4_GATEWAY_IFACE, TEST_IPV6_GATEWAY_IFACE) ==
nm_dns.find_interfaces_for_name_servers(iface_routes))
def test_find_interfaces_for_dns_with_ipv6_static_gateway_only():
iface_routes = {
TEST_IPV6_GATEWAY_IFACE: _get_test_ipv6_gateway(),
TEST_STATIC_ROUTE_IFACE: _get_test_static_routes()
}
assert ((None, TEST_IPV6_GATEWAY_IFACE) ==
nm_dns.find_interfaces_for_name_servers(iface_routes))
def test_find_interfaces_for_dns_with_ipv4_static_gateway_only():
iface_routes = {
TEST_IPV4_GATEWAY_IFACE: _get_test_ipv4_gateway(),
TEST_STATIC_ROUTE_IFACE: _get_test_static_routes()
}
assert ((TEST_IPV4_GATEWAY_IFACE, None) ==
nm_dns.find_interfaces_for_name_servers(iface_routes))
def test_find_interfaces_for_dns_with_no_routes():
iface_routes = {}
assert ((None, None) ==
nm_dns.find_interfaces_for_name_servers(iface_routes))
def test_find_interfaces_for_dns_with_no_gateway():
iface_routes = {
TEST_STATIC_ROUTE_IFACE: _get_test_static_routes()
}
assert ((None, None) ==
nm_dns.find_interfaces_for_name_servers(iface_routes))
def _get_test_ipv4_gateway():
return [{
Route.DESTINATION: '0.0.0.0/0',
Route.METRIC: 200,
Route.NEXT_HOP_ADDRESS: '192.0.2.1',
Route.NEXT_HOP_INTERFACE: TEST_IPV4_GATEWAY_IFACE,
Route.TABLE_ID: 54
}]
def _get_test_ipv6_gateway():
return [{
Route.DESTINATION: '::/0',
Route.METRIC: 201,
Route.NEXT_HOP_ADDRESS: '2001:db8:2::f',
Route.NEXT_HOP_INTERFACE: TEST_IPV6_GATEWAY_IFACE,
Route.TABLE_ID: 54
}]
def _get_test_static_routes():
return [
{
Route.DESTINATION: '2001:db8:3::1',
Route.METRIC: 201,
Route.NEXT_HOP_ADDRESS: '2001:db8:2::f',
Route.NEXT_HOP_INTERFACE: TEST_STATIC_ROUTE_IFACE,
Route.TABLE_ID: 54
},
{
Route.DESTINATION: '198.51.100.0/24',
Route.METRIC: 201,
Route.NEXT_HOP_ADDRESS: '192.0.2.1',
Route.NEXT_HOP_INTERFACE: TEST_STATIC_ROUTE_IFACE,
Route.TABLE_ID: 54
}
]
def _get_test_iface_routes():
return {
TEST_IPV4_GATEWAY_IFACE: _get_test_ipv4_gateway(),
TEST_IPV6_GATEWAY_IFACE: _get_test_ipv6_gateway(),
TEST_STATIC_ROUTE_IFACE: _get_test_static_routes(),
}