restarting rewrite of CLI

This commit is contained in:
2026-01-04 20:37:26 -05:00
parent b7e2a8e9db
commit 310fd28495

115
main.py
View File

@@ -1,112 +1,19 @@
"""
Library for the CLI commands and the related classes and functions
"""
import click as cli import click as cli
from pathlib import Path, PurePath, PurePosixPath, PureWindowsPath, PosixPath, WindowsPath
from whereami import PROJ_ROOT
from custtypes import ExecutedPath, IdlePath
import yaml as yams
from anodes import RemoteNode, ControlNode
# from typing import TypeAlias as Neotype
from typing import Literal
from enum import Enum
from ansible_vault import Vault
from random import choice
# import configparser as ini
# from cerberus import Validator as constrain_by
# import skansible_types as skato
class AnsibleScope(Enum): domain_pattern = r'^(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,}$'
INTERNAL = 0 # @TODO create regex pattern for matching IP addresses
INVENTORY = 1 # ip_pattern = r''
GROUPVARS = 2
HOSTVARS = 3
ROLE = 4
# @TODO for 'Config' class, write methods to pull and push from Ansible YAML files
# @NOTE https://docs.python.org/3/library/configparser.html#quick-start
class Config:
path: ExecutedPath = PROJ_ROOT / "config.ini"
_cnode = ControlNode(PROJ_ROOT)
__scope_paths = {
AnsibleScope.INTERNAL.name: path,
AnsibleScope.GROUPVARS.name: Path(str(_cnode.invvar_data[0])),
AnsibleScope.HOSTVARS.name: Path(str(_cnode.invvar_data[1]))
}
def __init__(self, filepath: str, anscope: AnsibleScope = AnsibleScope.INTERNAL.name, mode: str = "r+"):
filepath: ExecutedPath = self.__scope_paths[anscope] / filepath
if filepath.exists():
self.filepath = filepath
else:
raise FileNotFoundError
self.mode: str = mode
self.file = None
self.model = None
def __enter__(self):
self.file = open(str(self.filepath), self.mode)
self.model = yams.load(self.file.read())
return self.model
def __exit__(self, exc_type, exc_value, exc_traceback):
file_content = yams.dump(self.model)
self.file.write(file_content)
self.file.close()
@cli.group() @cli.group()
@cli.option("-d", "--debug", type=bool, is_flag=True, default=True, help="Use debugging mode")
@cli.pass_context @cli.pass_context
def skansible(ctx): def skansible(ctx, debug):
ctx.ensure_object(dict) ctx.ensure_object(dict)
ctx.obj["DEBUG"] = True
@skansible.group(help="Replace conventionally-typed Ansible variables")
@cli.pass_context
def mod(ctx):
with Config(entity, AnsibleScope.HOSTVARS.name) as config:
ctx.obj["fqdn"] = config["fqdn"]
@skansible.group(help="Remove conventionally-typed Ansible variables")
def rm():
pass
@skansible.group(help="Append conventionally-typed entries to Ansible variables")
def append():
pass
@skansible.group(help="Initialize Ansible variable or object with defaults")
def init():
pass
# @skansible.group(help="Show Ansible assets")
# @cli.argument("-d", "--datatype", type=str, help="Specify type of Ansible object or variable to show")
# def show(datatype):
# pass
@mod.command("vps", help="Add 'vps_service' Ansible variable")
@cli.argument("entity", type=str, help="Specify FQDN/alias or host group to associate with the VPS")
@cli.option("-p", "--password", type=str, prompt=True, prompt_required=False, help="Prompt for password of root or administrative user of VPS")
@cli.option("-a", "--api", type=str, help="API key for host service providing VPS")
@cli.option("-k", "--pubkey", multiple=True, help="A file glob pattern for acquiring user's public SSH keys")
@cli.option("-k", "--privkey", multiple=True, help="A file glob pattern for acquiring user's private SSH keys")
@cli.option("-m", "--motd", multiple=True, help="Provide basenames for MOTD SSH scripts")
@cli.option("-t", "--tag", multiple=True, type=str)
@cli.option("-s", "--service", type=str)
@cli.option("-r", "--region", type=str)
@cli.option("-f", "--fate", type=str)
@cli.pass_context
# @TODO rewrite below command function, using 'ctx' parameter for values shared with sibling commands
def mod_vps(ctx, entity: str, password: str | None = None, api: str | None = None, pubkey: tuple[str] = None, privkey: tuple[str] = None, service: str | int | None = None, region: Literal["us-east"] | None = None, tags: tuple[str] = None, fate: Literal["disposal", "retention"] | None = None):
with Config(entity, AnsibleScope.HOSTVARS.name) as config:
raise NotImplementedError
@mod.command("host", help="Add host to Ansible inventory")
@cli.argument("hostname", multiple=True, type=str, help="Provide aliases / FQDN / IP addresses for host(s)")
@cli.option("-g", "--group", type=str, default="ungrouped", help="Provide group name given host(s) fall under")
@cli.pass_context
# @TODO rewrite below command function, using 'ctx' parameter for values shared with sibling commands
def mod_host(ctx, group, hostname):
with Config(entity, AnsibleScope.INVENTORY.name) as config:
raise NotImplementedError
if __name__ == "__main__": if __name__ == "__main__":
skansible() skansible(obj={})