From 642fe5505fd55543d24ff47ba493f7b37a7288ce Mon Sep 17 00:00:00 2001 From: Roman Prykhodchenko Date: Fri, 18 Jan 2013 12:56:19 +0200 Subject: [PATCH] Adds support of TCP protocol for LBaaS VIPs. Adds validation of supplied protocols for VIPs and Pools at API and DB levels. Modifies the schema of the database to allow storing TCP VIPs. Change-Id: Idab3139f280b5f0a16633974c05f88d70fb8d683 Fixes: bug #1100724 --- quantum/db/loadbalancer/loadbalancer_db.py | 5 +-- quantum/extensions/loadbalancer.py | 4 +-- .../db/loadbalancer/test_db_loadbalancer.py | 33 +++++++++++++++++-- 3 files changed, 35 insertions(+), 7 deletions(-) diff --git a/quantum/db/loadbalancer/loadbalancer_db.py b/quantum/db/loadbalancer/loadbalancer_db.py index 4e731473c..61d2949e4 100644 --- a/quantum/db/loadbalancer/loadbalancer_db.py +++ b/quantum/db/loadbalancer/loadbalancer_db.py @@ -67,7 +67,7 @@ class Vip(model_base.BASEV2, models_v2.HasId, models_v2.HasTenant): subnet_id = sa.Column(sa.String(36), nullable=False) address = sa.Column(sa.String(64)) port = sa.Column(sa.Integer, nullable=False) - protocol = sa.Column(sa.Enum("HTTP", "HTTPS", name="vip_protocol"), + protocol = sa.Column(sa.Enum("HTTP", "HTTPS", "TCP", name="lb_protocols"), nullable=False) pool_id = sa.Column(sa.String(36), nullable=False) session_persistence = orm.relationship(SessionPersistence, @@ -96,7 +96,8 @@ class Pool(model_base.BASEV2, models_v2.HasId, models_v2.HasTenant): name = sa.Column(sa.String(255)) description = sa.Column(sa.String(255)) subnet_id = sa.Column(sa.String(36), nullable=False) - protocol = sa.Column(sa.String(64), nullable=False) + protocol = sa.Column(sa.Enum("HTTP", "HTTPS", "TCP", name="lb_protocols"), + nullable=False) lb_method = sa.Column(sa.Enum("ROUND_ROBIN", "LEAST_CONNECTIONS", "SOURCE_IP", diff --git a/quantum/extensions/loadbalancer.py b/quantum/extensions/loadbalancer.py index de66a48bc..46e252607 100644 --- a/quantum/extensions/loadbalancer.py +++ b/quantum/extensions/loadbalancer.py @@ -82,7 +82,7 @@ RESOURCE_ATTRIBUTE_MAP = { 'convert_to': attr.convert_to_int, 'is_visible': True}, 'protocol': {'allow_post': True, 'allow_put': False, - 'validate': {'type:string': None}, + 'validate': {'type:values': ['TCP', 'HTTP', 'HTTPS']}, 'is_visible': True}, 'pool_id': {'allow_post': True, 'allow_put': True, 'validate': {'type:uuid': None}, @@ -122,7 +122,7 @@ RESOURCE_ATTRIBUTE_MAP = { 'validate': {'type:uuid': None}, 'is_visible': True}, 'protocol': {'allow_post': True, 'allow_put': False, - 'validate': {'type:string': None}, + 'validate': {'type:values': ['TCP', 'HTTP', 'HTTPS']}, 'is_visible': True}, 'lb_method': {'allow_post': True, 'allow_put': True, 'validate': {'type:string': None}, diff --git a/quantum/tests/unit/db/loadbalancer/test_db_loadbalancer.py b/quantum/tests/unit/db/loadbalancer/test_db_loadbalancer.py index 4c5ebf058..8d85a718e 100644 --- a/quantum/tests/unit/db/loadbalancer/test_db_loadbalancer.py +++ b/quantum/tests/unit/db/loadbalancer/test_db_loadbalancer.py @@ -285,7 +285,7 @@ class LoadBalancerPluginDbTestCase(unittest2.TestCase): @contextlib.contextmanager def vip(self, fmt='json', name='vip1', pool=None, protocol='HTTP', port=80, admin_status_up=True, no_delete=False, - **kwargs): + address="172.16.1.123", **kwargs): if not pool: with self.pool() as pool: pool_id = pool['pool']['id'] @@ -295,7 +295,7 @@ class LoadBalancerPluginDbTestCase(unittest2.TestCase): protocol, port, admin_status_up, - address="172.16.1.123", + address=address, **kwargs) vip = self.deserialize(fmt, res) if res.status_int >= 400: @@ -311,7 +311,7 @@ class LoadBalancerPluginDbTestCase(unittest2.TestCase): protocol, port, admin_status_up, - address="172.16.1.123", + address=address, **kwargs) vip = self.deserialize(fmt, res) if res.status_int >= 400: @@ -402,6 +402,23 @@ class TestLoadBalancer(LoadBalancerPluginDbTestCase): for k, v in keys: self.assertEqual(vip['vip'][k], v) + def test_create_vip_with_invalid_values(self): + name = 'vip3' + + vip = self.vip(name=name, protocol='UNSUPPORTED') + self.assertRaises(webob.exc.HTTPClientError, vip.__enter__) + + vip = self.vip(name=name, port='NOT_AN_INT') + self.assertRaises(webob.exc.HTTPClientError, vip.__enter__) + + # 100500 is not a valid port number + vip = self.vip(name=name, port='100500') + self.assertRaises(webob.exc.HTTPClientError, vip.__enter__) + + # 192.168.130.130.130 is not a valid IP address + vip = self.vip(name=name, address='192.168.130.130.130') + self.assertRaises(webob.exc.HTTPClientError, vip.__enter__) + def test_create_vip_with_session_persistence(self): name = 'vip2' keys = [('name', name), @@ -484,6 +501,15 @@ class TestLoadBalancer(LoadBalancerPluginDbTestCase): for k, v in keys: self.assertEqual(res['vips'][0][k], v) + def test_create_pool_with_invalid_values(self): + name = 'pool3' + + pool = self.pool(name=name, protocol='UNSUPPORTED') + self.assertRaises(webob.exc.HTTPClientError, pool.__enter__) + + pool = self.pool(name=name, lb_method='UNSUPPORTED') + self.assertRaises(webob.exc.HTTPClientError, pool.__enter__) + def test_create_pool(self): name = "pool1" keys = [('name', name), @@ -493,6 +519,7 @@ class TestLoadBalancer(LoadBalancerPluginDbTestCase): ('lb_method', 'ROUND_ROBIN'), ('admin_state_up', True), ('status', 'PENDING_CREATE')] + with self.pool(name=name) as pool: for k, v in keys: self.assertEqual(pool['pool'][k], v) -- 2.45.2