Skip to content
Snippets Groups Projects
Commit 5b5b0e6b authored by Seblu's avatar Seblu
Browse files

Check remote functions in local command

Introduce new class RemoteCommand, which help checking needed remote functions are available
before adding a command to list of commands
parent 55c82c55
No related branches found
No related tags found
No related merge requests found
......@@ -55,18 +55,19 @@ class Cli(object):
self.printer.debug("Loaded history: %s"%len(self.printer.history))
# enable completion
self.printer.completion.set_completer(self._command_completer)
# load commands
# connecting
self._connect()
# auth
self._auth()
# load commands (need to be done after connection)
self.commands = Commands(self)
self.printer.debug("Remote functions: %d"%len(self.commands.functions))
self.printer.debug("Loaded commands: %d"%len(self.commands))
# load alias
self.aliases.load(self.settings.get("alias", None))
self.printer.debug("Loaded aliases: %d"%len(self.aliases))
# load tagdisplay
self.tagdisplay.load(self.settings.get("tagdisplay", ""))
# connecting
self._connect()
# auth
self._auth()
# parsing
self._parse()
# save history
......
......@@ -40,6 +40,9 @@ class Command_addaccount(TqlCommand):
if _pass is not None:
self.rpccall("passwd", "a=%s"%self.args[0], _pass, _direct=True)
def remote_functions(self):
return set(("addaccount", "passwd"))
class Command_delaccount(TqlCommand):
'''Delete an account'''
......@@ -54,6 +57,9 @@ class Command_delaccount(TqlCommand):
raise cmdBadArgument("<tql>")
self.rpccall("delaccount", self.args[0])
def remote_functions(self):
return set(("delaccount",))
class Command_close(TqlCommand):
'''Disable accounts'''
......@@ -68,6 +74,9 @@ class Command_close(TqlCommand):
raise cmdBadArgument("<tql>")
self.rpccall("close", self.args[0])
def remote_functions(self):
return set(("close",))
class Command_declose(TqlCommand):
'''Enable accounts'''
......@@ -82,6 +91,9 @@ class Command_declose(TqlCommand):
raise cmdBadArgument("<tql>")
self.rpccall("declose", self.args[0])
def remote_functions(self):
return set(("declose",))
class Command_passwd(TqlCommand):
'''Change account password'''
......@@ -120,3 +132,6 @@ class Command_passwd(TqlCommand):
raise cmdError("You don't type twice the same password. Aborted")
# execute command
self.rpccall("passwd", _tql, _pass)
def remote_functions(self):
return set(("passwd",))
......@@ -8,13 +8,13 @@ CloudControl jobs command
from cccli.exception import *
from sjrpc.core.exceptions import *
from cccli.printer import Printer, color
from cccli.command.command import OptionCommand
from cccli.command.command import RemoteCommand
class Command_cancel(OptionCommand):
class Command_cancel(RemoteCommand):
'''Cancel a job'''
def __init__(self, cli, argv0):
OptionCommand.__init__(self, cli, argv0)
RemoteCommand.__init__(self, cli, argv0)
self.set_usage("%prog [options] <job_id> ...")
def __call__(self, argv):
......@@ -32,3 +32,6 @@ class Command_cancel(OptionCommand):
self.printer.error("Invalid job id: %s"%jid)
except RpcError as e:
self.printer.error("%s"%e)
def remote_functions(self):
return set(("cancel",))
......@@ -29,7 +29,7 @@ class Command(object):
class OptionCommand(Command):
'''Add options parser to Command'''
'''Commands with options handling'''
class OptionCommandParser(OptionParser):
'''Parser of Option for OptionCommand'''
......@@ -67,12 +67,53 @@ class OptionCommand(Command):
'''Proxy to OptionParser'''
self.optionparser.set_usage(*args, **kwargs)
class TqlCommand(OptionCommand):
'''Add Tql stuff to Command'''
class RemoteCommand(OptionCommand):
'''Command which needs connection to server'''
def __init__(self, cli, argv0):
OptionCommand.__init__(self, cli, argv0)
self.rpc = cli.rpc
def remote_functions(self):
'''Return a set of needed remote functions'''
raise NotImplementedError
def print_objects(self, objectlist, ignore=None, index=False):
'''Trivial objectlist printing of tag'''
if objectlist is None:
return
_order = objectlist.get("order", None)
for (i,o) in enumerate(objectlist["objects"]):
if index:
self.printer.out("[%s] "%i, nl="")
self.print_tags(o, order=_order, ignore=ignore)
def print_tags(self, taglist, order=None, ignore=None):
'''Display a tag with tagdisplay settings'''
ignore = () if ignore is None else ignore
order = () if order is None else order
# copy dict to show
tl = taglist.copy()
# remove ignore tags
for tn in ignore:
tl.pop(tn, None)
# list to print
pls = []
# print firstly order tags
for tn in order:
tv = tl.pop(tn, None)
if tv is not None:
pls.append("%s%s:%s%s"%(self.tdtc(tn), tn, self.tdc(tn), self.tdr(tn, tv)))
# print tags without order, alpha ordered
for tn in sorted(tl.keys()):
pls.append("%s%s:%s%s"%(self.tdtc(tn), tn, self.tdc(tn), self.tdr(tn, tl[tn])))
self.printer.out("%s%s"%(" ".join(pls), color["reset"]))
class TqlCommand(RemoteCommand):
'''Command which handle TQL stuff'''
def __init__(self, cli, argv0):
RemoteCommand.__init__(self, cli, argv0)
self.set_usage("%prog [options] <tql>")
# set tql filter stuff
self.tql_filter = ""
......@@ -214,34 +255,3 @@ class TqlCommand(OptionCommand):
self.print_objects(d, ["output"], index=False)
except RpcError as e:
self.printer.error("RPCError: %s"%str(e))
def print_objects(self, objectlist, ignore=None, index=False):
'''Trivial objectlist printing of tag'''
if objectlist is None:
return
_order = objectlist.get("order", None)
for (i,o) in enumerate(objectlist["objects"]):
if index:
self.printer.out("[%s] "%i, nl="")
self.print_tags(o, order=_order, ignore=ignore)
def print_tags(self, taglist, order=None, ignore=None):
'''Display a tag with tagdisplay settings'''
ignore = () if ignore is None else ignore
order = () if order is None else order
# copy dict to show
tl = taglist.copy()
# remove ignore tags
for tn in ignore:
tl.pop(tn, None)
# list to print
pls = []
# print firstly order tags
for tn in order:
tv = tl.pop(tn, None)
if tv is not None:
pls.append("%s%s:%s%s"%(self.tdtc(tn), tn, self.tdc(tn), self.tdr(tn, tv)))
# print tags without order, alpha ordered
for tn in sorted(tl.keys()):
pls.append("%s%s:%s%s"%(self.tdtc(tn), tn, self.tdc(tn), self.tdr(tn, tl[tn])))
self.printer.out("%s%s"%(" ".join(pls), color["reset"]))
......@@ -30,3 +30,6 @@ class Command_execute(TqlCommand):
self.printer.out("%sid:%s%s%s output:"%(self.tdtc("id"), self.tdc("id"),
o["id"], color["reset"]))
self.printer.out(o.get("output", ""), nl="")
def remote_functions(self):
return set(("execute",))
......@@ -38,3 +38,6 @@ class Command_jobs(TqlCommand):
show_done=self.options.done,
show_running=self.options.running)
self.print_objects(objs, index=self.options.index)
def remote_functions(self):
return set(("jobs",))
......@@ -24,3 +24,6 @@ class Command_kill(TqlCommand):
raise cmdBadArgument()
# rpccall
self.rpccall("kill", self.args[0])
def remote_functions(self):
return set(("kill",))
......@@ -38,6 +38,9 @@ class Command_list(TqlCommand):
else:
self.print_objects(objs, index=self.options.index)
def remote_functions(self):
return set(("list",))
def list_align(self, objs):
'''Listing line aligned'''
# get max size by tag
......
......@@ -69,6 +69,9 @@ class Command_migrate(TqlCommand):
# run migration
self.rpccall("migrate", scrutin, _direct=True)
def remote_functions(self):
return set(("migrate", "electiontypes", "election"))
def get_electiontypes(self):
'''Return a list of migration type'''
try:
......
......@@ -38,6 +38,9 @@ class Command_rights(TqlCommand):
tags = " ".join([ "%s%s:%s%s"%(self.tdtc(t), t, self.tdc(t), v) for (t,v) in r.items() ])
self.printer.out("[%s] %s%s"%(i,tags, color["reset"]))
def remote_functions(self):
return set(('rights',))
class Command_addright(TqlCommand):
'''Add or edit account right'''
......@@ -67,6 +70,10 @@ class Command_addright(TqlCommand):
self.args[3],
self.args[4])
def remote_functions(self):
return set(('addright',))
class Command_delright(TqlCommand):
'''Delete account right'''
......@@ -93,3 +100,6 @@ class Command_delright(TqlCommand):
else:
for index in l:
self.rpccall("delright", self.args[0], index)
def remote_functions(self):
return set(('delright',))
......@@ -7,13 +7,13 @@ CloudControl server command
from cccli.exception import *
from sjrpc.core.exceptions import *
from cccli.printer import Printer, color
from cccli.command.command import OptionCommand
from cccli.command.command import RemoteCommand
class Command_server(OptionCommand):
class Command_server(RemoteCommand):
'''Server manipulation command'''
def __init__(self, cli, argv0):
OptionCommand.__init__(self, cli, argv0)
RemoteCommand.__init__(self, cli, argv0)
self.set_usage("%prog <options>")
self.add_option("-c", action="store_true", dest="cache",
help="show server cache")
......@@ -35,6 +35,9 @@ class Command_server(OptionCommand):
else:
self.printer.out(self.usage())
def remote_functions(self):
return set(('dbstats', 'version'))
def show_functions(self):
try:
for cmds in self.cli.rpc.call("functions"):
......
......@@ -30,3 +30,6 @@ class Command_shutdown(TqlCommand):
raise cmdBadArgument()
self.rpccall("shutdown", self.args[0], self.options.reboot,
self.options.graceful)
def remote_functions(self):
return set(("shutdown",))
......@@ -35,6 +35,9 @@ class Command_tags(TqlCommand):
# display answer
self.print_objects(objs)
def remote_functions(self):
return set(("tags",))
class Command_addtag(TqlCommand):
'''Add/Modify a static tag on an account'''
......@@ -52,6 +55,9 @@ class Command_addtag(TqlCommand):
# rpc call
self.rpccall("addtag", self.args[0], self.args[1], self.args[2])
def remote_functions(self):
return set(("addtag",))
class Command_deltag(TqlCommand):
'''Delete a static tag from an account'''
......@@ -68,3 +74,6 @@ class Command_deltag(TqlCommand):
raise cmdBadArgument()
# rpc call
self.rpccall("deltag", self.args[0], self.args[1])
def remote_functions(self):
return set(("deltag",))
......@@ -23,6 +23,9 @@ class Command_start(TqlCommand):
# rpc call
self.rpccall("start", self.args[0])
def remote_functions(self):
return set(("start",))
class Command_stop(TqlCommand):
'''Stop a running vm'''
......@@ -39,6 +42,9 @@ class Command_stop(TqlCommand):
# rpc call
self.rpccall("stop", self.args[0])
def remote_functions(self):
return set(("stop",))
class Command_destroy(TqlCommand):
'''Force a vm to stop'''
......@@ -55,6 +61,9 @@ class Command_destroy(TqlCommand):
# rpc call
self.rpccall("destroy", self.args[0])
def remote_functions(self):
return set(("destroy",))
class Command_pause(TqlCommand):
'''Pause a running vm'''
......@@ -71,6 +80,9 @@ class Command_pause(TqlCommand):
# rpc call
self.rpccall("pause", self.args[0])
def remote_functions(self):
return set(("pause",))
class Command_resume(TqlCommand):
'''Resume a paused vm'''
......@@ -87,6 +99,9 @@ class Command_resume(TqlCommand):
# rpc call
self.rpccall("resume", self.args[0])
def remote_functions(self):
return set(("resume",))
class Command_undefine(TqlCommand):
'''Undefine a stopped vm'''
......@@ -104,6 +119,9 @@ class Command_undefine(TqlCommand):
# rpc call
self.rpccall("undefine", self.args[0], self.options.clean)
def remote_functions(self):
return set(("undefine",))
class Command_clone(TqlCommand):
'''Clone vm'''
......@@ -149,3 +167,6 @@ class Command_clone(TqlCommand):
# run migration
self.tql_filter = ""
self.rpccall("clone", stql, dtql, newname, _direct=True)
def remote_functions(self):
return set(("clone",))
......@@ -21,6 +21,22 @@ class Commands(object):
self.cmds = dict()
for x in [ x for x in globals() if x.startswith("Command_") ]:
self.cmds[x[8:]] = globals()[x]
# build remote function list
try:
self.functions = set([ c["name"] for c in self.cli.rpc.call("functions") ])
except RpcError as e:
raise cliError("RPCError: Unable to retrieve remote commands: %s"%str(e))
# remove not available commands
for cname in tuple(self.cmds):
cobj = self.cmds[cname](self.cli, cname)
if isinstance(cobj, command.RemoteCommand):
try:
if not cobj.remote_functions().issubset(self.functions):
del self.cmds[cname]
self.cli.printer.debug("Command %s not available"%cname)
except NotImplementedError as e:
self.cli.printer.debug("Command %s lack of remote_functions"%cname)
del self.cmds[cname]
def __len__(self):
return len(self.cmds)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment