#!/usr/bin/python3 import pathlib from typing import List 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 class Module(SystemdUnitModule): """generates an systemd-networkd link""" name = "systemd_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_PATH.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: systemd_link options: description: description: - The description for the link required: false type: str 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 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 type: description: - A glob matching the device type, as exposed by networkctl list required: false type: str short_description: generates an systemd-networkd link """ if __name__ == "__main__": Module()()