class CLI(Cmd): """ Simple command-arg interface to talk to nodes. """ helpStr = ('The command format is: <bridge> command {args}\n' 'For example:\n' '\tEasyOVS> br-int dump\n' '\n' 'Default bridge can be set using\n\tset <bridge>.\n') def __init__(self, stdin=sys.stdin, foreground=True): self.bridge = None # default bridge self.ipt = IPtables() if foreground: output('EasyOVS %s, type help for information\n' % VERSION) self.prompt = color_str(PROMPT_KW, 'g') self.stdin = stdin self.in_poller = poll() self.in_poller.register(stdin) Cmd.__init__(self) output("***\n Welcome to EasyOVS," "type help to see available commands.\n***\n") info('*** Starting CLI:\n') debug("==Loading credentials==\n") debug("auth_url = %s\n" % os.getenv('OS_AUTH_URL') or cfg.CONF.OS.auth_url) debug("username = %s\n" % os.getenv('OS_USERNAME') or cfg.CONF.OS.username) passwd = os.getenv('OS_PASSWORD') or cfg.CONF.OS.password passwd = passwd[:len(passwd) / 4] + "****" + passwd[-len(passwd) / 4:] debug("password = %s\n" % passwd) debug("tenant_name = %s\n" % os.getenv('OS_TENANT_NAME') or cfg.CONF.OS.tenant_name) while True: try: #if self.isatty(): #quietRun( 'stty sane' ) self.cmdloop() break except KeyboardInterrupt: info('\nInterrupt\n') def do_addflow(self, arg, forced=False): """ addflow [bridge] flow Add a flow to a bridge. """ args = arg.replace('"', '').replace("'", "").split() if len(args) < 2: output('Not enough parameters are given, use like ') output('br-int addflow priority=3 ip actions=OUTPUT:1\n') return bridge, flow_str = args[0], ' '.join(args[1:]) if not br_exists(bridge): if self.bridge: bridge, flow_str = self.bridge, ' '.join(args) else: output('Please give a valid bridge.\n') return flow = fmt_flow_str(flow_str) if not flow: output('Please give a valid flow.\n') return if not br_addflow(bridge, flow): output('Add flow <%s> to %s failed.\n' % (flow, bridge)) else: output('Add flow <%s> to %s done.\n' % (flow, bridge)) def do_delflow(self, arg, forced=False): """ [bridge] delflow flow_id, flow_id Del a flow from a bridge. :param args: """ args = arg.split() if len(args) >= 2: flow_ids = ' '.join(args[1:]).replace(',', ' ').split() if not br_delflow(args[0], flow_ids, forced): output('Del flow#%s from %s failed.\n' % (' '.join(flow_ids), args[0])) else: output('Del flow#%s from %s done.\n' % (','.join(flow_ids), args[0])) elif len(args) == 1 and self.bridge: if not br_delflow(self.bridge, arg, forced): output('Del flow#%s from %s failed.\n' % (arg, self.bridge)) else: output('Del flow#%s from %s done.\n' % (arg, self.bridge)) else: output("Please use like [bridge] delflow flow_id.\n") def do_addbr(self, arg, forced=False): """ addbr br1, br2 create a new bridge with name """ brs = arg.replace(',', ' ').split() if len(brs) < 1: output('Not enough parameters are given, use like ') output('addbr br1,br2\n') return for br in brs: br_addbr(br) def do_delbr(self, arg, forced=False): """ delbr br1, br2 Delete a bridge """ brs = arg.replace(',', ' ').split() if len(brs) < 1: output('Not enough parameters are given, use like ') output('delbr br1,br2\n') return for br in brs: br_delbr(br) def do_dump(self, arg, forced=False): """ [bridge] dump Dump the flows from a bridge. """ if arg: br_dump(arg) elif self.bridge: br_dump(self.bridge) else: output("Please give a valid bridge.\n") return def do_EOF(self, arg): """ Exit. """ output('\n') return self.do_quit(arg) def do_exit(self, _arg): """ Go up one level in the command mode structure. If already at the top level, exit from the command line interface and log out. """ if self.bridge: self.bridge = None self.prompt = color_str(PROMPT_KW, 'g') else: return self.do_quit(_arg) def do_get(self, _arg): """ Get current default bridge. """ if self.bridge: output('Current default bridge is %s\n' % self.bridge) else: output( 'Default bridge is not set yet.\nPlease try <bridge> set.\n') def do_help(self, line): """ Describe available CLI commands. """ Cmd.do_help(self, line) if line is '': output(self.helpStr) def do_ipt(self, arg): """ Show the iptables rules, e.g., ipt vm vm1,vm2 ipt show nat,raw,filter [INPUT] ipt check nat,raw,filter """ args = arg.split() if len(args) < 1 or len(args) > 3: # only 1-3 is valid warn("Not correct parameters, use as:\n") warn("ipt vm vm_ip\n") warn("ipt show|check [filter] [INPUT]\n") return cmd = args[0] if not hasattr(self.ipt, '%s' % cmd): error('Unsupported cmd=%s\n' % cmd) return self.ipt.load() # load all chains if cmd == 'vm': if len(args) == 1: error('No vm ip is given\n') return else: for vm_ip in args[1:]: debug('run self.ipt.%s(...)\n' % cmd) getattr(self.ipt, '%s' % cmd)(vm_ip) elif cmd in ['check', 'show']: if len(args) == 1: # show debug('run self.ipt.%s()\n' % cmd) getattr(self.ipt, '%s' % cmd)() elif len(args) == 2: # filter|INPUT if args[1] in self.ipt.get_valid_tables(): # filter debug('run self.ipt.%s(table=%s)\n' % (cmd, args[1])) getattr(self.ipt, '%s' % cmd)(table=args[1]) else: # INPUT debug('run self.ipt.%s(chain=%s)\n' % (cmd, args[1])) getattr(self.ipt, '%s' % cmd)(chain=args[1]) elif len(args) == 3: if args[1] in self.ipt.get_valid_tables(): # filter INPUT debug('run self.ipt.%s(table=%s, chain=%s\n)' % (cmd, args[1], args[2])) getattr(self.ipt, '%s' % cmd)(table=args[1], chain=args[2]) else: warn("Unknown table, table=%s\n" % args[1]) def do_query(self, line): """ Show the port information of given keywords. """ show_port_info(line) def do_list(self, _arg=None): """ List available bridges in the system. """ br_list() def do_quit(self, line): """ Exit """ output('***\n Quit by user command.***\n') return True def do_set(self, arg): """ <bridge> set Set the default bridge """ if not arg: output('Argument is missed\n') elif not br_exists(arg): output('The bridge does not exist.\n ' 'You can check available bridges using show\n') else: self.prompt = \ color_str(PROMPT_KW[:-2] + ':%s> ' % color_str('b', arg), 'g') self.bridge = arg output('Set the default bridge to %s.\n' % self.bridge) def do_sh(self, line): """ Run an external shell command. """ call(line, shell=True) def do_show(self, arg, forced=False): """ Show port details of a bridge, with neutron information. """ if arg: br_show(arg) elif self.bridge: br_show(self.bridge) else: output("Please give a valid bridge.\n") return def emptyline(self): """ Don't repeat last command when you hit return. """ pass def default(self, line): #bridge, cmd, line = self.parseline( line ) if len(line.split()) < 2: error('*** Unknown command: %s ***\n' % line) return bridge, cmd, args = '', '', '' if len(line.split()) == 2: bridge, cmd = line.split() else: bridge, cmd, args = \ line.split()[0], line.split()[1], ' '.join(line.split()[2:]) if br_exists(bridge): try: if args: getattr(self, 'do_%s' % cmd)(' '.join([bridge, args])) else: getattr(self, 'do_%s' % cmd)(bridge) except AttributeError: error('*** Unknown command: ' '%s, cmd=%s, bridge=%s, args=%s ' '***\n' % (line, cmd, bridge, args)) else: error('*** Bridge %s is not existed\n' % bridge) def run(self, cmd, forced=False): ''' Run given commands from -m 'xxxx'. Treat this similar with CLI. :param args: :param forced: :return: ''' cmd_split = cmd.split() if cmd_split[0] in CMDS_ONE: # list func = cmd_split[0] getattr(self, 'do_' + func)() elif cmd_split[0] in CMDS_BR: if len(cmd_split) > 2: # e.g., delflow br0 9,10 func, args = cmd_split[0], ' '.join(cmd_split[1:]) debug("run do_%s(%s, %s)\n" % (func, args.replace(',', ' '), forced)) getattr(self, 'do_' + func)(args.replace(',', ' '), forced) else: # e.g., delbr br0 func, args = cmd_split[0], cmd_split[1] getattr(self, 'do_' + func)(args) elif cmd_split[0] in CMDS_OTHER: # e.g., ipt vm 10.0.0.1, 10.0.0.2 func, args = cmd_split[0], ' '.join(cmd_split[1:]) getattr(self, 'do_' + func)(args) else: output('Wrong command format is given\n')
class CLI(Cmd): """ Simple command-arg interface to talk to nodes. """ helpStr = ( 'The command format is: <bridge> command {args}\n' 'For example:\n' '\tEasyOVS> br-int dump\n' '\n' 'Default bridge can be set using\n\tset <bridge>.\n' ) def __init__(self, stdin=sys.stdin, foreground=True): self.bridge = None # default bridge self.ipt = IPtables() if foreground: output('EasyOVS %s, type help for information\n' % VERSION) self.prompt = color_str(PROMPT_KW, 'g') self.stdin = stdin self.in_poller = poll() self.in_poller.register(stdin) Cmd.__init__(self) output("***\n Welcome to EasyOVS," "type help to see available commands.\n***\n") info('*** Starting CLI:\n') debug("==Loading credentials==\n") debug("auth_url = %s\n" % os.getenv('OS_AUTH_URL') or cfg.CONF.OS.auth_url) debug("username = %s\n" % os.getenv('OS_USERNAME') or cfg.CONF.OS.username) passwd = os.getenv('OS_PASSWORD') or cfg.CONF.OS.password passwd = passwd[:len(passwd)/4] + "****" + passwd[-len(passwd)/4:] debug("password = %s\n" % passwd) debug("tenant_name = %s\n" % os.getenv('OS_TENANT_NAME') or cfg.CONF.OS.tenant_name) while True: try: #if self.isatty(): #quietRun( 'stty sane' ) self.cmdloop() break except KeyboardInterrupt: info('\nInterrupt\n') def do_addflow(self, arg, forced=False): """ addflow [bridge] flow Add a flow to a bridge. """ args = arg.replace('"', '').replace("'", "").split() if len(args) < 2: output('Not enough parameters are given, use like ') output('br-int addflow priority=3 ip actions=OUTPUT:1\n') return bridge, flow_str = args[0], ' '.join(args[1:]) if not br_exists(bridge): if self.bridge: bridge, flow_str = self.bridge, ' '.join(args) else: output('Please give a valid bridge.\n') return flow = fmt_flow_str(flow_str) if not flow: output('Please give a valid flow.\n') return if not br_addflow(bridge, flow): output('Add flow <%s> to %s failed.\n' % (flow, bridge)) else: output('Add flow <%s> to %s done.\n' % (flow, bridge)) def do_delflow(self, arg, forced=False): """ [bridge] delflow flow_id, flow_id Del a flow from a bridge. :param args: """ args = arg.split() if len(args) >= 2: flow_ids = ' '.join(args[1:]).replace(',', ' ').split() if not br_delflow(args[0], flow_ids, forced): output('Del flow#%s from %s failed.\n' % (' '.join(flow_ids), args[0])) else: output('Del flow#%s from %s done.\n' % (','.join(flow_ids), args[0])) elif len(args) == 1 and self.bridge: if not br_delflow(self.bridge, arg, forced): output('Del flow#%s from %s failed.\n' % (arg, self.bridge)) else: output('Del flow#%s from %s done.\n' % (arg, self.bridge)) else: output("Please use like [bridge] delflow flow_id.\n") def do_addbr(self, arg, forced=False): """ addbr br1, br2 create a new bridge with name """ brs = arg.replace(',', ' ').split() if len(brs) < 1: output('Not enough parameters are given, use like ') output('addbr br1,br2\n') return for br in brs: br_addbr(br) def do_delbr(self, arg, forced=False): """ delbr br1, br2 Delete a bridge """ brs = arg.replace(',', ' ').split() if len(brs) < 1: output('Not enough parameters are given, use like ') output('delbr br1,br2\n') return for br in brs: br_delbr(br) def do_dump(self, arg, forced=False): """ [bridge] dump Dump the flows from a bridge. """ if arg: br_dump(arg) elif self.bridge: br_dump(self.bridge) else: output("Please give a valid bridge.\n") return def do_EOF(self, arg): """ Exit. """ output('\n') return self.do_quit(arg) def do_exit(self, _arg): """ Go up one level in the command mode structure. If already at the top level, exit from the command line interface and log out. """ if self.bridge: self.bridge = None self.prompt = color_str(PROMPT_KW, 'g') else: return self.do_quit(_arg) def do_get(self, _arg): """ Get current default bridge. """ if self.bridge: output('Current default bridge is %s\n' % self.bridge) else: output('Default bridge is not set yet.\nPlease try <bridge> set.\n') def do_help(self, line): """ Describe available CLI commands. """ Cmd.do_help(self, line) if line is '': output(self.helpStr) def do_ipt(self, arg): """ Show the iptables rules, e.g., ipt vm vm1,vm2 ipt show nat,raw,filter [INPUT] ipt check nat,raw,filter """ args = arg.split() if len(args) < 1 or len(args) > 3: # only 1-3 is valid warn("Not correct parameters, use as:\n") warn("ipt vm vm_ip\n") warn("ipt show|check [filter] [INPUT]\n") return cmd = args[0] if not hasattr(self.ipt, '%s' % cmd): error('Unsupported cmd=%s\n' % cmd) return self.ipt.load() # load all chains if cmd == 'vm': if len(args) == 1: error('No vm ip is given\n') return else: for vm_ip in args[1:]: debug('run self.ipt.%s(...)\n' % cmd) getattr(self.ipt, '%s' % cmd)(vm_ip) elif cmd in ['check', 'show']: if len(args) == 1: # show debug('run self.ipt.%s()\n' % cmd) getattr(self.ipt, '%s' % cmd)() elif len(args) == 2: # filter|INPUT if args[1] in self.ipt.get_valid_tables(): # filter debug('run self.ipt.%s(table=%s)\n' % (cmd, args[1])) getattr(self.ipt, '%s' % cmd)(table=args[1]) else: # INPUT debug('run self.ipt.%s(chain=%s)\n' % (cmd, args[1])) getattr(self.ipt, '%s' % cmd)(chain=args[1]) elif len(args) == 3: if args[1] in self.ipt.get_valid_tables(): # filter INPUT debug('run self.ipt.%s(table=%s, chain=%s\n)' % (cmd, args[1], args[2])) getattr(self.ipt, '%s' % cmd)(table=args[1], chain=args[2]) else: warn("Unknown table, table=%s\n" % args[1]) def do_query(self, line): """ Show the port information of given keywords. """ show_port_info(line) def do_list(self, _arg=None): """ List available bridges in the system. """ br_list() def do_quit(self, line): """ Exit """ output('***\n Quit by user command.***\n') return True def do_set(self, arg): """ <bridge> set Set the default bridge """ if not arg: output('Argument is missed\n') elif not br_exists(arg): output('The bridge does not exist.\n ' 'You can check available bridges using show\n') else: self.prompt = \ color_str(PROMPT_KW[:-2] + ':%s> ' % color_str('b', arg), 'g') self.bridge = arg output('Set the default bridge to %s.\n' % self.bridge) def do_sh(self, line): """ Run an external shell command. """ call(line, shell=True) def do_show(self, arg, forced=False): """ Show port details of a bridge, with neutron information. """ if arg: br_show(arg) elif self.bridge: br_show(self.bridge) else: output("Please give a valid bridge.\n") return def emptyline(self): """ Don't repeat last command when you hit return. """ pass def default(self, line): #bridge, cmd, line = self.parseline( line ) if len(line.split()) < 2: error('*** Unknown command: %s ***\n' % line) return bridge, cmd, args = '', '', '' if len(line.split()) == 2: bridge, cmd = line.split() else: bridge, cmd, args = \ line.split()[0], line.split()[1], ' '.join(line.split()[2:]) if br_exists(bridge): try: if args: getattr(self, 'do_%s' % cmd)(' '.join([bridge, args])) else: getattr(self, 'do_%s' % cmd)(bridge) except AttributeError: error('*** Unknown command: ' '%s, cmd=%s, bridge=%s, args=%s ' '***\n' % (line, cmd, bridge, args)) else: error('*** Bridge %s is not existed\n' % bridge) def run(self, cmd, forced=False): """ Run given commands from -m 'xxxx'. Treat this similar with CLI. :param args: :param forced: :return: """ cmd_split = cmd.split() if cmd_split[0] in CMDS_ONE: # list func = cmd_split[0] getattr(self, 'do_' + func)() elif cmd_split[0] in CMDS_BR: if len(cmd_split) > 2: # e.g., delflow br0 9,10 func, args = cmd_split[0], ' '.join(cmd_split[1:]) debug("run do_%s(%s, %s)\n" % (func, args.replace(',', ' '), forced)) getattr(self, 'do_' + func)(args.replace(',', ' '), forced) else: # e.g., delbr br0 func, args = cmd_split[0], cmd_split[1] getattr(self, 'do_' + func)(args) elif cmd_split[0] in CMDS_OTHER: # e.g., ipt vm 10.0.0.1, 10.0.0.2 func, args = cmd_split[0], ' '.join(cmd_split[1:]) getattr(self, 'do_' + func)(args) else: output('Wrong command format is given\n')