#!/usr/bin/python3 import pathlib from typing import List try: from ansible_collections.sebastian.systemd.plugins.module_utils.generic import SYSTEMD_NETWORK_CONFIG, Types from ansible_collections.sebastian.systemd.plugins.module_utils.module import SystemdUnitModule except ImportError: from plugins.module_utils.generic import SYSTEMD_NETWORK_CONFIG, Types from plugins.module_utils.module import SystemdUnitModule class Module(SystemdUnitModule): """generates an systemd-networkd link""" name = "link" module_spec = dict( argument_spec=dict( mac=Types.str(help="The Mac address of the device"), permanentmac=Types.str(help="The Permanent Mac address advertised by the device"), path=Types.str(help="A shell-style glob matching the persistent path, as exposed by the udev property ID_PATH."), driver=Types.str(help="A glob matching the driver currently bound to the device"), type=Types.str(help="A glob matching the device type, as exposed by networkctl list"), kind=Types.str(help="a glob matching the device kind, as exposed by networkctl status INTERFACE or ip -d link show INTERFACE."), 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 = "\n".join((self.match(), self.link())) return self.__unit def match(self) -> str: options = [] if self.get("mac", False): options.append("MACAddress={}\n".format(self.get("mac", False))) if self.get("permanentmac", False): options.append("PermanentAddress={}\n".format(self.get("permanentmac", False))) if self.get("path", False): options.append("Path={}\n".format(self.get("path", False))) if self.get("driver", False): options.append("Driver={}\n".format(self.get("driver", False))) if self.get("type", False): options.append("Type={}\n".format(self.get("type", False))) if self.get("kind", False): options.append("Kind={}\n".format(self.get("kind", False))) return "[Match]\n" + "".join(options) def link(self) -> 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))) 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 required: false type: str kind: description: - a glob matching the device kind, as exposed by networkctl status INTERFACE or ip -d link show INTERFACE. required: false type: str mac: description: - The Mac address of the device 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. required: false type: str permanentmac: description: - The Permanent Mac address advertised by the device 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 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()()