1212from optparse import OptionParser
1313
1414def getPassword (opts ):
15+ if opts .no_passwd :
16+ return ""
1517 if opts .fv_passwdfile is None :
1618 passwd = getpass .getpass ("Password: " )
1719 else :
@@ -21,10 +23,12 @@ def getPassword(opts):
2123def addCommonOpts (parser ):
2224 parser .add_option ("-h" , "--hostname" , dest = "host" , default = "localhost" ,
2325 help = "Specify the FlowVisor host; default='localhost'" )
24- parser .add_option ("-p" , "--port" , dest = "port" , default = "8080 " ,
25- help = "Specify the FlowVisor web port; default=8080 " )
26+ parser .add_option ("-p" , "--port" , dest = "port" , default = "8081 " ,
27+ help = "Specify the FlowVisor web port; default=8081 " )
2628 parser .add_option ("-u" , "--user" , dest = "fv_user" , default = "fvadmin" ,
2729 help = "FlowVisor admin user; default='fvadmin'" )
30+ parser .add_option ("-n" , "--no-passwd" , action = "store_true" , dest = "no_passwd" , default = False ,
31+ help = "Run fvctl with no password; default false" )
2832 parser .add_option ("-f" , "--passwd-file" , dest = "fv_passwdfile" , default = None ,
2933 help = "Password file; default=none" )
3034 parser .add_option ("-v" , "--version" , action = "callback" , callback = printVersion )
@@ -241,6 +245,9 @@ def toHex(match):
241245 match [field ] = hex (value )
242246 return match
243247
248+ def prettify (fs ):
249+ pass
250+
244251
245252def do_listFlowSpace (gopts , opts , args ):
246253 passwd = getPassword (gopts )
@@ -260,6 +267,7 @@ def do_listFlowSpace(gopts, opts, args):
260267 print " None"
261268 sys .exit ()
262269 for item in ret :
270+ prettify (item )
263271 if opts .pretty :
264272 print json .dumps (item , sort_keys = True , indent = 1 )
265273 print "\n \n "
@@ -319,7 +327,7 @@ def do_addFlowSpace(gopts, opts, args):
319327 req ['slice-action' ] = acts
320328 ret = connect (gopts , "add-flowspace" , passwd , data = [req ])
321329 if ret :
322- print "Flowspace %s has been created ." % args [0 ]
330+ print "FlowSpace %s was added with request id %s ." % ( args [0 ], ret )
323331
324332def pa_updateFlowSpace (args , cmd ):
325333 usage = "%s [options] <flowspace-name>" % USAGE .format (cmd )
@@ -374,7 +382,7 @@ def do_updateFlowSpace(gopts, opts, args):
374382 sys .exit ()
375383 ret = connect (gopts , "update-flowspace" , passwd , data = [req ])
376384 if ret :
377- print "Flowspace %s has been updated. " % args [0 ]
385+ print "Flowspace %s was updated with request id %s " % ( args [0 ], ret )
378386
379387def do_listVersion (gopts , opts , args ):
380388 passwd = getPassword (gopts )
@@ -658,6 +666,21 @@ def do_listrewritedb(gopts, opts, args):
658666 for fbe in ret :
659667 print fbe
660668
669+ def pa_listFSStatus (args , cmd ):
670+ usage = "%s <fs-id>" % USAGE .format (cmd )
671+ (sdesc , ldesc ) = DESCS [cmd ]
672+ parser = OptionParser (usage , description = ldesc )
673+ return parser .parse_args (args )
674+
675+ def do_listFSStatus (gopts , opts , args ):
676+ if len (args ) != 1 :
677+ print "list-fs-status : Please specify a flowspace id"
678+ sys .exit ()
679+ passwd = getPassword (gopts )
680+ req = { 'fs-id' : int (args [0 ]) }
681+ ret = connect (gopts , "list-fs-status" , passwd , data = req )
682+ print "FlowSpace Request id %s : %s" % (args [0 ], ret )
683+
661684
662685def pa_help (args , cmd ):
663686 usage = "%s <cmd>" % USAGE .format (cmd )
@@ -714,6 +737,10 @@ def connect(opts, cmd, passwd, data=None):
714737 sys .exit (1 )
715738 else :
716739 print e
740+ except urllib2 .URLError , e :
741+ print "Could not reach a FlowVisor RPC server at %s:%s." % (opts .host , opts .port )
742+ print "Please check that FlowVisor is running and try again."
743+ sys .exit (1 )
717744 except RuntimeError , e :
718745 print e
719746
@@ -731,6 +758,14 @@ def toInt(val):
731758 return int (val ,16 )
732759 return int (val )
733760
761+ def toMacInt (val ):
762+ if val is None :
763+ return
764+ if val .find (":" ) != - 1 :
765+ return int (val .replace (':' , '' ),16 )
766+ if val .find ("-" ) != - 1 :
767+ int (val .replace ('-' , '' ),16 )
768+
734769def toStr (val ):
735770 return str (val )
736771
@@ -766,10 +801,10 @@ def print_help(option, opt, value, parser):
766801MATCHSTRS = {
767802 'in_port' : ('in_port' , toInt ),
768803 'input_port' : ('in_port' , toInt ),
769- 'dl_dst' : ('dl_dst' , toInt ),
770- 'eth_dst' : ('dl_dst' , toInt ),
771- 'dl_src' : ('dl_src' , toInt ),
772- 'eth_src' : ('dl_src' ,toInt ),
804+ 'dl_dst' : ('dl_dst' , toStr ),
805+ 'eth_dst' : ('dl_dst' , toStr ),
806+ 'dl_src' : ('dl_src' , toStr ),
807+ 'eth_src' : ('dl_src' ,toStr ),
773808 'dl_type' : ('dl_type' ,toInt ),
774809 'eth_type' : ('dl_type' ,toInt ),
775810 'dl_vlan' : ('dl_vlan' , toInt ),
@@ -799,6 +834,7 @@ def print_help(option, opt, value, parser):
799834 'save-config' : (pa_saveConfig , do_saveConfig ),
800835 'get-config' : (pa_getConfig , do_getConfig ),
801836 'set-config' : (pa_setConfig , do_setConfig ),
837+ 'list-fs-status' : (pa_listFSStatus , do_listFSStatus ),
802838 'list-slice-info' : (pa_listSliceInfo , do_listSliceInfo ),
803839 'list-datapaths' : (pa_none , do_listDatapaths ),
804840 'list-datapath-info' : (pa_listDatapathInfo , do_listDatapathInfo ),
@@ -822,7 +858,7 @@ def print_help(option, opt, value, parser):
822858 - 32603 : "Internal Error"
823859}
824860
825- USAGE = "%prog {}"
861+ USAGE = "%prog {0 }"
826862
827863URL = "https://%s:%s"
828864
@@ -907,6 +943,14 @@ def print_help(option, opt, value, parser):
907943 "global flood permissions. For flowmod limits, the limit is set per slice per dpid. The dpid in "
908944 "case could be 'any'."
909945 )),
946+ 'list-fs-status' : ("Check the insertion status of a add-flowspace or update-flowspace request." ,
947+ ("In some cases, inserting FlowSpace can take a long time. This command allows you to check "
948+ "whether the FlowSpace request has been processed or rejected. Return values are: UNKNOWN, PENDING, "
949+ "SUCCESS, or an error message. PENDING means the request has not been handled yet, UNKNOWN means the "
950+ "given id is not known to the system and SUCCESS means the request was successfully handled. An error "
951+ "is returned when a request fails."
952+ )),
953+
910954 'list-slice-info' : ("Displays slice information" ,
911955 ("Displays slice information about the configured slices at the FlowVisor, "
912956 "including the current message rate and the number of currently installed "
0 commit comments