blob: 73507041f37ddf38ba0114eb53d372861e35eda9 [file] [log] [blame]
Dave Pigott281203e2014-09-17 23:45:02 +01001#! /usr/bin/python
2
3# Copyright 2014 Linaro Limited
Steve McIntyre663dc062014-10-20 11:11:47 +01004# Author: Dave Pigott <dave.pigott@linaro.org>
Dave Pigott281203e2014-09-17 23:45:02 +01005#
6# This program is free software; you can redistribute it and/or modify
7# it under the terms of the GNU General Public License as published by
8# the Free Software Foundation; either version 2 of the License, or
9# (at your option) any later version.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License
17# along with this program; if not, write to the Free Software
18# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19# MA 02110-1301, USA.
20
21import psycopg2
22import psycopg2.extras
Steve McIntyred74d97c2014-11-28 14:44:39 +000023import datetime
Dave Pigott9b73f3a2014-09-18 22:55:42 +010024from errors import CriticalError
Dave Pigott281203e2014-09-17 23:45:02 +010025
26class VlanDB:
27 def __init__(self, db_name="vland", username="vland"):
28 try:
Steve McIntyree38f6222014-11-27 15:09:49 +000029 self.connection = psycopg2.connect(database=db_name, user=username)
30 self.cursor = self.connection.cursor(cursor_factory=psycopg2.extras.DictCursor)
Dave Pigott281203e2014-09-17 23:45:02 +010031 except Exception as e:
32 print "Failed to access database: %s" % e
33
34 def __del__(self):
35 self.cursor.close()
36 self.connection.close()
37
Steve McIntyredbd7fe52014-11-27 16:54:29 +000038 def create_switch(self, name):
Dave Pigott2649a1a2014-09-18 00:04:49 +010039 try:
Steve McIntyredbd7fe52014-11-27 16:54:29 +000040 sql = "INSERT INTO switch (name) VALUES (%s) RETURNING switch_id"
41 data = name
42 self.cursor.execute(sql, data)
Dave Pigott2649a1a2014-09-18 00:04:49 +010043 switch_id = self.cursor.fetchone()[0]
44 self.connection.commit()
45 except:
46 self.connection.rollback()
47 raise
Dave Pigott281203e2014-09-17 23:45:02 +010048 return switch_id
49
Steve McIntyre90a4a972014-11-28 16:50:56 +000050 # Create a new port in the database. Two of the fields are created
51 # with default values (is_locked, is_trunk) here, and should be
52 # updated separately if desired. For the current_vlan_id and
53 # base_vlan_id fields, *BE CAREFUL* that you have already looked
54 # up the correct VLAN_ID for each. This is *NOT* the same as the
55 # VLAN tag (likely to be 1).
56 # You Have Been Warned!
57 def create_port(self, name, switch_id, current_vlan_id, base_vlan_id):
Dave Pigott2649a1a2014-09-18 00:04:49 +010058 try:
Steve McIntyred74d97c2014-11-28 14:44:39 +000059 sql = "INSERT INTO port (name, switch_id, is_locked, is_trunk, current_vlan_id, base_vlan_id) VALUES (%s, %s, %s, %s, %s, %s) RETURNING port_id"
Steve McIntyre90a4a972014-11-28 16:50:56 +000060 data = (name, switch_id,
61 False, False,
62 current_vlan_id, base_vlan_id)
Steve McIntyredbd7fe52014-11-27 16:54:29 +000063 self.cursor.execute(sql, data)
Dave Pigott2649a1a2014-09-18 00:04:49 +010064 port_id = self.cursor.fetchone()[0]
65 self.connection.commit()
66 except:
67 self.connection.rollback()
68 raise
Dave Pigott281203e2014-09-17 23:45:02 +010069 return port_id
70
Steve McIntyredbd7fe52014-11-27 16:54:29 +000071 def create_vlan(self, name, tag, is_base_vlan):
Dave Pigott2649a1a2014-09-18 00:04:49 +010072 try:
Steve McIntyred74d97c2014-11-28 14:44:39 +000073 dt = datetime.datetime.now()
74 sql = "INSERT INTO vlan (name, tag, is_base_vlan, creation_time) VALUES (%s, %s, %s, %s) RETURNING vlan_id"
75 data = (name, tag, is_base_vlan, dt)
Steve McIntyredbd7fe52014-11-27 16:54:29 +000076 self.cursor.execute(sql, data)
Dave Pigott2649a1a2014-09-18 00:04:49 +010077 vlan_id = self.cursor.fetchone()[0]
78 self.connection.commit()
79 except:
80 self.connection.rollback()
81 raise
Dave Pigott281203e2014-09-17 23:45:02 +010082 return vlan_id
83
84 def _delete_row(self, table, field, value):
Dave Pigott2649a1a2014-09-18 00:04:49 +010085 try:
Steve McIntyredbd7fe52014-11-27 16:54:29 +000086 sql = "DELETE FROM %s WHERE %s = %s"
87 data = (table, field, value)
88 self.cursor.execute(sql, data)
Dave Pigott2649a1a2014-09-18 00:04:49 +010089 self.connection.commit()
90 except:
91 self.connection.rollback()
92 raise
Dave Pigott281203e2014-09-17 23:45:02 +010093
94 def delete_switch(self, switch_id):
95 self._delete_row("switch", "switch_id", switch_id)
96
97 def delete_port(self, port_id):
98 self._delete_row("port", "port_id", port_id)
99
100 def delete_vlan(self, vlan_id):
101 self._delete_row("vlan", "vlan_id", vlan_id)
102
Dave Pigott9b73f3a2014-09-18 22:55:42 +0100103 def _get_element(self, select_field, table, compare_field, value):
Steve McIntyredbd7fe52014-11-27 16:54:29 +0000104 sql = "SELECT %s FROM %s WHERE %s = %s"
105 data = (select_field, table, compare_field, value)
106 self.cursor.execute(sql, data)
Dave Pigott281203e2014-09-17 23:45:02 +0100107 return self.cursor.fetchone()[0]
108
109 def get_switch_id(self, name):
Dave Pigott9b73f3a2014-09-18 22:55:42 +0100110 return self._get_element("switch_id", "switch", "name", name)
Dave Pigott281203e2014-09-17 23:45:02 +0100111
112 def get_port_id(self, name):
Dave Pigott9b73f3a2014-09-18 22:55:42 +0100113 return self._get_element("port_id", "port", "name", name)
Dave Pigott281203e2014-09-17 23:45:02 +0100114
115 def get_vlan_id(self, name):
Dave Pigott9b73f3a2014-09-18 22:55:42 +0100116 return self._get_element("vlan_id", "vlan", "name", name)
Dave Pigott281203e2014-09-17 23:45:02 +0100117
118 def get_switch_name(self, switch_id):
Dave Pigott9b73f3a2014-09-18 22:55:42 +0100119 return self._get_element("name", "switch", "switch_id", switch_id)
Dave Pigott281203e2014-09-17 23:45:02 +0100120
121 def get_port_name(self, port_id):
Dave Pigott9b73f3a2014-09-18 22:55:42 +0100122 return self._get_element("port_name", "port", "port_id", port_id)
Dave Pigott281203e2014-09-17 23:45:02 +0100123
124 def get_vlan_name(self, vlan_id):
Dave Pigott9b73f3a2014-09-18 22:55:42 +0100125 return self._get_element("vlan_name", "vlan", "vlan_id", vlan_id)
126
127 def _get_row(self, table, field, value):
Steve McIntyredbd7fe52014-11-27 16:54:29 +0000128 sql = "SELECT * FROM %s WHERE %s = %s"
129 data = (table, field, value)
130 self.cursor.execute(sql, data)
Dave Pigott9b73f3a2014-09-18 22:55:42 +0100131 return self.cursor.fetchone()
132
133 def get_switch(self, switch_id):
134 return self._get_row("switch", "switch_id", switch_id)
135
136 def get_port(self, port_id):
137 return self._get_row("port", "port_id", port_id)
138
139 def get_vlan(self, vlan_id):
140 return self._get_row("vlan", "vlan_id", vlan_id)
141
142 def set_vlan(self, port_id, vlan_id):
143 port = self.get_port(port_id)
144 if port == None:
145 raise("Port %s does not exist" % port_id)
146
147 if port["is_trunk"] or port["is_locked"]:
148 raise CriticalError("The port is locked")
149
150 vlan = self.get_vlan(vlan_id)
151 if vlan == None:
152 raise CriticalError("VLAN %s does not exist" % vlan_id)
153
154 try:
Steve McIntyredbd7fe52014-11-27 16:54:29 +0000155 sql = "UPDATE port SET current_vlan_id=%s WHERE port_id=%s"
156 data = (vlan_id, port_id)
157 self.cursor.execute(sql, data)
Dave Pigott9b73f3a2014-09-18 22:55:42 +0100158 except:
159 self.connection.rollback()
160 raise
161
162 def restore_default_vlan(self, port_id):
163 port = self.get_port(port_id)
164 if port == None:
165 raise CriticalError("Port %s does not exist")
166
167 if port["is_trunk"] or port["is_locked"]:
168 raise CriticalError("The port is locked")
169
170 try:
Steve McIntyredbd7fe52014-11-27 16:54:29 +0000171 sql = "UPDATE port SET current_vlan_id=base_vlan_id WHERE port_id=%d"
172 data = port_id
173 self.cursor.execute(sql, data)
Dave Pigott9b73f3a2014-09-18 22:55:42 +0100174 except:
175 self.connection.rollback()
176 raise
177
Dave Pigott281203e2014-09-17 23:45:02 +0100178 def _dump_table(self, table):
179 result = []
180 self.cursor.execute("SELECT * FROM %s" % table)
Dave Pigott281203e2014-09-17 23:45:02 +0100181 record = self.cursor.fetchone()
182 while record != None:
Steve McIntyree73eb122014-11-27 15:18:47 +0000183 result.append(record)
Dave Pigott281203e2014-09-17 23:45:02 +0100184 record = self.cursor.fetchone()
185 return result
186
187 def all_switches(self):
188 return self._dump_table("switch")
189
190 def all_ports(self):
191 return self._dump_table("port")
192
193 def all_vlans(self):
194 return self._dump_table("vlan")
Dave Pigott9b73f3a2014-09-18 22:55:42 +0100195