#!/usr/bin/python3 import pathlib from typing import List, Optional try: from ansible_module.module_utils.generic import SYSTEMD_NETWORK_CONFIG, Types, modspec from ansible_module.module_utils.module import SystemdUnitModule except ImportError: from ansible_collections.sebastian.base.plugins.module_utils.generic import SYSTEMD_NETWORK_CONFIG, Types, modspec from ansible_collections.sebastian.base.plugins.module_utils.module import SystemdUnitModule class Module(SystemdUnitModule): # type: ignore """generates an systemd-networkd link""" name = "link" module_spec = modspec( argument_spec=dict( mac=Types.str(help="The Mac address of the device." "An ! before the value matches anything but this value."), permanentmac=Types.str( help="The Permanent Mac address advertised by the device. " "An ! before the value matches anything but this value." ), path=Types.str( help="A shell-style glob matching the persistent path, as exposed by the udev property ID_PATH. " "An ! before the value matches anything but this value." ), driver=Types.str( help="A glob matching the driver currently bound to the device. " "An ! before the value matches anything but this value." ), type=Types.str( help="A glob matching the device type, as exposed by networkctl list. " "An ! before the value matches anything but this value." ), kind=Types.str( help="a glob matching the device kind, as exposed by networkctl status INTERFACE or ip -d link show INTERFACE. " "An ! before the value matches anything but this value." ), virtualization=Types.str(help="The virtualization type. An ! before the value matches anything but this value."), description=Types.str(help="The description for the link"), name=Types.str(required=True, help="The new name of the device"), mtu=Types.int(help="The maximum Transmission unit for the link"), ), required_one_of=( ("mac", "permanentmac", "path", "driver", "type", "kind"), ("name", "mac", "permanentmac"), ), ) def prepare(self): self.__unit = None newname = self.get("name", "") or self.get("mac", "") or self.get("permanentmac", "") newname = newname.replace(":", "").replace("/", "-").lower() self.unitfile = SYSTEMD_NETWORK_CONFIG.joinpath("50-" + newname).with_suffix(".link") def unit(self) -> str: if self.__unit is None: self.__unit = self._unit(self.match(), self.link()) return self.__unit def match(self) -> Optional[str]: options = self.map_param( mac="MACAddress", permanentmac="PermanentAddress", path="Path", driver="Driver", type="Type", kind="Kind", virtualization="Virtualization", ) if len(options) == 0: return None return "[Match]\n" + "".join(options) def link(self) -> Optional[str]: options = [] if self.get("description", False): options.append("Description={}\n".format(self.get("description", False))) if self.get("name", False): options.append("Name={}\n".format(self.get("name", False))) if self.get("mtu", False): options.append("MTUBytes={}\n".format(self.get("mtu", False))) if len(options) == 0: return None return "[Link]\n" + "".join(options) def post(self): if not self.changed: return args = [ "/usr/bin/udevadm", "trigger", "-c", "add", ] if self.module.check_mode: args.append("-n") if self.get("mac", False): args.append("--attr-match=address={}".format(self.get("mac"))) if self.get("path", False): args.append(self.get("path")) self.module.run_command(args, check_rc=True) DOCUMENTATION = """--- description: - generates an systemd-networkd link module: link options: after: default: [] description: - list of units that this unit wants to be started after this unit elements: str required: false type: list before: default: [] description: - list of units that this unit needs to be started before this unit. elements: str required: false type: list description: description: - The description for the link required: false type: str documentation: default: [] description: - Paths where documentation can be found elements: str required: false type: list driver: description: - A glob matching the driver currently bound to the device. An ! before the value matches anything but this value. required: false type: str kind: description: - a glob matching the device kind, as exposed by networkctl status INTERFACE or ip -d link show INTERFACE. An ! before the value matches anything but this value. required: false type: str mac: description: - The Mac address of the device.An ! before the value matches anything but this value. required: false type: str mtu: description: - The maximum Transmission unit for the link required: false type: int name: description: - The new name of the device required: true type: str partof: default: [] description: - list of units that this unit is part of. - If the restart this unit does it too, but if this restarts it does not affect the other units. elements: str required: false type: list path: description: - A shell-style glob matching the persistent path, as exposed by the udev property ID_PATH. An ! before the value matches anything but this value. required: false type: str permanentmac: description: - The Permanent Mac address advertised by the device. An ! before the value matches anything but this value. required: false type: str requires: default: [] description: - list of units that this unit requires. If it fails or can't be started this unit fails. without before/after this is started at the same time elements: str required: false type: list type: description: - A glob matching the device type, as exposed by networkctl list. An ! before the value matches anything but this value. required: false type: str virtualization: description: - The virtualization type. An ! before the value matches anything but this value. required: false type: str wants: default: [] description: - list of units that this unit wants. If it fails or can't be started it does not affect this unit elements: str required: false type: list short_description: generates an systemd-networkd link """ if __name__ == "__main__": Module()()