2023-04-14 22:58:51 +00:00
|
|
|
import pathlib
|
|
|
|
from functools import partial
|
|
|
|
from typing import Any, Callable, Dict, Optional, Sequence, Tuple, Type, Union
|
|
|
|
|
|
|
|
__all__ = (
|
|
|
|
"Types",
|
|
|
|
"SYSTEMD_SERVICE_CONFIG",
|
|
|
|
"SYSTEMD_NETWORK_CONFIG",
|
|
|
|
"SYSTEMD_CONFIG_ROOT",
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
SYSTEMD_CONFIG_ROOT = pathlib.Path("/etc/systemd")
|
|
|
|
SYSTEMD_NETWORK_CONFIG = SYSTEMD_CONFIG_ROOT / "network"
|
|
|
|
SYSTEMD_SERVICE_CONFIG = SYSTEMD_CONFIG_ROOT / "system"
|
|
|
|
|
|
|
|
|
|
|
|
class _sdict(dict):
|
|
|
|
_help: Optional[str]
|
|
|
|
__name__: str
|
|
|
|
|
|
|
|
|
|
|
|
class _Type(type):
|
|
|
|
def __new__(metacls, cls, bases, classdict, **kwds):
|
|
|
|
individual = dict()
|
|
|
|
virtfunc = None
|
|
|
|
virtual = ()
|
|
|
|
special = dict()
|
|
|
|
for key, value in classdict.items():
|
|
|
|
if key.startswith("_"):
|
|
|
|
if key == "__getattr__":
|
|
|
|
virtfunc = value
|
2023-04-21 15:31:52 +00:00
|
|
|
special[key] = value
|
2023-04-14 22:58:51 +00:00
|
|
|
elif key == "__dir__":
|
|
|
|
virtual = tuple(value(None))
|
2023-04-21 15:31:52 +00:00
|
|
|
special[key] = value
|
|
|
|
elif key in ("__doc__", "__module__", "__qualname__"):
|
2023-04-14 22:58:51 +00:00
|
|
|
special[key] = value
|
|
|
|
else:
|
|
|
|
individual[key] = value
|
|
|
|
if len(virtual) != 0 and virtfunc is None: # pragma: nocover
|
2023-04-20 22:10:13 +00:00
|
|
|
raise TypeError("Virtual funcs defined, but no func to generate them defined")
|
2023-04-14 22:58:51 +00:00
|
|
|
special["_attr"] = tuple(virtual + tuple(individual.keys()))
|
|
|
|
special["_vfunc"] = virtfunc
|
|
|
|
special["_virtual"] = virtual
|
|
|
|
special["_individual"] = individual
|
|
|
|
annotations = dict()
|
|
|
|
if len(virtual) != 0 and virtfunc is not None: # pragma: nocover
|
|
|
|
anno = virtfunc(None, virtual[0]).__annotations__
|
|
|
|
for virtualkey in virtual:
|
|
|
|
annotations[virtualkey] = Callable[[*anno.values()], Dict[str, Any]]
|
|
|
|
annotations["__dir__"] = Callable[[], Tuple[str]]
|
|
|
|
special["__annotations__"] = annotations
|
|
|
|
inst = super().__new__(metacls, cls, bases, special, **kwds)
|
|
|
|
return inst
|
|
|
|
|
|
|
|
def __getattribute__(self, __name: str) -> Any:
|
|
|
|
if __name in (
|
|
|
|
"__dict__",
|
|
|
|
"__doc__",
|
|
|
|
"_attr",
|
|
|
|
"__annotations__",
|
|
|
|
"_virtual",
|
|
|
|
"_vfunc",
|
|
|
|
"_individual",
|
|
|
|
):
|
|
|
|
return super().__getattribute__(__name)
|
|
|
|
if __name in self._virtual:
|
|
|
|
return self._vfunc(self, __name)
|
|
|
|
if __name in self._individual:
|
|
|
|
return partial(self._individual[__name], self)
|
2023-04-21 15:31:52 +00:00
|
|
|
return super().__getattribute__(__name)
|
2023-04-14 22:58:51 +00:00
|
|
|
|
2023-04-20 21:08:43 +00:00
|
|
|
def __dir__(self):
|
|
|
|
data = set()
|
|
|
|
data.update(("__dir__", "__doc__", "__annotations__"))
|
|
|
|
data.update(self._virtual)
|
|
|
|
data.update(self._individual.keys())
|
|
|
|
return tuple(data)
|
|
|
|
|
2023-04-14 22:58:51 +00:00
|
|
|
|
|
|
|
class Types(metaclass=_Type):
|
|
|
|
"""Provides helpers for the ansible types"""
|
|
|
|
|
2023-04-20 21:08:43 +00:00
|
|
|
@staticmethod
|
2023-04-14 22:58:51 +00:00
|
|
|
def list(
|
|
|
|
self,
|
|
|
|
elements: Union[Type[object], str],
|
|
|
|
required: bool = False,
|
|
|
|
help: Optional[str] = None,
|
|
|
|
) -> dict:
|
|
|
|
if not isinstance(elements, str):
|
|
|
|
elements = elements.__name__
|
|
|
|
option = _sdict(type="list", elements=elements, required=required)
|
|
|
|
option._help = help
|
|
|
|
return option
|
|
|
|
|
|
|
|
def __dir__(self) -> tuple:
|
|
|
|
return (
|
|
|
|
"str",
|
|
|
|
"dict",
|
|
|
|
"bool",
|
|
|
|
"int",
|
|
|
|
"float",
|
|
|
|
"path",
|
|
|
|
"raw",
|
|
|
|
"jsonarg",
|
|
|
|
"json",
|
|
|
|
"bytes",
|
|
|
|
"bits",
|
|
|
|
)
|
|
|
|
|
|
|
|
def __getattr__(self, name: str):
|
|
|
|
def argument(
|
|
|
|
required: bool = False,
|
|
|
|
help: Optional[str] = None,
|
|
|
|
choices: Optional[Sequence] = None,
|
|
|
|
default: Optional[Any] = None,
|
|
|
|
):
|
2023-04-21 15:31:52 +00:00
|
|
|
"""Simple wrapper for Ansible {0} argument dict"""
|
2023-04-14 22:58:51 +00:00
|
|
|
output = _sdict(type=name, required=required)
|
|
|
|
if choices is not None:
|
|
|
|
output["choices"] = choices
|
|
|
|
if default is not None:
|
|
|
|
output["default"] = default
|
|
|
|
output._help = help
|
|
|
|
return output
|
|
|
|
|
|
|
|
argument.__name__ = name
|
2023-04-21 15:31:52 +00:00
|
|
|
argument.__doc__ = argument.__doc__.format(name)
|
2023-04-14 22:58:51 +00:00
|
|
|
return argument
|