Commit b6c36592 authored by Seblu's avatar Seblu
Browse files

Big improving of TqlCommands (direct,raw,status)

parent a031a960
Loading
Loading
Loading
Loading
+25 −4
Original line number Diff line number Diff line
@@ -15,6 +15,8 @@ class Command_addaccount(TqlCommand):

    def __init__(self, cli, argv0):
        TqlCommand.__init__(self, cli, argv0)
        self.remove_option("--direct")
        self.remove_option("--raw")
        self.set_usage("%prog [options] <account name> <role> [password]")

    def __call__(self, argv):
@@ -25,20 +27,27 @@ class Command_addaccount(TqlCommand):
        elif len(self.args) == 3:
            _pass = self.args[2]
            if self.printer.isinteractive():
                self.printer.warn("Removing last line from history")
                self.printer.warn("Password detected, removing last line from history")
                self.printer.history.removelast()
        else:
            raise cmdBadArgument()
        try:
            # add account
        self.rpccall("addaccount", self.args[0], self.args[1], _status=False)
            self.cli.rpc.call("addaccount", self.args[0], self.args[1])
        except RpcError as e:
            raise cmdError("RPCError: %s"%str(e))
        # set password
        if _pass is not None:
            self.rpccall("passwd", "a=%s"%self.args[0], _pass)
            self.rpccall("passwd", "a=%s"%self.args[0], _pass, _direct=True)


class Command_delaccount(TqlCommand):
    '''Delete an account'''

    def __init__(self, cli, argv0):
        TqlCommand.__init__(self, cli, argv0)
        self.tql_filter += "&a"

    def __call__(self, argv):
        self.parse_args(argv)
        if len(self.args) != 1:
@@ -49,6 +58,10 @@ class Command_delaccount(TqlCommand):
class Command_close(TqlCommand):
    '''Disable accounts'''

    def __init__(self, cli, argv0):
        TqlCommand.__init__(self, cli, argv0)
        self.tql_filter += "&a&-close"

    def __call__(self, argv):
        self.parse_args(argv)
        if len(self.args) != 1:
@@ -59,6 +72,10 @@ class Command_close(TqlCommand):
class Command_declose(TqlCommand):
    '''Enable accounts'''

    def __init__(self, cli, argv0):
        TqlCommand.__init__(self, cli, argv0)
        self.tql_filter += "&a&close"

    def __call__(self, argv):
        self.parse_args(argv)
        if len(self.args) != 1:
@@ -69,6 +86,10 @@ class Command_declose(TqlCommand):
class Command_passwd(TqlCommand):
    '''Change account password'''

    def __init__(self, cli, argv0):
        TqlCommand.__init__(self, cli, argv0)
        self.tql_filter += "&a"

    def __init__(self, cli, argv0):
        TqlCommand.__init__(self, cli, argv0)
        self.set_usage("%prog [options] [tql] [password]")
+121 −29
Original line number Diff line number Diff line
@@ -74,54 +74,146 @@ class TqlCommand(OptionCommand):
        OptionCommand.__init__(self, cli, argv0)
        self.rpc = cli.rpc
        self.set_usage("%prog [options] <tql>")
        # set tql filter stuff
        self.tql_filter = ""
        self.add_option("-r", "--raw", action="callback", dest="raw",
                        callback=self._cb_raw,
                        help="Don't append security filter to TQL")
        # set tql check stuff
        self.add_option("-d", "--direct", action="store_true", dest="direct",
                        help="Directly send TQL to server")
        # set tql status stuff
        self.add_option("-s", "--status", action="store_true", dest="status",
                        help="Show status of each tql object")
        self.add_option("-q", "--quiet", action="store_false", dest="status",
                        help="Dont status of call request")
        # tql printer option
        self.add_option("--print-tql", action="store_true", dest="tql_print",
                        help="Print TQL before sending to server")
        # set tagdisplay stuff
        self.tdr = self.cli.tagdisplay.resolve
        self.tdc = self.cli.tagdisplay.color
        self.tdtc = self.cli.tagdisplay.titlecolor
        self.add_option("-n", "--no-tagdisplay", action="callback", dest="tagdisplay",
        self.add_option("--no-tagdisplay", action="callback", dest="tagdisplay",
                        callback=self._cb_notagdisplay,
                        help="No tagdisplay custom display")


    def _cb_notagdisplay(self, option, opt, value, parser):
        '''Callback for option --no-tagdisplay'''
        self.tdr = lambda tagname, tagvalue: tagvalue
        self.tdc = self.cli.tagdisplay.default_color
        self.tdtc = self.cli.tagdisplay.default_titlecolor

    def _cb_raw(self, option, opt, value, parser):
        '''Callback for option --raw'''
        self.tql_filter = ""

    def rpccall(self, *args, **kwargs):
        '''Call a RPC method an show tql return'''
        # check for status printing
        if "_status" in kwargs:
            _status = kwargs["_status"]
            del kwargs["_status"]
        elif self.options.status:
            _status = True
        else:
            _status = False
        # Do RPC Call
        '''
        Call a RPC method an show tql return
        _callback: call function _callback after each rpccall
        _status: display call status
        _tql_index: is index in args where filter should be appended (def: 1)
        _tql_print: print tql with filter
        _exception: catch or not RPCError exception
        '''

        # set default option value
        _options = { "status": True,
                     "direct": False,
                     "exception": False,
                     "tql": "",
                     "tql_index": 1,
                     "tql_print": False,
                     "callback": None,
                     }
        # check for options modifiers
        for o in _options.keys():
            _o = "_%s"%o
            if _o in kwargs:
                _options[o] =  kwargs[_o]
                del kwargs[_o]
            elif o in dir(self.options):
                x = getattr(self.options, o)
                if x is not None:
                    _options[o] = x
        # check tql index and get a copy
        if _options["tql_index"] < 0 or _options["tql_index"] >= len(args):
            raise cmdError("No indexed TQL")
        # append filter (empty if raw mode)
        if self.tql_filter != "":
            l = list(args)
            l[_options["tql_index"]] += self.tql_filter
            args = tuple(l)
        # Tql printer
        if _options["tql_print"]:
            self.printer.out("TQL: %s"%args[_options["tql_index"]])
        # Tql check
        if _options["direct"]:
            return self._unsecure_rpccall(_options, args, kwargs)
        return self._secure_rpccall(_options, args, kwargs)

    def _unsecure_rpccall(self, _options, args, kwargs):
        '''Just call an RPC without checking before'''
        try:
            d = self.rpc.call(*args, **kwargs)
            if _status:
                self.show_status(d)
            if _options["callback"] is not None:
                _options["callback"](d)
            if _options["status"]:
                self.print_status(d)
            return d
        except RpcError as e:
            if _options["exception"]:
                raise
            raise cmdError("RPCError: %s"%str(e))

    def show_status(self, ans):
        '''Show status of an Tql request'''
    def _secure_rpccall(self, _options, args, kwargs):
        '''Call RPC after listing, confirmation and with id'''
        # get objects id
        try:
            self.printer.out("Status:")
            for o in ans:
                s = "%sid: %s%s %sstatus: %s%s %smessage:%s%s%s"%(
                    self.tdtc("id"), self.tdc("id"), self.tdr("id", o),
                    self.tdtc("status"), self.tdc("status"), ans[o][0],
                    self.tdtc("message"), self.tdc("message"), ans[o][1],
                    color["reset"])
                if s:
                    self.printer.out(s)
        except Exception:
            pass
            objs = self.cli.rpc.call("list", args[_options["tql_index"]])
        except RpcError as e:
            raise cmdError("RPCError: %s"%str(e))
        # no result, goodbye
        if len(objs) == 0:
            raise cmdError("No selected object by TQL.")
        self.printer.out("Objects:")
        self.print_taglist(objs)
        self.printer.out("Objects count: %s"%len(objs))
        # be sure boby want do that
        if self.printer.ask("%sProceed?%s (yes): "%(color["lred"], color["reset"])) != "yes":
            raise cmdWarning("User aborted")
        # bobby doing many things, he needs to be really sure!
        if len(objs) > 5:
            self.printer.out("%sYou will act on more than 5 objets!%s"%(color["uyellow"], color["reset"]))
            if self.printer.ask("%sAre you really sure?%s (Yes Mistress): "
                                %(color["lred"], color["reset"])) != "Yes Mistress":
                raise cmdWarning("User aborted")
        # per validated id execution (this is a kind of atomic implementation)
        for obj in objs:
            dobj = dict(obj)
            try:
                l = list(args)
                l[_options["tql_index"]] = "id=%s"%dobj["id"]
                d = self.cli.rpc.call(*tuple(l), **kwargs)
                if _options["callback"] is not None:
                    _options["callback"](d)
                if _options["status"]:
                    self.print_status(d)
            except RpcError as e:
                self.printer.error("RPCError: %s"%str(e))

    def print_taglist(self, objs):
        '''Trivial listing of tag'''
        for o in objs:
            self.print_tags(o)

    def print_tags(self, taglist):
        '''Display a tag with tagdisplay settings'''
        line = list()
        for (tn, tv) in taglist:
            line.append("%s%s:%s%s"%(self.tdtc(tn), tn, self.tdc(tn), self.tdr(tn, tv)))
        self.printer.out("%s%s"%(" ".join(line), color["reset"]))

    def print_status(self, outputlist):
        '''Display status from an object list '''
        for o in outputlist:
            self.print_tags(o[1][1])
+9 −1
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@ class Command_exec(TqlCommand):
    def __init__(self, cli, argv0):
        TqlCommand.__init__(self, cli, argv0)
        self.set_usage("%prog [options] <tql> <command>")
        self.tql_filter += "&con&r~'host|hv'"

    def __call__(self, argv):
        # arg parse
@@ -21,8 +22,13 @@ class Command_exec(TqlCommand):
        if len(self.args) != 2:
            raise cmdBadArgument()
        # rpc call
        self.rpccall("exec", self.args[0], self.args[1])
        self.rpccall("execute", self.args[0], self.args[1], _callback=self._cb_print_output)

    def _cb_print_output(self, d):
        '''Print output of execute by object'''
        for o in d:
            self.printer.out("%s output:"%o[0])
            self.printer.out("".join(o[1][0][0:]), nl="")

class Command_shutdown(TqlCommand):
    '''Shutdown a physical host'''
@@ -36,6 +42,8 @@ class Command_shutdown(TqlCommand):
                        help="Halt after shutdown")
        self.add_option("-F", action="store_false", dest="graceful", default=True,
                        help="do not go through init but go down real fast")
        self.tql_filter += "&con&r~'host|hv'"


    def __call__(self, argv):
        # arg parse
+4 −0
Original line number Diff line number Diff line
@@ -13,6 +13,10 @@ from cccli.command.command import TqlCommand
class Command_kill(TqlCommand):
    '''Kill a server connection'''

    def __init__(self, cli, argv0):
        TqlCommand.__init__(self, cli, argv0)
        self.tql_filter += "&con"

    def __call__(self, argv):
        # args parse
        self.parse_args(argv)
+17 −39
Original line number Diff line number Diff line
@@ -20,78 +20,56 @@ class Command_list(TqlCommand):
                        help="column aligment display")
        self.add_option("-l", action="store_true", dest="align",
                        help="line aligment display")
        self.remove_option("-s")
        self.remove_option("--quiet")
        self.remove_option("--direct")

    def __call__(self, argv):
        self.parse_args(argv)
        if len(self.args) == 0:
            self.args.append("")
        objs = self.rpccall("list", str.join("", self.args))
        objs = self.rpccall("list", str.join("", self.args), _status=False, _direct=True)
        if len(objs) == 0:
            return
        if self.options.align:
            self._list_align(objs)
            self.list_align(objs)
        elif self.options.table:
            self._list_table(objs)
            self.list_table(objs)
        else:
            self._trivial_list(objs)
            self.print_taglist(objs)

    def _trivial_list(self, objs):
        '''Trivial listing of tag'''
        for o in objs:
            id = self.tdr("id", o.pop("id"))
            tags = " ".join([ "%s%s:%s%s"%(self.tdtc(t),
                                           t,
                                           self.tdc(t),
                                           self.tdr(t, v))
                              for (t,v) in o.items() ])
            self.printer.out("%sid=%s%s %s%s"%(self.tdtc("id"), self.tdc("id"), id, tags, color["reset"]))

    def _list_align(self, objs):
    def list_align(self, objs):
        '''Listing line aligned'''
        # get max size by tag
        tags = dict()
        for o in objs:
            for t,v in o.items():
            for (t, v) in o:
                tags[t] = max(len(self.tdr(t, v)), tags.get(t, len(t)))
        # extract id size
        idsize = tags.pop("id")
        # dislay each object by line
        for o in objs:
            # show id tag
            line = "%sid=%s%s"%(self.tdtc("id"),
                                self.tdc("id"),
                                self.tdr("id", o.pop("id")).ljust(idsize + 2))
            # show others tags
            for tagname in sorted(tags.keys()):
            line = str()
            for (tagname,tagvalue) in o:
                line += "%s%s:%s%s"%(self.tdtc(tagname),
                                     tagname,
                                     self.tdc(tagname),
                                      self.tdr(tagname, o.get(tagname, u"")).ljust(tags[tagname] + 1))
                                     self.tdr(tagname, tagvalue).ljust(tags[tagname] + 1))
            self.printer.out("%s%s"%(line, color["reset"]))

    def _list_table(self, objs):
    def list_table(self, objs):
        '''Listing table style'''
        # get max size by tag
        tags = dict()
        for o in objs:
            for t,v in o.items():
            for (t,v) in o:
                tags[t] = max(len(self.tdr(t, v)), tags.get(t, len(t)))
        # extract id size
        idsize = tags.pop("id")
        # print id title
        self.printer.out(self.tdtc("id"), nl="")
        self.printer.out("id".ljust(idsize+1), nl=" ")
        # print others titles
        # print title
        for t,v in tags.items():
            self.printer.out(self.tdtc(t), nl="")
            self.printer.out(t.ljust(v), nl=" ")
        self.printer.out(color["reset"])
        # print obj
        for obj in objs:
            # print id first
            self.printer.out(self.tdc("id"), nl="")
            self.printer.out(self.tdr("id", obj.pop("id")).ljust(idsize+1), nl=" ")
            obj = dict(obj)
            # print others tags
            for (t, v) in tags.items():
                self.printer.out(self.tdc(t), nl="")
Loading