102 lines
3.9 KiB
Python
102 lines
3.9 KiB
Python
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
"""Shell completion script generation."""
|
|
from __future__ import annotations
|
|
|
|
COMMANDS = (
|
|
"run", "check", "baseline", "list-detectors", "rules", "web", "tui",
|
|
"triage", "fim-baseline", "fim-update", "fim-check", "pkgdb-check",
|
|
"pkgdb-verify", "rootcheck", "status", "incident", "posture", "respond",
|
|
"watchdog", "completion",
|
|
)
|
|
|
|
RULE_ACTIONS = ("list", "show", "test", "docs")
|
|
BASELINE_ACTIONS = ("build", "accept", "revoke", "list")
|
|
INCIDENT_ACTIONS = ("list", "show", "export")
|
|
POSTURE_ACTIONS = ("check",)
|
|
RESPOND_ACTIONS = ("plan",)
|
|
COMPLETION_SHELLS = ("bash", "zsh")
|
|
|
|
|
|
def bash_completion(prog: str = "enodia-sentinel") -> str:
|
|
commands = " ".join(COMMANDS)
|
|
rule_actions = " ".join(RULE_ACTIONS)
|
|
baseline_actions = " ".join(BASELINE_ACTIONS)
|
|
incident_actions = " ".join(INCIDENT_ACTIONS)
|
|
posture_actions = " ".join(POSTURE_ACTIONS)
|
|
respond_actions = " ".join(RESPOND_ACTIONS)
|
|
shells = " ".join(COMPLETION_SHELLS)
|
|
return f"""# bash completion for {prog}
|
|
_{prog.replace('-', '_')}_complete() {{
|
|
local cur prev cmd
|
|
COMPREPLY=()
|
|
cur="${{COMP_WORDS[COMP_CWORD]}}"
|
|
prev="${{COMP_WORDS[COMP_CWORD-1]}}"
|
|
cmd=""
|
|
for word in "${{COMP_WORDS[@]:1}}"; do
|
|
case "$word" in
|
|
-* ) ;;
|
|
* ) cmd="$word"; break ;;
|
|
esac
|
|
done
|
|
if [[ $COMP_CWORD -le 1 || -z "$cmd" ]]; then
|
|
COMPREPLY=( $(compgen -W "--version --config -c {commands}" -- "$cur") )
|
|
return 0
|
|
fi
|
|
case "$cmd" in
|
|
rules) COMPREPLY=( $(compgen -W "{rule_actions} --json" -- "$cur") ) ;;
|
|
baseline) COMPREPLY=( $(compgen -W "{baseline_actions} --reason --expires --force --stale --json" -- "$cur") ) ;;
|
|
incident) COMPREPLY=( $(compgen -W "{incident_actions} --json" -- "$cur") ) ;;
|
|
posture) COMPREPLY=( $(compgen -W "{posture_actions} --json" -- "$cur") ) ;;
|
|
respond) COMPREPLY=( $(compgen -W "{respond_actions} --json" -- "$cur") ) ;;
|
|
completion) COMPREPLY=( $(compgen -W "{shells}" -- "$cur") ) ;;
|
|
check|fim-check|status) COMPREPLY=( $(compgen -W "--json --packages" -- "$cur") ) ;;
|
|
pkgdb-verify) COMPREPLY=( $(compgen -W "--sample" -- "$cur") ) ;;
|
|
watchdog) COMPREPLY=( $(compgen -W "--url --token --max-age --insecure-tls" -- "$cur") ) ;;
|
|
esac
|
|
}}
|
|
complete -F _{prog.replace('-', '_')}_complete {prog}
|
|
"""
|
|
|
|
|
|
def zsh_completion(prog: str = "enodia-sentinel") -> str:
|
|
command_specs = " ".join(f"{c}:{c}" for c in COMMANDS)
|
|
return f"""#compdef {prog}
|
|
# zsh completion for {prog}
|
|
local -a commands
|
|
commands=({command_specs})
|
|
|
|
_arguments -C \\
|
|
'(-h --help)'{{-h,--help}}'[show help]' \\
|
|
'--version[show version]' \\
|
|
'(-c --config)'{{-c,--config}}'[path to TOML config]:config file:_files' \\
|
|
'1:command:->command' \\
|
|
'*::arg:->args'
|
|
|
|
case $state in
|
|
command)
|
|
_describe 'command' commands
|
|
;;
|
|
args)
|
|
case $words[2] in
|
|
rules) _arguments '1:action:((list show test docs))' '--json[emit JSON]' ;;
|
|
baseline) _arguments '1:action:((build accept revoke list))' '2:kind:((fim pkgfile listener suid))' '--reason[reason]' '--expires[TTL]' '--force[force]' '--stale[stale]' '--json[emit JSON]' ;;
|
|
incident) _arguments '1:action:((list show export))' '--json[emit JSON]' ;;
|
|
posture) _arguments '1:action:((check))' '--json[emit JSON]' ;;
|
|
respond) _arguments '1:action:((plan))' '--json[emit JSON]' ;;
|
|
completion) _arguments '1:shell:((bash zsh))' ;;
|
|
check|status) _arguments '--json[emit JSON]' ;;
|
|
fim-check) _arguments '--packages[verify package-owned files]' ;;
|
|
pkgdb-verify) _arguments '--sample[package sample size]' ;;
|
|
watchdog) _arguments '--url[dashboard URL]' '--token[bearer token]' '--max-age[seconds]' '--insecure-tls[allow self-signed TLS]' ;;
|
|
esac
|
|
;;
|
|
esac
|
|
"""
|
|
|
|
|
|
def script(shell: str, prog: str = "enodia-sentinel") -> str:
|
|
if shell == "bash":
|
|
return bash_completion(prog)
|
|
if shell == "zsh":
|
|
return zsh_completion(prog)
|
|
raise ValueError(f"unsupported shell: {shell}")
|