Skip to content

Commit

Permalink
Reduce duplicated code and add more iptables functions
Browse files Browse the repository at this point in the history
  • Loading branch information
yeasy committed Jul 24, 2015
1 parent eefebe5 commit f4e8d66
Show file tree
Hide file tree
Showing 6 changed files with 120 additions and 134 deletions.
81 changes: 10 additions & 71 deletions bin/easyovs
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,11 @@ class Platform(object):
"""
Setup and validate environment.
"""

# set logging verbosity
if LEVELS[cfg.CONF.verbosity] > LEVELS['output']:
print ('*** WARNING: selected verbosity level (%s) will hide CLI '
'output!\n'
'Please restart easyOVS with -v [debug, info, output].'
print ('*** WARNING: selected verbosity level (%s) will '
' hide CLI output!\n'
'Please restart with -v [debug, info, output].'
% cfg.CONF.verbosity)
lg.set_log_level(cfg.CONF.verbosity)
info("Set log level to %s\n" % cfg.CONF.verbosity)
Expand All @@ -57,79 +56,19 @@ class Platform(object):
cleanup()
exit()

output('EasyOVS %s, type help for information\n' % VERSION)
start = time.time()
cmd = cfg.CONF.cmd
info("cmd = %s\n" % cmd)
info("Run direct cmd = %s\n" % cmd)
cmd_split = cmd.split()
if len(cmd_split) == 1 and cmd in CMDS_ONE:
if cmd == 'cli':
CLI()
elif cmd == 'list':
self.list()
elif len(cmd_split) >= 2:
if cmd_split[1] in CMDS_BR: # e.g., br0 delflow 9
if len(cmd_split) > 2:
br, func, arg = cmd_split[0], cmd_split[1], ' '.join(
cmd_split[2:])
getattr(self, func)(br, arg.replace(',', ' '))
else:
br, func = cmd_split[0], cmd_split[1]
getattr(self, func)(br)
elif cmd_split[0] in CMDS_BR: # e.g., delflow br0 9
if len(cmd_split) > 2:
br, func, arg = cmd_split[1], cmd_split[0], ' '.join(
cmd_split[2:])
getattr(self, func)(br, arg.replace(',', ' '))
else:
br, func = cmd_split[1], cmd_split[0]
getattr(self, func)(br)
elif cmd_split[0] in CMDS_OTHER: # e.g., ipt 10.0.0.1, 10.0.0.2
func, arg = cmd_split[0], ' '.join(cmd_split[1:])
getattr(self, func)(arg)
else:
output('Wrong command format is given\n')
if len(cmd_split) == 1 and cmd == 'cli':
CLI()
elif cmd_split[0] in CMDS_ONE + CMDS_BR + CMDS_OTHER:
CLI(foreground=False).run(cmd, cfg.CONF.forced)
else:
output('Wrong command format is given\n')
error('Unknown command, cmd=%s\n' % cmd)
elapsed = float(time.time() - start)
info('\n### Completed in %0.3f seconds ###\n' % elapsed)

@staticmethod
def dump(br):
br_dump(br)

@staticmethod
def ipt(ips):
show_vm_rules(ips)

@staticmethod
def query(keyword):
show_port_info(keyword)

@staticmethod
def list():
br_list()

@staticmethod
def addbr(br):
br_addbr(br)

@staticmethod
def delbr(br):
br_delbr(br)

@staticmethod
def show(br):
br_show(br)

@staticmethod
def addflow(br, flow_str):
br_addflow(br, fmt_flow_str(flow_str))

@staticmethod
def delflow(br, flow_id):
br_delflow(br, flow_id)


if __name__ == "__main__":
try:
Expand All @@ -150,4 +89,4 @@ if __name__ == "__main__":

stackTrace = traceback.format_exc()
debug(stackTrace + "\n")
cleanup()
cleanup()
146 changes: 94 additions & 52 deletions easyovs/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@
from subprocess import call
import sys

from easyovs import VERSION
from easyovs.bridge_ctrl import br_addflow, br_delbr, br_addbr, br_delflow, \
br_dump, br_exists,br_list, br_show
from easyovs.common import CMDS_ONE, CMDS_BR, CMDS_OTHER
from easyovs.iptables import IPtables, show_vm_rules
from easyovs.log import info, output, error, debug
from easyovs.log import info, output, error, debug, warn
from easyovs.neutron import show_port_info
from easyovs.util import color_str, fmt_flow_str

Expand Down Expand Up @@ -42,32 +44,34 @@ class CLI(Cmd):
'Default bridge can be set using\n\tset <bridge>.\n'
)

def __init__(self, bridge=None, stdin=sys.stdin):
self.prompt = color_str('g', PROMPT_KW)
self.bridge = bridge # default bridge
def __init__(self, stdin=sys.stdin, foreground=True):
self.bridge = None # default bridge
self.ipt = IPtables()
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("==cfg.ADMIN==\n")
debug("auth_url = %s\n" % cfg.CONF.OS.auth_url)
debug("username = %s\n" % cfg.CONF.OS.username)
debug("password = %s\n" % cfg.CONF.OS.password)
debug("tenant_name = %s\n" % cfg.CONF.OS.tenant_name)
while True:
try:
#if self.isatty():
#quietRun( 'stty sane' )
self.cmdloop()
break
except KeyboardInterrupt:
info('\nInterrupt\n')
if foreground:
output('EasyOVS %s, type help for information\n' % VERSION)
self.prompt = color_str('g', PROMPT_KW)
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("==cfg.ADMIN==\n")
debug("auth_url = %s\n" % cfg.CONF.OS.auth_url)
debug("username = %s\n" % cfg.CONF.OS.username)
debug("password = %s\n" % cfg.CONF.OS.password)
debug("tenant_name = %s\n" % 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):
def do_addflow(self, arg, forced=False):
"""
addflow [bridge] flow
Add a flow to a bridge.
Expand All @@ -93,10 +97,11 @@ def do_addflow(self, arg):
else:
output('Add flow <%s> to %s done.\n' % (flow, bridge))

def do_delflow(self, arg):
def do_delflow(self, arg, forced=False):
"""
[bridge] delflow flow_id
[bridge] delflow flow_id, flow_id
Del a flow from a bridge.
:param args:
"""
args = arg.split()
if len(args) >= 2:
Expand All @@ -116,9 +121,9 @@ def do_delflow(self, arg):
else:
output("Please use like [bridge] delflow flow_id.\n")

def do_addbr(self, arg):
def do_addbr(self, arg, forced=False):
"""
addbr [bridge]
addbr br1, br2
create a new bridge with name
"""
brs = arg.replace(',', ' ').split()
Expand All @@ -129,20 +134,22 @@ def do_addbr(self, arg):
for br in brs:
br_addbr(br)

def do_delbr(self, arg):
def do_delbr(self, arg, forced=False):
"""
delbr [bridge]
delbr br1, br2
Delete a bridge
"""

brs = arg.replace(',', ' ').split()
if len(brs) < 1:
output('Not enough parameters are given, use like ')
output('del br1,br2\n')
output('delbr br1,br2\n')
return
for br in brs:
br_delbr(br)

def do_dump(self, arg):
def do_dump(self, arg, forced=False):
"""
[bridge] dump
Dump the flows from a bridge.
Expand Down Expand Up @@ -194,27 +201,36 @@ def do_help(self, line):
def do_ipt(self, arg):
"""
Show the iptables rules, e.g.,
ipt show vm1,vm2
ipt show nat,raw,forward
ipt check nat,raw,forward
ipt vm vm1,vm2
ipt show nat,raw,filter [INPUT]
ipt check nat,raw,filter
"""
args = arg.split()
if len(args) < 2:
error("Not engough paramers, use as:\n")
error("ipt show vm_ip1, vm_ip2\n")
error("ipt show filter INPUT\n")
if len(args) < 1 or len(args) > 3: # only 1-3 is valid
warn("Not correct parameters, use as:\n")
warn("ipt vm vm_ip1, vm_ip2\n")
warn("ipt show|check [filter] [INPUT]\n")
return
if args[0] == 'show':
if args[1] in self.ipt.get_available_tables():
self.ipt.show(args[1], args[2])
elif args[0] == 'check':
pass
else:
error("ipt only support show and check\n")
return

flow_ids = ' '.join(args[1:]).replace(',', ' ').split()
show_vm_rules(line)
cmd = args[0]
if not hasattr(self.ipt, '%s' % cmd):
error('Unsupported cmd=%s\n' % cmd)
if len(args) == 1: # filter|INPUT
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):
"""
Expand Down Expand Up @@ -257,7 +273,7 @@ def do_sh(self, line):
"""
call(line, shell=True)

def do_show(self, arg):
def do_show(self, arg, forced=False):
"""
Show port details of a bridge, with neutron information.
"""
Expand Down Expand Up @@ -298,3 +314,29 @@ def default(self, line):
'***\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')
4 changes: 4 additions & 0 deletions easyovs/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@
short='m',
default='cli',
help='Run some inside command directly'),
cfg.StrOpt('forced',
short='f',
default=False,
help='Run command without confirmation'),
cfg.BoolOpt('clean',
short='c',
default=False,
Expand Down
17 changes: 9 additions & 8 deletions easyovs/iptables.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,13 +129,13 @@ class IPtables(object):
represent a iptables object, which can handle the table rules
"""
def __init__(self):
self.available_tables = ['raw', 'nat', 'filter', 'mangle', 'security']
self.valid_tables = ['raw', 'nat', 'filter', 'mangle', 'security']
self.tables = {}
for tb in self.available_tables:
for tb in self.valid_tables:
self.tables[tb] = IPtable(tb)

def get_available_tables(self):
return self.available_tables
def get_valid_tables(self):
return self.valid_tables

def load(self, table=None, chain=None):
'''
Expand All @@ -145,10 +145,10 @@ def load(self, table=None, chain=None):
:param chain: which chain to load, None for all
:return:
'''
if table in self.available_tables:
if table in self.valid_tables:
self.tables[table].load(chain)
else:
for tb in self.available_tables:
for tb in self.valid_tables:
self.tables[tb].load(chain)

def show(self, table='filter', chain=None):
Expand All @@ -158,8 +158,9 @@ def show(self, table='filter', chain=None):
:param chain: which chain to show, None for all.
:return:
'''
debug("Show table=%s, chain=%s\n" % (table, chain))
if table in self.available_tables:
debug("Show table=%s, chain=%s\n" % (table, chain or 'None'))
self.load(table, chain)
if table in self.valid_tables:
self.tables[table].show(chain)

def check_table(self, table='filter'):
Expand Down
2 changes: 1 addition & 1 deletion easyovs/neutron.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ def __init__(self):
endpoint_url=neutron_endpoint_url,
token=self.token)
except AuthorizationFailure:
warn("OpenStack auth failed\n")
warn("OpenStack auth not loaded\n")
self.neutron = None
except Unauthorized:
warn("No valid OpenStack auth info is found\n")
Expand Down
Loading

0 comments on commit f4e8d66

Please sign in to comment.