updates the Module classes with documentation and deduplicated some code
Dieser Commit ist enthalten in:
Ursprung
aa0723809a
Commit
e3a4c894ea
|
@ -1,5 +1,5 @@
|
||||||
import pathlib
|
import pathlib
|
||||||
from typing import Any, Callable, ClassVar, Dict, Optional, TypeVar
|
from typing import Any, Callable, ClassVar, Dict, Optional, TypeVar, NoReturn, overload
|
||||||
|
|
||||||
import ansible.module_utils.basic as basic
|
import ansible.module_utils.basic as basic
|
||||||
from ansible.module_utils.generic import _sdict
|
from ansible.module_utils.generic import _sdict
|
||||||
|
@ -14,17 +14,24 @@ T = TypeVar("T")
|
||||||
|
|
||||||
|
|
||||||
class AnsibleModule(object):
|
class AnsibleModule(object):
|
||||||
"""Simple wrapper for the mo"""
|
"""Simple wrapper for the basic.AnsibleModule"""
|
||||||
|
|
||||||
|
#: name of the module. This is required for the generation of the Ansible documentation
|
||||||
name: ClassVar[str]
|
name: ClassVar[str]
|
||||||
|
#: The AnsibleModule for this Module
|
||||||
module: basic.AnsibleModule
|
module: basic.AnsibleModule
|
||||||
|
#: TODO
|
||||||
msg: str
|
msg: str
|
||||||
|
#: The result of this Module call. It always contains the changed key, so in any case an Module can report if it changed anything
|
||||||
result: dict
|
result: dict
|
||||||
|
#: the specification of the arguments. Subclasses that are usable Modules must set this value.
|
||||||
module_spec: ClassVar[dict]
|
module_spec: ClassVar[dict]
|
||||||
|
#: This is set by classes that define common things for their subclasses, like behaviour of the run and check methods. This is used by `SystemdUnitModule`
|
||||||
_common_args = dict()
|
_common_args = dict()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def params(self) -> Dict[str, Any]:
|
def params(self) -> Dict[str, Any]:
|
||||||
|
"""params is an wrapper for the module.params"""
|
||||||
return self.module.params # type: ignore
|
return self.module.params # type: ignore
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
@ -37,17 +44,26 @@ class AnsibleModule(object):
|
||||||
self.tmpdir = pathlib.Path(self.module.tmpdir)
|
self.tmpdir = pathlib.Path(self.module.tmpdir)
|
||||||
|
|
||||||
def set(self, key: str, value):
|
def set(self, key: str, value):
|
||||||
|
"""sets an value for the result"""
|
||||||
self.result[key] = value
|
self.result[key] = value
|
||||||
|
|
||||||
|
@overload
|
||||||
|
def diff(self, diff: Dict[str, str]):
|
||||||
|
pass
|
||||||
|
|
||||||
def diff(
|
def diff(
|
||||||
self,
|
self,diff: Optional[Dict[str, str]] = None,*,
|
||||||
before,
|
before: Optional[str] = None,
|
||||||
after,
|
after: Optional[str] = None,
|
||||||
before_header: Optional[str] = None,
|
before_header: Optional[str] = None,
|
||||||
after_header: Optional[str] = None,
|
after_header: Optional[str] = None,
|
||||||
):
|
):
|
||||||
|
"""adds the special return value "diff". This allows Modules to present the changes of files to the caller. it takes care of the special semantics of the return value"""
|
||||||
if "diff" not in self.result:
|
if "diff" not in self.result:
|
||||||
self.result["diff"] = list()
|
self.result["diff"] = list()
|
||||||
|
if diff is not None and not any((before is not None, after is not None)):
|
||||||
|
pass
|
||||||
|
elif all((before is not None, after is not None, diff is None)):
|
||||||
diff = dict(
|
diff = dict(
|
||||||
before=before,
|
before=before,
|
||||||
after=after,
|
after=after,
|
||||||
|
@ -56,9 +72,12 @@ class AnsibleModule(object):
|
||||||
diff["before_header"] = before_header
|
diff["before_header"] = before_header
|
||||||
if after_header is not None:
|
if after_header is not None:
|
||||||
diff["after_header"] = after_header
|
diff["after_header"] = after_header
|
||||||
|
else:
|
||||||
|
raise TypeError("only diff or before and after can be set, not both of them")
|
||||||
self.result["diff"].append(diff)
|
self.result["diff"].append(diff)
|
||||||
|
|
||||||
def get(self, key: str, default: T = None) -> T:
|
def get(self, key: str, default: T = None) -> T:
|
||||||
|
"""returns an Parameter of the Module."""
|
||||||
if key not in self.params.keys():
|
if key not in self.params.keys():
|
||||||
return default
|
return default
|
||||||
if self.params[key] is None and default is not None:
|
if self.params[key] is None and default is not None:
|
||||||
|
@ -69,10 +88,12 @@ class AnsibleModule(object):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def changed(self):
|
def changed(self):
|
||||||
|
"""returns if changes were detected/made"""
|
||||||
return self.result["changed"]
|
return self.result["changed"]
|
||||||
|
|
||||||
@changed.setter
|
@changed.setter
|
||||||
def changed_set(self, value):
|
def changed_set(self, value):
|
||||||
|
"""sets the changed value. this is always converted to bool"""
|
||||||
self.result["changed"] = not not value
|
self.result["changed"] = not not value
|
||||||
|
|
||||||
def prepare(self):
|
def prepare(self):
|
||||||
|
@ -84,7 +105,9 @@ class AnsibleModule(object):
|
||||||
def run(self):
|
def run(self):
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
def __call__(self):
|
def __call__(self) -> NoReturn:
|
||||||
|
"""This calls the module. first prepare is called and then check or run, depending on the check mode.
|
||||||
|
If an exception is raised this is catched and the module automatically fails with an traceback"""
|
||||||
self.prepare()
|
self.prepare()
|
||||||
try:
|
try:
|
||||||
if self.module.check_mode:
|
if self.module.check_mode:
|
||||||
|
@ -102,6 +125,7 @@ class AnsibleModule(object):
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def doc(cls) -> str:
|
def doc(cls) -> str:
|
||||||
|
"""this returns the documentation string of the module. If the help arguments of an Types method was given, it adds this as an helptext of this parameter"""
|
||||||
try:
|
try:
|
||||||
import yaml
|
import yaml
|
||||||
except ImportError:
|
except ImportError:
|
||||||
|
@ -145,11 +169,14 @@ class AnsibleModule(object):
|
||||||
|
|
||||||
|
|
||||||
class SystemdUnitModule(AnsibleModule):
|
class SystemdUnitModule(AnsibleModule):
|
||||||
|
#: path of the unitfile managed by this module
|
||||||
unitfile: pathlib.Path
|
unitfile: pathlib.Path
|
||||||
|
#: subclasses of this always support the file common args and the check mode
|
||||||
_common_args = dict(
|
_common_args = dict(
|
||||||
supports_check_mode=True,
|
supports_check_mode=True,
|
||||||
add_file_common_args=True,
|
add_file_common_args=True,
|
||||||
)
|
)
|
||||||
|
#: if defined it will be called after run has changed the unitfile
|
||||||
post: Optional[Callable[[], None]]
|
post: Optional[Callable[[], None]]
|
||||||
|
|
||||||
def unit(self) -> str:
|
def unit(self) -> str:
|
||||||
|
@ -163,55 +190,50 @@ class SystemdUnitModule(AnsibleModule):
|
||||||
self.module.set_group_if_different(path.as_posix(), "root", False)
|
self.module.set_group_if_different(path.as_posix(), "root", False)
|
||||||
self.module.set_mode_if_different(path.as_posix(), "0644", False)
|
self.module.set_mode_if_different(path.as_posix(), "0644", False)
|
||||||
if self.unitfile.exists():
|
if self.unitfile.exists():
|
||||||
if "diff" not in self.result:
|
|
||||||
self.result["diff"] = list()
|
|
||||||
diff = dict()
|
diff = dict()
|
||||||
self.result["changed"] = self.module.set_owner_if_different(
|
self.changed = self.changed | self.module.set_owner_if_different(
|
||||||
self.unitfile.as_posix(),
|
self.unitfile.as_posix(),
|
||||||
"root",
|
"root",
|
||||||
self.result["changed"],
|
self.result["changed"],
|
||||||
diff,
|
diff,
|
||||||
)
|
)
|
||||||
self.result["changed"] = self.module.set_group_if_different(
|
self.diff(diff)
|
||||||
|
diff = dict()
|
||||||
|
self.changed = self.changed | self.module.set_group_if_different(
|
||||||
self.unitfile.as_posix(),
|
self.unitfile.as_posix(),
|
||||||
"root",
|
"root",
|
||||||
self.result["changed"],
|
self.result["changed"],
|
||||||
diff,
|
diff,
|
||||||
)
|
)
|
||||||
self.result["changed"] = self.module.set_mode_if_different(
|
self.diff(diff)
|
||||||
|
diff = dict()
|
||||||
|
self.changed = self.changed | self.module.set_mode_if_different(
|
||||||
self.unitfile.as_posix(),
|
self.unitfile.as_posix(),
|
||||||
"0644",
|
"0644",
|
||||||
self.result["changed"],
|
self.result["changed"],
|
||||||
diff,
|
diff,
|
||||||
)
|
)
|
||||||
self.result["diff"].append(diff)
|
self.diff(diff)
|
||||||
|
|
||||||
def check(self):
|
def check(self):
|
||||||
if "changed" in self.result:
|
|
||||||
changed = self.result["changed"]
|
|
||||||
else:
|
|
||||||
changed = False
|
|
||||||
self.unitfile_gen()
|
self.unitfile_gen()
|
||||||
if not self.unitfile.exists():
|
if not self.unitfile.exists():
|
||||||
self.diff("", self.unit(), self.unitfile.as_posix())
|
self.diff(before="", after=self.unit(), before_header=self.unitfile.as_posix())
|
||||||
changed = True
|
self.changed = True
|
||||||
else:
|
else:
|
||||||
if self.module.sha256(self.unitfile.as_posix()) != self.module.sha256(
|
if self.module.sha256(self.unitfile.as_posix()) != self.module.sha256(
|
||||||
(self.tmpdir / "newunit").as_posix()
|
(self.tmpdir / "newunit").as_posix()
|
||||||
):
|
):
|
||||||
changed = True
|
self.changed = True
|
||||||
self.diff(
|
self.diff(
|
||||||
before=self.unitfile.read_text(),
|
before=self.unitfile.read_text(),
|
||||||
after=self.unit(),
|
after=self.unit(),
|
||||||
before_header=self.unitfile.as_posix(),
|
before_header=self.unitfile.as_posix(),
|
||||||
)
|
)
|
||||||
self.set("changed", changed)
|
|
||||||
if hasattr(self, "post") and self.post is not None:
|
|
||||||
self.post()
|
|
||||||
return changed
|
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
if not self.check():
|
self.check()
|
||||||
|
if not self.changed:
|
||||||
return
|
return
|
||||||
self.module.atomic_move(
|
self.module.atomic_move(
|
||||||
src=(self.tmpdir / "newunit").as_posix(),
|
src=(self.tmpdir / "newunit").as_posix(),
|
||||||
|
|
Laden…
In neuem Issue referenzieren