#!/usr/bin/python3 import pathlib from typing import List, Optional from ansible_module.generic import SYSTEMD_NETWORK_CONFIG, Types, joindict, modspec, systemdbool from ansible_module.module import SystemdUnitModule kinds = ( "bond", "bridge", "dummy", "wireguard", "vlan", ) matchspec = dict( host=Types.str(help="hostname of the host that is matched against"), virtualization=Types.str("Virtualization that is checked against"), kernelcmd=Types.str(help="checks an kernel commandline argument"), ) netdevspec = dict( description=Types.str(help="Description of the device"), name=Types.str(required=True, help="name of the device"), kind=Types.str(required=True, help="type of the device", choices=kinds), ) bridgespec = dict( stp=Types.bool(help="enable the stp protocol"), priority=Types.int(help="Priority of the bridge"), ) bondspec = dict( mode=Types.str( help="bonding policy", choices=("balance-rr", "active-backup", "balance-xor", "broadcast", "802.3ad", "balance-tlb", "balance-alb"), ), minlinks=Types.int(help="Specifies the minimum number of links that must be active before asserting carrier."), ) wireguardspec = dict( privatekey=Types.str(help="private key of this side of the tunnel"), privatekeyfile=Types.path(help="Path of the private key on the host."), port=Types.raw(help="Port that wireguard uses to listen for packets. the value 'auto' means that the port is automatically decided."), ) class Module(SystemdUnitModule): """Creates an netdev unit that creates an virtual devices""" name = "netdev" module_spec = modspec(argument_spec=joindict(bondspec, bridgespec, matchspec, netdevspec)) _common_args = dict( supports_check_mode=True, add_file_common_args=True, ) def prepare(self): self.__unit = None self.unitfile = SYSTEMD_NETWORK_CONFIG.joinpath(self.get("name")).with_suffix(".netdev") def unit(self): if self.__unit is None: kind = self.get("kind") parts = [self.match(), self.netdev()] if kind != "dummy": parts.append(getattr(self, kind)()) self.__unit = "\n".join(parts) return self.__unit def match(self) -> str: options = self.map_param( host="Host", kernelcmd="KernelCommandLine", virtualization="Virtualization", ) return "[Match]\n" + "".join(options) def netdev(self) -> str: options = self.map_param( description="Description", name="Name", kind="Kind", ) return "[NetDev]\n" + "".join(options) def bond(self) -> str: return "[Bond]\n" + "".join( self.map_param( mode="Mode", minlinks="MinLinks", ) ) def bridge(self) -> str: return "[Bridge]\n" + "".join( self.map_param( stp="STP", priority="Priority", ) ) def wireguard(self) -> str: port = self.get("port", False) if port not in (False, "auto") and (port < 1 or port > 65535): raise ValueError("Port must be between 0 and 65536") return "[Wireguard]\n" + "".join( self.map_param( privatekey="PrivateKey", privatekeyfile="PrivateKeyFile", port="ListenPort", ) ) def vlan(self) -> str: return "" DOCUMENTATION = """--- description: - Creates an netdev unit that creates an virtual devices module: netdev options: description: description: - Description of the device required: false type: str host: description: - hostname of the host that is matched against required: false type: str kernelcmd: description: - checks an kernel commandline argument required: false type: str kind: choices: - bond - bridge - dummy - wireguard - vlan description: - type of the device required: true type: str minlinks: description: - Specifies the minimum number of links that must be active before asserting carrier. required: false type: int mode: choices: - balance-rr - active-backup - balance-xor - broadcast - 802.3ad - balance-tlb - balance-alb description: - bonding policy required: false type: str name: description: - name of the device required: true type: str priority: description: - Priority of the bridge required: false type: int stp: description: - enable the stp protocol required: false type: bool virtualization: required: true type: str short_description: Creates an netdev unit that creates an virtual devices """ if __name__ == "__main__": Module()()