clean: code, add features, better cli
This commit is contained in:
parent
b8df31f036
commit
eda4c8ffd9
50
iam/app.py
50
iam/app.py
@ -35,14 +35,6 @@ class App:
|
||||
"Init application with ident"
|
||||
|
||||
self.ident_raw = ident
|
||||
|
||||
# # Split ident from scope
|
||||
# scope = ""
|
||||
# if "/" in ident:
|
||||
# parts = ident.split("/", 2)
|
||||
# ident = parts[0]
|
||||
# scope = parts[1]
|
||||
|
||||
view = scoped_ident(ident)
|
||||
|
||||
# Save important vars
|
||||
@ -69,8 +61,11 @@ class App:
|
||||
else:
|
||||
path = os.path.join(BaseDirectory.xdg_config_home, self.name)
|
||||
|
||||
self.config_dir = path
|
||||
|
||||
if os.path.isdir(path):
|
||||
files = glob.glob("*.yml", root_dir=path)
|
||||
# files = glob.glob("*.yml", root_dir=path) # Python > 3.10
|
||||
files = glob.glob(f"{path}/*.yml")
|
||||
|
||||
for file_ in files:
|
||||
file_ = os.path.join(path, file_)
|
||||
@ -105,7 +100,6 @@ class App:
|
||||
providers_conf = {}
|
||||
providers_conf.update(self.plugin_providers)
|
||||
providers_conf.update(db.get("providers", {}))
|
||||
# pprint (providers_conf)
|
||||
self.providers = Providers("ConfigProviders", providers_conf)
|
||||
|
||||
# Load idents
|
||||
@ -159,20 +153,6 @@ class App:
|
||||
|
||||
return ret
|
||||
|
||||
# def get_resource(self, name):
|
||||
# "Query and resolve a resource"
|
||||
|
||||
# return self.catalog.get_resource(name)
|
||||
|
||||
# # def get_service(self, name, resolve=False):
|
||||
# # "Query and resolve a service"
|
||||
|
||||
# # return self.catalog.get_service(name, resolve=resolve)
|
||||
|
||||
# def list_resources(self):
|
||||
# "List all resources"
|
||||
# return self.catalog.resources
|
||||
|
||||
def list_services(self):
|
||||
"List all services"
|
||||
|
||||
@ -190,17 +170,27 @@ class App:
|
||||
return self.catalog.shell_disable(**kwargs)
|
||||
|
||||
|
||||
def shell_install(self, shell="bash"):
|
||||
"Install iam in shell"
|
||||
def shell_install(self, shell="bash", completion=True):
|
||||
"Show your install script for shell"
|
||||
|
||||
assets_dir = os.path.join(get_root_pkg_dir("iam"), "assets")
|
||||
|
||||
|
||||
if shell == "bash":
|
||||
# Shell selector
|
||||
if shell.endswith("bash"):
|
||||
config_file = ".bashrc"
|
||||
template_file = os.path.join(assets_dir, "init_bash.sh")
|
||||
init_file = os.path.join(assets_dir, "init_bash.sh")
|
||||
completion_file = os.path.join(assets_dir, "iam_completion.sh")
|
||||
|
||||
else:
|
||||
raise Exception(f"Unsupported shell: {shell}")
|
||||
|
||||
return f"source {template_file}"
|
||||
# TOFIX: Implement for other shells ?
|
||||
out = []
|
||||
out.append(f"### IAM ###")
|
||||
out.append(f"if command -v iam &>/dev/null; then")
|
||||
out.append(f" source {init_file}")
|
||||
if completion:
|
||||
out.append(f" source {completion_file}")
|
||||
out.append(f"fi")
|
||||
out.append(f"### IAM ###")
|
||||
return '\n'.join(out)
|
||||
29
iam/assets/iam_completion.sh
Normal file
29
iam/assets/iam_completion.sh
Normal file
@ -0,0 +1,29 @@
|
||||
_iam_completion() {
|
||||
local IFS=$'\n'
|
||||
local response
|
||||
|
||||
response=$(env COMP_WORDS="${COMP_WORDS[*]}" COMP_CWORD=$COMP_CWORD _IAM_COMPLETE=bash_complete $1)
|
||||
|
||||
for completion in $response; do
|
||||
IFS=',' read type value <<< "$completion"
|
||||
|
||||
if [[ $type == 'dir' ]]; then
|
||||
COMPREPLY=()
|
||||
compopt -o dirnames
|
||||
elif [[ $type == 'file' ]]; then
|
||||
COMPREPLY=()
|
||||
compopt -o default
|
||||
elif [[ $type == 'plain' ]]; then
|
||||
COMPREPLY+=($value)
|
||||
fi
|
||||
done
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
_iam_completion_setup() {
|
||||
complete -o nosort -F _iam_completion iam
|
||||
}
|
||||
|
||||
_iam_completion_setup;
|
||||
|
||||
@ -16,7 +16,7 @@
|
||||
IAM_BIN=$(command -v iam)
|
||||
IAM_IDENT=
|
||||
|
||||
_usage ()
|
||||
i_usage ()
|
||||
{
|
||||
echo "iam shell wrapper"
|
||||
|
||||
@ -156,7 +156,7 @@ i ()
|
||||
#echo $IAM_BIN shell status $current_ident
|
||||
;;
|
||||
help)
|
||||
_usage
|
||||
i_usage
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
139
iam/catalog.py
139
iam/catalog.py
@ -1,12 +1,18 @@
|
||||
|
||||
import os
|
||||
import logging
|
||||
from collections import namedtuple
|
||||
from pprint import pprint
|
||||
from types import SimpleNamespace
|
||||
import sh
|
||||
|
||||
# TO BE REMOVED !!!!
|
||||
import click
|
||||
|
||||
from . import exceptions as error
|
||||
from .framework import DictCtrl, DictItem, KeyValue, KeyValueExtra
|
||||
from .idents import Ident
|
||||
from .lib.utils import format_render, jinja_render, uniq
|
||||
from .lib.utils import format_render, jinja_render, uniq, jinja_template_vars, empty
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
cli_logger = logging.getLogger("iam.cli")
|
||||
@ -52,31 +58,38 @@ class ServiceCommand(DictItem):
|
||||
"cmd": "", # Direct commands to launch
|
||||
|
||||
"shell": "", # Will be run in a shell (or specific shell below)
|
||||
"shell_sh": "",
|
||||
"shell_bash": "",
|
||||
"shell_zsh": "",
|
||||
"shell_fish": "",
|
||||
"shell_bash": "",
|
||||
|
||||
"source": False, # True for enable commands !
|
||||
# "shell_sh": "",
|
||||
# "shell_bash": "",
|
||||
# "shell_zsh": "",
|
||||
# "shell_fish": "",
|
||||
# "shell_bash": "",
|
||||
|
||||
# "source_output": False, # True for shell commands by default !
|
||||
|
||||
}
|
||||
|
||||
# Overrides
|
||||
# ---------------
|
||||
|
||||
def payload_transform(self, name, kwargs=None):
|
||||
def init(self):
|
||||
"Transform short form into long form"
|
||||
self.service = self.parent
|
||||
|
||||
payload = self._payload
|
||||
if not isinstance(payload, dict):
|
||||
payload = {"cmd": payload}
|
||||
self._payload = payload
|
||||
|
||||
# def payload_transform(self, name, kwargs=None):
|
||||
# "Transform short form into long form"
|
||||
# self.service = self.parent
|
||||
|
||||
# payload = self._payload
|
||||
# if not isinstance(payload, dict):
|
||||
# payload = {"cmd": payload}
|
||||
# self._payload = payload
|
||||
|
||||
def cmd_name(self):
|
||||
return self.name.replace("_", " ")
|
||||
|
||||
|
||||
class Service(DictItem):
|
||||
"Hold provider services"
|
||||
|
||||
@ -772,9 +785,16 @@ class Context(DictItem):
|
||||
assert isinstance(self.ident, Ident), f"Gotr: {self.ident}"
|
||||
|
||||
def init(self):
|
||||
self.catalog = self.parent
|
||||
|
||||
root_dir = self.catalog.app.config_dir
|
||||
self._vars = {
|
||||
"ident": self.ident.name,
|
||||
"user": self.ident.name,
|
||||
|
||||
"config_dir": root_dir,
|
||||
"scripts_dir": os.path.join(root_dir, "scripts"),
|
||||
"bin_dir": os.path.join(root_dir, "bin"),
|
||||
}
|
||||
|
||||
def get_vars(self):
|
||||
@ -790,16 +810,16 @@ class Context(DictItem):
|
||||
class Catalog:
|
||||
"Manage catalog resources"
|
||||
|
||||
def __init__(self, mgr, ident):
|
||||
def __init__(self, app, ident):
|
||||
# Prepare catalog
|
||||
self.mgr = mgr
|
||||
self.app = app
|
||||
self.ident = ident
|
||||
|
||||
# Prepare context
|
||||
ctx_conf = {
|
||||
"ident": ident,
|
||||
}
|
||||
self.context = Context("current_context", ctx_conf)
|
||||
self.context = Context("current_context", ctx_conf, parent=self)
|
||||
|
||||
self._prepare_catalog()
|
||||
|
||||
@ -807,7 +827,7 @@ class Catalog:
|
||||
# ================
|
||||
|
||||
def _merge_inst_configs(self, merge=True):
|
||||
plugins_confs = self.mgr.providers.get_resource_configs()
|
||||
plugins_confs = self.app.providers.get_resource_configs()
|
||||
user_confs = self.ident.get_resource_configs()
|
||||
|
||||
final_config = {}
|
||||
@ -840,7 +860,7 @@ class Catalog:
|
||||
"Prepare catalog resources configs"
|
||||
|
||||
# Get resources from providers and user
|
||||
providers = self.mgr.providers
|
||||
providers = self.app.providers
|
||||
ident = self.ident
|
||||
|
||||
# Build kind catalog
|
||||
@ -949,8 +969,8 @@ class Catalog:
|
||||
continue
|
||||
|
||||
# Build loop with at least ONE item
|
||||
cmd = command.cmd
|
||||
if not cmd:
|
||||
cmd_shell = command.shell
|
||||
if not cmd_shell:
|
||||
continue
|
||||
|
||||
# Create context var dict
|
||||
@ -972,7 +992,7 @@ class Catalog:
|
||||
logger.debug(f"{log_action_name} service: {res.name}")
|
||||
|
||||
# pprint (ctx_vars)
|
||||
cmd = jinja_render(cmd, ctx_vars)
|
||||
cmd = jinja_render(cmd_shell, ctx_vars)
|
||||
output_code.append(f"# Loading: {action_name} {res.name} ({service.name})")
|
||||
output_code.append(f"# =====================")
|
||||
output_code.append(cmd)
|
||||
@ -989,15 +1009,13 @@ class Catalog:
|
||||
cmd, args = self.services.get_svc_command(cmd)
|
||||
|
||||
|
||||
|
||||
|
||||
# pprint (cmd.cmd)
|
||||
pprint (args)
|
||||
# pprint (args)
|
||||
|
||||
service = cmd.service
|
||||
|
||||
pprint (service)
|
||||
pprint (service.__dict__)
|
||||
# pprint (service)
|
||||
# pprint (service.__dict__)
|
||||
# pprint (dir(service))
|
||||
res = service.get_linked_resource()
|
||||
# pprint (res)
|
||||
@ -1020,25 +1038,82 @@ class Catalog:
|
||||
# }
|
||||
# )
|
||||
|
||||
pprint (ctx_vars)
|
||||
# pprint (ctx_vars)
|
||||
|
||||
new_env = dict(os.environ)
|
||||
new_env.update(ctx_vars)
|
||||
# pprint(new_env)
|
||||
|
||||
if cmd.cmd and cmd.shell:
|
||||
logger.warning(f"Duplicate cmd and shell for {service.name}")
|
||||
|
||||
out = None
|
||||
|
||||
|
||||
if cmd.cmd:
|
||||
|
||||
if cmd.shell:
|
||||
mode = "shell"
|
||||
payload = cmd.shell
|
||||
|
||||
# Scan for missing vars !!!
|
||||
tmp = jinja_template_vars(payload)
|
||||
prompt_vars = []
|
||||
for var_name in tmp:
|
||||
if var_name not in ctx_vars:
|
||||
prompt_vars.append(var_name)
|
||||
else:
|
||||
var_value = ctx_vars[var_name]
|
||||
if empty(var_value):
|
||||
prompt_vars.append(var_name)
|
||||
|
||||
# Ask for missing vars
|
||||
if len(prompt_vars) > 0:
|
||||
# print ("MISSING VARS")
|
||||
# pprint (prompt_vars)
|
||||
|
||||
answered_items = {}
|
||||
for missed in prompt_vars:
|
||||
default = ctx_vars.get(missed, None)
|
||||
result = click.prompt(f'Select value for {missed}', default=default)
|
||||
answered_items[missed] = result
|
||||
|
||||
ctx_vars.update(answered_items)
|
||||
|
||||
real_cmd = jinja_render(payload, ctx_vars)
|
||||
|
||||
# print ("RUN SHELL")
|
||||
builtins = sh.bash.bake("-c")
|
||||
out = builtins(real_cmd, _fg=True, _env=new_env)
|
||||
|
||||
# print (out)
|
||||
|
||||
elif cmd.cmd:
|
||||
mode = "cmd"
|
||||
payload = cmd.cmd
|
||||
real_cmd = jinja_render(payload, ctx_vars)
|
||||
|
||||
cmd_parts = real_cmd.split(" ", 1)
|
||||
sh_cmd = cmd_parts[0]
|
||||
sh_args = cmd_parts[1] if len(cmd_parts) > 0 else []
|
||||
|
||||
elif cmd.shell:
|
||||
mode = "shell"
|
||||
payload = cmd.shell
|
||||
real_cmd = jinja_render(payload, ctx_vars)
|
||||
# print ("Prepare", sh_cmd, " ||| ", sh_args)
|
||||
|
||||
# proc = sh.bake(sh_cmd)
|
||||
# sh(sh_cmd, *sh_args, _fg=True)
|
||||
|
||||
cmd = sh.Command(sh_cmd)
|
||||
if sh_args:
|
||||
out = cmd(sh_args, _fg=True, _env=new_env)
|
||||
else:
|
||||
out = cmd( _fg=True, _env=new_env)
|
||||
|
||||
# print (out)
|
||||
|
||||
else:
|
||||
raise Exception("MIssing cmd or shell in config !")
|
||||
|
||||
|
||||
return out
|
||||
|
||||
|
||||
print ("RUN CMD", mode, "\n\n\n====\n", real_cmd)
|
||||
# print ("RUN CMD", mode, "\n\n\n====\n", real_cmd)
|
||||
@ -100,6 +100,7 @@ DEBUG = os.environ.get("IAM_DEBUG", "False")
|
||||
DEFAULT_IDENT = os.environ.get("IAM_IDENT", os.environ.get("SHELL_IDENT", ""))
|
||||
DEFAULT_FORMAT = os.environ.get("IAM_FORMAT", "table")
|
||||
DEFAULT_HELP_OPTIONS=["-h", "--help"]
|
||||
DEFAULT_SHELL = os.environ.get("SHELL", "bash")
|
||||
|
||||
# list_view.formats_enum
|
||||
|
||||
@ -849,7 +850,7 @@ class TmpGroup(click.Group):
|
||||
@click.pass_context
|
||||
def cli_app_run(ctx, cmd_params):
|
||||
|
||||
print("Will run cmd:", cmd_params)
|
||||
# print("Will run cmd:", cmd_params)
|
||||
|
||||
# Check first help parameter only
|
||||
show_help = False
|
||||
@ -891,7 +892,8 @@ def cli_app_run(ctx, cmd_params):
|
||||
|
||||
# Run the output
|
||||
ret = app.catalog.run_svc_cmd(cmd=cmd_params)
|
||||
pprint (ret, expand_all=True)
|
||||
print (ret)
|
||||
# pprint (ret, expand_all=True)
|
||||
|
||||
|
||||
|
||||
@ -910,11 +912,14 @@ def cli_app_run(ctx, cmd_params):
|
||||
|
||||
|
||||
@cli__shell.command("install")
|
||||
@click.argument("shell",
|
||||
required=False,
|
||||
default=DEFAULT_SHELL)
|
||||
@click.pass_context
|
||||
def shell_install(ctx, verbose=None):
|
||||
def shell_install(ctx, shell=None, verbose=None):
|
||||
"Install iam in your shell"
|
||||
|
||||
ret = ctx.obj.app.shell_install()
|
||||
ret = ctx.obj.app.shell_install(shell=shell)
|
||||
|
||||
# print("-- %< --" * 8)
|
||||
print(ret)
|
||||
|
||||
@ -1,5 +1,9 @@
|
||||
import logging
|
||||
import click
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
# Click Plugins
|
||||
# ===============================
|
||||
|
||||
@ -9,8 +13,53 @@ class NestedHelpGroup(click.Group):
|
||||
"""This class provides a way to show all commands of all children
|
||||
instead of just the parent. Optionnaly accept to hides groups or not.
|
||||
|
||||
This class is aimed to serve simple resource based CLIs, à la [cliff](),
|
||||
but with the click library.
|
||||
|
||||
This class provides:
|
||||
* Recursive command listing
|
||||
* Command aliasing as described in (documentation)[https://click.palletsprojects.com/en/8.1.x/advanced/#command-aliases]
|
||||
* Rich support (TODO, more complete wrapper of click-rich)
|
||||
* Basic views (TODO)
|
||||
|
||||
# Recursive command list
|
||||
# =============
|
||||
Recursive listing on help commands, this is helpful to
|
||||
have an quick overview of all commands on small clis. It also provides
|
||||
an option to hide groups if you don't use them, which may reduce the size of
|
||||
the help message in case of many groups.
|
||||
|
||||
|
||||
# Command shortcuts
|
||||
# =============
|
||||
Let's image a command line that provides:
|
||||
```
|
||||
myapp user show <USER>
|
||||
myapp user state <USER>
|
||||
myapp user disable <USER>
|
||||
```
|
||||
You could use as shortcuts:
|
||||
```
|
||||
mysapp u sh USER
|
||||
mysapp u st USER
|
||||
mysapp u sd USER
|
||||
```
|
||||
But `mysapp u s USER` would fail as it would not know if it have to redirect to
|
||||
`show` or `state` command, as both starts with `s`
|
||||
|
||||
"""
|
||||
|
||||
|
||||
# For partial name resolution
|
||||
def resolve_command(self, ctx, args):
|
||||
"Return the full command name if changed"
|
||||
|
||||
_, cmd, args = super().resolve_command(ctx, args)
|
||||
if _ != cmd.name:
|
||||
logger.debug(f"Rewrite command '{_}' to '{cmd.name}'")
|
||||
return cmd.name, cmd, args
|
||||
|
||||
|
||||
def get_command(self, ctx, cmd_name: str):
|
||||
"""Given a context and a command name, this returns a :class:`Command`
|
||||
object if it exists or returns ``None``.
|
||||
@ -18,19 +67,37 @@ class NestedHelpGroup(click.Group):
|
||||
|
||||
# Resolve name part by part
|
||||
parts = cmd_name.split(" ")
|
||||
len_parts = len(parts) -1
|
||||
curr = self
|
||||
for idx, part in enumerate(parts):
|
||||
curr = curr.commands.get(part)
|
||||
match = curr.commands.get(part)
|
||||
|
||||
# Look for shortcut if last part
|
||||
if match is None:
|
||||
# Look for direct children only
|
||||
matches = [x for x in self._resolve_children(self, ctx=ctx, ignore_groups=False, deep=0)
|
||||
if x.startswith(cmd_name)]
|
||||
|
||||
# Look for possible matches
|
||||
if not matches:
|
||||
pass
|
||||
elif len(matches) == 1:
|
||||
match = click.Group.get_command(self, ctx, matches[0])
|
||||
else:
|
||||
ctx.fail(f"Too many matches for {cmd_name}: {', '.join(sorted(matches))}")
|
||||
|
||||
# Iterate over next child!
|
||||
curr = match
|
||||
|
||||
return curr
|
||||
|
||||
def list_commands(self, ctx) -> list[str]:
|
||||
"List all children commands"
|
||||
|
||||
return self._resolve_children(self, ctx=ctx, ignore_groups=True)
|
||||
return sorted(self._resolve_children(self, ctx=ctx, ignore_groups=True))
|
||||
|
||||
@classmethod
|
||||
def _resolve_children(cls, obj, ctx=None, ignore_groups=False, _parent=None):
|
||||
def _resolve_children(cls, obj, ctx=None, ignore_groups=False, _parent=None, deep=-1):
|
||||
"Resolve recursively all children"
|
||||
# Source: Adapted from https://stackoverflow.com/a/56159096
|
||||
|
||||
@ -51,12 +118,15 @@ class NestedHelpGroup(click.Group):
|
||||
ret.append(record)
|
||||
|
||||
# Recursive loop
|
||||
if deep != 0:
|
||||
deep = deep -1
|
||||
ret.extend(
|
||||
cls._resolve_children(
|
||||
child, ctx=ctx, ignore_groups=ignore_groups, _parent=full_name
|
||||
child, ctx=ctx, ignore_groups=ignore_groups, _parent=full_name, deep=deep
|
||||
)
|
||||
)
|
||||
|
||||
return ret
|
||||
|
||||
return []
|
||||
|
||||
|
||||
@ -83,6 +83,20 @@ def prune(items):
|
||||
raise Exception(f"Function prune requires a list or a dict, got: {items}")
|
||||
return ret
|
||||
|
||||
# from jinja2 import Environment, FileSystemLoader, meta
|
||||
|
||||
# env = Environment(loader=FileSystemLoader('templates'))
|
||||
# parsed_content = env.parse(payload)
|
||||
|
||||
|
||||
from jinja2 import Environment, PackageLoader, meta
|
||||
|
||||
def jinja_template_vars(payload):
|
||||
|
||||
env = Environment() #loader=PackageLoader('templates'))
|
||||
parsed_content = env.parse(payload)
|
||||
return meta.find_undeclared_variables(parsed_content)
|
||||
|
||||
|
||||
def jinja_render(payload, vars):
|
||||
"Parse a string with jinja"
|
||||
|
||||
@ -43,19 +43,19 @@ plugin_base = {
|
||||
"commands": {
|
||||
"shell_enable": {
|
||||
"desc": "Enable shell ident",
|
||||
"cmd": "export SHELL_IDENT={{ident}}",
|
||||
"shell": "export SHELL_IDENT={{ident}}",
|
||||
},
|
||||
"shell_disable": {
|
||||
"desc": "Disable shell ident",
|
||||
"cmd": "unset SHELL_IDENT",
|
||||
"shell": "unset SHELL_IDENT",
|
||||
},
|
||||
"id new": {
|
||||
"desc": "Create shell identy",
|
||||
"cmd": "add_ident {{ param }}",
|
||||
"shell": "add_ident {{ param }}",
|
||||
},
|
||||
"id delete": {
|
||||
"desc": "Delete shell identy",
|
||||
"cmd": "rm_ident {{ param }}",
|
||||
"shell": "rm_ident {{ param }}",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@ -17,13 +17,13 @@ providers:
|
||||
|
||||
shell_enable:
|
||||
desc: Enable git identity
|
||||
cmd: |
|
||||
shell: |
|
||||
export GH_TOKEN='{{gh_token}}'
|
||||
export GH_REPO='{{ident}}'
|
||||
|
||||
shell_disable:
|
||||
desc: Disable git identity
|
||||
cmd: |
|
||||
shell: |
|
||||
unset GH_TOKEN GH_REPO
|
||||
|
||||
|
||||
@ -69,13 +69,13 @@ providers:
|
||||
|
||||
shell_enable:
|
||||
desc: Enable git identity
|
||||
cmd: |
|
||||
shell: |
|
||||
export GITEA_SERVER_URL='{{gitea_server_url}}'
|
||||
export GITEA_LOGIN='{{email}}'
|
||||
|
||||
shell_disable:
|
||||
desc: Disable git identity
|
||||
cmd: |
|
||||
shell: |
|
||||
unset GITEA_SERVER_URL GITEA_LOGIN
|
||||
|
||||
|
||||
@ -120,7 +120,7 @@ providers:
|
||||
|
||||
shell_enable:
|
||||
desc: Enable minio alias
|
||||
cmd: |
|
||||
shell: |
|
||||
export MINIO_ACCESS_KEY={{minio_access}}
|
||||
export MINIO_SECRET_KEY={{minio_secret}}
|
||||
# cmd_FUTURE: |
|
||||
@ -130,18 +130,18 @@ providers:
|
||||
|
||||
shell_disable:
|
||||
desc: Disable minio alias
|
||||
cmd: |
|
||||
shell: |
|
||||
unset MINIO_ACCESS_KEY MINIO_SECRET_KEY
|
||||
|
||||
|
||||
minio new alias:
|
||||
desc: Create alias
|
||||
cmd: |
|
||||
shell: |
|
||||
mc alias set {{ident}} {{api_url}} {{minio_user}} {{minio_password}}
|
||||
|
||||
minio delete alias:
|
||||
desc: Remove alias
|
||||
cmd: |
|
||||
shell: |
|
||||
mc alias rm {{ident}}
|
||||
|
||||
|
||||
|
||||
@ -5,174 +5,8 @@ from iam.lib.utils import get_pkg_dir, open_yaml, to_yaml
|
||||
|
||||
yml_dir = get_pkg_dir(__name__)
|
||||
plugin_conf = open_yaml(os.path.join(yml_dir, "local.yml"))[0]
|
||||
|
||||
|
||||
|
||||
|
||||
all = plugin_conf.get("providers", {})
|
||||
|
||||
|
||||
# plugin_ssh = {
|
||||
|
||||
# "services": {
|
||||
|
||||
# "local.ssh_key": {
|
||||
# "desc": "Local ssh key",
|
||||
# # "input": {
|
||||
# # "ssh_agent_socket_dir": "/run/user/ssh-agent",
|
||||
# # "ssh_agent_tmout": "7d",
|
||||
# # },
|
||||
# "commands": {
|
||||
# "shell_enable": {
|
||||
# "cmd": """
|
||||
# export SSH_AUTH_SOCK={{ssh_agent_socket_dir}}/{{user}} && \
|
||||
# ssh-agent -a $SSH_AUTH_SOCK -t {{ssh_agent_tmout}}
|
||||
# """,
|
||||
# },
|
||||
# "shell_disable": {
|
||||
# "cmd": "ssh-agent -k && unset SSH_AUTH_SOCK",
|
||||
# },
|
||||
# },
|
||||
# },
|
||||
# },
|
||||
|
||||
|
||||
# "resources_def": {
|
||||
# "service.local.ssh_key": {
|
||||
# "desc": "A local ssh key",
|
||||
# },
|
||||
|
||||
# "auth.ssh_certificate": {
|
||||
# "desc": "SSH Certificates",
|
||||
# "input": {"ssh_cert_file": None},
|
||||
# "needs": ["auth.ssh_key"],
|
||||
# },
|
||||
|
||||
# "auth.ssh_key": {
|
||||
# "desc": "ssh_key",
|
||||
# "input": {
|
||||
# "ssh_key_file": None,
|
||||
# "ssh_key_secret": None
|
||||
# },
|
||||
# "needs": [
|
||||
# {"kind": "auth.password", "remap": {"ssh_key_secret": "passord"}}
|
||||
# ],
|
||||
# },
|
||||
|
||||
# "account.ssh": {"desc": "An unix account", "input": {"host": None}},
|
||||
|
||||
|
||||
# },
|
||||
|
||||
# "resources": {
|
||||
|
||||
# "service.local.ssh_agent": {
|
||||
# "enabled": True,
|
||||
# # "contains": [
|
||||
# # "auth.ssh_key:{ident}/ed25519",
|
||||
# # "auth.ssh_key:{ident}/rsa4096",
|
||||
# # "auth.ssh_key:{ident}/rsa2048",
|
||||
# # "auth.ssh_key:{ident}/rsa1024",
|
||||
# # "auth.ssh_key:{ident}",
|
||||
# # ],
|
||||
# },
|
||||
|
||||
# "service.local.ssh_agent_keys": {
|
||||
# "enabled": True,
|
||||
# "loop_limit": 3,
|
||||
# "loop": [
|
||||
# "auth.ssh_key:{ident}/ed25519",
|
||||
# "auth.ssh_key:{ident}/rsa4096",
|
||||
# "auth.ssh_key:{ident}/rsa2048",
|
||||
# "auth.ssh_key:{ident}/rsa1024",
|
||||
# "auth.ssh_key:{ident}",
|
||||
# ],
|
||||
# },
|
||||
|
||||
# },
|
||||
|
||||
# }
|
||||
|
||||
|
||||
# plugin_ssh_agent = {
|
||||
# "services": {
|
||||
|
||||
# "local.ssh_agent": {
|
||||
# "desc": "Local ssh-agent",
|
||||
# "input": {
|
||||
# "ssh_agent_socket_dir": "/run/user/ssh-agent",
|
||||
# "ssh_agent_tmout": "7d",
|
||||
# },
|
||||
# "commands": {
|
||||
# "shell_enable": {
|
||||
# "cmd": """
|
||||
# export SSH_AUTH_SOCK={{ssh_agent_socket_dir}}/{{user}} && \
|
||||
# ssh-agent -a $SSH_AUTH_SOCK -t {{ssh_agent_tmout}}
|
||||
# """,
|
||||
# },
|
||||
# "shell_disable": {
|
||||
# "cmd": "ssh-agent -k && unset SSH_AUTH_SOCK",
|
||||
# },
|
||||
# },
|
||||
# },
|
||||
|
||||
# "local.ssh_agent_keys": {
|
||||
# "desc": "Local ssh-agent keys",
|
||||
# "required_services": [
|
||||
# "local.ssh_agent"
|
||||
# ],
|
||||
# "commands": {
|
||||
# "shell_enable": {
|
||||
# "cmd": """
|
||||
# ssh-add {% for item in loop %} {{item.ssh_key_file}} {% endfor %}
|
||||
# """,
|
||||
# },
|
||||
# "shell_disable": {
|
||||
# "cmd": "ssh-agent -d {ssh_key_file}",
|
||||
# },
|
||||
# },
|
||||
# },
|
||||
|
||||
# },
|
||||
|
||||
# "resources_def": {
|
||||
# "service.local.ssh_agent": {
|
||||
# "desc": "A local ssh_agent service",
|
||||
# },
|
||||
# "service.local.ssh_agent_keys": {
|
||||
# "desc": "A local ssh_agent_keys service",
|
||||
# },
|
||||
# },
|
||||
|
||||
# "resources": {
|
||||
|
||||
# "service.local.ssh_agent": {
|
||||
# "enabled": True,
|
||||
# # "contains": [
|
||||
# # "auth.ssh_key:{ident}/ed25519",
|
||||
# # "auth.ssh_key:{ident}/rsa4096",
|
||||
# # "auth.ssh_key:{ident}/rsa2048",
|
||||
# # "auth.ssh_key:{ident}/rsa1024",
|
||||
# # "auth.ssh_key:{ident}",
|
||||
# # ],
|
||||
# },
|
||||
|
||||
# "service.local.ssh_agent_keys": {
|
||||
# "enabled": True,
|
||||
# "loop_limit": 3,
|
||||
# "loop": [
|
||||
# "auth.ssh_key:{ident}/ed25519",
|
||||
# "auth.ssh_key:{ident}/rsa4096",
|
||||
# "auth.ssh_key:{ident}/rsa2048",
|
||||
# "auth.ssh_key:{ident}/rsa1024",
|
||||
# "auth.ssh_key:{ident}",
|
||||
# ],
|
||||
# },
|
||||
|
||||
# },
|
||||
# }
|
||||
|
||||
|
||||
# all = {
|
||||
# "ssh": plugin_ssh,
|
||||
# "ssh_agent": plugin_ssh_agent,
|
||||
# }
|
||||
|
||||
|
||||
# print (to_yaml(all))
|
||||
|
||||
@ -17,18 +17,32 @@ providers:
|
||||
ssh new:
|
||||
desc: Create new SSH key
|
||||
|
||||
|
||||
# shell: |
|
||||
# echo "This is my shelll !!! $SHELL"
|
||||
# env | grep jez
|
||||
|
||||
# cmd: |
|
||||
# env
|
||||
# # echo Create ssh key: {{ssh_key_alg}} for ident '{{ident}}' with pass: {{ssh_key_secret}}
|
||||
|
||||
shell: |
|
||||
# env | sort
|
||||
# echo
|
||||
|
||||
|
||||
SSH_KEY_ALG={{ssh_key_alg}}
|
||||
|
||||
SSH_KEY_VERSION="$(date +'%Y%m%d')"
|
||||
SSH_KEY_HOST="$(hostname -f)"
|
||||
|
||||
SSH_KEY_FILE=$HOME/.ssh/{ident}/{user}_${SSH_KEY_ALG}_${SSH_KEY_VERSION}
|
||||
SSH_KEY_COMMENT={user}@${SSH_KEY_HOST}:${SSH_KEY_ALG}_${SSH_KEY_VERSION}
|
||||
SSH_KEY_FILE=$HOME/.ssh/{{ident}}/{{user}}_${SSH_KEY_ALG}_${SSH_KEY_VERSION}
|
||||
SSH_KEY_COMMENT={{user}}@${SSH_KEY_HOST}:${SSH_KEY_ALG}_${SSH_KEY_VERSION}
|
||||
|
||||
ssh-keygen -f "{SSH_KEY_FILE}" \
|
||||
echo mkdir -p $HOME/.ssh/{{ident}}/
|
||||
echo ssh-keygen -f "${SSH_KEY_FILE}" \
|
||||
-t ed25519 -a 100 \
|
||||
-N "{{ssh_key_secret}}" \
|
||||
{% if ssh_key_secret %}-N "{{ssh_key_secret}}"{%endif%} \
|
||||
-C "$SSH_KEY_COMMENT"
|
||||
|
||||
|
||||
@ -36,7 +50,7 @@ providers:
|
||||
ssh delete:
|
||||
desc: Delete existing SSH key
|
||||
cmd: |
|
||||
find $HOME/.ssh/{ident}/ -name "{user}_*"
|
||||
find $HOME/.ssh/{{ident}}/ -name "{{user}}_*"
|
||||
|
||||
|
||||
|
||||
@ -124,7 +138,7 @@ providers:
|
||||
|
||||
shell_start:
|
||||
desc: Start ssh-agent
|
||||
cmd: |
|
||||
shell: |
|
||||
socket=$HOME/.local/state/ssh-agent/{{user}}
|
||||
start=true
|
||||
|
||||
@ -154,7 +168,7 @@ providers:
|
||||
shell_enable:
|
||||
desc: Enable ssh-agent
|
||||
|
||||
cmd: |
|
||||
shell: |
|
||||
socket=$HOME/.local/state/ssh-agent/{{user}}
|
||||
|
||||
if [[ -e "$socket.env" ]]; then
|
||||
@ -168,13 +182,13 @@ providers:
|
||||
|
||||
shell_disable:
|
||||
desc: Disable ssh-agent
|
||||
cmd: |
|
||||
shell: |
|
||||
unset SSH_AUTH_SOCK SSH_AGENT_PID
|
||||
|
||||
|
||||
shell_stop:
|
||||
desc: Kill ssh-agent
|
||||
cmd: |
|
||||
shell: |
|
||||
socket=$HOME/.local/state/ssh-agent/{{user}}
|
||||
|
||||
if [[ -e "$socket.env" ]]; then
|
||||
@ -205,11 +219,11 @@ providers:
|
||||
commands:
|
||||
ssh add:
|
||||
desc: Unload keys into ssh-agent
|
||||
cmd: ssh-agent -d {ssh_key_file}
|
||||
shell: ssh-agent -d {ssh_key_file}
|
||||
|
||||
ssh rm:
|
||||
desc: Load keys into ssh-agent
|
||||
cmd: |
|
||||
shell: |
|
||||
ssh-add {% for item in loop %} {{item.ssh_key_file}} {% endfor %}
|
||||
|
||||
|
||||
@ -261,7 +275,7 @@ providers:
|
||||
|
||||
shell_enable:
|
||||
desc: Enable git identity
|
||||
cmd: |
|
||||
shell: |
|
||||
export GIT_AUTHOR_NAME='{{ident}}'
|
||||
export GIT_AUTHOR_EMAIL='{{email}}'
|
||||
export GIT_COMMITTER_NAME='{{ident}}'
|
||||
@ -270,7 +284,7 @@ providers:
|
||||
|
||||
shell_disable:
|
||||
desc: Disable git identity
|
||||
cmd: |
|
||||
shell: |
|
||||
unset GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_COMMITTER_NAME GIT_COMMITTER_EMAIL
|
||||
|
||||
|
||||
@ -284,13 +298,13 @@ providers:
|
||||
|
||||
shell_enable:
|
||||
desc: Enable git home management
|
||||
cmd: |
|
||||
shell: |
|
||||
export GIT_DIR="{{git_dir}}"
|
||||
export GIT_WORK_TREE="{{git_work_tree}}/{{ ident }}"
|
||||
|
||||
shell_disable:
|
||||
desc: Disable git home management
|
||||
cmd: |
|
||||
shell: |
|
||||
unset GIT_DIR GIT_WORK_TREE
|
||||
|
||||
required_services:
|
||||
@ -331,13 +345,13 @@ providers:
|
||||
|
||||
shell_enable:
|
||||
desc: Enable PS1
|
||||
cmd: |
|
||||
shell: |
|
||||
export OLD_PS1=$PS1
|
||||
export PS1="\033[0;34m\]({{ident}})\033[00m\] ${PS1}"
|
||||
|
||||
shell_disable:
|
||||
desc: Disable PS1
|
||||
cmd: |
|
||||
shell: |
|
||||
export PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
|
||||
# export PS1="$OLD_PS1"
|
||||
|
||||
|
||||
13
poetry.lock
generated
13
poetry.lock
generated
@ -424,6 +424,17 @@ rich = ">=10.7.0"
|
||||
[package.extras]
|
||||
dev = ["pre-commit"]
|
||||
|
||||
[[package]]
|
||||
name = "sh"
|
||||
version = "2.0.6"
|
||||
description = "Python subprocess replacement"
|
||||
optional = false
|
||||
python-versions = ">=3.8.1,<4.0"
|
||||
files = [
|
||||
{file = "sh-2.0.6-py3-none-any.whl", hash = "sha256:ced8f2e081a858b66a46ace3703dec243779abbd5a1887ba7e3c34f34da70cd2"},
|
||||
{file = "sh-2.0.6.tar.gz", hash = "sha256:9b2998f313f201c777e2c0061f0b1367497097ef13388595be147e2a00bf7ba1"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typer"
|
||||
version = "0.9.0"
|
||||
@ -459,4 +470,4 @@ files = [
|
||||
[metadata]
|
||||
lock-version = "2.0"
|
||||
python-versions = "^3.11"
|
||||
content-hash = "1747400a30523d50e0ccaf55386f60f05b4d6e5e222aeb8a737d4e78b702a210"
|
||||
content-hash = "2673f8f06cf73701e5dac7ef463abeaf01bfb40b5c003e0898c7d97d0c589158"
|
||||
|
||||
@ -21,6 +21,7 @@ coloredlogs = "^15.0.1"
|
||||
rich = "^13.6.0"
|
||||
rich-click = "^1.6.1"
|
||||
colorama = "^0.4.6"
|
||||
sh = "^2.0.6"
|
||||
|
||||
|
||||
[tool.poetry.scripts]
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user