Files
skato-ansible/softman.py

157 lines
5.6 KiB
Python

from typing import Self, Never, Callable, Sequence
from custtypes import Roles, Scopes, PathCollection, PathRoles
from custtypes import Software, SoftwareRoles, ExecutedPath
from custtypes import PacMans, UserName, GroupName, IdlePath
from custtypes import ExecutedPath, AnsibleRoles
from sshkey import SSHKeyCollection, SSHKeyType, SSHKey
from whereami import PROJ_ROLES
class App:
def __init__(self, name: Software, role: SoftwareRoles = SoftwareRoles.client, paths: PathRoles | None = None):
self.__name = name.name.lower().replace("_", "-")
# @TODO create dict type hint for below data struct
self.alt_names = dict()
self.alt_names[PacMans.APT.name.lower()] = self.__name
self.role = role.name.lower()
if paths is not None:
if Roles.EXE in paths:
setattr(self, "_" + Roles.EXE.name.lower(), paths[Roles.EXE.name.lower()])
if Roles.CONF in paths:
setattr(self, "_" + Roles.CONF.name.lower(), paths[Roles.CONF.name.lower()])
if Roles.DATA in paths:
setattr(self, "_" + Roles.DATA.name.lower(), paths[Roles.DATA.name.lower()])
if Roles.MEM in paths:
setattr(self, "_" + Roles.MEM.name.lower(), paths[Roles.MEM.name.lower()])
self.__parents: tuple[Self] | None = None
self.__children: tuple[Self| None] = []
self.__api: str | None = None
self.__current_filepath: IdlePath | ExecutedPath | None = None
self.__content: str | None = None
@property
def conf_paths(self):
if hasattr(self, "_" + Roles.CONF.name.lower()):
return self._conf
else:
raise Exception
@property
def data_paths(self):
if hasattr(self, "_" + Roles.DATA.name.lower()):
return self._data
else:
raise Exception
@property
def exec_paths(self):
if hasattr(self, "_" + Roles.EXE.name.lower()):
return self._exe
else:
raise Exception
@property
def mem_paths(self):
if hasattr(self, "_" + Roles.MEM.name.lower()):
return self._mem
else:
raise Exception
def get_paths(self, role: Roles = Roles.CONF):
if hasattr(self, "_" + role.name.lower()):
return getattr(self, "_" + role.name.lower())
else:
raise Exception
def append(self, datatype: Roles = Roles.CONF, scope: Scopes | None = None, path: IdlePath | ExecutedPath | str | PathCollection | None = None):
if path is None:
raise TypeError
datatype = datatype.name.lower()
if hasattr(self, "_" + datatype):
paths = getattr(self, "_" + datatype)
else:
setattr(self, "_" + datatype, dict())
paths = getattr(self, "_" + datatype)
if scope is not None:
if isinstance(path, str):
path: ExecutedPath = Path(path)
if scope.name.lower() not in paths:
paths[scope.name.lower()] = []
paths[scope.name.lower()].append(path)
else:
paths: PathCollection = path
setattr(self, "_" + datatype, paths)
def inherit(self, other):
if other._App__children is None:
other._App__children = tuple()
if self not in other._App__children:
other.adopt(self)
self.__parents = (*self.__parents, other)
def adopt(self, other: Self):
if other._App__parents is None:
other._App__parents = tuple()
if self not in other._App__parent:
other.inherit(self)
self.__children = (*self.__children, other)
def __enter__(self) -> dict | Sequence:
self.__content = self.__current_filepath.read_text()
return self.__content
def __exit__(self, exc_type, exc_value, exc_traceback) -> None:
# txt = yams.dump(self.__content)
# self.__file.write(txt)
# del txt
self.__file.close()
def __call__(self, path = str, mode = "r+", scope: Scopes = Scopes.PROJ, role: Roles = Roles.CONF, index: int = 0) -> Callable:
if not hasattr(self, "_" + role.name.lower()):
raise Exception
else:
config = getattr(self, "_" + role.name.lower())
conf_coll = config[scope.name.lower()]
if isinstance(conf_coll, Sequence):
conf_coll = conf_coll[index]
if isinstance(conf_coll, str):
conf_coll = Path(conf_coll)
filepath = conf_coll / path
self.__current_filepath = filepath
self.__file = open(str(filepath), mode)
return __enter__
# @TODO write below method to duplicate file or template in local to project role file/template
def clone(self, source_scope: Scopes = Scopes.SYS, target_scope: Scopes = Scopes.PROJ, index: int = 0) -> Never:
raise NotImplementedError
def declare(self, **kwargs):
for k, v in kwargs.items():
setattr(self, k, v)
sshd_proj_files = map(lambda r: r / AnsibleRoles.bootstrap.name.lower() / "files" / "sshd_config.d", PROJ_ROLES)
sshd_proj_files = list(filter(lambda p: p.exists(), sshd_proj_files))
sshd_proj_templates = map(lambda r: r / AnsibleRoles.bootstrap.name.lower() / "templates" / "sshd_config.d", PROJ_ROLES)
sshd_proj_templates = list(filter(lambda p: p.exists(), sshd_proj_templates))
# @TODO rewrite below using DIR_ROOTS var from whereami module
sshd_paths: PathRoles = {
Roles.CONF.name.lower(): {
Scopes.PROJ.name.lower(): sshd_proj_files + sshd_proj_templates
}
}
sshd = App(Software.openssh_server, SoftwareRoles.server, sshd_paths)