]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
Add session persistence support to LBaaS HAProxy driver
authorOleg Bondarev <obondarev@mirantis.com>
Thu, 28 Feb 2013 09:35:01 +0000 (13:35 +0400)
committerOleg Bondarev <obondarev@mirantis.com>
Thu, 28 Feb 2013 13:52:32 +0000 (17:52 +0400)
fixes bug 1135324

Change-Id: I5bcd6c84d6b402adecfb5a4cf81925ddbefccbb0

quantum/plugins/services/agent_loadbalancer/drivers/haproxy/cfg.py
quantum/tests/unit/services/agent_loadbalancer/driver/haproxy/test_cfg.py [new file with mode: 0644]

index 936bcff3031ac9c6abb6bebf95c9773479c01604..10a5f33cc730f42636da630ae62b51d192718bd5 100644 (file)
@@ -117,13 +117,18 @@ def _build_backend(config):
     server_addon, health_opts = _get_server_health_option(config)
     opts.extend(health_opts)
 
+    # add session persistence (if available)
+    persist_opts = _get_session_persistence(config)
+    opts.extend(persist_opts)
+
     # add the members
-    opts.extend(
-        (('server %(id)s %(address)s:%(protocol_port)s '
-         'weight %(weight)s') % member) + server_addon
-        for member in config['members']
-        if (member['status'] == ACTIVE and member['admin_state_up'])
-    )
+    for member in config['members']:
+        if member['status'] == ACTIVE and member['admin_state_up']:
+            server = (('server %(id)s %(address)s:%(protocol_port)s '
+                       'weight %(weight)s') % member) + server_addon
+            if _has_http_cookie_persistence(config):
+                server += ' cookie %d' % config['members'].index(member)
+            opts.append(server)
 
     return itertools.chain(
         ['backend %s' % config['pool']['id']],
@@ -163,6 +168,31 @@ def _get_server_health_option(config):
     return server_addon, opts
 
 
+def _get_session_persistence(config):
+    persistence = config['vip'].get('session_persistence')
+    if not persistence:
+        return []
+
+    opts = []
+    if persistence['type'] == constants.SESSION_PERSISTENCE_SOURCE_IP:
+        opts.append('stick-table type ip size 10k')
+        opts.append('stick on src')
+    elif persistence['type'] == constants.SESSION_PERSISTENCE_HTTP_COOKIE:
+        opts.append('cookie SRV insert indirect nocache')
+    elif (persistence['type'] == constants.SESSION_PERSISTENCE_APP_COOKIE and
+          persistence.get('cookie_name')):
+        opts.append('appsession %s len 56 timeout 3h' %
+                    persistence['cookie_name'])
+
+    return opts
+
+
+def _has_http_cookie_persistence(config):
+    return (config['vip'].get('session_persistence') and
+            config['vip']['session_persistence']['type'] ==
+            constants.SESSION_PERSISTENCE_HTTP_COOKIE)
+
+
 def _expand_expected_codes(codes):
     """Expand the expected code string in set of codes.
 
diff --git a/quantum/tests/unit/services/agent_loadbalancer/driver/haproxy/test_cfg.py b/quantum/tests/unit/services/agent_loadbalancer/driver/haproxy/test_cfg.py
new file mode 100644 (file)
index 0000000..8bddcb9
--- /dev/null
@@ -0,0 +1,55 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2013 Mirantis, Inc.
+# All Rights Reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+#
+# @author: Oleg Bondarev (obondarev@mirantis.com)
+
+import testtools
+
+from quantum.plugins.services.agent_loadbalancer.drivers.haproxy import cfg
+
+
+class TestHaproxyCfg(testtools.TestCase):
+
+    def test_has_http_cookie_persistence(self):
+        config = {'vip': {'session_persistence': {'type': 'HTTP_COOKIE'}}}
+        self.assertTrue(cfg._has_http_cookie_persistence(config))
+
+        config = {'vip': {'session_persistence': {'type': 'SOURCE_IP'}}}
+        self.assertFalse(cfg._has_http_cookie_persistence(config))
+
+        config = {'vip': {'session_persistence': {}}}
+        self.assertFalse(cfg._has_http_cookie_persistence(config))
+
+    def test_get_session_persistence(self):
+        config = {'vip': {'session_persistence': {'type': 'SOURCE_IP'}}}
+        self.assertEqual(cfg._get_session_persistence(config),
+                         ['stick-table type ip size 10k', 'stick on src'])
+
+        config = {'vip': {'session_persistence': {'type': 'HTTP_COOKIE'}}}
+        self.assertEqual(cfg._get_session_persistence(config),
+                         ['cookie SRV insert indirect nocache'])
+
+        config = {'vip': {'session_persistence': {'type': 'APP_COOKIE',
+                                                  'cookie_name': 'test'}}}
+        self.assertEqual(cfg._get_session_persistence(config),
+                         ['appsession test len 56 timeout 3h'])
+
+        config = {'vip': {'session_persistence': {'type': 'APP_COOKIE'}}}
+        self.assertEqual(cfg._get_session_persistence(config), [])
+
+        config = {'vip': {'session_persistence': {'type': 'UNSUPPORTED'}}}
+        self.assertEqual(cfg._get_session_persistence(config), [])