---
lib/networktables.py | 108 +++++++++++++++++++++++++++++++++++--------------
1 files changed, 77 insertions(+), 31 deletions(-)
diff --git a/lib/networktables.py b/lib/networktables.py
index f2006e0..585405f 100644
--- a/lib/networktables.py
+++ b/lib/networktables.py
@@ -1,6 +1,23 @@
#
#
+
# Copyright 2009 Google Inc. All Rights Reserved.
+#
+# 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.
+
"""Neighbour IPs interface
@@ -10,7 +27,6 @@ Besides adding and removing individual entries, it can also
be used to
add (or replace, if necessary) the entries in a given dictionary with
src_ip:dest_addr mapping.
-
"""
@@ -18,79 +34,109 @@ from ganeti import errors
from ganeti import utils
-NEIGHBOUR = 'neigh'
-ROUTING = 'route'
+NEIGHBOUR_CONTEXT = 'neigh'
+ROUTING_CONTEXT = 'route'
+CONTEXTS = frozenset([NEIGHBOUR_CONTEXT, ROUTING_CONTEXT])
-def RemoveNetworkEntry(ip_address, context, iface):
+def _CheckValidContext(context):
+ """Verify if the context is valid.
+
+ @type context: str
+ @param context: one of CONTEXTS
+
+ @raise errors.ConfigurationError: if a check fails
"""
- Remove an entry in the local Neighbour or Routing table.
+ if context not in CONTEXTS:
+ raise errors.ConfigurationError("Invalid context '%s'" % context)
+
+
+def RemoveNetworkEntry(ip_address, context, iface):
+ """Remove an entry in the local Neighbour or Routing table.
@type ip_address: str
@param ip_address: IP address to be updated
@type context: str
- @param context: NEIGHBOUR or ROUTING
+ @param context: one of CONTEXTS
@type iface: str
@param iface: network interface to use
- """
- # This command returns an error when asked to remove a non-existent
- # address. We don't care about that, so no need to raise an error
- # here.
- cmd = 'ip %s del %s dev %s' % (context, ip_address, iface)
- result = utils.RunCmd(cmd)
+ @raise errors.Commanderror: if an error occurs during removal
+
+ """
+ _CheckValidContext(context)
+ result = utils.RunCmd(["ip", context, "del", ip_address, "dev", iface])
+
+ # Check the command return code.
+ # 0: success
+ # 2: non-existent entry, we're fine with that
+ # something else: unknown, raise error
+ if (result.exit_code == 0) or (result.exit_code == 2):
+ pass
+ else:
+ raise errors.CommandError("Can't remove network entry")
def UpdateNetworkEntry(ip_address, dest_address, context, iface):
- """
- Update (add if inexistant) an entry in the Neigh or Routing table.
+ """Update (add if inexistant) an entry in the Neigh or Routing table.
@type ip_address: str
@param ip_address: IP address to be updated
@type dest_address: str
@param dest_address: new destination address
@type context: str
- @param context: NEIGHBOUR or ROUTING
+ @param context: one of CONTEXTS
@type iface: str
@param iface: network interface to use
+
+ @raise errors.CommandError: if an error occurs when updating an entry
+
"""
-
- args = (ip_address, dest_address, iface)
- if context == ROUTING:
- cmd = 'ip route replace %s via %s dev %s' % args
+ _CheckValidContext(context)
+
+ # Context-specific args
+ if context == NEIGHBOUR_CONTEXT:
+ dest_token = "lladdr"
+ extra_args = ["nud", "permanent"]
else:
- cmd = 'ip neigh replace %s lladdr %s dev %s nud permanent' % args
+ dest_token = "via"
- result = utils.RunCmd(cmd)
+ result = utils.RunCmd(["ip", context, "replace", ip_address,
+ dest_token, dest_address, "dev", iface,
+ extra_args])
if result.failed:
- raise errors.OpExecError("Could not update table, error %s" %
- result.output)
+ raise errors.CommandError("Could not update table, error %s" %
+ result.output)
def UpdateNetworkTable(instances, context, iface):
- """
- Add (or replace) the entries in instance_list to the Neigh|Routing table.
+ """Add or replace the entries in instances in the Neigh|Routing table.
If the instance's IP is not there, add it.
@type instances: dict
@param instances: dict with instance:dest_address mapping
@type context: str
- @param context: NEIGHBOUR or ROUTING
+ @param context: one of CONTEXTS
@type iface: str
@param iface: network interface to use
- """
+ @raise errors.CommandError: if an error occurs when listing a table
+
+ """
+ _CheckValidContext(context)
# Check the local table
- cmd = 'ip %s show dev %s' % (context, iface)
- result = utils.RunCmd(cmd)
- table = result.output.split('\n')
+ result = utils.RunCmd(["ip", context, "show", "dev", iface])
+ if result.failed:
+ raise errors.CommandError("Could not list table, error %s" %
+ result.output)
+ table = result.output.splitlines()
# Remove newline entry at the end
table.pop()
# Check if the local entries are up to date.
for entry in table:
- parts = entry.split(' ')
+ parts = entry.split()
# Get the address (first field)
src_ip = parts[0]
if src_ip in instances:
--
1.5.4.3