Commit 994ed27b authored by Sébastien Luttringer's avatar Sébastien Luttringer
Browse files

wip

parent 4419665d
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -37,6 +37,8 @@ import shlex
import StringIO

class Cli(object):
    '''Command Line Class'''

    def __init__(self, settings):
        self.settings = settings
        self.rpc = None
+54 −76
Original line number Diff line number Diff line
@@ -19,96 +19,74 @@
CloudControl right releated commands
'''

import tempfile
import subprocess
from cccli.command import RemoteCommand
from cccli.exception import *
import os
import re
import pprint

from cccli.exception import *
from sjrpc.core.exceptions import *
from cccli.printer import Printer, color
from cccli.command import Command, RemoteCommand
class RightCommand(RemoteCommand):
    '''Right Base Class'''

class Command_rights(RemoteCommand):
    '''List account rights'''
    @staticmethod
    def obj2str(obj_rights):
        '''Convert rights object to string'''
        s = ""
        col_len = ""
        for r in obj_rights:
            s += "%(match)s\t%(method)s\t%(tql)s\t%(action)s\n" % r
        return s

    @staticmethod
    def str2obj(str_rights):
        '''Convert rigths string to object'''
        obj = []
        for line in str_rights.split(os.linesep):
            line = line.strip()
            if len(line) == 0 or line.startswith("#"):
                continue
            #print line
            match, method, tql, action = line.split(None, 4)
            obj.append({"match": match,
                        "method": method,
                        "tql": tql,
                        "action": action})
        return obj

    def __init__(self, cli, argv0):
        RemoteCommand.__init__(self, cli, argv0)
        self.set_usage("%prog [options]")
    def check_file(self, fo):
        '''Check if fo is valid rights strings'''
        try:
            self.str2obj(fo.read())
        except Exception as e:
            raise
            self.printer.debug("Invalid format: %s" % e)
            return False
        return True


class Command_rights(RightCommand):
    '''List server rights'''

    def __call__(self, argv):
        # ask server
        al = self.rpc.call("loadrights")
        o_rights = self.rpc.call("loadrights")
        # display answer
        for r in al:
            self.printer.out("%(match)s\t%(method)s\t%(tql)s\t%(action)s" % r)
        self.printer.out(self.obj2str(o_rights), nl=None)

    def remote_functions(self):
    @staticmethod
    def remote_functions():
        return set(('loadrights',))


class Command_editrights(RemoteCommand):
    ''' Edit rights '''

    def __init__(self, cli, argv0):
        RemoteCommand.__init__(self, cli, argv0)
        self.set_usage("%prog [options]")

    def indent(self, rights, space):
        indents = {}
        fields = ('match', 'method', 'tql', 'action')
        for f in fields:
            cur = 0
            for r in rights:
                cur = max(cur, len(r[f]))
            indents[f] = cur + space
        return indents

    def edit(self, out):
        editor = os.environ.get('EDITOR', '/bin/nano')
        subprocess.call([editor, out.name])
        out.seek(0)
        new_rights = []
        nb = 1
        for line in out:
            line = line.lstrip().rstrip()
            if len(line) == 0 or line.startswith('#'):
                continue
            items = line.split()
            if len(items) < 4 or (len(items) > 4 and not items[5].startswith('#')):
                while True:
                    s = raw_input("Error: bad file format at line %d, do you want to reedit ? [yes/no] " % nb)
                    answer = s.lstrip().rstrip()
                    if answer == 'yes':
                        return self.edit(out)
                    elif answer == 'no':
                        raise cmdError('Bad file format at line %d' % nb)
                    else:
                        self.printer.out("Please answer by yes or no")
            new_rights.append({'match': items[0], 'method': items[1], 'tql': items[2], 'action': items[3]})
            nb += 1
        return new_rights
class Command_editrights(RightCommand):
    ''' Edit server rights '''

    def __call__(self, argv):
        with tempfile.NamedTemporaryFile(dir='/tmp') as temp:
            al = self.rpc.call("loadrights")
            indents = self.indent(al, 2)
            temp.write("# match%smethod%stql%saction\n" % (' '*(indents['match'] - len('match') - 2),
                                                             ' '*(indents['method'] - len('method')),
                                                             ' '*(indents['tql'] - len('tql'))))
            for r in al:
                temp.write("%s%s%s%s%s%s%s\n" % (r['match'],
                                                   ' '*(indents['match'] - len(r['match'])),
                                                   r['method'],
                                                   ' '*(indents['method'] - len(r['method'])),
                                                   r['tql'],
                                                   ' '*(indents['tql'] - len(r['tql'])),
                                                   r['action']))
            temp.flush()
            new_rights = self.edit(temp)
            temp.close()
            self.rpc.call('saverights', new_rights)
        obj_rights = self.rpc.call("loadrights")
        str_rights = self.obj2str(obj_rights)
        new_rights = self.printer.editor(str_rights, self.check_file)
        if new_rights is not None:
            self.rpc.call('saverights', self.str2obj(new_rights))
        else:
            self.printer.out("Nothing change.")

    def remote_functions(self):
        return set(('saverights',))
+44 −2
Original line number Diff line number Diff line
@@ -19,15 +19,16 @@
CloudControl CLI Printer module
'''

import cccli
from cccli.exception import *

import cccli
import fcntl
import os
import shutil
import signal
import struct
import subprocess
import sys
import tempfile
import termios
import tty

@@ -201,6 +202,8 @@ class Printer(object):

    def pager(self, data):
        '''Page data using PAGER'''
        if self.readline is None:
            return
        binary = os.environ.get("CC_PAGER", os.environ.get("PAGER", "more"))
        if isinstance(data, basestring):
            p = subprocess.Popen(binary, stdin=subprocess.PIPE, close_fds=True,
@@ -211,6 +214,45 @@ class Printer(object):
                                 shell=True)
            p.wait()

    def editor(self, data, checker=None):
        '''
        Edit data using editor and verify validity with checker
        Return edited files or None
        '''
        if self.readline is None:
            return False
        binary = os.environ.get("CC_EDITOR", os.environ.get("EDITOR", "vi"))
        # create tempory files
        f_tmp = tempfile.NamedTemporaryFile()
        # fullfill temp file with data
        if isinstance(data, basestring):
            f_tmp.write(data)
        else:
            shutil.copyfileobj(data, f_tmp)
        f_tmp.flush()
        # run editor
        to_save = False
        while True:
            subprocess.Popen("%s '%s'" % (binary, f_tmp.name), shell=True).wait()
            if checker is not None:
                f_tmp.seek(0)
                if checker(f_tmp):
                    to_save = True
                    break
                else:
                    if self.ask("Invalid file format! Retry (Y/n)? ").lower() != "Y":
                        break
            else:
                to_save = True
                break
        if to_save:
            f_tmp.seek(0)
            ans = f_tmp.read()
        else:
            ans = None
        f_tmp.close()
        return ans


class History(object):
    '''History class'''