mirror of https://github.com/apache/cloudstack.git
cli: Pygments based output in cloudmonkey and new cfg processing
- Pygments based colored output for tabular and normal list outputs - Fix cfg processing as per new cfg paths and ds - Get rid of clint and old way of parsing and color printing Signed-off-by: Rohit Yadav <bhaisaab@apache.org>
This commit is contained in:
parent
233c0adcf3
commit
cb8705c756
|
|
@ -20,7 +20,6 @@
|
|||
try:
|
||||
import atexit
|
||||
import cmd
|
||||
import clint
|
||||
import codecs
|
||||
import json
|
||||
import logging
|
||||
|
|
@ -32,14 +31,15 @@ try:
|
|||
import time
|
||||
import types
|
||||
|
||||
from clint.textui import colored
|
||||
from ConfigParser import ConfigParser, SafeConfigParser
|
||||
from urllib2 import HTTPError, URLError
|
||||
from httplib import BadStatusLine
|
||||
|
||||
from prettytable import PrettyTable
|
||||
from common import __version__, config_file, config_fields
|
||||
from common import __version__, config_dir, config_file, config_fields
|
||||
from common import precached_verbs
|
||||
from lexer import monkeyprint
|
||||
|
||||
from marvin.cloudstackConnection import cloudConnection
|
||||
from marvin.cloudstackException import cloudstackAPIException
|
||||
from marvin.cloudstackAPI import *
|
||||
|
|
@ -70,37 +70,47 @@ class CloudMonkeyShell(cmd.Cmd, object):
|
|||
intro = ("☁ Apache CloudStack 🐵 cloudmonkey " + __version__ +
|
||||
". Type help or ? to list commands.\n")
|
||||
ruler = "="
|
||||
config_dir = config_dir
|
||||
config_file = config_file
|
||||
config_fields = config_fields
|
||||
# datastructure {'verb': {cmd': ['api', [params], doc, required=[]]}}
|
||||
cache_verbs = precached_verbs
|
||||
config_options = []
|
||||
|
||||
def __init__(self, pname, verbs):
|
||||
self.program_name = pname
|
||||
self.verbs = verbs
|
||||
global config_fields
|
||||
first_time = False
|
||||
if not os.path.exists(self.config_dir):
|
||||
os.makedirs(self.config_dir)
|
||||
if os.path.exists(self.config_file):
|
||||
config = self.read_config()
|
||||
else:
|
||||
for key in self.config_fields.keys():
|
||||
setattr(self, key, self.config_fields[key])
|
||||
config = self.write_config()
|
||||
first_time = True
|
||||
config = self.write_config(first_time)
|
||||
|
||||
for section in config_fields.keys():
|
||||
for key in config_fields[section].keys():
|
||||
try:
|
||||
self.config_options.append(key)
|
||||
setattr(self, key, config.get(section, key))
|
||||
except Exception:
|
||||
print "Please fix `%s` in %s" % (key, self.config_file)
|
||||
sys.exit()
|
||||
|
||||
if first_time:
|
||||
print "Welcome! Using `set` configure the necessary settings:"
|
||||
print " ".join(sorted(self.config_fields.keys()))
|
||||
print " ".join(sorted(self.config_options))
|
||||
print "Config file:", self.config_file
|
||||
print "For debugging, tail -f", self.log_file, "\n"
|
||||
|
||||
for key in self.config_fields.keys():
|
||||
try:
|
||||
setattr(self, key, config.get('CLI', key))
|
||||
self.config_fields[key] = config.get('CLI', key)
|
||||
except Exception:
|
||||
print "Please fix `%s` config in %s" % (key, self.config_file)
|
||||
sys.exit()
|
||||
|
||||
self.prompt = self.prompt.strip() + " " # Cosmetic fix for prompt
|
||||
|
||||
logging.basicConfig(filename=self.log_file,
|
||||
level=logging.DEBUG, format=log_fmt)
|
||||
logger.debug("Loaded config fields:\n%s" % self.config_fields)
|
||||
logger.debug("Loaded config fields:\n%s" % map(lambda x: "%s=%s" %
|
||||
(x, getattr(self, x)),
|
||||
self.config_options))
|
||||
|
||||
cmd.Cmd.__init__(self)
|
||||
if not os.path.exists(self.config_file):
|
||||
|
|
@ -122,11 +132,16 @@ class CloudMonkeyShell(cmd.Cmd, object):
|
|||
self.print_shell("Error: config_file not found", e)
|
||||
return config
|
||||
|
||||
def write_config(self):
|
||||
def write_config(self, first_time=False):
|
||||
global config_fields
|
||||
config = ConfigParser()
|
||||
config.add_section('CLI')
|
||||
for key in self.config_fields.keys():
|
||||
config.set('CLI', key, getattr(self, key))
|
||||
for section in config_fields.keys():
|
||||
config.add_section(section)
|
||||
for key in config_fields[section].keys():
|
||||
if first_time:
|
||||
config.set(section, key, config_fields[section][key])
|
||||
else:
|
||||
config.set(section, key, getattr(self, key))
|
||||
with open(self.config_file, 'w') as cfg:
|
||||
config.write(cfg)
|
||||
return config
|
||||
|
|
@ -144,35 +159,19 @@ class CloudMonkeyShell(cmd.Cmd, object):
|
|||
print("^C")
|
||||
|
||||
def print_shell(self, *args):
|
||||
output = ""
|
||||
try:
|
||||
for arg in args:
|
||||
arg = str(arg)
|
||||
if isinstance(type(args), types.NoneType):
|
||||
continue
|
||||
if self.color == 'true':
|
||||
if str(arg).count(self.ruler) == len(str(arg)):
|
||||
print colored.green(arg),
|
||||
elif 'Error' in arg:
|
||||
print colored.red(arg),
|
||||
elif ":\n=" in arg:
|
||||
print colored.red(arg),
|
||||
elif ':' in arg:
|
||||
print colored.blue(arg),
|
||||
elif 'type' in arg:
|
||||
print colored.green(arg),
|
||||
elif 'state' in arg or 'count' in arg:
|
||||
print colored.magenta(arg),
|
||||
elif 'id =' in arg:
|
||||
print colored.yellow(arg),
|
||||
elif 'name =' in arg:
|
||||
print colored.cyan(arg),
|
||||
else:
|
||||
print arg,
|
||||
else:
|
||||
print arg,
|
||||
print
|
||||
output += arg
|
||||
if self.color == 'true':
|
||||
monkeyprint(output)
|
||||
else:
|
||||
print output
|
||||
except Exception, e:
|
||||
print colored.red("Error: "), e
|
||||
self.print_shell("Error: " + e)
|
||||
|
||||
def print_result(self, result, result_filter=None):
|
||||
if result is None or len(result) == 0:
|
||||
|
|
@ -180,7 +179,7 @@ class CloudMonkeyShell(cmd.Cmd, object):
|
|||
|
||||
def printer_helper(printer, toprow):
|
||||
if printer:
|
||||
print printer
|
||||
self.print_shell(printer)
|
||||
return PrettyTable(toprow)
|
||||
|
||||
def print_result_tabular(result, result_filter=None):
|
||||
|
|
@ -201,16 +200,16 @@ class CloudMonkeyShell(cmd.Cmd, object):
|
|||
if printer and row:
|
||||
printer.add_row(row)
|
||||
if printer:
|
||||
print printer
|
||||
self.print_shell(printer)
|
||||
|
||||
def print_result_as_dict(result, result_filter=None):
|
||||
for key in sorted(result.keys(),
|
||||
key=lambda x: x != 'id' and x != 'count' and x):
|
||||
for key in sorted(result.keys(), key=lambda x:
|
||||
x not in ['id', 'count', 'name'] and x):
|
||||
if not (isinstance(result[key], list) or
|
||||
isinstance(result[key], dict)):
|
||||
self.print_shell("%s = %s" % (key, result[key]))
|
||||
else:
|
||||
self.print_shell(key + ":\n" + len(key) * self.ruler)
|
||||
self.print_shell(key + ":")
|
||||
self.print_result(result[key], result_filter)
|
||||
|
||||
def print_result_as_list(result, result_filter=None):
|
||||
|
|
@ -360,7 +359,7 @@ class CloudMonkeyShell(cmd.Cmd, object):
|
|||
command.required)
|
||||
|
||||
if len(missing_args) > 0:
|
||||
self.print_shell("Missing arguments:", ' '.join(missing_args))
|
||||
self.print_shell("Missing arguments: ", ' '.join(missing_args))
|
||||
return
|
||||
|
||||
isAsync = False
|
||||
|
|
@ -441,7 +440,7 @@ class CloudMonkeyShell(cmd.Cmd, object):
|
|||
def complete_set(self, text, line, begidx, endidx):
|
||||
mline = line.partition(" ")[2]
|
||||
offs = len(mline) - len(text)
|
||||
return [s[offs:] for s in self.config_fields.keys()
|
||||
return [s[offs:] for s in self.config_options
|
||||
if s.startswith(mline)]
|
||||
|
||||
def do_shell(self, args):
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ def get_colorscheme():
|
|||
|
||||
|
||||
class MonkeyLexer(RegexLexer):
|
||||
keywords = ['[a-z]*id', '[a-zA-Z]*:']
|
||||
keywords = ['[a-z]*id', '^[a-z A-Z]*:']
|
||||
attributes = ['[Tt]rue', '[Ff]alse']
|
||||
params = ['[a-z]*[Nn]ame', 'type', '[Ss]tate']
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue