blob: 8e9902b10bd024d8ff173309b92dc9fa38d35dc1 [file] [log] [blame]
Steve McIntyre844bfd42014-11-27 16:58:31 +00001#! /usr/bin/python
2
3# Copyright 2014 Linaro Limited
4#
5# This program is free software; you can redistribute it and/or modify
6# it under the terms of the GNU General Public License as published by
7# the Free Software Foundation; either version 2 of the License, or
8# (at your option) any later version.
9#
10# This program is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13# GNU General Public License for more details.
14#
15# You should have received a copy of the GNU General Public License
16# along with this program; if not, write to the Free Software
17# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18# MA 02110-1301, USA.
19#
20# VLANd admin interface
21#
22
23import os, sys, types
24import time
25import logging
26import optparse
Steve McIntyrea4ad70e2014-12-02 12:39:43 +000027from errors import CriticalError, InputError
Steve McIntyre844bfd42014-11-27 16:58:31 +000028
29vlandpath = os.path.abspath(os.path.normpath(os.path.dirname(sys.argv[0])))
30sys.path.insert(0, vlandpath)
31
32import drivers
33from db.db import VlanDB
34
35version = "0.0.0-DEV"
36banner = "Linaro VLANd admin interface, version %s" % version
37
Steve McIntyreae95fd62014-12-05 16:51:41 +000038def is_positive(text):
39 if text in ('1', 'y', 'Y', 't', 'T', 'True'):
40 return True
41 elif text in ('0', 'n', 'N', 'f', 'F', 'False'):
42 return False
43 else:
44 raise InputError("Cannot parse \"%s\" as True or False" % text)
45
Steve McIntyrea132c362014-12-05 15:53:21 +000046def dump_switch(switch):
47 print switch
48
Steve McIntyre11e4cbd2014-12-05 16:03:03 +000049def dump_port(port):
50 print port
51
Steve McIntyree41e3f32014-12-05 18:08:21 +000052def dump_vlan(vlan):
53 print vlan
54
Steve McIntyre844bfd42014-11-27 16:58:31 +000055#print '%s' % banner
56
57#print 'Connecting to DB...'
58db = VlanDB()
59
Steve McIntyre4b0193d2014-11-28 18:06:12 +000060# For sanity, we need to know the vlan_id for the default vlan (tag
61# 1). Make sure we know that before anybody attempts to create things
62# that depend on it.
63default_vlan_tag = 1
Steve McIntyre50eb0602014-12-05 15:29:04 +000064default_vlan_id = db.get_vlan_id_by_tag(default_vlan_tag)
Steve McIntyrec99e93b2014-12-02 18:21:33 +000065if default_vlan_id is None:
Steve McIntyre4b0193d2014-11-28 18:06:12 +000066 # It doesn't exist - create it and try again
67 default_vlan_id = db.create_vlan("DEFAULT",
68 default_vlan_tag,
69 True)
70
71
Steve McIntyre844bfd42014-11-27 16:58:31 +000072usage = 'Usage: %prog --command [command options]'
Steve McIntyre844bfd42014-11-27 16:58:31 +000073parser = optparse.OptionParser(usage=usage, description=banner)
74
Steve McIntyre9cd6c3d2014-12-05 18:10:35 +000075# System commands
76system_group = optparse.OptionGroup(parser, "System commands")
77system_group.add_option("--status",
78 dest="status",
79 action = "store_true",
80 default = False,
81 help = "Describe current system status")
82parser.add_option_group(system_group)
83# May add shutdown, self-check etc. later
84
Steve McIntyre844bfd42014-11-27 16:58:31 +000085# Switch commands
86switch_group = optparse.OptionGroup(parser, "Switch commands")
87switch_group.add_option("--list_all_switches",
88 dest = "list_all_switches",
89 action = "store_true",
90 default = False,
91 help = "List all the existing switches in the system")
92switch_group.add_option("--create_switch",
93 dest = "create_switch",
94 action = "store",
95 type = "string",
96 help = "Add a new switch to the system",
97 nargs = 1,
98 metavar = "<name>")
Steve McIntyre99feaee2014-12-02 18:22:36 +000099switch_group.add_option("--delete_switch",
100 dest = "delete_switch",
Steve McIntyre844bfd42014-11-27 16:58:31 +0000101 action = "store",
102 type = "int",
103 help = "Remove an existing switch from the system",
Steve McIntyre59e04632014-12-02 18:02:16 +0000104 default = None,
Steve McIntyre844bfd42014-11-27 16:58:31 +0000105 nargs = 1,
106 metavar = "<switch_id>")
107switch_group.add_option("--show_switch",
108 dest = "show_switch",
109 action = "store",
110 type = "int",
111 help = "Show the details of an existing switch in the system",
Steve McIntyre59e04632014-12-02 18:02:16 +0000112 default = None,
Steve McIntyre844bfd42014-11-27 16:58:31 +0000113 nargs = 1,
114 metavar = "<switch_id>")
115switch_group.add_option("--lookup_switch_by_name",
116 dest = "lookup_switch_by_name",
117 action = "store",
118 type = "string",
119 help = "Lookup a switch ID by name",
120 nargs = 1,
121 metavar = "<name>")
122switch_group.add_option("--list_switch_ports",
123 dest = "list_switch_ports",
124 action = "store",
125 type = "int",
Steve McIntyre11e4cbd2014-12-05 16:03:03 +0000126 help = "List the IDs of the ports on an existing switch in the system",
Steve McIntyre59e04632014-12-02 18:02:16 +0000127 default = None,
Steve McIntyre844bfd42014-11-27 16:58:31 +0000128 nargs = 1,
129 metavar = "<switch_id>")
130parser.add_option_group(switch_group)
131
132# Port commands
133port_group = optparse.OptionGroup(parser, "Port commands")
134port_group.add_option("--list_all_ports",
135 dest = "list_all_ports",
136 action = "store_true",
137 default = False,
138 help = "List all the existing ports in the system")
139port_group.add_option("--create_port",
140 dest = "create_port",
141 action = "store",
142 type = "string",
143 help = "Add a new port to the system",
144 nargs = 2,
145 metavar = "<switch_id> <name>")
Steve McIntyre99feaee2014-12-02 18:22:36 +0000146port_group.add_option("--delete_port",
147 dest = "delete_port",
Steve McIntyre844bfd42014-11-27 16:58:31 +0000148 action = "store",
149 type = "int",
150 help = "Remove an existing port from the system",
Steve McIntyre59e04632014-12-02 18:02:16 +0000151 default = None,
Steve McIntyre844bfd42014-11-27 16:58:31 +0000152 nargs = 1,
153 metavar = "<port_id>")
154port_group.add_option("--show_port",
155 dest = "show_port",
156 action = "store",
157 type = "int",
158 help = "Show the details of an existing port in the system",
Steve McIntyre59e04632014-12-02 18:02:16 +0000159 default = None,
Steve McIntyre844bfd42014-11-27 16:58:31 +0000160 nargs = 1,
161 metavar = "<port_id>")
162port_group.add_option("--lookup_port_by_switch_and_name",
163 dest = "lookup_port_by_switch_and_name",
164 action = "store",
165 type = "string",
166 help = "Lookup a port ID by switch and port name",
167 nargs = 2,
168 metavar = "<switch_id> <name>")
Steve McIntyre71b41022014-12-05 17:17:44 +0000169port_group.add_option("--set_port_mode",
170 dest = "set_port_mode",
Steve McIntyre844bfd42014-11-27 16:58:31 +0000171 action = "store",
172 type = "string",
173 help = "Set the mode of a port to 'trunk' or 'access'",
174 nargs = 2,
175 metavar = "<port_id> <mode>")
176port_group.add_option("--lock_port",
177 dest = "lock_port",
178 action = "store",
179 type = "string",
180 help = "Lock the settings on a port",
181 nargs = 1,
182 metavar = "<port_id>")
183port_group.add_option("--unlock_port",
184 dest = "unlock_port",
185 action = "store",
186 type = "string",
187 help = "Unock the settings on a port",
188 nargs = 1,
189 metavar = "<port_id>")
190port_group.add_option("--set_port_current_vlan",
191 dest = "set_port_current_vlan",
192 action = "store",
193 type = "int",
194 help = "Set the current VLAN assignment for a port",
195 nargs = 2,
196 metavar = "<port_id> <vlan_id>")
197port_group.add_option("--get_port_current_vlan",
198 dest = "get_port_current_vlan",
199 action = "store",
200 type = "int",
201 help = "Get the current VLAN assignment for a port",
202 nargs = 1,
203 metavar = "<port_id>")
204port_group.add_option("--set_port_base_vlan",
205 dest = "set_port_base_vlan",
206 action = "store",
207 type = "int",
208 help = "Set the base VLAN assignment for a port",
209 nargs = 2,
210 metavar = "<port_id> <vlan_id>")
211port_group.add_option("--get_port_base_vlan",
212 dest = "get_port_base_vlan",
213 action = "store",
214 type = "int",
215 help = "Get the base VLAN assignment for a port",
216 nargs = 1,
217 metavar = "<port_id>")
Steve McIntyrea2bbcda2014-12-05 17:57:36 +0000218port_group.add_option("--restore_port_to_base_vlan",
219 dest = "restore_port_to_base_vlan",
220 action = "store",
221 type = "int",
222 help = "Reset the port back to its base VLAN",
223 nargs = 1,
224 metavar = "<port_id>")
Steve McIntyre844bfd42014-11-27 16:58:31 +0000225parser.add_option_group(port_group)
226
227# VLAN commands
228vlan_group = optparse.OptionGroup(parser, "VLAN commands")
229vlan_group.add_option("--list_all_vlans",
230 dest = "list_all_vlans",
231 action = "store_true",
232 default = False,
233 help = "List all the existing vlans in the system")
234vlan_group.add_option("--create_vlan",
235 dest = "create_vlan",
236 action = "store",
237 type = "string",
238 help = "Add a new vlan to the system",
239 nargs = 3,
Steve McIntyre9f0bb602014-11-28 14:36:39 +0000240 metavar = "<name> <tag> <is_base_vlan>")
Steve McIntyre99feaee2014-12-02 18:22:36 +0000241vlan_group.add_option("--delete_vlan",
242 dest = "delete_vlan",
Steve McIntyre844bfd42014-11-27 16:58:31 +0000243 action = "store",
244 type = "int",
245 help = "Remove an existing vlan from the system",
Steve McIntyre59e04632014-12-02 18:02:16 +0000246 default = None,
Steve McIntyre844bfd42014-11-27 16:58:31 +0000247 nargs = 1,
248 metavar = "<vlan_id>")
249vlan_group.add_option("--show_vlan",
250 dest = "show_vlan",
251 action = "store",
252 type = "int",
253 help = "Show the details of an existing vlan in the system",
Steve McIntyre59e04632014-12-02 18:02:16 +0000254 default = None,
Steve McIntyre844bfd42014-11-27 16:58:31 +0000255 nargs = 1,
256 metavar = "<vlan_id>")
257parser.add_option_group(vlan_group)
258
259(opts, args) = parser.parse_args()
260
Steve McIntyre844bfd42014-11-27 16:58:31 +0000261if opts.list_all_switches:
262 result = db.all_switches()
263 count = 0;
264 for line in result:
265 print line
266 count += 1
267 print '%d entries' % count
Steve McIntyreaf2d5ed2014-12-02 12:42:28 +0000268elif opts.list_all_ports:
269 result = db.all_ports()
270 count = 0;
271 for line in result:
272 print line
273 count += 1
274 print '%d entries' % count
275elif opts.list_all_vlans:
276 result = db.all_vlans()
277 count = 0;
278 for line in result:
279 print line
280 count += 1
281 print '%d entries' % count
Steve McIntyre844bfd42014-11-27 16:58:31 +0000282elif opts.create_switch is not None:
Steve McIntyreaf2d5ed2014-12-02 12:42:28 +0000283 try:
284 switch_id = db.create_switch(opts.create_switch)
285 print 'Created switch_id %d' % switch_id
286 except InputError as inst:
287 print 'Failed: %s' % inst
Steve McIntyre844bfd42014-11-27 16:58:31 +0000288elif opts.create_port is not None:
Steve McIntyreaf2d5ed2014-12-02 12:42:28 +0000289 try:
290 port_id = db.create_port(opts.create_port[0],
291 opts.create_port[1],
292 default_vlan_id, default_vlan_id)
293 print 'Created port_id %d' % port_id
294 except InputError as inst:
295 print 'Failed: %s' % inst
Steve McIntyrec21d8d12014-11-28 14:42:40 +0000296elif opts.create_vlan is not None:
Steve McIntyrec8aba4c2014-12-02 12:48:51 +0000297 try:
298 vlan_id = db.create_vlan(opts.create_vlan[0],
299 opts.create_vlan[1],
Steve McIntyreae95fd62014-12-05 16:51:41 +0000300 is_positive(opts.create_vlan[2]))
Steve McIntyrec8aba4c2014-12-02 12:48:51 +0000301 print 'Created vlan_id %d' % vlan_id
302 except InputError as inst:
303 print 'Failed: %s' % inst
Steve McIntyre99feaee2014-12-02 18:22:36 +0000304elif opts.delete_switch is not None:
Steve McIntyre64e38862014-12-02 17:19:37 +0000305 try:
Steve McIntyre99feaee2014-12-02 18:22:36 +0000306 switch_id = db.delete_switch(opts.delete_switch)
Steve McIntyre64e38862014-12-02 17:19:37 +0000307 print 'Deleted switch_id %d' % switch_id
308 except InputError as inst:
309 print 'Failed: %s' % inst
Steve McIntyre99feaee2014-12-02 18:22:36 +0000310elif opts.delete_port is not None:
Steve McIntyre6f7ee5c2014-12-02 18:02:50 +0000311 try:
Steve McIntyre99feaee2014-12-02 18:22:36 +0000312 port_id = db.delete_port(opts.delete_port)
Steve McIntyre6f7ee5c2014-12-02 18:02:50 +0000313 print 'Deleted port_id %d' % port_id
314 except InputError as inst:
315 print 'Failed: %s' % inst
Steve McIntyreed5cbea2014-12-02 18:23:00 +0000316elif opts.delete_vlan is not None:
317 try:
318 vlan_id = db.delete_vlan(opts.delete_vlan)
319 print 'Deleted vlan_id %d' % vlan_id
320 except InputError as inst:
321 print 'Failed: %s' % inst
Steve McIntyre8e839a62014-12-05 15:46:05 +0000322elif opts.lookup_switch_by_name is not None:
323 try:
324 switch_id = db.get_switch_id_by_name(opts.lookup_switch_by_name)
325 if switch_id is not None:
326 print 'Switch %s has switch_id %d' % (opts.lookup_switch_by_name, switch_id)
327 else:
328 print 'No switch found for name %s' % opts.lookup_switch_by_name
329 except InputError as inst:
330 print 'Failed: %s' % inst
Steve McIntyrea132c362014-12-05 15:53:21 +0000331elif opts.show_switch is not None:
332 try:
333 switch = db.get_switch_by_id(opts.show_switch)
334 if switch is not None:
335 dump_switch(switch)
336 else:
337 print 'No switch found for switch_id %d' % opts.show_switch
338 except InputError as inst:
339 print 'Failed: %s' % inst
Steve McIntyre11e4cbd2014-12-05 16:03:03 +0000340elif opts.list_switch_ports is not None:
341 try:
342 ports = db.get_ports_by_switch(opts.list_switch_ports)
343 if ports is not None:
344 for port in ports:
345 dump_port(port)
346 else:
347 print 'No ports found for switch_id %d' % opts.list_switch_ports
348 except InputError as inst:
349 print 'Failed: %s' % inst
Steve McIntyre08dd8392014-12-05 16:07:20 +0000350elif opts.show_port is not None:
351 try:
352 port = db.get_port_by_id(opts.show_port)
353 if port is not None:
354 dump_port(port)
355 else:
356 print 'No port found for port_id %d' % opts.show_port
357 except InputError as inst:
358 print 'Failed: %s' % inst
Steve McIntyre73106572014-12-05 16:13:36 +0000359elif opts.lookup_port_by_switch_and_name is not None:
360 try:
361 port = db.get_port_by_switch_and_name(opts.lookup_port_by_switch_and_name[0], opts.lookup_port_by_switch_and_name[1])
362 if port is not None:
363 print port
364 else:
365 print 'No port found for switch_id %d, name %s' % (int(opts.lookup_port_by_switch_and_name[0]), opts.lookup_port_by_switch_and_name[1])
366 except InputError as inst:
367 print 'Failed: %s' % inst
Steve McIntyre71b41022014-12-05 17:17:44 +0000368elif opts.set_port_mode is not None:
369 try:
370 port_id = db.set_port_mode(opts.set_port_mode[0], opts.set_port_mode[1])
371 print "Updated mode for port_id %d" % port_id
372 except InputError as inst:
373 print 'Failed: %s' % inst
Steve McIntyre75dc4ec2014-12-05 17:20:42 +0000374elif opts.lock_port is not None:
375 try:
376 port_id = db.set_port_is_locked(opts.lock_port, True)
377 print "Locked port_id %d" % port_id
378 except InputError as inst:
379 print 'Failed: %s' % inst
380elif opts.unlock_port is not None:
381 try:
382 port_id = db.set_port_is_locked(opts.unlock_port, False)
383 print "Unlocked port_id %d" % port_id
384 except InputError as inst:
385 print 'Failed: %s' % inst
Steve McIntyrea2bbcda2014-12-05 17:57:36 +0000386elif opts.set_port_current_vlan is not None:
387 try:
388 port_id = db.set_current_vlan(opts.set_port_current_vlan[0], opts.set_port_current_vlan[1])
389 print "Set current VLAN on port_id %d" % port_id
390 except InputError as inst:
391 print 'Failed: %s' % inst
392elif opts.get_port_current_vlan is not None:
393 try:
394 vlan_id = db.get_current_vlan_id_by_port(opts.get_port_current_vlan)
395 if vlan_id is not None:
396 print vlan_id
397 else:
398 print "No current_vlan_id found for port_id %d" % opts.get_port_current_vlan
399 except InputError as inst:
400 print 'Failed: %s' % inst
401elif opts.set_port_base_vlan is not None:
402 try:
403 port_id = db.set_base_vlan(opts.set_port_base_vlan[0], opts.set_port_base_vlan[1])
404 print "Set base VLAN on port_id %d" % port_id
405 except InputError as inst:
406 print 'Failed: %s' % inst
407elif opts.get_port_base_vlan is not None:
408 try:
409 vlan_id = db.get_base_vlan_id_by_port(opts.get_port_base_vlan)
410 if vlan_id is not None:
411 print vlan_id
412 else:
413 print "No base_vlan_id found for port_id %d" % port_id
414 except InputError as inst:
415 print 'Failed: %s' % inst
416elif opts.restore_port_to_base_vlan is not None:
417 try:
418 port_id = db.restore_base_vlan(opts.restore_port_to_base_vlan)
419 print "Restored port_id %d back to base VLAN" % port_id
420 except InputError as inst:
421 print 'Failed: %s' % inst
Steve McIntyree41e3f32014-12-05 18:08:21 +0000422elif opts.show_vlan is not None:
423 try:
424 vlan = db.get_vlan_by_id(opts.show_vlan)
425 if vlan is not None:
426 dump_vlan(vlan)
427 else:
428 print 'No vlan found for vlan_id %d' % opts.show_vlan
429 except InputError as inst:
430 print 'Failed: %s' % inst
Steve McIntyre9cd6c3d2014-12-05 18:10:35 +0000431elif opts.status:
432 print banner
433 switches = db.all_switches()
434 print 'The DB knows about %d switch(es)' % len(switches)
435 ports = db.all_ports()
436 print 'The DB knows about %d port(s)' % len(ports)
437 vlans = db.all_vlans()
438 print 'The DB knows about %d vlan(s)' % len(vlans)
439 print 'The default vlan tag (%d) is vlan_id %d' % (default_vlan_tag, default_vlan_id)
Steve McIntyrea0534a52014-12-05 17:58:40 +0000440else:
Steve McIntyre4a808912014-12-05 15:24:39 +0000441 print 'No recognised command given. Try -h for help'