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:

<projectroot>
├── 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:

@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:

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

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 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.