Add better distinction of error cases
Add a new NotFoundError exception for use internally, so we can track
specific failure cases.
Also add a new Error class as a central place to store our error
numbers consistently.
In the API protocol, add a "NOTFOUND" error string alongside "ERROR"
to help the admin interface and other callers distinguish error cases
better.
In the admin interface, actually return distinct non-zero errors in
failure cases. Previously, almost all failures would have returned
suceesfully to the calling shell.
Change-Id: Ie382b737a80b7cd41c551e3a4a2a7e0827260bdc
diff --git a/admin.py b/admin.py
index 1e833d1..26964f4 100755
--- a/admin.py
+++ b/admin.py
@@ -27,14 +27,14 @@
vlandpath = os.path.abspath(os.path.normpath(os.path.dirname(sys.argv[0])))
sys.path.insert(0, vlandpath)
-from errors import InputError, SocketError
+from errors import InputError, SocketError, NotFoundError, Error
from config.config import VlanConfig
from ipc.ipc import VlanIpc
prog = "admin"
version = "0.6-DEV"
banner = "Linaro VLANd admin interface, version %s" % version
-
+exit = Error.OK
TRUNK_ID_NONE = -1
def is_positive(text):
@@ -85,8 +85,9 @@
if 'response' not in ret:
raise SocketError("Badly-formed response from VLANd server")
if ret['response'] == "ERROR":
- print "Input error: VLANd server said \"%s\"" % ret['error']
- sys.exit(1)
+ raise InputError("VLANd server said \"%s\"" % ret['error'])
+ if ret['response'] == "NOTFOUND":
+ raise NotFoundError("VLANd server said \"%s\"" % ret['error'])
return ret['data']
config = VlanConfig(filenames=('./vland.cfg',))
@@ -366,71 +367,103 @@
# Now work out what to do
if args.which == 'status':
- print 'Config:'
- print ' knows about %d switch(es)' % len(config.switches)
- default_vlan_id = call_vland('db_query',
- {'command':'db.get_vlan_id_by_tag',
- 'data':
- {'tag': config.vland.default_vlan_tag}})
- print 'The default vlan tag (%d) is vlan ID %d' % (config.vland.default_vlan_tag, default_vlan_id)
- stat = call_vland('daemon_query', {'command':'daemon.status', 'data': None})
- print 'VLANd is running %s' % stat['running']
- lastmod = datetime.datetime.strptime(stat['last_modified'], '%Y-%m-%dT%H:%M:%S.%f')
- print 'DB Last modified %s' % lastmod.strftime('%Y-%m-%d %H:%M:%S %Z')
- print 'DB via VLANd:'
- switches = call_vland('db_query', {'command':'db.all_switches', 'data':None})
- print ' knows about %d switch(es)' % len(switches)
- ports = call_vland('db_query', {'command':'db.all_ports', 'data':None})
- print ' knows about %d port(s)' % len(ports)
- vlans = call_vland('db_query', {'command':'db.all_vlans', 'data':None})
- print ' DB knows about %d vlan(s)' % len(vlans)
+ try:
+ print 'Config:'
+ print ' knows about %d switch(es)' % len(config.switches)
+ default_vlan_id = call_vland('db_query',
+ {'command':'db.get_vlan_id_by_tag',
+ 'data':
+ {'tag': config.vland.default_vlan_tag}})
+ print 'The default vlan tag (%d) is vlan ID %d' % (config.vland.default_vlan_tag, default_vlan_id)
+ stat = call_vland('daemon_query', {'command':'daemon.status', 'data': None})
+ print 'VLANd is running %s' % stat['running']
+ lastmod = datetime.datetime.strptime(stat['last_modified'], '%Y-%m-%dT%H:%M:%S.%f')
+ print 'DB Last modified %s' % lastmod.strftime('%Y-%m-%d %H:%M:%S %Z')
+ print 'DB via VLANd:'
+ switches = call_vland('db_query', {'command':'db.all_switches', 'data':None})
+ print ' knows about %d switch(es)' % len(switches)
+ ports = call_vland('db_query', {'command':'db.all_ports', 'data':None})
+ print ' knows about %d port(s)' % len(ports)
+ vlans = call_vland('db_query', {'command':'db.all_vlans', 'data':None})
+ print ' DB knows about %d vlan(s)' % len(vlans)
+ except:
+ exit = Error.FAILED
elif args.which == 'shutdown':
- print 'Asking VLANd to shutdown'
- shutdown = call_vland('daemon_query',
- {'command':'daemon.shutdown',
- 'data': None})
- for field in shutdown:
- print '%s: %s' % (field, shutdown[field])
+ try:
+ print 'Asking VLANd to shutdown'
+ shutdown = call_vland('daemon_query',
+ {'command':'daemon.shutdown',
+ 'data': None})
+ for field in shutdown:
+ print '%s: %s' % (field, shutdown[field])
+ except:
+ exit = Error.FAILED
elif args.which == 'vland_version':
- ver = call_vland('daemon_query', {'command':'daemon.version', 'data': None})
- print 'VLANd version %s' % ver['version']
+ try:
+ ver = call_vland('daemon_query', {'command':'daemon.version', 'data': None})
+ print 'VLANd version %s' % ver['version']
+ except:
+ exit = Error.FAILED
elif args.which == 'statistics':
- stats = call_vland('daemon_query', {'command':'daemon.statistics', 'data': None})
- print 'VLANd uptime: %d seconds' % stats['uptime']
+ try:
+ stats = call_vland('daemon_query', {'command':'daemon.statistics', 'data': None})
+ print 'VLANd uptime: %d seconds' % stats['uptime']
+ except:
+ exit = Error.FAILED
elif args.which == 'version':
print 'VLANd admin interface version %s' % version
elif args.which == 'auto_import_switch':
print 'Attempting to import switch %s' % args.name
if args.name not in config.switches:
raise InputError("Can't find switch %s in config" % args.name)
- imp = call_vland('vlan_update',
- {'command':'api.auto_import_switch',
- 'data':
- {'switch': args.name}})
- print 'VLANd imported switch %s successfully: new switch_id %d, %d new ports, %d new VLANs' % (args.name, imp['switch_id'], imp['num_ports_added'], imp['num_vlans_added'])
+ try:
+ imp = call_vland('vlan_update',
+ {'command':'api.auto_import_switch',
+ 'data':
+ {'switch': args.name}})
+ print 'VLANd imported switch %s successfully: new switch_id %d, %d new ports, %d new VLANs' % (args.name, imp['switch_id'], imp['num_ports_added'], imp['num_vlans_added'])
+ except:
+ print 'Import failed - see log for details'
+ exit = Error.FAILED
elif args.which == 'probe_switches':
print 'Asking VLANd to probe all the configured switches'
- probe = call_vland('daemon_query',
- {'command':'daemon.probe_switches',
- 'data': None})
- for field in probe:
- print '%s: %s' % (field, probe[field])
+ try:
+ probe = call_vland('daemon_query',
+ {'command':'daemon.probe_switches',
+ 'data': None})
+ for field in probe:
+ print '%s: %s' % (field, probe[field])
+ except:
+ print 'Probe failed - see log for details'
+ exit = Error.FAILED
elif args.which == 'list_all_switches':
- result = call_vland('db_query', {'command':'db.all_switches', 'data':None})
- for line in result:
- dump_switch(line)
+ try:
+ result = call_vland('db_query', {'command':'db.all_switches', 'data':None})
+ for line in result:
+ dump_switch(line)
+ except:
+ exit = Error.FAILED
elif args.which == 'list_all_ports':
- result = call_vland('db_query', {'command':'db.all_ports', 'data':None})
- for line in result:
- dump_port(line)
+ try:
+ result = call_vland('db_query', {'command':'db.all_ports', 'data':None})
+ for line in result:
+ dump_port(line)
+ except:
+ exit = Error.FAILED
elif args.which == 'list_all_vlans':
- result = call_vland('db_query', {'command':'db.all_vlans', 'data':None})
- for line in result:
- dump_vlan(line)
+ try:
+ result = call_vland('db_query', {'command':'db.all_vlans', 'data':None})
+ for line in result:
+ dump_vlan(line)
+ except:
+ exit = Error.FAILED
elif args.which == 'list_all_trunks':
- result = call_vland('db_query', {'command':'db.all_trunks', 'data':None})
- for line in result:
- dump_trunk(line)
+ try:
+ result = call_vland('db_query', {'command':'db.all_trunks', 'data':None})
+ for line in result:
+ dump_trunk(line)
+ except:
+ exit = Error.FAILED
elif args.which == 'create_switch':
try:
switch_id = call_vland('db_update',
@@ -440,6 +473,7 @@
print 'Created switch_id %d' % switch_id
except InputError as inst:
print 'Failed: %s' % inst
+ exit = Error.FAILED
elif args.which == 'create_port':
try:
port_id = call_vland('db_update',
@@ -451,6 +485,10 @@
print 'Created port_id %d' % port_id
except InputError as inst:
print 'Failed: %s' % inst
+ exit = Error.FAILED
+ except NotFoundError as inst:
+ print 'Failed: %s' % inst
+ exit = Error.NOTFOUND
elif args.which == 'create_vlan':
try:
(vlan_id, vlan_tag) = call_vland('vlan_update',
@@ -462,6 +500,10 @@
print 'Created VLAN tag %d as vlan_id %d' % (vlan_tag, vlan_id)
except InputError as inst:
print 'Failed: %s' % inst
+ exit = Error.FAILED
+ except NotFoundError as inst:
+ print 'Failed: %s' % inst
+ exit = Error.NOTFOUND
elif args.which == 'create_trunk':
try:
trunk_id = call_vland('db_update',
@@ -472,6 +514,10 @@
print 'Created trunk_id %d' % trunk_id
except InputError as inst:
print 'Failed: %s' % inst
+ exit = Error.FAILED
+ except NotFoundError as inst:
+ print 'Failed: %s' % inst
+ exit = Error.NOTFOUND
elif args.which == 'delete_switch':
try:
switch_id = call_vland('db_update',
@@ -480,6 +526,10 @@
print 'Deleted switch_id %s' % switch_id
except InputError as inst:
print 'Failed: %s' % inst
+ exit = Error.FAILED
+ except NotFoundError as inst:
+ print 'Failed: %s' % inst
+ exit = Error.NOTFOUND
elif args.which == 'delete_port':
try:
port_id = call_vland('db_update',
@@ -488,6 +538,10 @@
print 'Deleted port_id %s' % port_id
except InputError as inst:
print 'Failed: %s' % inst
+ exit = Error.FAILED
+ except NotFoundError as inst:
+ print 'Failed: %s' % inst
+ exit = Error.NOTFOUND
elif args.which == 'delete_vlan':
try:
vlan_id = call_vland('vlan_update',
@@ -496,6 +550,10 @@
print 'Deleted vlan_id %d' % vlan_id
except InputError as inst:
print 'Failed: %s' % inst
+ exit = Error.FAILED
+ except NotFoundError as inst:
+ print 'Failed: %s' % inst
+ exit = Error.NOTFOUND
elif args.which == 'delete_trunk':
try:
port_id = call_vland('db_update',
@@ -504,6 +562,10 @@
print 'Deleted trunk_id %s' % trunk_id
except InputError as inst:
print 'Failed: %s' % inst
+ exit = Error.FAILED
+ except NotFoundError as inst:
+ print 'Failed: %s' % inst
+ exit = Error.NOTFOUND
elif args.which == 'lookup_switch_by_name':
try:
switch_id = call_vland('db_query',
@@ -513,8 +575,10 @@
print '%d' % switch_id
else:
print 'No switch found for name %s' % args.name
+ exit = Error.NOTFOUND
except InputError as inst:
print 'Failed: %s' % inst
+ exit = Error.FAILED
elif args.which == 'show_switch':
try:
this_switch = call_vland('db_query',
@@ -527,6 +591,7 @@
print 'No switch found for switch_id %s' % args.switch_id
except InputError as inst:
print 'Failed: %s' % inst
+ exit = Error.FAILED
elif args.which == 'show_port':
try:
this_port = call_vland('db_query',
@@ -537,8 +602,10 @@
dump_port(this_port)
else:
print 'No port found for port_id %s' % args.port_id
+ exit = Error.NOTFOUND
except InputError as inst:
print 'Failed: %s' % inst
+ exit = Error.FAILED
elif args.which == 'lookup_port_by_switch_and_name':
try:
p = call_vland('db_query',
@@ -550,6 +617,7 @@
print p
else:
print 'No port found for switch_id %s, name %s' % (args.switch_id, args.name)
+ exit = Error.NOTFOUND
except InputError as inst:
print 'Failed: %s' % inst
elif args.which == 'lookup_port_by_switch_and_number':
@@ -565,6 +633,7 @@
print 'No port found for switch_id %s, port number %s' % (args.switch_id, args.number)
except InputError as inst:
print 'Failed: %s' % inst
+ exit = Error.FAILED
elif args.which == 'lookup_ports_by_switch':
try:
p = call_vland('db_query',
@@ -576,8 +645,10 @@
print port_id
else:
print 'No ports found for switch_id %s' % args.switch_id
+ exit = Error.NOTFOUND
except InputError as inst:
print 'Failed: %s' % inst
+ exit = Error.FAILED
elif args.which == 'lookup_ports_by_current_vlan':
try:
p = call_vland('db_query',
@@ -589,8 +660,10 @@
print port_id
else:
print 'No ports found for current vlan_id %s' % args.vlan_id
+ exit = Error.NOTFOUND
except InputError as inst:
print 'Failed: %s' % inst
+ exit = Error.FAILED
elif args.which == 'lookup_ports_by_base_vlan':
try:
p = call_vland('db_query',
@@ -602,8 +675,10 @@
print port_id
else:
print 'No ports found for base vlan_id %s' % args.vlan_id
+ exit = Error.NOTFOUND
except InputError as inst:
print 'Failed: %s' % inst
+ exit = Error.FAILED
elif args.which == 'lookup_ports_by_trunk':
try:
p = call_vland('db_query',
@@ -615,8 +690,10 @@
print port_id
else:
print 'No ports found for trunk_id %s' % args.trunk_id
+ exit = Error.NOTFOUND
except InputError as inst:
print 'Failed: %s' % inst
+ exit = Error.FAILED
elif args.which == 'set_port_mode':
try:
port_id = call_vland('vlan_update',
@@ -627,6 +704,10 @@
print "Updated mode for port_id %d" % port_id
except InputError as inst:
print 'Failed: %s' % inst
+ exit = Error.FAILED
+ except NotFoundError as inst:
+ print 'Failed: %s' % inst
+ exit = Error.NOTFOUND
elif args.which == 'lock_port':
try:
port_id = call_vland('db_update',
@@ -637,6 +718,10 @@
print "Locked port_id %d" % port_id
except InputError as inst:
print 'Failed: %s' % inst
+ exit = Error.FAILED
+ except NotFoundError as inst:
+ print 'Failed: %s' % inst
+ exit = Error.NOTFOUND
elif args.which == 'unlock_port':
try:
port_id = call_vland('db_update',
@@ -647,6 +732,10 @@
print "Unlocked port_id %d" % port_id
except InputError as inst:
print 'Failed: %s' % inst
+ exit = Error.FAILED
+ except NotFoundError as inst:
+ print 'Failed: %s' % inst
+ exit = Error.NOTFOUND
elif args.which == 'set_port_current_vlan':
try:
port_id = call_vland('vlan_update',
@@ -657,6 +746,10 @@
print "Set current VLAN on port_id %d" % port_id
except InputError as inst:
print 'Failed: %s' % inst
+ exit = Error.FAILED
+ except NotFoundError as inst:
+ print 'Failed: %s' % inst
+ exit = Error.NOTFOUND
elif args.which == 'get_port_current_vlan':
try:
vlan_id = call_vland('db_query',
@@ -669,6 +762,10 @@
print "No current_vlan_id found for port_id %s" % args.port_id
except InputError as inst:
print 'Failed: %s' % inst
+ exit = Error.FAILED
+ except NotFoundError as inst:
+ print 'Failed: %s' % inst
+ exit = Error.NOTFOUND
elif args.which == 'set_port_base_vlan':
try:
port_id = call_vland('db_update',
@@ -679,6 +776,10 @@
print "Set base VLAN on port_id %d" % port_id
except InputError as inst:
print 'Failed: %s' % inst
+ exit = Error.FAILED
+ except NotFoundError as inst:
+ print 'Failed: %s' % inst
+ exit = Error.NOTFOUND
elif args.which == 'get_port_base_vlan':
try:
vlan_id = call_vland('db_query',
@@ -691,6 +792,10 @@
print "No base_vlan_id found for port_id %d" % port_id
except InputError as inst:
print 'Failed: %s' % inst
+ exit = Error.FAILED
+ except NotFoundError as inst:
+ print 'Failed: %s' % inst
+ exit = Error.NOTFOUND
elif args.which == 'restore_port_to_base_vlan':
try:
port_id = call_vland('vlan_update',
@@ -700,6 +805,10 @@
print "Restored port_id %d back to base VLAN" % port_id
except InputError as inst:
print 'Failed: %s' % inst
+ exit = Error.FAILED
+ except NotFoundError as inst:
+ print 'Failed: %s' % inst
+ exit = Error.NOTFOUND
elif args.which == 'show_vlan':
try:
v = call_vland('db_query',
@@ -712,6 +821,10 @@
print 'No VLAN found for vlan_id %s' % args.vlan_id
except InputError as inst:
print 'Failed: %s' % inst
+ exit = Error.FAILED
+ except NotFoundError as inst:
+ print 'Failed: %s' % inst
+ exit = Error.NOTFOUND
elif args.which == 'lookup_vlan_by_tag':
try:
vlan_id = call_vland('db_query',
@@ -722,8 +835,10 @@
print vlan_id
else:
print 'No VLAN found for vlan tag %s' % args.tag
+ exit = Error.NOTFOUND
except InputError as inst:
print 'Failed: %s' % inst
+ exit = Error.FAILED
elif args.which == 'show_vlan_tag':
try:
vlan_tag = call_vland('db_query',
@@ -734,8 +849,10 @@
print vlan_tag
else:
print 'No VLAN found for vlan id %s' % args.vlan_id
+ exit = Error.NOTFOUND
except InputError as inst:
print 'Failed: %s' % inst
+ exit = Error.FAILED
elif args.which == 'show_trunk':
try:
this_trunk = call_vland('db_query',
@@ -748,6 +865,12 @@
print 'No port found for port_id %s' % args.trunk_id
except InputError as inst:
print 'Failed: %s' % inst
-
+ print 'Failed: %s' % inst
+ exit = Error.FAILED
+ except NotFoundError as inst:
+ print 'Failed: %s' % inst
+ exit = Error.NOTFOUND
else:
print 'No recognised command given. Try -h for help'
+
+sys.exit(exit)