From 1a460a79dd65a7571a1ffe59df9d38c9294d0cfd Mon Sep 17 00:00:00 2001 From: Zsombor Welker <fedora@zdeqb.com> Date: Sun, 25 Apr 2021 18:55:53 +0200 Subject: [PATCH] Move systemd-resolved dbus handling into separate class --- src/systemd_resolved_docker/cli.py | 17 ++++--- .../dockerdnsconnector.py | 41 --------------- .../resolvedconnector.py | 51 +++++++++++++++++++ 3 files changed, 62 insertions(+), 47 deletions(-) create mode 100644 src/systemd_resolved_docker/resolvedconnector.py diff --git a/src/systemd_resolved_docker/cli.py b/src/systemd_resolved_docker/cli.py index 278259c..b216dfd 100644 --- a/src/systemd_resolved_docker/cli.py +++ b/src/systemd_resolved_docker/cli.py @@ -5,6 +5,7 @@ import docker import signal from systemd import daemon, journal +from systemd_resolved_docker.resolvedconnector import SystemdResolvedConnector from .dockerdnsconnector import DockerDNSConnector from .utils import find_default_docker_bridge_gateway, find_docker_dns_servers @@ -15,10 +16,9 @@ class Handler: self.log("Started daemon") def on_update(self, hosts): - os.system('resolvectl flush-caches') - message = "Refreshed - %d items (%s)" % ( len(hosts), ' '.join(["%s/%s" % (host.ip, ','.join(host.host_names)) for host in hosts])) + self.log(message) def on_stop(self): @@ -56,13 +56,18 @@ def main(): handler = Handler() handler.log("Default domain: %s, allowed domains: %s" % (default_domain, ", ".join(domains))) - connector = DockerDNSConnector(listen_addresses, listen_port, dns_server, domains, default_domain, interface, - handler, cli) - connector.start() + resolved = SystemdResolvedConnector(interface, listen_addresses, domains) + + dns_connector = DockerDNSConnector(listen_addresses, listen_port, dns_server, domains, default_domain, interface, + handler, cli) + dns_connector.start() + + resolved.register() def sig_handler(signum, frame): handler.log("Stopping - %s" % signal.Signals(signum)) - connector.stop() + resolved.unregister() + dns_connector.stop() signal.signal(signal.SIGTERM, sig_handler) signal.signal(signal.SIGINT, sig_handler) diff --git a/src/systemd_resolved_docker/dockerdnsconnector.py b/src/systemd_resolved_docker/dockerdnsconnector.py index 5cfb002..705e014 100644 --- a/src/systemd_resolved_docker/dockerdnsconnector.py +++ b/src/systemd_resolved_docker/dockerdnsconnector.py @@ -1,12 +1,8 @@ -import ipaddress import threading -from socket import AF_INET, AF_INET6 -import dbus from dnslib import A, CLASS, DNSLabel, QTYPE, RR from dnslib.proxy import ProxyResolver from dnslib.server import DNSServer -from pyroute2 import IPRoute from .dockerwatcher import DockerWatcher, DockerHost from .interceptresolver import InterceptResolver @@ -24,7 +20,6 @@ class DockerDNSConnector: self.dns_domains = dns_domains self.docker_interface = docker_interface self.handler = handler - self.resolved_registered = False self.dns_domains_globs = ['*%s' % domain if domain.startswith('.') else domain for domain in dns_domains] @@ -53,8 +48,6 @@ class DockerDNSConnector: self.handler.on_start() def stop(self): - self.update_resolved(enabled=False) - for server in self.servers: server.stop() @@ -63,39 +56,6 @@ class DockerDNSConnector: self.handler.on_stop() - def update_resolved(self, enabled=True): - if self.resolved_registered == enabled: - return - - with IPRoute() as ipr: - ifi = ipr.link_lookup(ifname=self.docker_interface) - if not ifi: - raise ValueError("Unknown interface '%s'" % self.docker_interface) - - ifindex = ifi[0] - - system_bus = dbus.SystemBus() - proxy = system_bus.get_object('org.freedesktop.resolve1', '/org/freedesktop/resolve1') - manager = dbus.Interface(proxy, 'org.freedesktop.resolve1.Manager') - - if enabled: - domains = [[domain.strip("."), True] for domain in self.dns_domains] - ips = [ - [ - AF_INET if isinstance(ip, ipaddress.IPv4Address) else AF_INET6, - ip.packed - ] - for ip in [ipaddress.ip_address(ip) for ip in self.listen_addresses] - ] - - manager.SetLinkDomains(ifindex, domains) - manager.SetLinkDNS(ifindex, ips) - manager.SetLinkDNSSEC(ifindex, "no") - else: - manager.RevertLink(ifindex) - - self.resolved_registered = enabled - def handle_hosts(self, hosts): zone = [] host_names = [] @@ -114,7 +74,6 @@ class DockerDNSConnector: host_names.append(hn) self.resolver.update(zone) - self.update_resolved(enabled=len(host_names) > 0) self.handler.on_update(mapped_hosts) diff --git a/src/systemd_resolved_docker/resolvedconnector.py b/src/systemd_resolved_docker/resolvedconnector.py new file mode 100644 index 0000000..cc9560a --- /dev/null +++ b/src/systemd_resolved_docker/resolvedconnector.py @@ -0,0 +1,51 @@ +import ipaddress +from socket import AF_INET, AF_INET6 + +import dbus + +from pyroute2 import IPRoute + + +class SystemdResolvedConnector: + def __init__(self, docker_interface, listen_addresses, dns_domains): + super().__init__() + + self.docker_interface = docker_interface + self.listen_addresses = listen_addresses + self.dns_domains = dns_domains + + self.ifindex = self.resolve_ifindex(docker_interface) + + @staticmethod + def resolve_ifindex(docker_interface): + with IPRoute() as ipr: + ifi = ipr.link_lookup(ifname=docker_interface) + if not ifi: + raise ValueError("Unknown interface '%s'" % docker_interface) + + return ifi[0] + + @staticmethod + def if_manager(): + system_bus = dbus.SystemBus() + proxy = system_bus.get_object('org.freedesktop.resolve1', '/org/freedesktop/resolve1') + return dbus.Interface(proxy, 'org.freedesktop.resolve1.Manager') + + def register(self): + domains = [[domain.strip("."), True] for domain in self.dns_domains] + ips = [ + [ + AF_INET if isinstance(ip, ipaddress.IPv4Address) else AF_INET6, + ip.packed + ] + for ip in [ipaddress.ip_address(ip) for ip in self.listen_addresses] + ] + + manager = self.if_manager() + manager.SetLinkDomains(self.ifindex, domains) + manager.SetLinkDNS(self.ifindex, ips) + manager.SetLinkDNSSEC(self.ifindex, "no") + + def unregister(self): + manager = self.if_manager() + manager.RevertLink(self.ifindex) -- GitLab