diff --git a/CHANGELOG.rst b/CHANGELOG.rst index ed2389a..8d953e0 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,10 +1,18 @@ ===================================== -sebastian.systemd 0.3.1 Release Notes +sebastian.systemd 0.3.2 Release Notes ===================================== .. contents:: Topics +v0.3.2 +====== + +Changelog +--------- + +added virtualization and negative matches to link and network + v0.3.1 ====== diff --git a/Makefile b/Makefile index a3f3ce0..438ff08 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,11 @@ +format: + black . + isort . + changelog: antsibull-changelog generate -docs: + +docs: format ./update_doc release: changelog docs diff --git a/changelogs/changelog.yaml b/changelogs/changelog.yaml index 37a8750..115e125 100644 --- a/changelogs/changelog.yaml +++ b/changelogs/changelog.yaml @@ -44,3 +44,7 @@ releases: changes: release_date: "2023-04-23" release_summary: "fixed runtime.yml" + 0.3.2: + changes: + release_date: "2023-07-15" + release_summary: "added virtualization and negative matches to link and network" diff --git a/plugins/module_utils/generic.py b/plugins/module_utils/generic.py index c5bd9f9..20fbe06 100644 --- a/plugins/module_utils/generic.py +++ b/plugins/module_utils/generic.py @@ -116,3 +116,10 @@ def modspec( required_if=required_if, required_by=required_by, ) + + +def format_condition(key: str, value: str) -> str: + if value[0] == "!": + value = value[1:] + key = "!" + key + return f"{key}={value}\n" diff --git a/plugins/module_utils/module.py b/plugins/module_utils/module.py index f3cef69..78da2d0 100644 --- a/plugins/module_utils/module.py +++ b/plugins/module_utils/module.py @@ -5,9 +5,9 @@ from typing import Any, Callable, ClassVar, Dict, NoReturn, Optional, Type, Type import ansible.module_utils.basic as basic try: - from ansible_collections.sebastian.systemd.plugins.module_utils.generic import AnsibleParameter, Types + from ansible_collections.sebastian.systemd.plugins.module_utils.generic import AnsibleParameter, Types, format_condition except ImportError: - from plugins.module_utils.generic import AnsibleParameter, Types + from plugins.module_utils.generic import AnsibleParameter, Types, format_condition __all__ = ( @@ -250,9 +250,9 @@ class SystemdUnitModule(AnsibleModule): if self.params[param] is not None: params = self.params[param] if isinstance(params, list): - output.extend(("{}={}\n".format(key, p) for p in params)) + output.extend((format_condition(key, p) for p in params)) else: - output.append("{}={}\n".format(key, self.params[param])) + output.append(format_condition(key, self.params[param])) return output def unitfile_gen(self): @@ -352,6 +352,7 @@ class SystemdReloadMixin: unitfile: pathlib.Path restartable: bool = True changed: bool + def post(self): if not self.changed: return diff --git a/plugins/modules/link.py b/plugins/modules/link.py index 0ef3d5b..8734111 100644 --- a/plugins/modules/link.py +++ b/plugins/modules/link.py @@ -3,10 +3,10 @@ import pathlib from typing import List try: - from ansible_collections.sebastian.systemd.plugins.module_utils.generic import SYSTEMD_NETWORK_CONFIG, Types, modspec + from ansible_collections.sebastian.systemd.plugins.module_utils.generic import SYSTEMD_NETWORK_CONFIG, Types, format_condition, modspec from ansible_collections.sebastian.systemd.plugins.module_utils.module import SystemdUnitModule except ImportError: - from plugins.module_utils.generic import SYSTEMD_NETWORK_CONFIG, Types, modspec + from plugins.module_utils.generic import SYSTEMD_NETWORK_CONFIG, Types, format_condition, modspec from plugins.module_utils.module import SystemdUnitModule @@ -16,12 +16,26 @@ class Module(SystemdUnitModule): # type: ignore name = "link" module_spec = modspec( 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."), + 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"), @@ -51,6 +65,7 @@ class Module(SystemdUnitModule): # type: ignore driver="Driver", type="Type", kind="Kind", + virtualization="Virtualization", ) return "[Match]\n" + "".join(options) @@ -115,18 +130,20 @@ options: type: list driver: description: - - A glob matching the driver currently bound to the device + - 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. + 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 + - The Mac address of the device.An ! before the value matches anything but this + value. required: false type: str mtu: @@ -151,12 +168,13 @@ options: path: description: - A shell-style glob matching the persistent path, as exposed by the udev property - ID_PATH. + 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 + - The Permanent Mac address advertised by the device. An ! before the value matches + anything but this value. required: false type: str requires: @@ -169,7 +187,13 @@ options: type: list type: description: - - A glob matching the device type, as exposed by networkctl list + - 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: diff --git a/plugins/modules/network.py b/plugins/modules/network.py index 1d57a23..7094bac 100644 --- a/plugins/modules/network.py +++ b/plugins/modules/network.py @@ -16,8 +16,9 @@ class Module(SystemdUnitModule): # type: ignore name = "network" module_spec = modspec( argument_spec=dict( - mac=Types.str(help="The MAC-Address of the device"), - device=Types.str(help="The name of the network device"), + mac=Types.str(help="The MAC-Address of the device. An ! before the value matches anything but this value."), + device=Types.str(help="The name of the network device. 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."), name=Types.str(required=True, help="name of the unit"), 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( @@ -35,7 +36,7 @@ class Module(SystemdUnitModule): # type: ignore ), ), required_if=(("defaultdns", True, ("dns",), False),), - required_one_of=(("mac", "device"),), + required_one_of=(("mac", "device", "virtualization"),), ) def prepare(self): @@ -56,11 +57,13 @@ class Module(SystemdUnitModule): # type: ignore 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) + return "[Match]\n" + "".join( + self.map_param( + mac="MACAddress", + device="Name", + virtualization="Virtualization", + ) + ) def network(self) -> str: output = "[Network]\n" @@ -140,7 +143,8 @@ options: type: str device: description: - - The name of the network device + - The name of the network device. An ! before the value matches anything but this + value. required: false type: str dns: @@ -179,7 +183,8 @@ options: type: bool mac: description: - - The MAC-Address of the device + - The MAC-Address of the device. An ! before the value matches anything but this + value. required: false type: str name: @@ -211,6 +216,11 @@ options: elements: str required: false type: list + virtualization: + description: + - The virtualization type. An ! before the value matches anything but this value. + required: false + type: str wants: default: [] description: