|
Packit Service |
0535c1 |
#
|
|
Packit Service |
0535c1 |
# Copyright (c) 2019-2020 Red Hat, Inc.
|
|
Packit Service |
0535c1 |
#
|
|
Packit Service |
0535c1 |
# This file is part of nmstate
|
|
Packit Service |
0535c1 |
#
|
|
Packit Service |
0535c1 |
# This program is free software: you can redistribute it and/or modify
|
|
Packit Service |
0535c1 |
# it under the terms of the GNU Lesser General Public License as published by
|
|
Packit Service |
0535c1 |
# the Free Software Foundation, either version 2.1 of the License, or
|
|
Packit Service |
0535c1 |
# (at your option) any later version.
|
|
Packit Service |
0535c1 |
#
|
|
Packit Service |
0535c1 |
# This program is distributed in the hope that it will be useful,
|
|
Packit Service |
0535c1 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit Service |
0535c1 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit Service |
0535c1 |
# GNU Lesser General Public License for more details.
|
|
Packit Service |
0535c1 |
#
|
|
Packit Service |
0535c1 |
# You should have received a copy of the GNU Lesser General Public License
|
|
Packit Service |
0535c1 |
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
Packit Service |
0535c1 |
#
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
from itertools import chain
|
|
Packit Service |
0535c1 |
from operator import itemgetter
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
from libnmstate import iplib
|
|
Packit Service |
0535c1 |
from libnmstate.dns import DnsState
|
|
Packit Service |
0535c1 |
from libnmstate.error import NmstateInternalError
|
|
Packit Service |
0535c1 |
from libnmstate.nm import active_connection as nm_ac
|
|
Packit Service |
0535c1 |
from libnmstate.schema import DNS
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
DNS_DEFAULT_PRIORITY_VPN = 50
|
|
Packit Service |
0535c1 |
DNS_DEFAULT_PRIORITY_OTHER = 100
|
|
Packit Service |
0535c1 |
DEFAULT_DNS_PRIORITY = 0
|
|
Packit Service |
0535c1 |
# The 40 is chose as default DHCP DNS priority is 100, and VPN DNS priority is
|
|
Packit Service |
0535c1 |
# 50, the static DNS configuration should be list before them.
|
|
Packit Service |
0535c1 |
DNS_PRIORITY_STATIC_BASE = 40
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
IPV6_ADDRESS_LENGTH = 128
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
def get_running(context):
|
|
Packit Service |
0535c1 |
dns_state = {DNS.SERVER: [], DNS.SEARCH: []}
|
|
Packit Service |
0535c1 |
for dns_conf in context.get_dns_configuration():
|
|
Packit Service |
0535c1 |
iface_name = dns_conf.get_interface()
|
|
Packit Service |
0535c1 |
for ns in dns_conf.get_nameservers():
|
|
Packit Service |
0535c1 |
if iplib.is_ipv6_link_local_addr(ns, IPV6_ADDRESS_LENGTH):
|
|
Packit Service |
0535c1 |
if not iface_name:
|
|
Packit Service |
0535c1 |
# For IPv6 link local address, the interface name should be
|
|
Packit Service |
0535c1 |
# appended also.
|
|
Packit Service |
0535c1 |
raise NmstateInternalError(
|
|
Packit Service |
0535c1 |
"Missing interface for IPv6 link-local DNS server "
|
|
Packit Service |
0535c1 |
"entry {}".format(ns)
|
|
Packit Service |
0535c1 |
)
|
|
Packit Service |
0535c1 |
ns_addr = "{}%{}".format(ns, iface_name)
|
|
Packit Service |
0535c1 |
else:
|
|
Packit Service |
0535c1 |
ns_addr = ns
|
|
Packit Service |
0535c1 |
if ns_addr not in dns_state[DNS.SERVER]:
|
|
Packit Service |
0535c1 |
dns_state[DNS.SERVER].append(ns_addr)
|
|
Packit Service |
0535c1 |
dns_domains = [
|
|
Packit Service |
0535c1 |
dns_domain
|
|
Packit Service |
0535c1 |
for dns_domain in dns_conf.get_domains()
|
|
Packit Service |
0535c1 |
if dns_domain not in dns_state[DNS.SEARCH]
|
|
Packit Service |
0535c1 |
]
|
|
Packit Service |
0535c1 |
dns_state[DNS.SEARCH].extend(dns_domains)
|
|
Packit Service |
0535c1 |
if not dns_state[DNS.SERVER] and not dns_state[DNS.SEARCH]:
|
|
Packit Service |
0535c1 |
dns_state = {}
|
|
Packit Service |
0535c1 |
return dns_state
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
def get_config(acs_and_ipv4_profiles, acs_and_ipv6_profiles):
|
|
Packit Service |
0535c1 |
dns_conf = {DNS.SERVER: [], DNS.SEARCH: []}
|
|
Packit Service |
0535c1 |
tmp_dns_confs = []
|
|
Packit Service |
0535c1 |
for ac, ip_profile in chain(acs_and_ipv6_profiles, acs_and_ipv4_profiles):
|
|
Packit Service |
0535c1 |
if not ip_profile.props.dns and not ip_profile.props.dns_search:
|
|
Packit Service |
0535c1 |
continue
|
|
Packit Service |
0535c1 |
priority = ip_profile.props.dns_priority
|
|
Packit Service |
0535c1 |
if priority == DEFAULT_DNS_PRIORITY:
|
|
Packit Service |
0535c1 |
# ^ The dns_priority in 'NetworkManager.conf' is been ignored
|
|
Packit Service |
0535c1 |
# due to the lacking of query function in libnm API.
|
|
Packit Service |
0535c1 |
if ac.get_vpn():
|
|
Packit Service |
0535c1 |
priority = DNS_DEFAULT_PRIORITY_VPN
|
|
Packit Service |
0535c1 |
else:
|
|
Packit Service |
0535c1 |
priority = DNS_DEFAULT_PRIORITY_OTHER
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
tmp_dns_confs.append(
|
|
Packit Service |
0535c1 |
{
|
|
Packit Service |
0535c1 |
"server": ip_profile.props.dns,
|
|
Packit Service |
0535c1 |
"priority": priority,
|
|
Packit Service |
0535c1 |
"search": ip_profile.props.dns_search,
|
|
Packit Service |
0535c1 |
}
|
|
Packit Service |
0535c1 |
)
|
|
Packit Service |
0535c1 |
# NetworkManager sorts the DNS entries based on various criteria including
|
|
Packit Service |
0535c1 |
# which profile was activated first when profiles are activated. Therefore
|
|
Packit Service |
0535c1 |
# the configuration does not completely define the order. To define the
|
|
Packit Service |
0535c1 |
# order in a declarative way, Nmstate only uses the priority to order the
|
|
Packit Service |
0535c1 |
# entries. Reference:
|
|
Packit Service |
0535c1 |
# https://developer.gnome.org/NetworkManager/stable/nm-settings.html#nm-settings.property.ipv4.dns-priority
|
|
Packit Service |
0535c1 |
tmp_dns_confs.sort(key=itemgetter("priority"))
|
|
Packit Service |
0535c1 |
for e in tmp_dns_confs:
|
|
Packit Service |
0535c1 |
dns_conf[DNS.SERVER].extend(e["server"])
|
|
Packit Service |
0535c1 |
dns_conf[DNS.SEARCH].extend(e["search"])
|
|
Packit Service |
0535c1 |
if not dns_conf[DNS.SERVER] and dns_conf[DNS.SEARCH]:
|
|
Packit Service |
0535c1 |
return {}
|
|
Packit Service |
0535c1 |
return dns_conf
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
def add_dns(setting_ip, dns_state):
|
|
Packit Service |
0535c1 |
priority = dns_state.get(DnsState.PRIORITY_METADATA)
|
|
Packit Service |
0535c1 |
if priority is not None:
|
|
Packit Service |
0535c1 |
setting_ip.props.dns_priority = priority + DNS_PRIORITY_STATIC_BASE
|
|
Packit Service |
0535c1 |
for server in dns_state.get(DNS.SERVER, []):
|
|
Packit Service |
0535c1 |
setting_ip.add_dns(server)
|
|
Packit Service |
0535c1 |
for search in dns_state.get(DNS.SEARCH, []):
|
|
Packit Service |
0535c1 |
setting_ip.add_dns_search(search)
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
def get_dns_config_iface_names(acs_and_ipv4_profiles, acs_and_ipv6_profiles):
|
|
Packit Service |
0535c1 |
"""
|
|
Packit Service |
0535c1 |
Return a list of interface names which hold static DNS configuration.
|
|
Packit Service |
0535c1 |
"""
|
|
Packit Service |
0535c1 |
iface_names = []
|
|
Packit Service |
0535c1 |
for ac, ip_profile in chain(acs_and_ipv6_profiles, acs_and_ipv4_profiles):
|
|
Packit Service |
0535c1 |
if ip_profile.props.dns or ip_profile.props.dns_search:
|
|
Packit Service |
0535c1 |
iface_names.append(nm_ac.ActiveConnection(nm_ac_con=ac).devname)
|
|
Packit Service |
0535c1 |
return iface_names
|