summaryrefslogtreecommitdiffstats
path: root/func
diff options
context:
space:
mode:
authorAdrian Likins <alikins@grimlock.devel.redhat.com>2008-09-17 15:15:31 -0400
committerAdrian Likins <alikins@grimlock.devel.redhat.com>2008-09-17 15:15:31 -0400
commit2bbab70e9f83bd8f0cadec000c1aca258c791472 (patch)
tree582f94754381d3658a7e9416de8b373375ee218d /func
parente9234be855f26f5880ad78532c32263da7f1079e (diff)
parent49eb67062181ba8af2c10e9ef4f11f4908d065ea (diff)
downloadfunc-2bbab70e9f83bd8f0cadec000c1aca258c791472.tar.gz
func-2bbab70e9f83bd8f0cadec000c1aca258c791472.tar.xz
func-2bbab70e9f83bd8f0cadec000c1aca258c791472.zip
Merge branch 'bridge_module'
Diffstat (limited to 'func')
-rw-r--r--func/minion/modules/bridge.py170
1 files changed, 170 insertions, 0 deletions
diff --git a/func/minion/modules/bridge.py b/func/minion/modules/bridge.py
new file mode 100644
index 0000000..1058425
--- /dev/null
+++ b/func/minion/modules/bridge.py
@@ -0,0 +1,170 @@
+#!/usr/bin/python
+#
+# Copyright 2008, Stone-IT
+# Jasper Capel <capel@stone-it.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301 USA
+
+import func_module
+import os
+
+class Bridge(func_module.FuncModule):
+ version = "0.0.1"
+ api_version = "0.0.1"
+ description = "Func module for Bridge management"
+
+ # A list of bridge names that should be ignored. You can use this if you
+ # have bridges that should never be touched by func.
+ # This should go the the module-specific configuration file in the future.
+ # Will ignore virbr0 by default, as it's managed by libvirtd, it's probably
+ # a bad idea to touch it.
+ ignorebridges = [ "virbr0" ]
+ brctl = "/usr/sbin/brctl"
+ ip = "/sbin/ip"
+
+ def list(self):
+ # Returns a dictionary. Elements look like this:
+ # key: bridgename, value: [ interface1, interface2, ..., interfacen ]
+
+ retlist = {}
+
+ command = self.brctl + " show"
+
+ fp = os.popen(command)
+
+ # Read output, discard the first line (header):
+ # Example output:
+ # bridge name bridge id STP enabled interfaces
+ # mgmtbr 8000.feffffffffff no vif12.0
+ # vif11.0
+ # netsbr 8000.feffffffffff no pbond1
+ # vif0.2
+
+ lines = fp.readlines()[1:]
+ fp.close()
+
+ curbr = ""
+ for line in lines:
+ elements = line.split()
+
+ if len(elements) > 1:
+ # Line containing a new bridge name + interface
+ curbr = elements[0]
+ if not curbr in self.ignorebridges:
+ if len(elements) == 3:
+ # This is a bridge without connected devices
+ retlist[elements[0]] = [ ]
+ elif len(elements) == 4:
+ # This is a bridge with one or more devices attached to
+ # it.
+ retlist[elements[0]] = [ elements[3] ]
+
+ elif len(elements) == 1:
+ # Dictionary key containing interface name should already
+ # exist, append the interface.
+ if not curbr in self.ignorebridges:
+ retlist[curbr].append(elements[0])
+
+ return retlist
+
+ def add_bridge(self, brname):
+ # Creates a bridge
+ if brname not in self.ignorebridges:
+ exitcode = os.spawnv(os.P_WAIT, self.brctl, [ self.brctl, "addbr", brname ] )
+ else:
+ exitcode = -1
+
+ return exitcode
+
+ def add_interface(self, brname, ifname):
+ # Adds an interface to a bridge
+ if brname not in self.ignorebridges:
+ exitcode = os.spawnv(os.P_WAIT, self.brctl, [ self.brctl, "addif", brname, ifname ] )
+ else:
+ exitcode = -1
+
+ return exitcode
+
+ def delete_bridge(self, brname):
+ # Deletes a bridge
+ if brname not in self.ignorebridges:
+ # This needs some more error checking. :)
+ exitcode = os.spawnv(os.P_WAIT, self.brctl, [ self.brctl, "delbr", brname ] )
+ else:
+ exitcode = -1
+
+ return exitcode
+
+ def delete_interface(self, brname, ifname):
+ # Deletes an interface from a bridge
+ if brname not in self.ignorebridges:
+ exitcode = os.spawnv(os.P_WAIT, self.brctl, [ self.brctl, "delif", brname, ifname ] )
+ else:
+ exitcode = -1
+
+ return exitcode
+
+ def add_promisc_bridge(self, brname, ifname):
+ # Creates a new bridge brname, attaches interface ifname to it and sets
+ # the MAC address of the connected interface to FE:FF:FF:FF:FF:FF so
+ # traffic can flow freely through the bridge. This is required for use
+ # with Xen.
+ addbrret = self.add_bridge(brname)
+ addifret = self.add_interface(brname,ifname)
+ # Set the MAC address of the interface we're adding to the bridge to
+ # FE:FF:FF:FF:FF:FF. This is consistent with the behaviour of the
+ # Xen network-bridge script.
+ setaddrret = os.spawnv(os.P_WAIT, self.ip, [ self.ip, "link", "set", ifname, "address", "fe:ff:ff:ff:ff:ff" ])
+ if addbrret or addifret or setaddrret:
+ return -1
+ else:
+ return 0
+
+ def updown_bridge(self, brname, up):
+ # Marks a bridge and all it's connected interfaces up or down (used
+ # internally)
+
+ if up:
+ updown = "up"
+ else:
+ updown = "down"
+
+ bridges = self.list()
+ if not brname in bridges:
+ # Bridge doesn't exist, or should be ignored.
+ return -1
+
+ interfaces = [ brname ]
+ for bridgemember in bridges[brname]:
+ interfaces.append(bridgemember)
+
+ exitcode = 0
+
+ for ifname in interfaces:
+ retcode = os.spawnv(os.P_WAIT, self.ip, [self.ip, "link", "set", ifname, updown ] )
+ if retcode != 0:
+ exitcode = retcode
+
+ return exitcode
+
+ def up_bridge(self, brname):
+ # Marks a bridge and all it's connected interfaces up
+ return self.updown_bridge(brname, 1)
+
+ def down_bridge(self, brname):
+ # Marks a bridge and all it's connected interfaces down
+ return self.updown_bridge(brname, 0)
+