diff --git a/README.md b/README.md index 8e1d8d0..37a8d41 100644 --- a/README.md +++ b/README.md @@ -183,4 +183,12 @@ Code review will be happening on github. If everything is nice, you should squas ``` git rebase --interactive git push --force -``` \ No newline at end of file +``` + +### Argcomplete + +https://kislyuk.github.io/argcomplete/ + +Is a argparse extension that registers the command line arguments for bash. It requires a command line command to register it globally. This is added to init.sh + +The configuration will be set in /etc/bash_completion.d/ . Keep in mind: It will require a shell restart to be activated \ No newline at end of file diff --git a/caldera_control.py b/caldera_control.py index ba70683..0880861 100755 --- a/caldera_control.py +++ b/caldera_control.py @@ -1,9 +1,10 @@ #!/usr/bin/env python3 - +# PYTHON_ARGCOMPLETE_OK """ A command line tool to control a caldera server """ import argparse from pprint import pprint +import argcomplete # from app.calderacontrol import CalderaControl from app.calderaapi_4 import CalderaAPI @@ -319,6 +320,7 @@ def create_parser(): if __name__ == "__main__": parser = create_parser() + argcomplete.autocomplete(parser) args = parser.parse_args() print(args.caldera_url) diff --git a/doc_generator.py b/doc_generator.py index 6415a34..80feb7e 100755 --- a/doc_generator.py +++ b/doc_generator.py @@ -1,8 +1,9 @@ #!/usr/bin/env python3 - +# PYTHON_ARGCOMPLETE_OK """ Generate human readable document describing the attack based on an attack log """ import argparse +import argcomplete from app.doc_generator import DocGenerator DEFAULT_ATTACK_LOG = "removeme/loot/2021_09_08___07_41_35/attack.json" # FIN 7 first run on environment @@ -10,16 +11,18 @@ DEFAULT_ATTACK_LOG = "removeme/loot/2021_09_08___07_41_35/attack.json" # FIN 7 def create_parser(): """ Creates the parser for the command line arguments""" - parser = argparse.ArgumentParser("Controls an experiment on the configured systems") + lparser = argparse.ArgumentParser("Controls an experiment on the configured systems") - parser.add_argument("--attack_log", default=DEFAULT_ATTACK_LOG, help="The attack log the document is based on") - parser.add_argument("--outfile", default="tools/human_readable_documentation/source/contents.rst", help="The default output file") + lparser.add_argument("--attack_log", default=DEFAULT_ATTACK_LOG, help="The attack log the document is based on") + lparser.add_argument("--outfile", default="tools/human_readable_documentation/source/contents.rst", help="The default output file") - return parser + return lparser if __name__ == "__main__": - arguments = create_parser().parse_args() + parser = create_parser() + argcomplete.autocomplete(parser) + arguments = parser.parse_args() dg = DocGenerator() dg.generate(arguments.attack_log, arguments.outfile) diff --git a/experiment_control.py b/experiment_control.py index 504015b..1113cc0 100755 --- a/experiment_control.py +++ b/experiment_control.py @@ -1,7 +1,9 @@ #!/usr/bin/env python3 +# PYTHON_ARGCOMPLETE_OK """ The main tool to run experiments """ import argparse +import argcomplete from app.experimentcontrol import Experiment @@ -36,11 +38,11 @@ def run(args): def create_parser(): """ Creates the parser for the command line arguments""" - parser = argparse.ArgumentParser("Controls an experiment on the configured systems") - subparsers = parser.add_subparsers(help="sub-commands") + lparser = argparse.ArgumentParser("Controls an experiment on the configured systems") + subparsers = lparser.add_subparsers(help="sub-commands") - parser.set_defaults(func=explain) - parser.add_argument('--verbose', '-v', action='count', default=0) + lparser.set_defaults(func=explain) + lparser.add_argument('--verbose', '-v', action='count', default=0) # Sub parser for machine creation parser_run = subparsers.add_parser("run", help="run experiments") @@ -49,9 +51,11 @@ def create_parser(): parser_run.add_argument("--caldera_attack", default=None, help="The id of a specific caldera attack to run, will override experiment configuration for attacks") parser_run.add_argument("--caldera_attack_file", default=None, help="The file name containing a list of caldera attacks to run, will override experiment configuration for attacks") - return parser + return lparser if __name__ == "__main__": - arguments = create_parser().parse_args() + parser = create_parser() + argcomplete.autocomplete(parser) + arguments = parser.parse_args() arguments.func(arguments) diff --git a/init.sh b/init.sh index 4572b40..62acebe 100755 --- a/init.sh +++ b/init.sh @@ -13,4 +13,7 @@ sudo apt-get -y install latexmk texlive-fonts-recommended texlive-latex-recommen python3 -m venv venv source venv/bin/activate -pip3 install -r requirements.txt \ No newline at end of file +pip3 install -r requirements.txt + +# Registering argcomplete globally. See README.md +sudo ./venv/bin/activate-global-python-argcomplete \ No newline at end of file diff --git a/machine_control.py b/machine_control.py index b1780eb..836707e 100644 --- a/machine_control.py +++ b/machine_control.py @@ -1,7 +1,9 @@ #!/usr/bin/env python3 +# PYTHON_ARGCOMPLETE_OK """ Demo program to set up and control the machines """ import argparse +import argcomplete import yaml @@ -89,7 +91,7 @@ def create_parser(): if __name__ == "__main__": parser = create_parser() - + argcomplete.autocomplete(parser) args = parser.parse_args() args.func(args) diff --git a/plugin_manager.py b/plugin_manager.py index 42f4ae3..57aea51 100755 --- a/plugin_manager.py +++ b/plugin_manager.py @@ -1,8 +1,10 @@ #!/usr/bin/env python3 +# PYTHON_ARGCOMPLETE_OK """ Managing plugins """ import argparse import sys +import argcomplete from app.pluginmanager import PluginManager from app.attack_log import AttackLog @@ -66,7 +68,7 @@ def create_parser(): if __name__ == "__main__": parser = create_parser() - + argcomplete.autocomplete(parser) args = parser.parse_args() exval = args.func(args) diff --git a/pydantic_test.py b/pydantic_test.py index 83729ad..79e2b24 100755 --- a/pydantic_test.py +++ b/pydantic_test.py @@ -1,10 +1,12 @@ #!/usr/bin/env python3 - +# PYTHON_ARGCOMPLETE_OK """ A command line tool to verify PurpleDome configuration files """ import argparse from pprint import pprint import sys +import argcomplete + import yaml from app.config_verifier import MainConfig @@ -18,15 +20,17 @@ def load(filename): def create_parser(): """ Creates the parser for the command line arguments""" - parser = argparse.ArgumentParser("Parse a config file and verifies it") + lparser = argparse.ArgumentParser("Parse a config file and verifies it") - parser.add_argument('--filename', default="experiment_ng.yaml") + lparser.add_argument('--filename', default="experiment_ng.yaml") - return parser + return lparser if __name__ == "__main__": - arguments = create_parser().parse_args() + parser = create_parser() + argcomplete.autocomplete(parser) + arguments = parser.parse_args() try: r = load(arguments.filename) except TypeError as e: diff --git a/requirements.txt b/requirements.txt index ddf586e..30906be 100644 --- a/requirements.txt +++ b/requirements.txt @@ -26,3 +26,6 @@ types-PyYAML==5.4.6 types-requests==2.25.6 types-simplejson==3.17.0 types-paramiko==2.7.0 + +# Argcomplete. See README.md +argcomplete==2.0.0 diff --git a/tox.ini b/tox.ini index 24cbb81..fba54b8 100644 --- a/tox.ini +++ b/tox.ini @@ -35,6 +35,7 @@ deps = -r requirements.txt safety bandit pylint + argcomplete commands =