[racktables-users] Patch for VLAN support

Hi all,

I found support for "Live VLANs", but I want "Dead VLANs" - I don't
want to have the webapp configure my switch for me, I want my webapp
to *document* how the switch is configured.  Live VLAN support also
uses Telnet which is not an option for me.

So, I patched in VLAN support.  Nothing fancy, just added a column to
Port, added a trigger, and modified some functions here and there.  I
even modified upgrade.php and tested that, it works fine.  To test
yourselves, apply this patch to trunk, run upgrade.php (or add the
column vlan_id to table port and add the word "Generic Managed Switch
(VLAN Support)" to your network switch dictionary).

No data conversion is needed, any port without a VLAN specified is
VLAN ID 1 by default, which is pretty much what the spec says.  I
create a table VLAN to store comments about VLAN's, but got lazy and
didn't implement the interface into it.

To use it after patching, create a network switch object with a
hardware type of "Generic Managed Switch (VLAN Support)", and click on
the Ports tab.

Not for sure if this is the place to post a patch, but here goes.  I
would love to see this feature in trunk - any feedback is much
appreciated.

Justin


--------BEGIN PATCH-------------------------
Index: /home/justintime/workspace/RackTables/install/init-structure.sql
===================================================================
--- /home/justintime/workspace/RackTables/install/init-structure.sql
 (revision 2224)
+++ /home/justintime/workspace/RackTables/install/init-structure.sql
 (working copy)
@@ -158,7 +158,8 @@
   PRIMARY KEY  (`id`),
   UNIQUE KEY `object_id` (`object_id`,`name`),
   UNIQUE KEY `l2address` (`l2address`),
-  KEY `type` (`type`)
+  KEY `type` (`type`),
+  KEY `vlanid` (`vlan_id`)
 ) ENGINE=MyISAM;

 CREATE TABLE `PortCompat` (
@@ -277,3 +278,9 @@
   PRIMARY KEY  (`user_id`),
   UNIQUE KEY `user_name` (`user_name`)
 ) ENGINE=MyISAM AUTO_INCREMENT=10000;
+
+CREATE TABLE `Vlan` (
+  `id` int(10) unsigned NOT NULL,
+  `comment` text,
+  PRIMARY KEY  (`id`)
+) ENGINE=MyISAM;
Index: /home/justintime/workspace/RackTables/install/init-dictvendors.sql
===================================================================
--- /home/justintime/workspace/RackTables/install/init-dictvendors.sql
 (revision 2224)
+++ /home/justintime/workspace/RackTables/install/init-dictvendors.sql
 (working copy)
@@ -742,3 +742,4 @@
 INSERT INTO `Dictionary` (`chapter_no`, `dict_key`, `dict_value`)
VALUES (11,792,'[[SGI%GPASS%Altix XE250 |
http://www.sgi.com/products/servers/altix/xe/configs.html]]');
 INSERT INTO `Dictionary` (`chapter_no`, `dict_key`, `dict_value`)
VALUES (11,793,'[[SGI%GPASS%Altix XE310 |
http://www.sgi.com/products/servers/altix/xe/configs.html]]');
 INSERT INTO `Dictionary` (`chapter_no`, `dict_key`, `dict_value`)
VALUES (11,794,'[[SGI%GPASS%Altix XE320 |
http://www.sgi.com/products/servers/altix/xe/configs.html]]');
+INSERT INTO `Dictionary` (`chapter_no`, `dict_key`, `dict_value`)
VALUES (12,795,'Generic Managed Switch (VLAN Support)');
\ No newline at end of file
Index: /home/justintime/workspace/RackTables/inc/navigation.php
===================================================================
--- /home/justintime/workspace/RackTables/inc/navigation.php    (revision 2224)
+++ /home/justintime/workspace/RackTables/inc/navigation.php    (working copy)
@@ -120,6 +120,7 @@
 $trigger['object']['editrspvs'] = 'trigger_natv4';
 $trigger['object']['lvsconfig'] = 'trigger_lvsconfig';
 $trigger['object']['autoports'] = 'trigger_autoports';
+$trigger['object']['vlans'] = 'trigger_vlans';
 $trigger['object']['tags'] = 'trigger_tags';
 $ophandler['object']['ports']['addPort'] = 'addPortForObject';
 $ophandler['object']['ports']['delPort'] = 'delPortFromObject';
Index: /home/justintime/workspace/RackTables/inc/ophandlers.php
===================================================================
--- /home/justintime/workspace/RackTables/inc/ophandlers.php    (revision 2224)
+++ /home/justintime/workspace/RackTables/inc/ophandlers.php    (working copy)
@@ -166,7 +166,7 @@
        assertStringArg ('port_name', __FUNCTION__, TRUE);
        if (empty ($_REQUEST['port_name']))
                return buildRedirectURL ('ERR1');
-       $error = commitAddPort ($_REQUEST['object_id'],
$_REQUEST['port_name'], $_REQUEST['port_type_id'],
$_REQUEST['port_label'], $_REQUEST['port_l2address']);
+       $error = commitAddPort ($_REQUEST['object_id'],
$_REQUEST['port_name'], $_REQUEST['port_type_id'],
$_REQUEST['port_label'],
$_REQUEST['port_l2address'],$_REQUEST['port_vlan_id']);
        if ($error != '')
                return buildRedirectURL ('ERR2', array ($error));
        else
@@ -185,7 +185,7 @@
                $port_rc = '"' . $_REQUEST['reservation_comment'] . '"';
        else
                $port_rc = 'NULL';
-       $error = commitUpdatePort ($_REQUEST['port_id'],
$_REQUEST['name'], $_REQUEST['label'], $_REQUEST['l2address'],
$port_rc);
+       $error = commitUpdatePort ($_REQUEST['port_id'],
$_REQUEST['name'], $_REQUEST['label'], $_REQUEST['l2address'],
$_REQUEST['vlan_id'], $port_rc);
        if ($error != '')
                return buildRedirectURL ('ERR2', array ($error));
        else
Index: /home/justintime/workspace/RackTables/inc/interface.php
===================================================================
--- /home/justintime/workspace/RackTables/inc/interface.php     (revision 2224)
+++ /home/justintime/workspace/RackTables/inc/interface.php     (working copy)
@@ -791,6 +791,9 @@
                        }
                        echo "<table cellspacing=0 cellpadding='5'
align='center' class='widetable'>\n";
                        echo "<tr><th>Local name</th><th>Visible
label</th><th>Port type</th><th>L2 address</th>";
+            if (trigger_vlans()) {
+                echo "<th>VLAN ID</th>";
+            }
                        echo "<th>Rem. Object</th><th>Rem. port</th></tr>\n";
                        foreach ($ports as $port)
                        {
@@ -799,6 +802,9 @@
                                        echo ' class=port_highlight';
                                echo
"><td>${port['name']}</td><td>${port['label']}</td><td>${port['type']}</td>";
                                echo "<td>${port['l2address']}</td>";
+                if (trigger_vlans()) {
+                   echo "<td>{$port['vlan_id']}</td>";
+                }
                                if ($port['remote_object_id'])
                                {
                                        echo "<td><a
href='${root}?page=object&object_id=${port['remote_object_id']}&hl_port_id=${port['remote_id']}'>${port['remote_object_name']}</a></td>";
@@ -1036,7 +1042,7 @@
        {
                printOpFormIntro ('addPort');
                echo "<tr><td>";
-               printImageHREF ('add', 'add a port', TRUE, 104);
+               printImageHREF ('add', 'add a port', TRUE, 105);
                echo "</td><td><input type=text size=8 name=port_name
tabindex=100></td>\n";
                echo "<td><input type=text size=24 name=port_label
tabindex=101></td>";
                $types = getPortTypes();
@@ -1052,8 +1058,11 @@
                }
                echo "</select></td>";
                echo "<td><input type=text name=port_l2address
tabindex=103></td>\n";
+        if (trigger_vlans()) {
+           echo "<td><input type=text size=5 name=port_vlan_id
tabindex=104 value=1></td>\n";
+        }
                echo "<td colspan=3>&nbsp;</td><td>";
-               printImageHREF ('add', 'add a port', TRUE, 104);
+               printImageHREF ('add', 'add a port', TRUE, 105);
                echo "</td></tr></form>";
        }
        global $root, $pageno, $tabno;
@@ -1068,6 +1077,9 @@
        usort($ports, 'sortByName');
        echo "<table cellspacing=0 cellpadding='5' align='center'
class='widetable'>\n";
        echo "<tr><th>&nbsp;</th><th>Local name</th><th>Visible
label</th><th>Port type</th><th>L2 address</th>";
+    if (trigger_vlans()) {
+       echo "<th>VLAN ID</th>";
+    }
        echo "<th>Rem. object</th><th>Rem. port</th><th>(Un)link or
(un)reserve</th><th>&nbsp;</th></tr>\n";
        if (getConfigVar ('ADDNEW_AT_TOP') == 'yes')
                printNewItemTR();
@@ -1081,6 +1093,9 @@
                echo "<td><input type=text name=label
value='${port['label']}' size=24></td>";
                echo "<td>${port['type']}</td>\n";
                echo "<td><input type=text name=l2address
value='${port['l2address']}'></td>\n";
+        if (trigger_vlans()) {
+           echo "<td><input type=text size=5 name=vlan_id
value='{$port['vlan_id']}'></td>\n";
+        }
                if ($port['remote_object_id'])
                {
                        echo "<td><a
href='${root}?page=object&object_id=${port['remote_object_id']}'>${port['remote_object_name']}</a></td>";
Index: /home/justintime/workspace/RackTables/inc/database.php
===================================================================
--- /home/justintime/workspace/RackTables/inc/database.php      (revision 2224)
+++ /home/justintime/workspace/RackTables/inc/database.php      (working copy)
@@ -302,7 +302,8 @@
                "RemotePort.id as RemotePort_id, ".
                "RemotePort.name as RemotePort_name, ".
                "RemotePort.object_id as RemotePort_object_id, ".
-               "RackObject.name as RackObject_name ".
+               "RackObject.name as RackObject_name, ".
+               "Port.vlan_id as vlan_id ".
                "from (".
                        "(".
                                "(".
@@ -325,6 +326,7 @@
                $ret[$count]['name'] = $row['Port_name'];
                $ret[$count]['l2address'] = l2addressFromDatabase
($row['Port_l2address']);
                $ret[$count]['label'] = $row['Port_label'];
+               $ret[$count]['vlan_id'] = ($row['vlan_id']) ?
$row['vlan_id'] : 1;
                $ret[$count]['type_id'] = $row['Port_type'];
                $ret[$count]['type'] = $row['PortType_name'];
                $ret[$count]['reservation_comment'] =
$row['Port_reservation_comment'];
@@ -751,7 +753,7 @@
        return $ret;
 }

-function commitAddPort ($object_id = 0, $port_name, $port_type_id,
$port_label, $port_l2address)
+function commitAddPort ($object_id = 0, $port_name, $port_type_id,
$port_label, $port_l2address, $port_vlan_id = 1)
 {
        if ($object_id <= 0)
        {
@@ -768,7 +770,8 @@
                        'object_id' => "'${object_id}'",
                        'label' => "'${port_label}'",
                        'type' => "'${port_type_id}'",
-                       'l2address' => "${port_l2address}"
+                       'l2address' => "${port_l2address}",
+                       'vlan_id' => "'${port_vlan_id}'"
                )
        );
        if ($result)
@@ -780,14 +783,17 @@
 // The fifth argument may be either explicit 'NULL' or some (already
quoted by the upper layer)
 // string value. In case it is omitted, we just assign it its current value.
 // It would be nice to simplify this semantics later.
-function commitUpdatePort ($port_id, $port_name, $port_label,
$port_l2address, $port_reservation_comment = 'reservation_comment')
+function commitUpdatePort ($port_id, $port_name, $port_label,
$port_l2address, $port_vlan_id, $port_reservation_comment =
'reservation_comment')
 {
        global $dbxlink;
        $port_l2address = l2addressForDatabase ($port_l2address);
        $query =
                "update Port set name='$port_name', label='$port_label', " .
-               "reservation_comment = ${port_reservation_comment},
l2address=${port_l2address} " .
-               "where id='$port_id'";
+               "reservation_comment = ${port_reservation_comment},
l2address=${port_l2address}";
+    if ($port_vlan_id) {
+        $query .= ", vlan_id=${port_vlan_id}";
+    }
+       $query .= " where id='$port_id'";
        $result = $dbxlink->exec ($query);
        if ($result == 1)
                return '';
Index: /home/justintime/workspace/RackTables/inc/config.php
===================================================================
--- /home/justintime/workspace/RackTables/inc/config.php        (revision 2224)
+++ /home/justintime/workspace/RackTables/inc/config.php        (working copy)
@@ -11,7 +11,7 @@


 // Current code version is subject to change with each new release.
-define ('CODE_VERSION', '0.16.2');
+define ('CODE_VERSION', '0.16.3');

 // The name of hash used to store account password hashes
 // in the database. I think, we are happy with this one forever.
Index: /home/justintime/workspace/RackTables/inc/triggers.php
===================================================================
--- /home/justintime/workspace/RackTables/inc/triggers.php      (revision 2224)
+++ /home/justintime/workspace/RackTables/inc/triggers.php      (working copy)
@@ -38,6 +38,27 @@
        return FALSE;
 }

+function trigger_vlans ()
+{
+       assertUIntArg ('object_id', __FUNCTION__);
+       $object_id = $_REQUEST['object_id'];
+       $object = getObjectInfo ($object_id);
+    if (trigger_livevlans()) {
+        return FALSE;
+    }
+    else {
+        if ($object['objtype_name'] != "network switch") {
+            return FALSE;
+        }
+        $values = getAttrValues ($object_id);
+        foreach ($values as $record) {
+            if ($record['name'] == "HW type") {
+                return ($record['value'] == "Generic Managed Switch
(VLAN Support)");
+            }
+        }
+    }
+}
+
 // SNMP port finder tab trigger. At the moment we decide on showing it
 // for pristine switches only. Once a user has begun
 // filling the data in, we stop showing the tab.
Index: /home/justintime/workspace/RackTables/upgrade.php
===================================================================
--- /home/justintime/workspace/RackTables/upgrade.php   (revision 2224)
+++ /home/justintime/workspace/RackTables/upgrade.php   (working copy)
@@ -1424,6 +1424,12 @@
                        $query[] = "INSERT INTO `Config` (varname,
varvalue, vartype, emptyok, is_hidden, description) VALUES
('IPV4_JAYWALK','no','string','no','no','Enable IPv4 address
allocations w/o covering network')";
                        $query[] = "INSERT INTO `Config` (varname,
varvalue, vartype, emptyok, is_hidden, description) VALUES
('ADDNEW_AT_TOP','yes','string','no','no','Render \"add new\" line at
top of the list')";
                        $query[] = "update Config set description =
'Extended IPv4 view' where varname = 'EXT_IPV4_VIEW'";
+            $query[] = "alter table Port add column vlan_id int(10)
unsigned after label";
+                       $new_words[] = array (12 => 'Generic Managed
Switch (VLAN Support)');
+            foreach ($new_words as $dict_key => $tmp)
+                foreach ($tmp as $chapter_no => $dict_value)
+                    $query[] = 'INSERT INTO `Dictionary`
(`chapter_no`, `dict_key`, `dict_value`) ' .
+                        "VALUES (${chapter_no}, ${dict_key}, '${dict_value}')";
                        $query[] = "update Config set varvalue =
'0.16.3' where varname = 'DB_VERSION'";
                        break;
                default:

Other related posts: