.. _command_line_tooling: **************************** Command Line Interface (CLI) **************************** Command line interface tools are written in Python and therefore install Python 3 before starting to enhance existing tooling. As CLI tools are bundled in a python package refer to this `Guide `_ for basics about python package management. To build nice and beautiful interfaces use python package `Click `_ . This enables easy to use defaults and prevent us from writing too much boilerplate code. Package Structure ----------------- The basic package structure is: :: ├── tooling ├── setup.py ├── common │ ├── __about__.py │ └── __init__.py ├── management │ ├── __init__.py │ └── management_cli.py ├── utils │ ├── __init__.py │ └── outputhandler.py ``setup.py`` can be used to add additional scripts or needed dependencies. The module folder ``management`` contains the python scripts which implements the business logic and this is the place where new functions or scripts needs to be implemented. The scripts within common folder were used when installing the tool using pip. Folder utils holds some dictinary elements and helper functions. They do not need to be changed when adding new business code .. important:: Do not change the structure or rename existing files in root package because docker build process use ``setup.py`` as entrypoint to install the CLI packages. Scenario -------- Let´s creating a scenario where you would like to give the administrator access to a Metrics Endpoint which is exposed vi Proxy´s Management API. Assuming Endpoint for this is http://localhost:8888, path to Endpoint is /metrics and you like to add a simple HTTP GET which prints the response on console. You can implement this by: * adding a new command to existing command line tool * creating a new command line tool Example One - Add a new command ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ In this first example the command line call for the above mentioned scenario should be ``appsuite-proxy metrics -s`` Let´s start adding a function to existing script ``management_cti.py``: .. code-block:: python @management_cli.command() @click.option('-s', "show,", default=False, show_default='False', is_flag=True, help="Prints metric on console") @click.option('--baseurl', default='http://127.0.0.1:8888', show_default='http://127.0.0.1:8888', prompt=True, help='Base URL to proxy`s management API') def metric(show, baseurl): """Request Metrics Endpoints. For further information refer to API documentation.""" path = 'metrics' try: if show: resp = requests.get(baseurl + '/' + path) print('Proxy Response: [{}]'.format(resp.status_code)) print('Metrics:') print(json.dumps(resp.json())) else: print('Did not find proper option. Run script with --h') except Exception: traceback.print_exc() That is all you need to do. The decorator style from python´s click package will do all the needed stuff to create a nice output. To test your changes create a new docker image, start the container with enabled API Management Endpoint (see installation / admin guide), login to docker console and run ``appsuite-proxy --help``. Section commands lists the newly created metric function available as command. :: root@e985276d7f68:/# appsuite-proxy --help Usage: appsuite-proxy [OPTIONS] COMMAND [ARGS]... Command line tool can be used to perform management tasks from shell which basically invoke Appsuite Proxy`s REST API Endpoints. Options: -u, --baseurl TEXT Base URL to proxy`s management API [default: (http://127.0.0.1:8888)] --debug Show debug output in case of any errors [default: (False)]] --version Show the version and exit. -h, --help Show this message and exit. Commands: config Actions calling Appsuite Proxy`s configuration endpoint health Actions calling Appsuite Proxy`s health endpoint metrics Actions calling Appsuite Proxy`s metrics endpoint Run 'appsuite-proxy COMMAND --help' for more information Let`s use it by calling ``appsuite-proxy metric -s``. The output should be something like this: :: root@4e973434179a:/# appsuite-proxy metric -s Baseurl [http://127.0.0.1:8888]: Proxy Response: [200] Metrics: # HELP zuul_filter_concurrency_current No help available # TYPE zuul_filter_concurrency_current gauge zuul_filter_concurrency_current{id="InitOidcSso.end",} 0.0 zuul_filter_concurrency_current{id="HttpRedirectFilter.end",} 0.0 zuul_filter_concurrency_current{id="GZipResponseCustomFilter.out",} 0.0 zuul_filter_concurrency_current{id="ProxyPassFilter.in",} 0.0 zuul_filter_concurrency_current{id="HttpSimpleResponseFilter.end",} 0.0 zuul_filter_concurrency_current{id="HeaderHandlingFilter.in",} 0.0 zuul_filter_concurrency_current{id="ZuulResponseFilter.out",} 0.0 Example Two - Create a new command line tool ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ In this second example the command line call for the above mentioned scenario should be ``metrics -s``. Therefore we need to create a new python script which ends up in an additional command line tool apart from the enhanced ``appsuite-proxy`` which we changed in our first example. Let´s start with a new script ``metrics_cli.py`` and place it in ``tooling/management``. Implement the needed logic: .. code-block:: python import click import requests import traceback @click.group() def metrics_cli(): """ CLI Documentation """ pass @metrics_cli.command() @click.option('-s', "show", default=False, show_default='False', is_flag=True, help="Print metrics") @click.option('--baseurl', default='http://127.0.0.1:8888', show_default='http://127.0.0.1:8888', prompt=True, help='Base URL to proxy`s management API') def metric(show, baseurl): """Request Metrics Endpoints""" path = 'metrics' try: if show: resp = requests.get(baseurl + '/' + path) print('Proxy Response: [{}]'.format(resp.status_code)) print('Metrics:') print(resp.content) else: print('Did not find proper option. run script with --h') except Exception: traceback.print_exc() if __name__ == '__main__': metrics_cli() Create a new entry point in our base setup script ``setup.py`` .. code-block:: python entry_points={ 'console_scripts': [ 'appsuite-proxy=management.management_cli:management_cli', 'metrics=management.metrics_cli:metrics_cli', ], }, To test your changes create a new docker image, start the container with enabled API Management Endpoint (see section :ref:`Management Endpoint ` in administration guide). and login to docker console and run Run ``metrics --help`` :: root@b1ebae43322d:/# metric --help Usage: metrics [OPTIONS] COMMAND [ARGS]... CLI Documentation Options: --help Show this message and exit. Commands: metric Request Metrics Endpoints Run ``metric -s`` to test your script. Result should be something like this: :: root@4e973434179a:/# metric -s Baseurl [http://127.0.0.1:8888]: Proxy Response: [200] Metrics: # HELP zuul_filter_concurrency_current No help available # TYPE zuul_filter_concurrency_current gauge zuul_filter_concurrency_current{id="InitOidcSso.end",} 0.0 zuul_filter_concurrency_current{id="HttpRedirectFilter.end",} 0.0 zuul_filter_concurrency_current{id="GZipResponseCustomFilter.out",} 0.0 zuul_filter_concurrency_current{id="ProxyPassFilter.in",} 0.0 zuul_filter_concurrency_current{id="HttpSimpleResponseFilter.end",} 0.0 zuul_filter_concurrency_current{id="HeaderHandlingFilter.in",} 0.0 zuul_filter_concurrency_current{id="ZuulResponseFilter.out",} 0.0 CLI Docker Image ---------------- Alternatively you can use the appsuite-proxy-cli docker image which includes the clt. You can build it with gradle ``./gradlew buildCliImage``. To use it you need just to run the image, e.g. ``docker run ImageId``. This will show you the help text and you can just add options or commands on your next docker run call, e.g. ``docker run ImageId -v config get``.