Newer
Older
#!/usr/bin/env python
#coding=utf8
'''
CloudControl CLI command module
'''
from cccli.exception import *
from cccli.printer import color
from sjrpc.client import SimpleRpcClient
from sjrpc.core.exceptions import *
# check valid command chars
if not re.match("^[a-zA-Z0-9]+", argv[0]):
cmdlist = [ x[4:] for x in dir(self) if x.startswith("cmd_") ]
matchlist = [ x for x in cmdlist if re.match("%s.+"%argv[0], x) ]
if argv[0] in cmdlist:
pass
elif len(matchlist) == 1:
argv[0] = matchlist[0]
else:
@classmethod
def usage(cls, cmdname):
'''Return usage of a command'''
fname = "cmd_%s"%cmdname
if not hasattr(cls, fname):
if hasattr(getattr(cls, fname), "usage"):
return getattr(getattr(cls, fname), "usage")
return ""
def call(self):
'''Run command'''
if re.match("^[a-zA-Z0-9]+$", self._argv[0]):
name = "cmd_%s"%self._argv[0]
if hasattr(self, name):
cmd = getattr(self, name)
return cmd(self._argv)
def cmd_exit(self, argv):
'''Quit application with respect'''
raise SystemExit()
cmd_exit.usage = "exit"
cmd_exit.desc = "Quit application with respect"
def cmd_quit(self, argv):
'''Quit application with respect'''
raise SystemExit()
cmd_quit.usage = "quit"
cmd_quit.desc = "Quit application with respect"
def cmd_version(self, argv):
'''Print cli version'''
cmd_version.usage = "version"
cmd_version.desc = "Print cli version"
def cmd_usage(self, argv):
'''Print usage of a command'''
if len(argv) != 2:
cmd_usage.usage = "usage [command]"
cmd_usage.desc = "Print usage of a command"
def cmd_help(self, argv):
'''Print help'''
if len(argv) == 1:
# build command list
cmdlist = list()
doclist = list()
for x in dir(self):
m = re.match("^cmd_([a-zA-Z0-9]+)$", x)
if m:
cmdlist.append(m.group(1))
if hasattr(getattr(self, x), "__doc__"):
doclist.append(getattr(getattr(self, x), "__doc__"))
# printing commands list
width = max(map(len, cmdlist)) + 3
self.printer.out("%sCommands:%s"%(color["lwhite"], color["reset"]))
for c, d in zip(cmdlist, doclist):
line = "%s"%c
line = line.ljust(width,)
line += "- %s"%d
elif len(argv) == 2:
fname = "cmd_%s"%argv[1]
if hasattr(self, fname):
if hasattr(getattr(self, fname), "__doc__"):
self.printer.out("Description: %s"%getattr(getattr(self, fname), "__doc__"))
self.printer.out("Usage: %s"%getattr(getattr(self, fname), "usage"))
Self.Printer.out("Details: %s"%getattr(getattr(self, fname), "details"))
cmd_help.usage = "help [command]"
cmd_help.desc = "Print help about a command"
def cmd_alias(self, argv):
'''Show or create alias'''
if len(argv) == 1:
for n, v in self.cli.alias.items():
elif len(argv) == 2:
if argv[1] not in self.cli.alias:
self.printer.out("%s=%s"%(argv[1], self.cli.alias[argv[1]]))
elif len(argv) == 3:
self.cli.alias[argv[1]] = argv[2]
cmd_alias.usage = "alias [name] [value]"
cmd_alias.desc = "Show or create aliases"
def cmd_unalias(self, argv):
'''Remove an alias'''
if len(argv) != 2:
cmd_unalias.usage = "unalias [name]"
cmd_unalias.desc = "Remove an aliases"
def cmd_rcmd(self, argv):
'''Show remote commands'''
for cmds in self.cli.rpc.list_commands():
cmd_rcmd.usage = "rcmd"
cmd_rcmd.desc = "Print remote command list"
def cmd_history(self, argv):
'''Show history of commands'''
cmd_history.usage = "history"
cmd_history.desc = "Show commands history"
oparser = OptionParser(prog="list")
oparser.add_option("-t", action="store_true", dest="table")
(options, args) = oparser.parse_args(argv[1:])
except SystemExit:
return
if len(args) == 0:
args.append("a")
try:
objs = self.cli.rpc.list(str.join("", args))
except RpcError as e:
raise cmdError("RPCError: %s"%str(e))
if options.table:
self._list_table(objs)
else:
self._list(objs)
cmd_list.usage = "list [tql]"
def _list(self, objs):
for o in objs:
id = o.pop("id")
tags = " ".join([ "%s%s:%s%s"%(color["green"], t, color["reset"], v) for (t,v) in o.items() ])
self.printer.out("%sid:%s%s %s"%(color["green"], color["yellow"], id, tags))
def _list_table(self, objs):
# get all tag list
tags = dict()
for o in objs:
for t,v in o.items():
tags[t] = max(len(str(v)), tags.get(t, len(str(t))))
# extract id info
idsize = tags.pop("id")
# print titles
self.printer.out(color["green"], nl="")
self.printer.out("id".ljust(idsize+1), nl=" ")
for t,v in tags.items():
self.printer.out(t.ljust(v), nl=" ")
# print obj
for obj in objs:
self.printer.out("%s%s%s"%(color["yellow"], obj.pop("id").ljust(idsize+1), color["reset"]) ,nl=" ")
for (t, v) in tags.items():
self.printer.out(str(obj.get(t, "")).ljust(v) ,nl=" ")
self.printer.out()
def _startstopsdestroypauseresume(self, argv):
# arg stuff
if len(argv) == 1:
try:
objs = self.cli.rpc.list(tql)
except RpcError as e:
raise cmdError("RPCError: %s"%str(e))
if len(objs) == 0:
raise cmdWarning("No selected object")
self.printer.out("You request give the following result:")
for obj in objs:
self.printer.out("%sid:%s%s%s"%(color["green"],color["yellow"],obj["id"],color["reset"]))
self.printer.out("%sCount: %s%s"%(color["green"],color["reset"], len(objs)))
if self.printer.ask("Are you sure to %s%s%s these %s id? (yes/NO) "%(color["lred"],
argv[0],
color["reset"],
len(objs)), "yes") != "yes":
if self.printer.ask("You request is on more than 5 objets. Are you really sure to %s its? (Yes, I am) "%argv[0], "Yes, I am") != "Yes, I am":
try:
self.cli.rpc[argv[0]](tql)
except RpcError as e:
raise cmdError("RPCError: %s"%str(e))
'''Start objects'''
self._startstopsdestroypauseresume(argv)
def cmd_stop(self, argv):
'''Stop objects'''
self._startstopsdestroypauseresume(argv)
cmd_stop.usage = "stop [tql]"
def cmd_pause(self, argv):
'''Pause objects'''
self._startstopsdestroypauseresume(argv)
cmd_pause.usage = "pause [tql]"
def cmd_resume(self, argv):
'''Resume objects'''
self._startstopsdestroypauseresume(argv)
cmd_resume.usage = "resume [tql]"
def cmd_destroy(self, argv):
'''Force objects to stop'''
self._startstopsdestroypauseresume(argv)
cmd_destroy.usage = "destroy [tql]"
def cmd_clear(self, argv):
'''Clear tty'''
self.printer.out("\033[H\033[2J", nl="")
cmd_clear.usage = "clear"
def cmd_uptime(self, argv):
'''Show connection uptime'''
if len(argv) == 1:
argv.append(self.cli.settings["login"])
tql = "a~(%s)$con"%"|".join(argv[1:])
try:
objs = self.cli.rpc.list(tql)
except RpcError as e:
raise cmdError("RPCError: %s"%str(e))
for o in objs:
self.printer.out("%s: %ss"%(o["a"],o["con"]))
cmd_uptime.usage = "uptime [login]"
def cmd_addtag(self, argv):
'''Add/Modify a tag on an account'''
if len(argv) != 4:
raise cmdBadArgument()
try:
self.cli.rpc.settag(argv[1], argv[2], argv[3])
except RpcError as e:
raise cmdError("RPCError: %s"%str(e))
if len(argv) != 3:
raise cmdBadArgument()
try:
self.cli.rpc.deltag(argv[1], argv[2])
except RpcError as e:
raise cmdError("RPCError: %s"%str(e))
cmd_deltag.usage = "deltag <account> <tag>"
def cmd_addaccount(self, argv):
'''Create an account'''
if len(argv) != 2:
raise cmdBadArgument()
try:
self.cli.rpc.addaccount(argv[1])
except RpcError as e:
raise cmdError("RPCError: %s"%str(e))
cmd_addaccount.usage = "addaccount <name>"
def cmd_delaccount(self, argv):
'''Delete an account'''
if len(argv) != 2:
raise cmdBadArgument()
try:
self.cli.rpc.delaccount(argv[1])
except RpcError as e:
raise cmdError("RPCError: %s"%str(e))
cmd_delaccount.usage = "delaccount <name>"
def cmd_passwd(self, argv):
'''Change account password'''
if len(argv) == 2:
if not self.cli.interactive:
raise cmdError("You must give a password argument in non interactive mode!")
a = self.printer.getpass("Password: ")
b = self.printer.getpass("Again: ")
if a != b:
raise cmdError("You don't type twice the same password. Aborted")
argv.append(a)
elif len(argv) == 3:
if self.cli.interactive:
s = "You cannot set password with clear argument in interactive mode.\n"
s += "*** Think to clean your history! ***"
raise cmdError(s)
else:
raise cmdBadArgument()
try:
self.cli.rpc.passwd(argv[1], argv[2])
except RpcError as e:
raise cmdError("RPCError: %s"%str(e))
cmd_passwd.usage = "passwd <account> [password]"
class Alias(dict):
''' Alias wrapper'''
def load(self, filename):
'''load alias from file'''
if os.access(filename, os.R_OK):
fparser = ConfigParser.SafeConfigParser()
fparser.read(filename)
if fparser.has_section("alias"):
self.clear()
self.update(fparser.items("alias"))
def save(self, filename):
'''save alias on file'''
if os.access(filename, os.R_OK or os.W_OK):
fparser = ConfigParser.SafeConfigParser()
fparser.read(filename)
fparser.remove_section("alias")
fparser.add_section("alias")
for n,v in self.items():
fparser.set("alias", n, v)
fparser.write(open(filename, "w"))