185 Zeilen
5.6 KiB
Python
185 Zeilen
5.6 KiB
Python
#!/usr/bin/python3
|
|
import pathlib
|
|
from typing import List, Union
|
|
|
|
try:
|
|
from ansible.module_utils.generic import SYSTEMD_NETWORK_CONFIG as SYSTEMD_PATH
|
|
from ansible.module_utils.generic import Types
|
|
from ansible.module_utils.module import SystemdUnitModule
|
|
except ImportError:
|
|
from module_utils.generic import SYSTEMD_NETWORK_CONFIG as SYSTEMD_PATH
|
|
from module_utils.generic import Types
|
|
from module_utils.module import SystemdUnitModule
|
|
|
|
def boolconvert(b: Union[bool, str]) -> str:
|
|
if b is True:
|
|
return "yes"
|
|
elif b is False:
|
|
return "no"
|
|
return b
|
|
|
|
|
|
class Module(SystemdUnitModule):
|
|
"""Sets up the systemd network unit"""
|
|
|
|
name = "systemd_network"
|
|
module_spec = dict(
|
|
argument_spec=dict(
|
|
mac=Types.str(help="The MAC-Address of the device"),
|
|
device=Types.str(help="The name of the network device"),
|
|
name=Types.str(required=True, help="name of the unit"),
|
|
description=Types.str(help="An optional description"),
|
|
dot=Types.bool(help="if DNS-over-TLS should be required or disabled. If it is unset, it will used if the server supports it"),
|
|
dnssec=Types.bool("if the Domainqueries should require DNSSEC or not. If its missing, domains that have DNSSEC enabled will be validated, all others it will be assumed to be okay."),
|
|
dns=Types.list(elements=str, help="List of DNS-Servers"),
|
|
domain=Types.list(elements=str, help="List of domains that are on this device"),
|
|
defaultdns=Types.bool(help="If the DNS-Server(s) on this device should be used for all domains that are not set on other devices"),
|
|
address=Types.list(elements=str, required=True, help="IP-Addresses of this networkdevice"),
|
|
route=Types.list(elements=str, help="Routes of networks that can be reached with this device"),
|
|
),
|
|
required_if=(("defaultdns", True, ("dns",), False),),
|
|
required_one_of=(("mac", "device"),),
|
|
)
|
|
|
|
def prepare(self):
|
|
self.unitfile = SYSTEMD_PATH.joinpath(self.get("name")).with_suffix(".network")
|
|
self.__unit = None
|
|
|
|
def unit(self) -> str:
|
|
if self.__unit is None:
|
|
self.__unit = "\n".join(
|
|
(
|
|
self.match(),
|
|
self.network(),
|
|
self.addresses(),
|
|
self.routes(),
|
|
)
|
|
)
|
|
return self.__unit
|
|
|
|
def match(self) -> str:
|
|
matches = []
|
|
if self.get("mac", False):
|
|
matches.append("MACAddress={}\n".format(self.get("mac")))
|
|
if self.get("device", False):
|
|
matches.append("Name={}\n".format(self.get("device")))
|
|
return "[Match]\n" + "".join(matches)
|
|
|
|
def network(self) -> str:
|
|
output = "[Network]\n"
|
|
options = []
|
|
try:
|
|
options.append("Description={}".format(self.get("description")))
|
|
except KeyError:
|
|
pass
|
|
try:
|
|
for server in self.get("dns", []):
|
|
options.append(f"DNS={server}")
|
|
options.append("DNSDefaultRoute={}".format(self.get("defaultdns", False)))
|
|
except KeyError:
|
|
pass
|
|
try:
|
|
domain = self.get("domain")
|
|
self.set("domainlog", str(domain))
|
|
options.append("Domains={}".format(" ".join(domain)))
|
|
options.append(
|
|
"DNSOverTLS={}".format(boolconvert(self.get("dot", "opportunistic")))
|
|
)
|
|
options.append(
|
|
"DNSSEC={}".format(boolconvert(self.get("dnssec", "allow-downgrade")))
|
|
)
|
|
except KeyError:
|
|
pass
|
|
output += "\n".join(options)
|
|
return output
|
|
|
|
def addresses(self) -> str:
|
|
output = []
|
|
for address in self.get("address"):
|
|
output.append(f"[Address]\nAddress={address}\n")
|
|
return "\n".join(output)
|
|
|
|
def routes(self) -> str:
|
|
output = []
|
|
routes = self.get("route", [])
|
|
self.set("routes", routes)
|
|
for gw in routes:
|
|
output.append(f"[Route]\nGateway={gw}\nGatewayOnLink=yes\nQuickAck=yes\n")
|
|
self.set("routes", output)
|
|
return "\n".join(output)
|
|
|
|
|
|
DOCUMENTATION = """---
|
|
description:
|
|
- Sets up the systemd network unit
|
|
module: systemd_network
|
|
options:
|
|
address:
|
|
description:
|
|
- IP-Addresses of this networkdevice
|
|
elements: str
|
|
required: true
|
|
type: list
|
|
defaultdns:
|
|
description:
|
|
- If the DNS-Server(s) on this device should be used for all domains that are
|
|
not set on other devices
|
|
required: false
|
|
type: bool
|
|
description:
|
|
description:
|
|
- An optional description
|
|
required: false
|
|
type: str
|
|
device:
|
|
description:
|
|
- The name of the network device
|
|
required: false
|
|
type: str
|
|
dns:
|
|
default: []
|
|
description:
|
|
- List of DNS-Servers
|
|
elements: str
|
|
required: false
|
|
type: list
|
|
dnssec:
|
|
required: true
|
|
type: bool
|
|
domain:
|
|
default: []
|
|
description:
|
|
- List of domains that are on this device
|
|
elements: str
|
|
required: false
|
|
type: list
|
|
dot:
|
|
description:
|
|
- if DNS-over-TLS should be required or disabled. If it is unset, it will used
|
|
if the server supports it
|
|
required: false
|
|
type: bool
|
|
mac:
|
|
description:
|
|
- The MAC-Address of the device
|
|
required: false
|
|
type: str
|
|
name:
|
|
description:
|
|
- name of the unit
|
|
required: true
|
|
type: str
|
|
route:
|
|
default: []
|
|
description:
|
|
- Routes of networks that can be reached with this device
|
|
elements: str
|
|
required: false
|
|
type: list
|
|
short_description: Sets up the systemd network unit
|
|
"""
|
|
|
|
|
|
if __name__ == "__main__":
|
|
Module()()
|