Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,18 @@
# contrail-introspect-cli

## SSL Support
This is a very slightly modified fork of https://github.com/vcheny/contrail-introspect-cli
The modifications are to add support for SSL enabled introspect endpoints.
When SSL is enabled we need to use SSL/TLS Client Authentication. The modifications allow passing of client side cert/key pair and a CA.
```set_ssl_envs``` contains example environment variable settings.
Alternatively use ```--key_file, --ca_file & --cert_file``` to pass as CLI arguments.
see ```ist.py --help``` for more details.

If easyRSA (e.g. via juju charm) has been used to generate CA & certs for the introspect APIs, the ```set_ssl_envs``` file and the referenced certs & key can be generated with https://github.com/dannyvernals/contrail-gen-introspect-cert

The rest of the README is verbatim from https://github.com/vcheny/contrail-introspect-cli

## Introduction
This script provides a Contrail CLI command mainly for troublelshooting prupose. It retrieves XML output from introspect services provided by Contrail main components e.g. control, config and comptue(vrouter) nodes and makes them CLI friendly.

Contrail 2.22+ is supported.
Expand Down
4 changes: 4 additions & 0 deletions clear_ssl_vars
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export SSL_KEY_FILE=""
export SSL_CA_FILE=""
export SSL_CERT_FILE=""

75 changes: 51 additions & 24 deletions ist.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,14 @@
}

class Introspect:
def __init__ (self, host, port, filename):

self.host_url = "http://" + host + ":" + str(port) + "/"
def __init__ (self, host, port, filename, ssl_vars):
if ssl_vars["cert_file"]:
self.host_url = "https://" + host + ":" + str(port) + "/"
self.ssl_vars = ssl_vars
self.has_ssl = True
else:
self.host_url = "http://" + host + ":" + str(port) + "/"
self.has_ssl = False
self.filename = filename

def get (self, path):
Expand All @@ -73,7 +78,13 @@ def get (self, path):
headers['X-Auth-Token'] = token
if debug: print "DEBUG: retrieving url " + url
try:
response = requests.get(url,headers=headers)
if self.has_ssl:
response = requests.get(url,headers=headers,
verify=self.ssl_vars["ca_file"],
cert=(self.ssl_vars["cert_file"], self.ssl_vars["key_file"])
)
else:
response = requests.get(url,headers=headers)
response.raise_for_status()
except requests.exceptions.HTTPError:
print 'The server couldn\'t fulfill the request.'
Expand Down Expand Up @@ -582,7 +593,7 @@ class CLI_basic(object):
common_parser.add_argument('--max_width', type=int,
help="Max width per column")

def __init__(self, parser, host, port, filename):
def __init__(self, parser, host, port, filename, ssl_vars):

host = host or '127.0.0.1'
if port is None:
Expand All @@ -592,7 +603,7 @@ def __init__(self, parser, host, port, filename):
except:
port = self.IntrospectPortMap[ServiceMap[cli_type] + ':0']

self.IST = Introspect(host, port, filename)
self.IST = Introspect(host, port, filename, ssl_vars)

self.subparser = parser.add_subparsers()

Expand Down Expand Up @@ -696,8 +707,8 @@ class CLI_nodemgr_analytics(CLI_basic):

class CLI_cfg_schema(CLI_basic):

def __init__(self, parser, host, port, filename):
CLI_basic.__init__(self, parser, host, port, filename)
def __init__(self, parser, host, port, filename, ssl_vars):
CLI_basic.__init__(self, parser, host, port, filename, ssl_vars)
self.add_parse_args()

def add_parse_args(self):
Expand Down Expand Up @@ -760,8 +771,8 @@ def SnhStObjectReq(self, args):

class CLI_cfg_svcmon(CLI_basic):

def __init__(self, parser, host, port, filename):
CLI_basic.__init__(self, parser, host, port, filename)
def __init__(self, parser, host, port, filename, ssl_vars):
CLI_basic.__init__(self, parser, host, port, filename, ssl_vars)
self.add_parse_args()

def add_parse_args(self):
Expand All @@ -782,8 +793,8 @@ def SnhServiceInstanceList(self, args):

class CLI_ctr(CLI_basic):

def __init__(self, parser, host, port, filename):
CLI_basic.__init__(self, parser, host, port, filename)
def __init__(self, parser, host, port, filename, ssl_vars):
CLI_basic.__init__(self, parser, host, port, filename, ssl_vars)
self.add_parse_args()

def add_parse_args(self):
Expand Down Expand Up @@ -1302,8 +1313,8 @@ def SnhShowRoute(self, args):
self.IST.showRoute_CTR(args.last, mode)

class CLI_vr(CLI_basic):
def __init__(self, parser, host, port, filename):
CLI_basic.__init__(self, parser, host, port, filename)
def __init__(self, parser, host, port, filename, ssl_vars):
CLI_basic.__init__(self, parser, host, port, filename, ssl_vars)
self.add_parse_args()

def add_parse_args(self):
Expand Down Expand Up @@ -1843,8 +1854,8 @@ def SnhShowIFMap(self, args):

class CLI_collector(CLI_basic):

def __init__(self, parser, host, port, filename):
CLI_basic.__init__(self, parser, host, port, filename)
def __init__(self, parser, host, port, filename, ssl_vars):
CLI_basic.__init__(self, parser, host, port, filename, ssl_vars)
self.add_parse_args()

def add_parse_args(self):
Expand Down Expand Up @@ -1997,22 +2008,38 @@ def main():
if '--debug' in argv:
debug = True

ssl_vars = dict()
try:
ssl_vars['key_file'] = argv[argv.index('--key_file') + 1]
except ValueError:
ssl_vars['key_file'] = os.environ.get('SSL_KEY_FILE', None)
try:
ssl_vars['ca_file'] = argv[argv.index('--ca_file') + 1]
except ValueError:
ssl_vars['ca_file'] = os.environ.get('SSL_CA_FILE', None)
try:
ssl_vars['cert_file'] = argv[argv.index('--cert_file') + 1]
except ValueError:
ssl_vars['cert_file'] = os.environ.get('SSL_CERT_FILE', None)
parser = argparse.ArgumentParser(prog='ist',
description='A script to make Contrail Introspect output CLI friendly.')
parser.add_argument('--version', action="store_true", help="Script version")
parser.add_argument('--debug', action="store_true", help="Verbose mode")
parser.add_argument('--host', type=str, help="Introspect host address. Default: localhost")
parser.add_argument('--port', type=int, help="Introspect port number")
parser.add_argument('--proxy', type=str, help="Introspect proxy URL")
parser.add_argument('--token', type=str, help="Token for introspect proxy requests")
parser.add_argument('--file', type=str, help="Introspect file")
parser.add_argument('--version', action="store_true", help="Script version")
parser.add_argument('--debug', action="store_true", help="Verbose mode")
parser.add_argument('--host', type=str, help="Introspect host address. Default: localhost")
parser.add_argument('--port', type=int, help="Introspect port number")
parser.add_argument('--proxy', type=str, help="Introspect proxy URL")
parser.add_argument('--token', type=str, help="Token for introspect proxy requests")
parser.add_argument('--file', type=str, help="Introspect file")
parser.add_argument('--key_file', type=str, help="SSL key file, alternatively set SSL_KEY_FILE env var")
parser.add_argument('--ca_file', type=str, help="SSL ca file, alternatively set SSL_CA_FILE env var")
parser.add_argument('--cert_file', type=str, help="SSL cert file, alternatively set SSL_CERT_FILE env var")

roleparsers = parser.add_subparsers()

for svc in sorted(ServiceMap.iterkeys()):
p = roleparsers.add_parser(svc, help=ServiceMap[svc])
if 'CLI_%s' % (svc) in globals():
globals()['CLI_%s' % (svc)](p, host, port, filename)
globals()['CLI_%s' % (svc)](p, host, port, filename, ssl_vars)

args, unknown = parser.parse_known_args()
args.func(args)
Expand Down
3 changes: 3 additions & 0 deletions set_ssl_envs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export SSL_KEY_FILE="/etc/contrail/ssl/private/server-privkey.pem"
export SSL_CA_FILE="/etc/contrail/ssl/certs/ca-cert.pem"
export SSL_CERT_FILE="/etc/contrail/ssl/certs/server.pem"