blob: 10ae74486473899ffa6e5e2ef2a04f5d976f68e8 [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 McIntyrec12f6312014-12-15 15:00:12 +000027from config.config import VlanConfig
28from errors import CriticalError, InputError, ConfigError, SocketError
Steve McIntyre844bfd42014-11-27 16:58:31 +000029
30vlandpath = os.path.abspath(os.path.normpath(os.path.dirname(sys.argv[0])))
31sys.path.insert(0, vlandpath)
32
33import drivers
34from db.db import VlanDB
35
36version = "0.0.0-DEV"
37banner = "Linaro VLANd admin interface, version %s" % version
38
Steve McIntyreae95fd62014-12-05 16:51:41 +000039def is_positive(text):
40 if text in ('1', 'y', 'Y', 't', 'T', 'True'):
41 return True
42 elif text in ('0', 'n', 'N', 'f', 'F', 'False'):
43 return False
44 else:
45 raise InputError("Cannot parse \"%s\" as True or False" % text)
46
Steve McIntyrea132c362014-12-05 15:53:21 +000047def dump_switch(switch):
48 print switch
49
Steve McIntyre11e4cbd2014-12-05 16:03:03 +000050def dump_port(port):
51 print port
52
Steve McIntyree41e3f32014-12-05 18:08:21 +000053def dump_vlan(vlan):
54 print vlan
55
Steve McIntyre844bfd42014-11-27 16:58:31 +000056#print '%s' % banner
57
Steve McIntyrec12f6312014-12-15 15:00:12 +000058config = VlanConfig(filenames=('./vland.cfg',))
Steve McIntyrec12f6312014-12-15 15:00:12 +000059
Steve McIntyre844bfd42014-11-27 16:58:31 +000060#print 'Connecting to DB...'
61db = VlanDB()
62
Steve McIntyrec12f6312014-12-15 15:00:12 +000063# We need to know the vlan_id for the default vlan (tag 1). Make sure
64# we know that before anybody attempts to create things that depend on
65# it.
66default_vlan_id = db.get_vlan_id_by_tag(config.vland.default_vlan_tag)
Steve McIntyrec99e93b2014-12-02 18:21:33 +000067if default_vlan_id is None:
Steve McIntyrec12f6312014-12-15 15:00:12 +000068 raise ConfigError("No vlan ID found for default VLAN tag %d" % config.vland.default_vlan_tag)
Steve McIntyre4b0193d2014-11-28 18:06:12 +000069
Steve McIntyre844bfd42014-11-27 16:58:31 +000070usage = 'Usage: %prog --command [command options]'
Steve McIntyre844bfd42014-11-27 16:58:31 +000071parser = optparse.OptionParser(usage=usage, description=banner)
72
Steve McIntyre9cd6c3d2014-12-05 18:10:35 +000073# System commands
74system_group = optparse.OptionGroup(parser, "System commands")
75system_group.add_option("--status",
76 dest="status",
77 action = "store_true",
78 default = False,
79 help = "Describe current system status")
80parser.add_option_group(system_group)
81# May add shutdown, self-check etc. later
82
Steve McIntyre844bfd42014-11-27 16:58:31 +000083# Switch commands
84switch_group = optparse.OptionGroup(parser, "Switch commands")
85switch_group.add_option("--list_all_switches",
86 dest = "list_all_switches",
87 action = "store_true",
88 default = False,
89 help = "List all the existing switches in the system")
90switch_group.add_option("--create_switch",
91 dest = "create_switch",
92 action = "store",
93 type = "string",
94 help = "Add a new switch to the system",
95 nargs = 1,
96 metavar = "<name>")
Steve McIntyre99feaee2014-12-02 18:22:36 +000097switch_group.add_option("--delete_switch",
98 dest = "delete_switch",
Steve McIntyre844bfd42014-11-27 16:58:31 +000099 action = "store",
100 type = "int",
101 help = "Remove an existing switch from the system",
Steve McIntyre59e04632014-12-02 18:02:16 +0000102 default = None,
Steve McIntyre844bfd42014-11-27 16:58:31 +0000103 nargs = 1,
104 metavar = "<switch_id>")
105switch_group.add_option("--show_switch",
106 dest = "show_switch",
107 action = "store",
108 type = "int",
109 help = "Show the details of an existing switch in the system",
Steve McIntyre59e04632014-12-02 18:02:16 +0000110 default = None,
Steve McIntyre844bfd42014-11-27 16:58:31 +0000111 nargs = 1,
112 metavar = "<switch_id>")
113switch_group.add_option("--lookup_switch_by_name",
114 dest = "lookup_switch_by_name",
115 action = "store",
116 type = "string",
117 help = "Lookup a switch ID by name",
118 nargs = 1,
119 metavar = "<name>")
120switch_group.add_option("--list_switch_ports",
121 dest = "list_switch_ports",
122 action = "store",
123 type = "int",
Steve McIntyre11e4cbd2014-12-05 16:03:03 +0000124 help = "List the IDs of the ports on an existing switch in the system",
Steve McIntyre59e04632014-12-02 18:02:16 +0000125 default = None,
Steve McIntyre844bfd42014-11-27 16:58:31 +0000126 nargs = 1,
127 metavar = "<switch_id>")
128parser.add_option_group(switch_group)
129
130# Port commands
131port_group = optparse.OptionGroup(parser, "Port commands")
132port_group.add_option("--list_all_ports",
133 dest = "list_all_ports",
134 action = "store_true",
135 default = False,
136 help = "List all the existing ports in the system")
137port_group.add_option("--create_port",
138 dest = "create_port",
139 action = "store",
140 type = "string",
141 help = "Add a new port to the system",
142 nargs = 2,
143 metavar = "<switch_id> <name>")
Steve McIntyre99feaee2014-12-02 18:22:36 +0000144port_group.add_option("--delete_port",
145 dest = "delete_port",
Steve McIntyre844bfd42014-11-27 16:58:31 +0000146 action = "store",
147 type = "int",
148 help = "Remove an existing port from the system",
Steve McIntyre59e04632014-12-02 18:02:16 +0000149 default = None,
Steve McIntyre844bfd42014-11-27 16:58:31 +0000150 nargs = 1,
151 metavar = "<port_id>")
152port_group.add_option("--show_port",
153 dest = "show_port",
154 action = "store",
155 type = "int",
156 help = "Show the details of an existing port in the system",
Steve McIntyre59e04632014-12-02 18:02:16 +0000157 default = None,
Steve McIntyre844bfd42014-11-27 16:58:31 +0000158 nargs = 1,
159 metavar = "<port_id>")
160port_group.add_option("--lookup_port_by_switch_and_name",
161 dest = "lookup_port_by_switch_and_name",
162 action = "store",
163 type = "string",
164 help = "Lookup a port ID by switch and port name",
165 nargs = 2,
166 metavar = "<switch_id> <name>")
Steve McIntyre71b41022014-12-05 17:17:44 +0000167port_group.add_option("--set_port_mode",
168 dest = "set_port_mode",
Steve McIntyre844bfd42014-11-27 16:58:31 +0000169 action = "store",
170 type = "string",
171 help = "Set the mode of a port to 'trunk' or 'access'",
172 nargs = 2,
173 metavar = "<port_id> <mode>")
174port_group.add_option("--lock_port",
175 dest = "lock_port",
176 action = "store",
177 type = "string",
178 help = "Lock the settings on a port",
179 nargs = 1,
180 metavar = "<port_id>")
181port_group.add_option("--unlock_port",
182 dest = "unlock_port",
183 action = "store",
184 type = "string",
185 help = "Unock the settings on a port",
186 nargs = 1,
187 metavar = "<port_id>")
188port_group.add_option("--set_port_current_vlan",
189 dest = "set_port_current_vlan",
190 action = "store",
191 type = "int",
192 help = "Set the current VLAN assignment for a port",
193 nargs = 2,
194 metavar = "<port_id> <vlan_id>")
195port_group.add_option("--get_port_current_vlan",
196 dest = "get_port_current_vlan",
197 action = "store",
198 type = "int",
199 help = "Get the current VLAN assignment for a port",
200 nargs = 1,
201 metavar = "<port_id>")
202port_group.add_option("--set_port_base_vlan",
203 dest = "set_port_base_vlan",
204 action = "store",
205 type = "int",
206 help = "Set the base VLAN assignment for a port",
207 nargs = 2,
208 metavar = "<port_id> <vlan_id>")
209port_group.add_option("--get_port_base_vlan",
210 dest = "get_port_base_vlan",
211 action = "store",
212 type = "int",
213 help = "Get the base VLAN assignment for a port",
214 nargs = 1,
215 metavar = "<port_id>")
Steve McIntyrea2bbcda2014-12-05 17:57:36 +0000216port_group.add_option("--restore_port_to_base_vlan",
217 dest = "restore_port_to_base_vlan",
218 action = "store",
219 type = "int",
220 help = "Reset the port back to its base VLAN",
221 nargs = 1,
222 metavar = "<port_id>")
Steve McIntyre844bfd42014-11-27 16:58:31 +0000223parser.add_option_group(port_group)
224
225# VLAN commands
226vlan_group = optparse.OptionGroup(parser, "VLAN commands")
227vlan_group.add_option("--list_all_vlans",
228 dest = "list_all_vlans",
229 action = "store_true",
230 default = False,
231 help = "List all the existing vlans in the system")
232vlan_group.add_option("--create_vlan",
233 dest = "create_vlan",
234 action = "store",
235 type = "string",
236 help = "Add a new vlan to the system",
237 nargs = 3,
Steve McIntyre9f0bb602014-11-28 14:36:39 +0000238 metavar = "<name> <tag> <is_base_vlan>")
Steve McIntyre99feaee2014-12-02 18:22:36 +0000239vlan_group.add_option("--delete_vlan",
240 dest = "delete_vlan",
Steve McIntyre844bfd42014-11-27 16:58:31 +0000241 action = "store",
242 type = "int",
243 help = "Remove an existing vlan from the system",
Steve McIntyre59e04632014-12-02 18:02:16 +0000244 default = None,
Steve McIntyre844bfd42014-11-27 16:58:31 +0000245 nargs = 1,
246 metavar = "<vlan_id>")
247vlan_group.add_option("--show_vlan",
248 dest = "show_vlan",
249 action = "store",
250 type = "int",
251 help = "Show the details of an existing vlan in the system",
Steve McIntyre59e04632014-12-02 18:02:16 +0000252 default = None,
Steve McIntyre844bfd42014-11-27 16:58:31 +0000253 nargs = 1,
254 metavar = "<vlan_id>")
255parser.add_option_group(vlan_group)
256
257(opts, args) = parser.parse_args()
258
Steve McIntyre844bfd42014-11-27 16:58:31 +0000259if opts.list_all_switches:
260 result = db.all_switches()
261 count = 0;
262 for line in result:
263 print line
264 count += 1
265 print '%d entries' % count
Steve McIntyreaf2d5ed2014-12-02 12:42:28 +0000266elif opts.list_all_ports:
267 result = db.all_ports()
268 count = 0;
269 for line in result:
270 print line
271 count += 1
272 print '%d entries' % count
273elif opts.list_all_vlans:
274 result = db.all_vlans()
275 count = 0;
276 for line in result:
277 print line
278 count += 1
279 print '%d entries' % count
Steve McIntyre844bfd42014-11-27 16:58:31 +0000280elif opts.create_switch is not None:
Steve McIntyreaf2d5ed2014-12-02 12:42:28 +0000281 try:
282 switch_id = db.create_switch(opts.create_switch)
283 print 'Created switch_id %d' % switch_id
284 except InputError as inst:
285 print 'Failed: %s' % inst
Steve McIntyre844bfd42014-11-27 16:58:31 +0000286elif opts.create_port is not None:
Steve McIntyreaf2d5ed2014-12-02 12:42:28 +0000287 try:
288 port_id = db.create_port(opts.create_port[0],
289 opts.create_port[1],
290 default_vlan_id, default_vlan_id)
291 print 'Created port_id %d' % port_id
292 except InputError as inst:
293 print 'Failed: %s' % inst
Steve McIntyrec21d8d12014-11-28 14:42:40 +0000294elif opts.create_vlan is not None:
Steve McIntyrec8aba4c2014-12-02 12:48:51 +0000295 try:
296 vlan_id = db.create_vlan(opts.create_vlan[0],
297 opts.create_vlan[1],
Steve McIntyreae95fd62014-12-05 16:51:41 +0000298 is_positive(opts.create_vlan[2]))
Steve McIntyrec8aba4c2014-12-02 12:48:51 +0000299 print 'Created vlan_id %d' % vlan_id
300 except InputError as inst:
301 print 'Failed: %s' % inst
Steve McIntyre99feaee2014-12-02 18:22:36 +0000302elif opts.delete_switch is not None:
Steve McIntyre64e38862014-12-02 17:19:37 +0000303 try:
Steve McIntyre99feaee2014-12-02 18:22:36 +0000304 switch_id = db.delete_switch(opts.delete_switch)
Steve McIntyre64e38862014-12-02 17:19:37 +0000305 print 'Deleted switch_id %d' % switch_id
306 except InputError as inst:
307 print 'Failed: %s' % inst
Steve McIntyre99feaee2014-12-02 18:22:36 +0000308elif opts.delete_port is not None:
Steve McIntyre6f7ee5c2014-12-02 18:02:50 +0000309 try:
Steve McIntyre99feaee2014-12-02 18:22:36 +0000310 port_id = db.delete_port(opts.delete_port)
Steve McIntyre6f7ee5c2014-12-02 18:02:50 +0000311 print 'Deleted port_id %d' % port_id
312 except InputError as inst:
313 print 'Failed: %s' % inst
Steve McIntyreed5cbea2014-12-02 18:23:00 +0000314elif opts.delete_vlan is not None:
315 try:
316 vlan_id = db.delete_vlan(opts.delete_vlan)
317 print 'Deleted vlan_id %d' % vlan_id
318 except InputError as inst:
319 print 'Failed: %s' % inst
Steve McIntyre8e839a62014-12-05 15:46:05 +0000320elif opts.lookup_switch_by_name is not None:
321 try:
322 switch_id = db.get_switch_id_by_name(opts.lookup_switch_by_name)
323 if switch_id is not None:
324 print 'Switch %s has switch_id %d' % (opts.lookup_switch_by_name, switch_id)
325 else:
326 print 'No switch found for name %s' % opts.lookup_switch_by_name
327 except InputError as inst:
328 print 'Failed: %s' % inst
Steve McIntyrea132c362014-12-05 15:53:21 +0000329elif opts.show_switch is not None:
330 try:
331 switch = db.get_switch_by_id(opts.show_switch)
332 if switch is not None:
333 dump_switch(switch)
334 else:
335 print 'No switch found for switch_id %d' % opts.show_switch
336 except InputError as inst:
337 print 'Failed: %s' % inst
Steve McIntyre11e4cbd2014-12-05 16:03:03 +0000338elif opts.list_switch_ports is not None:
339 try:
340 ports = db.get_ports_by_switch(opts.list_switch_ports)
341 if ports is not None:
342 for port in ports:
343 dump_port(port)
344 else:
345 print 'No ports found for switch_id %d' % opts.list_switch_ports
346 except InputError as inst:
347 print 'Failed: %s' % inst
Steve McIntyre08dd8392014-12-05 16:07:20 +0000348elif opts.show_port is not None:
349 try:
350 port = db.get_port_by_id(opts.show_port)
351 if port is not None:
352 dump_port(port)
353 else:
354 print 'No port found for port_id %d' % opts.show_port
355 except InputError as inst:
356 print 'Failed: %s' % inst
Steve McIntyre73106572014-12-05 16:13:36 +0000357elif opts.lookup_port_by_switch_and_name is not None:
358 try:
359 port = db.get_port_by_switch_and_name(opts.lookup_port_by_switch_and_name[0], opts.lookup_port_by_switch_and_name[1])
360 if port is not None:
361 print port
362 else:
363 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])
364 except InputError as inst:
365 print 'Failed: %s' % inst
Steve McIntyre71b41022014-12-05 17:17:44 +0000366elif opts.set_port_mode is not None:
367 try:
368 port_id = db.set_port_mode(opts.set_port_mode[0], opts.set_port_mode[1])
369 print "Updated mode for port_id %d" % port_id
370 except InputError as inst:
371 print 'Failed: %s' % inst
Steve McIntyre75dc4ec2014-12-05 17:20:42 +0000372elif opts.lock_port is not None:
373 try:
374 port_id = db.set_port_is_locked(opts.lock_port, True)
375 print "Locked port_id %d" % port_id
376 except InputError as inst:
377 print 'Failed: %s' % inst
378elif opts.unlock_port is not None:
379 try:
380 port_id = db.set_port_is_locked(opts.unlock_port, False)
381 print "Unlocked port_id %d" % port_id
382 except InputError as inst:
383 print 'Failed: %s' % inst
Steve McIntyrea2bbcda2014-12-05 17:57:36 +0000384elif opts.set_port_current_vlan is not None:
385 try:
386 port_id = db.set_current_vlan(opts.set_port_current_vlan[0], opts.set_port_current_vlan[1])
387 print "Set current VLAN on port_id %d" % port_id
388 except InputError as inst:
389 print 'Failed: %s' % inst
390elif opts.get_port_current_vlan is not None:
391 try:
392 vlan_id = db.get_current_vlan_id_by_port(opts.get_port_current_vlan)
393 if vlan_id is not None:
394 print vlan_id
395 else:
396 print "No current_vlan_id found for port_id %d" % opts.get_port_current_vlan
397 except InputError as inst:
398 print 'Failed: %s' % inst
399elif opts.set_port_base_vlan is not None:
400 try:
401 port_id = db.set_base_vlan(opts.set_port_base_vlan[0], opts.set_port_base_vlan[1])
402 print "Set base VLAN on port_id %d" % port_id
403 except InputError as inst:
404 print 'Failed: %s' % inst
405elif opts.get_port_base_vlan is not None:
406 try:
407 vlan_id = db.get_base_vlan_id_by_port(opts.get_port_base_vlan)
408 if vlan_id is not None:
409 print vlan_id
410 else:
411 print "No base_vlan_id found for port_id %d" % port_id
412 except InputError as inst:
413 print 'Failed: %s' % inst
414elif opts.restore_port_to_base_vlan is not None:
415 try:
416 port_id = db.restore_base_vlan(opts.restore_port_to_base_vlan)
417 print "Restored port_id %d back to base VLAN" % port_id
418 except InputError as inst:
419 print 'Failed: %s' % inst
Steve McIntyree41e3f32014-12-05 18:08:21 +0000420elif opts.show_vlan is not None:
421 try:
422 vlan = db.get_vlan_by_id(opts.show_vlan)
423 if vlan is not None:
424 dump_vlan(vlan)
425 else:
426 print 'No vlan found for vlan_id %d' % opts.show_vlan
427 except InputError as inst:
428 print 'Failed: %s' % inst
Steve McIntyre9cd6c3d2014-12-05 18:10:35 +0000429elif opts.status:
430 print banner
Steve McIntyrebb718cf2014-12-15 16:57:25 +0000431 print 'Config:'
432 print ' knows about %d switch(es)' % len(config.switches)
433 print 'DB:'
Steve McIntyre9cd6c3d2014-12-05 18:10:35 +0000434 switches = db.all_switches()
Steve McIntyrebb718cf2014-12-15 16:57:25 +0000435 print ' knows about %d switch(es)' % len(switches)
Steve McIntyre9cd6c3d2014-12-05 18:10:35 +0000436 ports = db.all_ports()
Steve McIntyrebb718cf2014-12-15 16:57:25 +0000437 print ' knows about %d port(s)' % len(ports)
Steve McIntyre9cd6c3d2014-12-05 18:10:35 +0000438 vlans = db.all_vlans()
Steve McIntyrebb718cf2014-12-15 16:57:25 +0000439 print ' DB knows about %d vlan(s)' % len(vlans)
Steve McIntyre0abacac2014-12-15 16:51:38 +0000440 print 'The default vlan tag (%d) is vlan_id %d' % (config.vland.default_vlan_tag, default_vlan_id)
Steve McIntyrea0534a52014-12-05 17:58:40 +0000441else:
Steve McIntyre4a808912014-12-05 15:24:39 +0000442 print 'No recognised command given. Try -h for help'