jenkins-bot has submitted this change and it was merged. ( 
https://gerrit.wikimedia.org/r/354506 )

Change subject: Split IPVS Manager into the interface and manager implementation
......................................................................


Split IPVS Manager into the interface and manager implementation

Right now we're just moving classes around, but on the long run we want to
implement other ipvs managers that don't need to shell out to ipvsadm(1)
in order to interact with the IPVS kernel subsystem.

Change-Id: Ia1619372a8f6aa038fe85f359674120caa25328e
---
D pybal/ipvs.py
A pybal/ipvs/__init__.py
A pybal/ipvs/interface.py
A pybal/ipvs/ipvsadm.py
M pybal/test/test_ipvs.py
5 files changed, 276 insertions(+), 271 deletions(-)

Approvals:
  Giuseppe Lavagetto: Looks good to me, approved
  Ema: Looks good to me, but someone else must approve
  jenkins-bot: Verified



diff --git a/pybal/ipvs.py b/pybal/ipvs.py
deleted file mode 100644
index 4429f65..0000000
--- a/pybal/ipvs.py
+++ /dev/null
@@ -1,258 +0,0 @@
-"""
-ipvsadm.py
-Copyright (C) 2006-2015 by Mark Bergsma <m...@nedworks.org>
-
-LVS state/configuration classes for PyBal
-"""
-from . import util
-
-import os
-log = util.log
-
-
-class IPVSManager(object):
-    """Class that provides a mapping from abstract LVS commands / state
-    changes to ipvsadm command invocations."""
-
-    ipvsPath = '/sbin/ipvsadm'
-
-    DryRun = True
-
-    Debug = False
-
-    @classmethod
-    def modifyState(cls, cmdList):
-        """
-        Changes the state using a supplied list of commands (by invoking 
ipvsadm)
-        """
-
-        if cls.Debug:
-            print cmdList
-        if cls.DryRun: return
-
-        command = [cls.ipvsPath, '-R']
-        stdin = os.popen(" ".join(command), 'w')
-        for line in cmdList:
-            stdin.write(line + '\n')
-        stdin.close()
-
-        # FIXME: Check return code and act on failure
-
-
-
-    @staticmethod
-    def subCommandService(service):
-        """Returns a partial command / parameter list as a single
-        string, that describes the supplied LVS service, ready for
-        passing to ipvsadm.
-
-        Arguments:
-            service:    tuple(protocol, address, port, ...)
-        """
-
-        protocol = {'tcp': '-t',
-                    'udp': '-u'}[service[0]]
-
-        if ':' in service[1]:
-            # IPv6 address
-            service = ' [%s]:%d' % service[1:3]
-        else:
-            # IPv4
-            service = ' %s:%d' % service[1:3]
-
-        return protocol + service
-
-    @staticmethod
-    def subCommandServer(server):
-        """Returns a partial command / parameter list as a single
-        string, that describes the supplied server, ready for passing
-        to ipvsadm.
-
-        Arguments:
-            server:    PyBal server object
-        """
-
-        return '-r %s' % (server.ip or server.host)
-
-    @staticmethod
-    def commandClearServiceTable():
-        """Returns an ipvsadm command to clear the current service
-        table."""
-        return '-C'
-
-    @classmethod
-    def commandRemoveService(cls, service):
-        """Returns an ipvsadm command to remove a single service."""
-        return '-D ' + cls.subCommandService(service)
-
-    @classmethod
-    def commandAddService(cls, service):
-        """Returns an ipvsadm command to add a specified service.
-
-        Arguments:
-            service:    tuple(protocol, address, port, ...)
-        """
-
-        cmd = '-A ' + cls.subCommandService(service)
-
-        # Include scheduler if specified
-        if len(service) > 3:
-            cmd += ' -s ' + service[3]
-
-        return cmd
-
-    @classmethod
-    def commandRemoveServer(cls, service, server):
-        """Returns an ipvsadm command to remove a server from a service.
-
-        Arguments:
-            service:   tuple(protocol, address, port, ...)
-            server:    Server
-        """
-
-        return " ".join(['-d', cls.subCommandService(service),
-                         cls.subCommandServer(server)])
-
-    @classmethod
-    def commandAddServer(cls, service, server):
-        """Returns an ipvsadm command to add a server to a service.
-
-        Arguments:
-            service:   tuple(protocol, address, port, ...)
-            server:    Server
-        """
-
-        cmd = " ".join(['-a', cls.subCommandService(service),
-                        cls.subCommandServer(server)])
-
-        # Include weight if specified
-        if server.weight:
-            cmd += ' -w %d' % server.weight
-
-        return cmd
-
-    @classmethod
-    def commandEditServer(cls, service, server):
-        """Returns an ipvsadm command to edit the parameters of a
-        server.
-
-        Arguments:
-            service:   tuple(protocol, address, port, ...)
-            server:    Server
-        """
-
-        cmd = " ".join(['-e', cls.subCommandService(service),
-                        cls.subCommandServer(server)])
-
-        # Include weight if specified
-        if server.weight:
-            cmd += ' -w %d' % server.weight
-
-        return cmd
-
-
-class LVSService:
-    """Class that maintains the state of a single LVS service
-    instance."""
-
-    ipvsManager = IPVSManager
-
-    SVC_PROTOS = ('tcp', 'udp')
-    SVC_SCHEDULERS = ('rr', 'wrr', 'lc', 'wlc', 'lblc', 'lblcr', 'dh', 'sh',
-                      'sed', 'nq')
-
-    def __init__(self, name, (protocol, ip, port, scheduler), configuration):
-        """Constructor"""
-
-        self.name = name
-        self.servers = set()
-
-        if (protocol not in self.SVC_PROTOS or
-                scheduler not in self.SVC_SCHEDULERS):
-            raise ValueError('Invalid protocol or scheduler')
-
-        self.protocol = protocol
-        self.ip = ip
-        self.port = port
-        self.scheduler = scheduler
-
-        self.configuration = configuration
-
-        self.ipvsManager.DryRun = configuration.getboolean('dryrun', False)
-        self.ipvsManager.Debug = configuration.getboolean('debug', False)
-
-        if self.configuration.getboolean('bgp', True):
-            from pybal import BGPFailover
-            # Add service ip to the BGP announcements
-            BGPFailover.addPrefix(self.ip)
-
-        self.createService()
-
-    def service(self):
-        """Returns a tuple (protocol, ip, port, scheduler) that
-        describes this LVS instance."""
-
-        return (self.protocol, self.ip, self.port, self.scheduler)
-
-    def createService(self):
-        """Initializes this LVS instance in LVS."""
-
-        # Remove a previous service and add the new one
-        cmdList = [self.ipvsManager.commandRemoveService(self.service()),
-                   self.ipvsManager.commandAddService(self.service())]
-        self.ipvsManager.modifyState(cmdList)
-
-    def assignServers(self, newServers):
-        """Takes a (new) set of servers (as a host->Server dictionary)
-        and updates the LVS state accordingly."""
-
-        cmdList = (
-            [self.ipvsManager.commandAddServer(self.service(), server)
-             for server in newServers - self.servers] +
-            [self.ipvsManager.commandEditServer(self.service(), server)
-             for server in newServers & self.servers] +
-            [self.ipvsManager.commandRemoveServer(self.service(), server)
-             for server in self.servers - newServers]
-        )
-
-        self.servers = newServers
-        self.ipvsManager.modifyState(cmdList)
-
-    def addServer(self, server):
-        """Adds (pools) a single Server to the LVS state."""
-
-        if server not in self.servers:
-            cmdList = [self.ipvsManager.commandAddServer(self.service(),
-                                                         server)]
-        else:
-            log.warn('bug: adding already existing server to LVS')
-            cmdList = [self.ipvsManager.commandEditServer(self.service(),
-                                                          server)]
-
-        self.servers.add(server)
-
-        self.ipvsManager.modifyState(cmdList)
-        server.pooled = True
-
-    def removeServer(self, server):
-        """Removes (depools) a single Server from the LVS state."""
-
-        cmdList = [self.ipvsManager.commandRemoveServer(self.service(),
-                                                        server)]
-
-        self.servers.remove(server)  # May raise KeyError
-
-        server.pooled = False
-        self.ipvsManager.modifyState(cmdList)
-
-    def initServer(self, server):
-        """Initializes a server instance with LVS service specific
-        configuration."""
-
-        server.port = self.port
-
-    def getDepoolThreshold(self):
-        """Returns the threshold below which no more down servers will
-        be depooled."""
-
-        return self.configuration.getfloat('depool-threshold', .5)
diff --git a/pybal/ipvs/__init__.py b/pybal/ipvs/__init__.py
new file mode 100644
index 0000000..442a9d0
--- /dev/null
+++ b/pybal/ipvs/__init__.py
@@ -0,0 +1,8 @@
+"""
+pybal.ipvs
+
+Copyright (c) 2006-2016 Mark Bergsma <m...@nedworks.org>
+
+LVS service interface for PyBal
+"""
+from pybal.ipvs.interface import LVSService
diff --git a/pybal/ipvs/interface.py b/pybal/ipvs/interface.py
new file mode 100644
index 0000000..9b749f8
--- /dev/null
+++ b/pybal/ipvs/interface.py
@@ -0,0 +1,108 @@
+from pybal.util import log
+from pybal.ipvs.ipvsadm import IPVSADMManager
+
+class LVSService:
+    """Class that maintains the state of a single LVS service
+    instance."""
+
+    ipvsManager = IPVSADMManager
+
+    SVC_PROTOS = ('tcp', 'udp')
+    SVC_SCHEDULERS = ('rr', 'wrr', 'lc', 'wlc', 'lblc', 'lblcr', 'dh', 'sh',
+                      'sed', 'nq')
+
+    def __init__(self, name, (protocol, ip, port, scheduler), configuration):
+        """Constructor"""
+
+        self.name = name
+        self.servers = set()
+
+        if (protocol not in self.SVC_PROTOS or
+                scheduler not in self.SVC_SCHEDULERS):
+            raise ValueError('Invalid protocol or scheduler')
+
+        self.protocol = protocol
+        self.ip = ip
+        self.port = port
+        self.scheduler = scheduler
+
+        self.configuration = configuration
+
+        self.ipvsManager.DryRun = configuration.getboolean('dryrun', False)
+        self.ipvsManager.Debug = configuration.getboolean('debug', False)
+
+        if self.configuration.getboolean('bgp', True):
+            from pybal.pybal import BGPFailover
+            # Add service ip to the BGP announcements
+            BGPFailover.addPrefix(self.ip)
+
+        self.createService()
+
+    def service(self):
+        """Returns a tuple (protocol, ip, port, scheduler) that
+        describes this LVS instance."""
+
+        return (self.protocol, self.ip, self.port, self.scheduler)
+
+    def createService(self):
+        """Initializes this LVS instance in LVS."""
+
+        # Remove a previous service and add the new one
+        cmdList = [self.ipvsManager.commandRemoveService(self.service()),
+                   self.ipvsManager.commandAddService(self.service())]
+        self.ipvsManager.modifyState(cmdList)
+
+    def assignServers(self, newServers):
+        """Takes a (new) set of servers (as a host->Server dictionary)
+        and updates the LVS state accordingly."""
+
+        cmdList = (
+            [self.ipvsManager.commandAddServer(self.service(), server)
+             for server in newServers - self.servers] +
+            [self.ipvsManager.commandEditServer(self.service(), server)
+             for server in newServers & self.servers] +
+            [self.ipvsManager.commandRemoveServer(self.service(), server)
+             for server in self.servers - newServers]
+        )
+
+        self.servers = newServers
+        self.ipvsManager.modifyState(cmdList)
+
+    def addServer(self, server):
+        """Adds (pools) a single Server to the LVS state."""
+
+        if server not in self.servers:
+            cmdList = [self.ipvsManager.commandAddServer(self.service(),
+                                                         server)]
+        else:
+            log.warn('bug: adding already existing server to LVS')
+            cmdList = [self.ipvsManager.commandEditServer(self.service(),
+                                                          server)]
+
+        self.servers.add(server)
+
+        self.ipvsManager.modifyState(cmdList)
+        server.pooled = True
+
+    def removeServer(self, server):
+        """Removes (depools) a single Server from the LVS state."""
+
+        cmdList = [self.ipvsManager.commandRemoveServer(self.service(),
+                                                        server)]
+
+        self.servers.remove(server)  # May raise KeyError
+
+        server.pooled = False
+        self.ipvsManager.modifyState(cmdList)
+
+    def initServer(self, server):
+        """Initializes a server instance with LVS service specific
+        configuration."""
+
+        server.port = self.port
+
+    def getDepoolThreshold(self):
+        """Returns the threshold below which no more down servers will
+        be depooled."""
+
+        return self.configuration.getfloat('depool-threshold', .5)
diff --git a/pybal/ipvs/ipvsadm.py b/pybal/ipvs/ipvsadm.py
new file mode 100644
index 0000000..d0c9123
--- /dev/null
+++ b/pybal/ipvs/ipvsadm.py
@@ -0,0 +1,145 @@
+"""
+ipvsadm.py
+Copyright (C) 2006-2016 by Mark Bergsma <m...@nedworks.org>
+
+Ipvsadm-based ipvs manager for PyBal
+"""
+import os
+
+
+class IPVSADMManager(object):
+    """Class that provides a mapping from abstract LVS commands / state
+    changes to ipvsadm command invocations."""
+
+    ipvsPath = '/sbin/ipvsadm'
+
+    DryRun = True
+
+    Debug = False
+
+    @classmethod
+    def modifyState(cls, cmdList):
+        """
+        Changes the state using a supplied list of commands (by invoking 
ipvsadm)
+        """
+
+        if cls.Debug:
+            print cmdList
+        if cls.DryRun:
+            return
+
+        command = [cls.ipvsPath, '-R']
+        stdin = os.popen(" ".join(command), 'w')
+        for line in cmdList:
+            stdin.write(line + '\n')
+        stdin.close()
+
+    @staticmethod
+    def subCommandService(service):
+        """Returns a partial command / parameter list as a single
+        string, that describes the supplied LVS service, ready for
+        passing to ipvsadm.
+
+        Arguments:
+            service:    tuple(protocol, address, port, ...)
+        """
+
+        protocol = {'tcp': '-t',
+                    'udp': '-u'}[service[0]]
+
+        if ':' in service[1]:
+            # IPv6 address
+            service = ' [%s]:%d' % service[1:3]
+        else:
+            # IPv4
+            service = ' %s:%d' % service[1:3]
+
+        return protocol + service
+
+    @staticmethod
+    def subCommandServer(server):
+        """Returns a partial command / parameter list as a single
+        string, that describes the supplied server, ready for passing
+        to ipvsadm.
+
+        Arguments:
+            server:    PyBal server object
+        """
+
+        return '-r %s' % (server.ip or server.host)
+
+    @staticmethod
+    def commandClearServiceTable():
+        """Returns an ipvsadm command to clear the current service
+        table."""
+        return '-C'
+
+    @classmethod
+    def commandRemoveService(cls, service):
+        """Returns an ipvsadm command to remove a single service."""
+        return '-D ' + cls.subCommandService(service)
+
+    @classmethod
+    def commandAddService(cls, service):
+        """Returns an ipvsadm command to add a specified service.
+
+        Arguments:
+            service:    tuple(protocol, address, port, ...)
+        """
+
+        cmd = '-A ' + cls.subCommandService(service)
+
+        # Include scheduler if specified
+        if len(service) > 3:
+            cmd += ' -s ' + service[3]
+
+        return cmd
+
+    @classmethod
+    def commandRemoveServer(cls, service, server):
+        """Returns an ipvsadm command to remove a server from a service.
+
+        Arguments:
+            service:   tuple(protocol, address, port, ...)
+            server:    Server
+        """
+
+        return " ".join(['-d', cls.subCommandService(service),
+                         cls.subCommandServer(server)])
+
+    @classmethod
+    def commandAddServer(cls, service, server):
+        """Returns an ipvsadm command to add a server to a service.
+
+        Arguments:
+            service:   tuple(protocol, address, port, ...)
+            server:    Server
+        """
+
+        cmd = " ".join(['-a', cls.subCommandService(service),
+                        cls.subCommandServer(server)])
+
+        # Include weight if specified
+        if server.weight:
+            cmd += ' -w %d' % server.weight
+
+        return cmd
+
+    @classmethod
+    def commandEditServer(cls, service, server):
+        """Returns an ipvsadm command to edit the parameters of a
+        server.
+
+        Arguments:
+            service:   tuple(protocol, address, port, ...)
+            server:    Server
+        """
+
+        cmd = " ".join(['-e', cls.subCommandService(service),
+                        cls.subCommandServer(server)])
+
+        # Include weight if specified
+        if server.weight:
+            cmd += ' -w %d' % server.weight
+
+        return cmd
diff --git a/pybal/test/test_ipvs.py b/pybal/test/test_ipvs.py
index f636c30..769941f 100644
--- a/pybal/test/test_ipvs.py
+++ b/pybal/test/test_ipvs.py
@@ -10,6 +10,8 @@
 import pybal.util
 import pybal.pybal
 
+from pybal.ipvs.ipvsadm import IPVSADMManager
+
 from .fixtures import PyBalTestCase, ServerStub
 
 
@@ -25,7 +27,7 @@
             ('udp', '208.0.0.1', 123): '-u 208.0.0.1:123',
         }
         for service, expected_subcommand in services.items():
-            subcommand = pybal.ipvs.IPVSManager.subCommandService(service)
+            subcommand = IPVSADMManager.subCommandService(service)
             self.assertEquals(subcommand, expected_subcommand)
 
     def testSubCommandServer(self):
@@ -35,12 +37,12 @@
             ServerStub('localhost', '127.0.0.1'): '-r 127.0.0.1',
         }
         for server, expected_subcommand in servers.items():
-            subcommand = pybal.ipvs.IPVSManager.subCommandServer(server)
+            subcommand = IPVSADMManager.subCommandServer(server)
             self.assertEquals(subcommand, expected_subcommand)
 
     def testCommandClearServiceTable(self):
         """Test `IPVSManager.commandClearServiceTable`."""
-        subcommand = pybal.ipvs.IPVSManager.commandClearServiceTable()
+        subcommand = IPVSADMManager.commandClearServiceTable()
         self.assertEquals(subcommand, '-C')
 
     def testCommandRemoveService(self):
@@ -50,7 +52,7 @@
             ('udp', '208.0.0.1', 123): '-D -u 208.0.0.1:123',
         }
         for service, expected_subcommand in services.items():
-            subcommand = pybal.ipvs.IPVSManager.commandRemoveService(service)
+            subcommand = IPVSADMManager.commandRemoveService(service)
             self.assertEquals(subcommand, expected_subcommand)
 
     def testCommandAddService(self):
@@ -60,14 +62,14 @@
             ('udp', '208.0.0.1', 123, 'rr'): '-A -u 208.0.0.1:123 -s rr',
         }
         for service, expected_subcommand in services.items():
-            subcommand = pybal.ipvs.IPVSManager.commandAddService(service)
+            subcommand = IPVSADMManager.commandAddService(service)
             self.assertEquals(subcommand, expected_subcommand)
 
     def testCommandRemoveServer(self):
         """Test `IPVSManager.commandRemoveServer`."""
         service = ('tcp', '2620::123', 443)
         server = ServerStub('localhost', None)
-        subcommand = pybal.ipvs.IPVSManager.commandRemoveServer(
+        subcommand = IPVSADMManager.commandRemoveServer(
             service, server)
         self.assertEquals(subcommand, '-d -t [2620::123]:443 -r localhost')
 
@@ -76,11 +78,11 @@
         service = ('tcp', '2620::123', 443)
 
         server = ServerStub('localhost', None)
-        subcommand = pybal.ipvs.IPVSManager.commandAddServer(service, server)
+        subcommand = IPVSADMManager.commandAddServer(service, server)
         self.assertEquals(subcommand, '-a -t [2620::123]:443 -r localhost')
 
         server.weight = 25
-        subcommand = pybal.ipvs.IPVSManager.commandAddServer(service, server)
+        subcommand = IPVSADMManager.commandAddServer(service, server)
         self.assertEquals(
             subcommand, '-a -t [2620::123]:443 -r localhost -w 25')
 
@@ -89,11 +91,11 @@
         service = ('tcp', '2620::123', 443)
 
         server = ServerStub('localhost', None)
-        subcommand = pybal.ipvs.IPVSManager.commandEditServer(service, server)
+        subcommand = IPVSADMManager.commandEditServer(service, server)
         self.assertEquals(subcommand, '-e -t [2620::123]:443 -r localhost')
 
         server.weight = 25
-        subcommand = pybal.ipvs.IPVSManager.commandEditServer(service, server)
+        subcommand = IPVSADMManager.commandEditServer(service, server)
         self.assertEquals(
             subcommand, '-e -t [2620::123]:443 -r localhost -w 25')
 
@@ -110,12 +112,12 @@
         def stubbedModifyState(cls, cmdList):
             cls.cmdList = cmdList
 
-        self.origModifyState = pybal.ipvs.IPVSManager.modifyState
-        setattr(pybal.ipvs.IPVSManager, 'modifyState',
+        self.origModifyState = IPVSADMManager.modifyState
+        setattr(IPVSADMManager, 'modifyState',
                 classmethod(stubbedModifyState))
 
     def tearDown(self):
-        pybal.ipvs.IPVSManager.modifyState = self.origModifyState
+        IPVSADMManager.modifyState = self.origModifyState
 
     def testConstructor(self):
         """Test `LVSService.__init__`."""

-- 
To view, visit https://gerrit.wikimedia.org/r/354506
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: Ia1619372a8f6aa038fe85f359674120caa25328e
Gerrit-PatchSet: 3
Gerrit-Project: operations/debs/pybal
Gerrit-Branch: 2.0-dev
Gerrit-Owner: Giuseppe Lavagetto <glavage...@wikimedia.org>
Gerrit-Reviewer: Ema <e...@wikimedia.org>
Gerrit-Reviewer: Giuseppe Lavagetto <glavage...@wikimedia.org>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to