Merge "create a Quantum port to reserve VIP address"
This commit is contained in:
commit
ce7f38cd40
@ -29,6 +29,7 @@ from quantum.db import model_base
|
|||||||
from quantum.db import models_v2
|
from quantum.db import models_v2
|
||||||
from quantum.extensions import loadbalancer
|
from quantum.extensions import loadbalancer
|
||||||
from quantum.extensions.loadbalancer import LoadBalancerPluginBase
|
from quantum.extensions.loadbalancer import LoadBalancerPluginBase
|
||||||
|
from quantum import manager
|
||||||
from quantum.openstack.common import log as logging
|
from quantum.openstack.common import log as logging
|
||||||
from quantum.openstack.common import uuidutils
|
from quantum.openstack.common import uuidutils
|
||||||
from quantum.plugins.common import constants
|
from quantum.plugins.common import constants
|
||||||
@ -64,9 +65,8 @@ class Vip(model_base.BASEV2, models_v2.HasId, models_v2.HasTenant):
|
|||||||
"""Represents a v2 quantum loadbalancer vip."""
|
"""Represents a v2 quantum loadbalancer vip."""
|
||||||
name = sa.Column(sa.String(255))
|
name = sa.Column(sa.String(255))
|
||||||
description = sa.Column(sa.String(255))
|
description = sa.Column(sa.String(255))
|
||||||
subnet_id = sa.Column(sa.String(36), nullable=False)
|
port_id = sa.Column(sa.String(36), sa.ForeignKey('ports.id'))
|
||||||
address = sa.Column(sa.String(64))
|
protocol_port = sa.Column(sa.Integer, nullable=False)
|
||||||
port = sa.Column(sa.Integer, nullable=False)
|
|
||||||
protocol = sa.Column(sa.Enum("HTTP", "HTTPS", "TCP", name="lb_protocols"),
|
protocol = sa.Column(sa.Enum("HTTP", "HTTPS", "TCP", name="lb_protocols"),
|
||||||
nullable=False)
|
nullable=False)
|
||||||
pool_id = sa.Column(sa.String(36), nullable=False)
|
pool_id = sa.Column(sa.String(36), nullable=False)
|
||||||
@ -77,6 +77,7 @@ class Vip(model_base.BASEV2, models_v2.HasId, models_v2.HasTenant):
|
|||||||
status = sa.Column(sa.String(16), nullable=False)
|
status = sa.Column(sa.String(16), nullable=False)
|
||||||
admin_state_up = sa.Column(sa.Boolean(), nullable=False)
|
admin_state_up = sa.Column(sa.Boolean(), nullable=False)
|
||||||
connection_limit = sa.Column(sa.Integer)
|
connection_limit = sa.Column(sa.Integer)
|
||||||
|
port = orm.relationship(models_v2.Port)
|
||||||
|
|
||||||
|
|
||||||
class Member(model_base.BASEV2, models_v2.HasId, models_v2.HasTenant):
|
class Member(model_base.BASEV2, models_v2.HasId, models_v2.HasTenant):
|
||||||
@ -84,7 +85,7 @@ class Member(model_base.BASEV2, models_v2.HasId, models_v2.HasTenant):
|
|||||||
pool_id = sa.Column(sa.String(36), sa.ForeignKey("pools.id"),
|
pool_id = sa.Column(sa.String(36), sa.ForeignKey("pools.id"),
|
||||||
nullable=False)
|
nullable=False)
|
||||||
address = sa.Column(sa.String(64), nullable=False)
|
address = sa.Column(sa.String(64), nullable=False)
|
||||||
port = sa.Column(sa.Integer, nullable=False)
|
protocol_port = sa.Column(sa.Integer, nullable=False)
|
||||||
weight = sa.Column(sa.Integer, nullable=False)
|
weight = sa.Column(sa.Integer, nullable=False)
|
||||||
status = sa.Column(sa.String(16), nullable=False)
|
status = sa.Column(sa.String(16), nullable=False)
|
||||||
admin_state_up = sa.Column(sa.Boolean(), nullable=False)
|
admin_state_up = sa.Column(sa.Boolean(), nullable=False)
|
||||||
@ -151,6 +152,10 @@ class LoadBalancerPluginDb(LoadBalancerPluginBase):
|
|||||||
loadbalancer plugin database access interface using SQLAlchemy models.
|
loadbalancer plugin database access interface using SQLAlchemy models.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@property
|
||||||
|
def _core_plugin(self):
|
||||||
|
return manager.QuantumManager.get_plugin()
|
||||||
|
|
||||||
# TODO(lcui):
|
# TODO(lcui):
|
||||||
# A set of internal facility methods are borrowed from QuantumDbPluginV2
|
# A set of internal facility methods are borrowed from QuantumDbPluginV2
|
||||||
# class and hence this is duplicate. We need to pull out those methods
|
# class and hence this is duplicate. We need to pull out those methods
|
||||||
@ -237,18 +242,22 @@ class LoadBalancerPluginDb(LoadBalancerPluginBase):
|
|||||||
########################################################
|
########################################################
|
||||||
# VIP DB access
|
# VIP DB access
|
||||||
def _make_vip_dict(self, vip, fields=None):
|
def _make_vip_dict(self, vip, fields=None):
|
||||||
|
fixed_ip = (vip.port.fixed_ips or [{}])[0]
|
||||||
|
|
||||||
res = {'id': vip['id'],
|
res = {'id': vip['id'],
|
||||||
'tenant_id': vip['tenant_id'],
|
'tenant_id': vip['tenant_id'],
|
||||||
'name': vip['name'],
|
'name': vip['name'],
|
||||||
'description': vip['description'],
|
'description': vip['description'],
|
||||||
'subnet_id': vip['subnet_id'],
|
'subnet_id': fixed_ip.get('subnet_id'),
|
||||||
'address': vip['address'],
|
'address': fixed_ip.get('ip_address'),
|
||||||
'port': vip['port'],
|
'port_id': vip['port_id'],
|
||||||
|
'protocol_port': vip['protocol_port'],
|
||||||
'protocol': vip['protocol'],
|
'protocol': vip['protocol'],
|
||||||
'pool_id': vip['pool_id'],
|
'pool_id': vip['pool_id'],
|
||||||
'connection_limit': vip['connection_limit'],
|
'connection_limit': vip['connection_limit'],
|
||||||
'admin_state_up': vip['admin_state_up'],
|
'admin_state_up': vip['admin_state_up'],
|
||||||
'status': vip['status']}
|
'status': vip['status']}
|
||||||
|
|
||||||
if vip['session_persistence']:
|
if vip['session_persistence']:
|
||||||
s_p = {
|
s_p = {
|
||||||
'type': vip['session_persistence']['type']
|
'type': vip['session_persistence']['type']
|
||||||
@ -320,22 +329,38 @@ class LoadBalancerPluginDb(LoadBalancerPluginBase):
|
|||||||
sess_qry = context.session.query(SessionPersistence)
|
sess_qry = context.session.query(SessionPersistence)
|
||||||
sess_qry.filter_by(vip_id=vip_id).delete()
|
sess_qry.filter_by(vip_id=vip_id).delete()
|
||||||
|
|
||||||
|
def _create_port_for_vip(self, context, vip_db, subnet_id, ip_address):
|
||||||
|
# resolve subnet and create port
|
||||||
|
subnet = self._core_plugin.get_subnet(context, subnet_id)
|
||||||
|
fixed_ip = {'subnet_id': subnet['id']}
|
||||||
|
if ip_address and ip_address != attributes.ATTR_NOT_SPECIFIED:
|
||||||
|
fixed_ip['ip_address'] = ip_address
|
||||||
|
|
||||||
|
port_data = {
|
||||||
|
'tenant_id': vip_db.tenant_id,
|
||||||
|
'name': 'vip-' + vip_db.id,
|
||||||
|
'network_id': subnet['network_id'],
|
||||||
|
'mac_address': attributes.ATTR_NOT_SPECIFIED,
|
||||||
|
'admin_state_up': False,
|
||||||
|
'device_id': '',
|
||||||
|
'device_owner': '',
|
||||||
|
'fixed_ips': [fixed_ip]
|
||||||
|
}
|
||||||
|
|
||||||
|
port = self._core_plugin.create_port(context, {'port': port_data})
|
||||||
|
vip_db.port_id = port['id']
|
||||||
|
|
||||||
def create_vip(self, context, vip):
|
def create_vip(self, context, vip):
|
||||||
v = vip['vip']
|
v = vip['vip']
|
||||||
tenant_id = self._get_tenant_id_for_create(context, v)
|
tenant_id = self._get_tenant_id_for_create(context, v)
|
||||||
|
|
||||||
with context.session.begin(subtransactions=True):
|
with context.session.begin(subtransactions=True):
|
||||||
if v['address'] is attributes.ATTR_NOT_SPECIFIED:
|
|
||||||
address = None
|
|
||||||
else:
|
|
||||||
address = v['address']
|
|
||||||
vip_db = Vip(id=uuidutils.generate_uuid(),
|
vip_db = Vip(id=uuidutils.generate_uuid(),
|
||||||
tenant_id=tenant_id,
|
tenant_id=tenant_id,
|
||||||
name=v['name'],
|
name=v['name'],
|
||||||
description=v['description'],
|
description=v['description'],
|
||||||
subnet_id=v['subnet_id'],
|
port_id=None,
|
||||||
address=address,
|
protocol_port=v['protocol_port'],
|
||||||
port=v['port'],
|
|
||||||
protocol=v['protocol'],
|
protocol=v['protocol'],
|
||||||
pool_id=v['pool_id'],
|
pool_id=v['pool_id'],
|
||||||
connection_limit=v['connection_limit'],
|
connection_limit=v['connection_limit'],
|
||||||
@ -350,9 +375,16 @@ class LoadBalancerPluginDb(LoadBalancerPluginBase):
|
|||||||
vip_db.session_persistence = s_p
|
vip_db.session_persistence = s_p
|
||||||
|
|
||||||
context.session.add(vip_db)
|
context.session.add(vip_db)
|
||||||
self._update_pool_vip_info(context, v['pool_id'], vip_id)
|
context.session.flush()
|
||||||
|
|
||||||
vip_db = self._get_resource(context, Vip, vip_id)
|
self._create_port_for_vip(
|
||||||
|
context,
|
||||||
|
vip_db,
|
||||||
|
v['subnet_id'],
|
||||||
|
v.get('address')
|
||||||
|
)
|
||||||
|
|
||||||
|
self._update_pool_vip_info(context, v['pool_id'], vip_id)
|
||||||
return self._make_vip_dict(vip_db)
|
return self._make_vip_dict(vip_db)
|
||||||
|
|
||||||
def update_vip(self, context, id, vip):
|
def update_vip(self, context, id, vip):
|
||||||
@ -383,7 +415,11 @@ class LoadBalancerPluginDb(LoadBalancerPluginBase):
|
|||||||
qry = context.session.query(Pool)
|
qry = context.session.query(Pool)
|
||||||
for pool in qry.filter_by(vip_id=id).all():
|
for pool in qry.filter_by(vip_id=id).all():
|
||||||
pool.update({"vip_id": None})
|
pool.update({"vip_id": None})
|
||||||
|
|
||||||
context.session.delete(vip)
|
context.session.delete(vip)
|
||||||
|
if vip.port: # this is a Quantum port
|
||||||
|
self._core_plugin.delete_port(context, vip.port.id)
|
||||||
|
context.session.flush()
|
||||||
|
|
||||||
def get_vip(self, context, id, fields=None):
|
def get_vip(self, context, id, fields=None):
|
||||||
vip = self._get_resource(context, Vip, id)
|
vip = self._get_resource(context, Vip, id)
|
||||||
@ -574,7 +610,7 @@ class LoadBalancerPluginDb(LoadBalancerPluginBase):
|
|||||||
'tenant_id': member['tenant_id'],
|
'tenant_id': member['tenant_id'],
|
||||||
'pool_id': member['pool_id'],
|
'pool_id': member['pool_id'],
|
||||||
'address': member['address'],
|
'address': member['address'],
|
||||||
'port': member['port'],
|
'protocol_port': member['protocol_port'],
|
||||||
'weight': member['weight'],
|
'weight': member['weight'],
|
||||||
'admin_state_up': member['admin_state_up'],
|
'admin_state_up': member['admin_state_up'],
|
||||||
'status': member['status']}
|
'status': member['status']}
|
||||||
@ -596,7 +632,7 @@ class LoadBalancerPluginDb(LoadBalancerPluginBase):
|
|||||||
tenant_id=tenant_id,
|
tenant_id=tenant_id,
|
||||||
pool_id=v['pool_id'],
|
pool_id=v['pool_id'],
|
||||||
address=v['address'],
|
address=v['address'],
|
||||||
port=v['port'],
|
protocol_port=v['protocol_port'],
|
||||||
weight=v['weight'],
|
weight=v['weight'],
|
||||||
admin_state_up=v['admin_state_up'],
|
admin_state_up=v['admin_state_up'],
|
||||||
status=constants.PENDING_CREATE)
|
status=constants.PENDING_CREATE)
|
||||||
|
@ -48,9 +48,8 @@ def upgrade(active_plugin=None, options=None):
|
|||||||
sa.Column(u'id', sa.String(36), nullable=False),
|
sa.Column(u'id', sa.String(36), nullable=False),
|
||||||
sa.Column(u'name', sa.String(255), nullable=True),
|
sa.Column(u'name', sa.String(255), nullable=True),
|
||||||
sa.Column(u'description', sa.String(255), nullable=True),
|
sa.Column(u'description', sa.String(255), nullable=True),
|
||||||
sa.Column(u'subnet_id', sa.String(36), nullable=False),
|
sa.Column(u'port_id', sa.String(36), nullable=True),
|
||||||
sa.Column(u'address', sa.String(64), nullable=True),
|
sa.Column(u'protocol_port', sa.Integer(), nullable=False),
|
||||||
sa.Column(u'port', sa.Integer(), nullable=False),
|
|
||||||
sa.Column(u'protocol',
|
sa.Column(u'protocol',
|
||||||
sa.Enum("HTTP", "HTTPS", "TCP", name="lb_protocols"),
|
sa.Enum("HTTP", "HTTPS", "TCP", name="lb_protocols"),
|
||||||
nullable=False),
|
nullable=False),
|
||||||
@ -58,6 +57,7 @@ def upgrade(active_plugin=None, options=None):
|
|||||||
sa.Column(u'status', sa.String(16), nullable=False),
|
sa.Column(u'status', sa.String(16), nullable=False),
|
||||||
sa.Column(u'admin_state_up', sa.Boolean(), nullable=False),
|
sa.Column(u'admin_state_up', sa.Boolean(), nullable=False),
|
||||||
sa.Column(u'connection_limit', sa.Integer(), nullable=True),
|
sa.Column(u'connection_limit', sa.Integer(), nullable=True),
|
||||||
|
sa.ForeignKeyConstraint(['port_id'], ['ports.id'], ),
|
||||||
sa.PrimaryKeyConstraint(u'id')
|
sa.PrimaryKeyConstraint(u'id')
|
||||||
)
|
)
|
||||||
op.create_table(
|
op.create_table(
|
||||||
@ -130,7 +130,7 @@ def upgrade(active_plugin=None, options=None):
|
|||||||
sa.Column(u'id', sa.String(36), nullable=False),
|
sa.Column(u'id', sa.String(36), nullable=False),
|
||||||
sa.Column(u'pool_id', sa.String(36), nullable=False),
|
sa.Column(u'pool_id', sa.String(36), nullable=False),
|
||||||
sa.Column(u'address', sa.String(64), nullable=False),
|
sa.Column(u'address', sa.String(64), nullable=False),
|
||||||
sa.Column(u'port', sa.Integer(), nullable=False),
|
sa.Column(u'protocol_port', sa.Integer(), nullable=False),
|
||||||
sa.Column(u'weight', sa.Integer(), nullable=False),
|
sa.Column(u'weight', sa.Integer(), nullable=False),
|
||||||
sa.Column(u'status', sa.String(16), nullable=False),
|
sa.Column(u'status', sa.String(16), nullable=False),
|
||||||
sa.Column(u'admin_state_up', sa.Boolean(), nullable=False),
|
sa.Column(u'admin_state_up', sa.Boolean(), nullable=False),
|
||||||
|
@ -79,10 +79,13 @@ RESOURCE_ATTRIBUTE_MAP = {
|
|||||||
'default': attr.ATTR_NOT_SPECIFIED,
|
'default': attr.ATTR_NOT_SPECIFIED,
|
||||||
'validate': {'type:ip_address_or_none': None},
|
'validate': {'type:ip_address_or_none': None},
|
||||||
'is_visible': True},
|
'is_visible': True},
|
||||||
'port': {'allow_post': True, 'allow_put': False,
|
'port_id': {'allow_post': False, 'allow_put': False,
|
||||||
'validate': {'type:range': [0, 65535]},
|
'validate': {'type:uuid': None},
|
||||||
'convert_to': attr.convert_to_int,
|
'is_visible': True},
|
||||||
'is_visible': True},
|
'protocol_port': {'allow_post': True, 'allow_put': False,
|
||||||
|
'validate': {'type:range': [0, 65535]},
|
||||||
|
'convert_to': attr.convert_to_int,
|
||||||
|
'is_visible': True},
|
||||||
'protocol': {'allow_post': True, 'allow_put': False,
|
'protocol': {'allow_post': True, 'allow_put': False,
|
||||||
'validate': {'type:values': ['TCP', 'HTTP', 'HTTPS']},
|
'validate': {'type:values': ['TCP', 'HTTP', 'HTTPS']},
|
||||||
'is_visible': True},
|
'is_visible': True},
|
||||||
@ -167,10 +170,10 @@ RESOURCE_ATTRIBUTE_MAP = {
|
|||||||
'address': {'allow_post': True, 'allow_put': False,
|
'address': {'allow_post': True, 'allow_put': False,
|
||||||
'validate': {'type:ip_address': None},
|
'validate': {'type:ip_address': None},
|
||||||
'is_visible': True},
|
'is_visible': True},
|
||||||
'port': {'allow_post': True, 'allow_put': False,
|
'protocol_port': {'allow_post': True, 'allow_put': False,
|
||||||
'validate': {'type:range': [0, 65535]},
|
'validate': {'type:range': [0, 65535]},
|
||||||
'convert_to': attr.convert_to_int,
|
'convert_to': attr.convert_to_int,
|
||||||
'is_visible': True},
|
'is_visible': True},
|
||||||
'weight': {'allow_post': True, 'allow_put': True,
|
'weight': {'allow_post': True, 'allow_put': True,
|
||||||
'default': 1,
|
'default': 1,
|
||||||
'validate': {'type:range': [0, 256]},
|
'validate': {'type:range': [0, 256]},
|
||||||
|
@ -15,7 +15,9 @@
|
|||||||
|
|
||||||
import contextlib
|
import contextlib
|
||||||
import logging
|
import logging
|
||||||
|
import mock
|
||||||
import os
|
import os
|
||||||
|
import testtools
|
||||||
|
|
||||||
from oslo.config import cfg
|
from oslo.config import cfg
|
||||||
import webob.exc
|
import webob.exc
|
||||||
@ -25,6 +27,7 @@ from quantum.api.extensions import PluginAwareExtensionManager
|
|||||||
from quantum.api.v2 import attributes
|
from quantum.api.v2 import attributes
|
||||||
from quantum.api.v2.router import APIRouter
|
from quantum.api.v2.router import APIRouter
|
||||||
from quantum.common import config
|
from quantum.common import config
|
||||||
|
from quantum.common import exceptions as q_exc
|
||||||
from quantum.common.test_lib import test_config
|
from quantum.common.test_lib import test_config
|
||||||
from quantum.db import api as db
|
from quantum.db import api as db
|
||||||
import quantum.extensions
|
import quantum.extensions
|
||||||
@ -79,16 +82,15 @@ class LoadBalancerPluginDbTestCase(test_db_plugin.QuantumDbPluginV2TestCase):
|
|||||||
app = config.load_paste_app('extensions_test_app')
|
app = config.load_paste_app('extensions_test_app')
|
||||||
self.ext_api = ExtensionMiddleware(app, ext_mgr=ext_mgr)
|
self.ext_api = ExtensionMiddleware(app, ext_mgr=ext_mgr)
|
||||||
|
|
||||||
def _create_vip(self, fmt, name, pool_id, protocol, port, admin_state_up,
|
def _create_vip(self, fmt, name, pool_id, protocol, protocol_port,
|
||||||
expected_res_status=None, **kwargs):
|
admin_state_up, expected_res_status=None, **kwargs):
|
||||||
data = {'vip': {'name': name,
|
data = {'vip': {'name': name,
|
||||||
'subnet_id': self._subnet_id,
|
|
||||||
'pool_id': pool_id,
|
'pool_id': pool_id,
|
||||||
'protocol': protocol,
|
'protocol': protocol,
|
||||||
'port': port,
|
'protocol_port': protocol_port,
|
||||||
'admin_state_up': admin_state_up,
|
'admin_state_up': admin_state_up,
|
||||||
'tenant_id': self._tenant_id}}
|
'tenant_id': self._tenant_id}}
|
||||||
for arg in ('description', 'address',
|
for arg in ('description', 'subnet_id', 'address',
|
||||||
'session_persistence', 'connection_limit'):
|
'session_persistence', 'connection_limit'):
|
||||||
if arg in kwargs and kwargs[arg] is not None:
|
if arg in kwargs and kwargs[arg] is not None:
|
||||||
data['vip'][arg] = kwargs[arg]
|
data['vip'][arg] = kwargs[arg]
|
||||||
@ -119,10 +121,10 @@ class LoadBalancerPluginDbTestCase(test_db_plugin.QuantumDbPluginV2TestCase):
|
|||||||
|
|
||||||
return pool_res
|
return pool_res
|
||||||
|
|
||||||
def _create_member(self, fmt, address, port, admin_state_up,
|
def _create_member(self, fmt, address, protocol_port, admin_state_up,
|
||||||
expected_res_status=None, **kwargs):
|
expected_res_status=None, **kwargs):
|
||||||
data = {'member': {'address': address,
|
data = {'member': {'address': address,
|
||||||
'port': port,
|
'protocol_port': protocol_port,
|
||||||
'admin_state_up': admin_state_up,
|
'admin_state_up': admin_state_up,
|
||||||
'tenant_id': self._tenant_id}}
|
'tenant_id': self._tenant_id}}
|
||||||
for arg in ('weight', 'pool_id'):
|
for arg in ('weight', 'pool_id'):
|
||||||
@ -164,44 +166,31 @@ class LoadBalancerPluginDbTestCase(test_db_plugin.QuantumDbPluginV2TestCase):
|
|||||||
return self.ext_api
|
return self.ext_api
|
||||||
|
|
||||||
@contextlib.contextmanager
|
@contextlib.contextmanager
|
||||||
def vip(self, fmt=None, name='vip1', pool=None,
|
def vip(self, fmt=None, name='vip1', pool=None, subnet=None,
|
||||||
protocol='HTTP', port=80, admin_state_up=True, no_delete=False,
|
protocol='HTTP', protocol_port=80, admin_state_up=True,
|
||||||
address="172.16.1.123", **kwargs):
|
no_delete=False, **kwargs):
|
||||||
if not fmt:
|
if not fmt:
|
||||||
fmt = self.fmt
|
fmt = self.fmt
|
||||||
if not pool:
|
|
||||||
with self.pool() as pool:
|
with test_db_plugin.optional_ctx(subnet, self.subnet) as tmp_subnet:
|
||||||
pool_id = pool['pool']['id']
|
with test_db_plugin.optional_ctx(pool, self.pool) as tmp_pool:
|
||||||
|
pool_id = tmp_pool['pool']['id']
|
||||||
res = self._create_vip(fmt,
|
res = self._create_vip(fmt,
|
||||||
name,
|
name,
|
||||||
pool_id,
|
pool_id,
|
||||||
protocol,
|
protocol,
|
||||||
port,
|
protocol_port,
|
||||||
admin_state_up,
|
admin_state_up,
|
||||||
address=address,
|
subnet_id=tmp_subnet['subnet']['id'],
|
||||||
**kwargs)
|
**kwargs)
|
||||||
vip = self.deserialize(fmt or self.fmt, res)
|
vip = self.deserialize(fmt or self.fmt, res)
|
||||||
if res.status_int >= 400:
|
if res.status_int >= 400:
|
||||||
raise webob.exc.HTTPClientError(code=res.status_int)
|
raise webob.exc.HTTPClientError(code=res.status_int)
|
||||||
yield vip
|
try:
|
||||||
if not no_delete:
|
yield vip
|
||||||
self._delete('vips', vip['vip']['id'])
|
finally:
|
||||||
else:
|
if not no_delete:
|
||||||
pool_id = pool['pool']['id']
|
self._delete('vips', vip['vip']['id'])
|
||||||
res = self._create_vip(fmt,
|
|
||||||
name,
|
|
||||||
pool_id,
|
|
||||||
protocol,
|
|
||||||
port,
|
|
||||||
admin_state_up,
|
|
||||||
address=address,
|
|
||||||
**kwargs)
|
|
||||||
vip = self.deserialize(fmt or self.fmt, res)
|
|
||||||
if res.status_int >= 400:
|
|
||||||
raise webob.exc.HTTPClientError(code=res.status_int)
|
|
||||||
yield vip
|
|
||||||
if not no_delete:
|
|
||||||
self._delete('vips', vip['vip']['id'])
|
|
||||||
|
|
||||||
@contextlib.contextmanager
|
@contextlib.contextmanager
|
||||||
def pool(self, fmt=None, name='pool1', lb_method='ROUND_ROBIN',
|
def pool(self, fmt=None, name='pool1', lb_method='ROUND_ROBIN',
|
||||||
@ -218,27 +207,30 @@ class LoadBalancerPluginDbTestCase(test_db_plugin.QuantumDbPluginV2TestCase):
|
|||||||
pool = self.deserialize(fmt or self.fmt, res)
|
pool = self.deserialize(fmt or self.fmt, res)
|
||||||
if res.status_int >= 400:
|
if res.status_int >= 400:
|
||||||
raise webob.exc.HTTPClientError(code=res.status_int)
|
raise webob.exc.HTTPClientError(code=res.status_int)
|
||||||
yield pool
|
try:
|
||||||
if not no_delete:
|
yield pool
|
||||||
self._delete('pools', pool['pool']['id'])
|
finally:
|
||||||
|
if not no_delete:
|
||||||
|
self._delete('pools', pool['pool']['id'])
|
||||||
|
|
||||||
@contextlib.contextmanager
|
@contextlib.contextmanager
|
||||||
def member(self, fmt=None, address='192.168.1.100',
|
def member(self, fmt=None, address='192.168.1.100', protocol_port=80,
|
||||||
port=80, admin_state_up=True, no_delete=False,
|
admin_state_up=True, no_delete=False, **kwargs):
|
||||||
**kwargs):
|
|
||||||
if not fmt:
|
if not fmt:
|
||||||
fmt = self.fmt
|
fmt = self.fmt
|
||||||
res = self._create_member(fmt,
|
res = self._create_member(fmt,
|
||||||
address,
|
address,
|
||||||
port,
|
protocol_port,
|
||||||
admin_state_up,
|
admin_state_up,
|
||||||
**kwargs)
|
**kwargs)
|
||||||
member = self.deserialize(fmt or self.fmt, res)
|
member = self.deserialize(fmt or self.fmt, res)
|
||||||
if res.status_int >= 400:
|
if res.status_int >= 400:
|
||||||
raise webob.exc.HTTPClientError(code=res.status_int)
|
raise webob.exc.HTTPClientError(code=res.status_int)
|
||||||
yield member
|
try:
|
||||||
if not no_delete:
|
yield member
|
||||||
self._delete('members', member['member']['id'])
|
finally:
|
||||||
|
if not no_delete:
|
||||||
|
self._delete('members', member['member']['id'])
|
||||||
|
|
||||||
@contextlib.contextmanager
|
@contextlib.contextmanager
|
||||||
def health_monitor(self, fmt=None, type='TCP',
|
def health_monitor(self, fmt=None, type='TCP',
|
||||||
@ -270,99 +262,84 @@ class LoadBalancerPluginDbTestCase(test_db_plugin.QuantumDbPluginV2TestCase):
|
|||||||
else:
|
else:
|
||||||
for arg in http_related_attributes:
|
for arg in http_related_attributes:
|
||||||
self.assertIsNone(the_health_monitor.get(arg))
|
self.assertIsNone(the_health_monitor.get(arg))
|
||||||
yield health_monitor
|
try:
|
||||||
if not no_delete:
|
yield health_monitor
|
||||||
self._delete('health_monitors', the_health_monitor['id'])
|
finally:
|
||||||
|
if not no_delete:
|
||||||
|
self._delete('health_monitors', the_health_monitor['id'])
|
||||||
|
|
||||||
|
|
||||||
class TestLoadBalancer(LoadBalancerPluginDbTestCase):
|
class TestLoadBalancer(LoadBalancerPluginDbTestCase):
|
||||||
def test_create_vip(self):
|
def test_create_vip(self, **extras):
|
||||||
name = 'vip1'
|
expected = {
|
||||||
keys = [('name', name),
|
'name': 'vip1',
|
||||||
('subnet_id', self._subnet_id),
|
'description': '',
|
||||||
('address', "172.16.1.123"),
|
'protocol_port': 80,
|
||||||
('port', 80),
|
'protocol': 'HTTP',
|
||||||
('protocol', 'HTTP'),
|
'connection_limit': -1,
|
||||||
('connection_limit', -1),
|
'admin_state_up': True,
|
||||||
('admin_state_up', True),
|
'status': 'PENDING_CREATE',
|
||||||
('status', 'PENDING_CREATE')]
|
'tenant_id': self._tenant_id,
|
||||||
|
}
|
||||||
|
|
||||||
with self.vip(name=name) as vip:
|
expected.update(extras)
|
||||||
for k, v in keys:
|
|
||||||
self.assertEqual(vip['vip'][k], v)
|
with self.subnet() as subnet:
|
||||||
|
expected['subnet_id'] = subnet['subnet']['id']
|
||||||
|
name = expected['name']
|
||||||
|
|
||||||
|
with self.vip(name=name, subnet=subnet, **extras) as vip:
|
||||||
|
for k in ('id', 'address', 'port_id', 'pool_id'):
|
||||||
|
self.assertTrue(vip['vip'].get(k, None))
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
dict((k, v)
|
||||||
|
for k, v in vip['vip'].items() if k in expected),
|
||||||
|
expected
|
||||||
|
)
|
||||||
|
return vip
|
||||||
|
|
||||||
def test_create_vip_with_invalid_values(self):
|
def test_create_vip_with_invalid_values(self):
|
||||||
name = 'vip3'
|
invalid = {
|
||||||
|
'protocol': 'UNSUPPORTED',
|
||||||
|
'protocol_port': 'NOT_AN_INT',
|
||||||
|
'protocol_port': 1000500,
|
||||||
|
'subnet': {'subnet': {'id': 'invalid-subnet'}}
|
||||||
|
}
|
||||||
|
|
||||||
vip = self.vip(name=name, protocol='UNSUPPORTED')
|
for param, value in invalid.items():
|
||||||
self.assertRaises(webob.exc.HTTPClientError, vip.__enter__)
|
kwargs = {'name': 'the-vip', param: value}
|
||||||
|
with testtools.ExpectedException(webob.exc.HTTPClientError):
|
||||||
|
with self.vip(**kwargs):
|
||||||
|
pass
|
||||||
|
|
||||||
vip = self.vip(name=name, port='NOT_AN_INT')
|
def test_create_vip_with_address(self):
|
||||||
self.assertRaises(webob.exc.HTTPClientError, vip.__enter__)
|
self.test_create_vip(address='10.0.0.7')
|
||||||
|
|
||||||
# 100500 is not a valid port number
|
def test_create_vip_with_address_outside_subnet(self):
|
||||||
vip = self.vip(name=name, port='100500')
|
with testtools.ExpectedException(webob.exc.HTTPClientError):
|
||||||
self.assertRaises(webob.exc.HTTPClientError, vip.__enter__)
|
self.test_create_vip(address='9.9.9.9')
|
||||||
|
|
||||||
# 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):
|
def test_create_vip_with_session_persistence(self):
|
||||||
name = 'vip2'
|
self.test_create_vip(session_persistence={'type': 'HTTP_COOKIE'})
|
||||||
keys = [('name', name),
|
|
||||||
('subnet_id', self._subnet_id),
|
|
||||||
('address', "172.16.1.123"),
|
|
||||||
('port', 80),
|
|
||||||
('protocol', 'HTTP'),
|
|
||||||
('session_persistence', {'type': "HTTP_COOKIE"}),
|
|
||||||
('connection_limit', -1),
|
|
||||||
('admin_state_up', True),
|
|
||||||
('status', 'PENDING_CREATE')]
|
|
||||||
|
|
||||||
with self.vip(name=name,
|
|
||||||
session_persistence={'type': "HTTP_COOKIE"}) as vip:
|
|
||||||
for k, v in keys:
|
|
||||||
self.assertEqual(vip['vip'][k], v)
|
|
||||||
|
|
||||||
def test_create_vip_with_session_persistence_with_app_cookie(self):
|
def test_create_vip_with_session_persistence_with_app_cookie(self):
|
||||||
name = 'vip7'
|
sp = {'type': 'APP_COOKIE', 'cookie_name': 'sessionId'}
|
||||||
keys = [('name', name),
|
self.test_create_vip(session_persistence=sp)
|
||||||
('subnet_id', self._subnet_id),
|
|
||||||
('address', "172.16.1.123"),
|
|
||||||
('port', 80),
|
|
||||||
('protocol', 'HTTP'),
|
|
||||||
('session_persistence', {'type': "APP_COOKIE",
|
|
||||||
'cookie_name': 'sessionId'}),
|
|
||||||
('connection_limit', -1),
|
|
||||||
('admin_state_up', True),
|
|
||||||
('status', 'PENDING_CREATE')]
|
|
||||||
|
|
||||||
with self.vip(name=name,
|
|
||||||
session_persistence={'type': "APP_COOKIE",
|
|
||||||
'cookie_name': 'sessionId'}) as vip:
|
|
||||||
for k, v in keys:
|
|
||||||
self.assertEqual(vip['vip'][k], v)
|
|
||||||
|
|
||||||
def test_create_vip_with_session_persistence_unsupported_type(self):
|
def test_create_vip_with_session_persistence_unsupported_type(self):
|
||||||
name = 'vip5'
|
with testtools.ExpectedException(webob.exc.HTTPClientError):
|
||||||
|
self.test_create_vip(session_persistence={'type': 'UNSUPPORTED'})
|
||||||
vip = self.vip(name=name, session_persistence={'type': "UNSUPPORTED"})
|
|
||||||
self.assertRaises(webob.exc.HTTPClientError, vip.__enter__)
|
|
||||||
|
|
||||||
def test_create_vip_with_unnecessary_cookie_name(self):
|
def test_create_vip_with_unnecessary_cookie_name(self):
|
||||||
name = 'vip8'
|
sp = {'type': "SOURCE_IP", 'cookie_name': 'sessionId'}
|
||||||
|
with testtools.ExpectedException(webob.exc.HTTPClientError):
|
||||||
s_p = {'type': "SOURCE_IP", 'cookie_name': 'sessionId'}
|
self.test_create_vip(session_persistence=sp)
|
||||||
vip = self.vip(name=name, session_persistence=s_p)
|
|
||||||
|
|
||||||
self.assertRaises(webob.exc.HTTPClientError, vip.__enter__)
|
|
||||||
|
|
||||||
def test_create_vip_with_session_persistence_without_cookie_name(self):
|
def test_create_vip_with_session_persistence_without_cookie_name(self):
|
||||||
name = 'vip6'
|
sp = {'type': "APP_COOKIE"}
|
||||||
|
with testtools.ExpectedException(webob.exc.HTTPClientError):
|
||||||
vip = self.vip(name=name, session_persistence={'type': "APP_COOKIE"})
|
self.test_create_vip(session_persistence=sp)
|
||||||
self.assertRaises(webob.exc.HTTPClientError, vip.__enter__)
|
|
||||||
|
|
||||||
def test_reset_session_persistence(self):
|
def test_reset_session_persistence(self):
|
||||||
name = 'vip4'
|
name = 'vip4'
|
||||||
@ -386,14 +363,14 @@ class TestLoadBalancer(LoadBalancerPluginDbTestCase):
|
|||||||
def test_update_vip(self):
|
def test_update_vip(self):
|
||||||
name = 'new_vip'
|
name = 'new_vip'
|
||||||
keys = [('name', name),
|
keys = [('name', name),
|
||||||
('subnet_id', self._subnet_id),
|
('address', "10.0.0.2"),
|
||||||
('address', "172.16.1.123"),
|
('protocol_port', 80),
|
||||||
('port', 80),
|
|
||||||
('connection_limit', 100),
|
('connection_limit', 100),
|
||||||
('admin_state_up', False),
|
('admin_state_up', False),
|
||||||
('status', 'PENDING_UPDATE')]
|
('status', 'PENDING_UPDATE')]
|
||||||
|
|
||||||
with self.vip(name=name) as vip:
|
with self.vip(name=name) as vip:
|
||||||
|
keys.append(('subnet_id', vip['vip']['subnet_id']))
|
||||||
data = {'vip': {'name': name,
|
data = {'vip': {'name': name,
|
||||||
'connection_limit': 100,
|
'connection_limit': 100,
|
||||||
'session_persistence':
|
'session_persistence':
|
||||||
@ -416,14 +393,13 @@ class TestLoadBalancer(LoadBalancerPluginDbTestCase):
|
|||||||
def test_show_vip(self):
|
def test_show_vip(self):
|
||||||
name = "vip_show"
|
name = "vip_show"
|
||||||
keys = [('name', name),
|
keys = [('name', name),
|
||||||
('subnet_id', self._subnet_id),
|
('address', "10.0.0.10"),
|
||||||
('address', "172.16.1.123"),
|
('protocol_port', 80),
|
||||||
('port', 80),
|
|
||||||
('protocol', 'HTTP'),
|
('protocol', 'HTTP'),
|
||||||
('connection_limit', -1),
|
('connection_limit', -1),
|
||||||
('admin_state_up', True),
|
('admin_state_up', True),
|
||||||
('status', 'PENDING_CREATE')]
|
('status', 'PENDING_CREATE')]
|
||||||
with self.vip(name=name) as vip:
|
with self.vip(name=name, address='10.0.0.10') as vip:
|
||||||
req = self.new_show_request('vips',
|
req = self.new_show_request('vips',
|
||||||
vip['vip']['id'])
|
vip['vip']['id'])
|
||||||
res = self.deserialize(self.fmt, req.get_response(self.ext_api))
|
res = self.deserialize(self.fmt, req.get_response(self.ext_api))
|
||||||
@ -433,44 +409,52 @@ class TestLoadBalancer(LoadBalancerPluginDbTestCase):
|
|||||||
def test_list_vips(self):
|
def test_list_vips(self):
|
||||||
name = "vips_list"
|
name = "vips_list"
|
||||||
keys = [('name', name),
|
keys = [('name', name),
|
||||||
('subnet_id', self._subnet_id),
|
('address', "10.0.0.2"),
|
||||||
('address', "172.16.1.123"),
|
('protocol_port', 80),
|
||||||
('port', 80),
|
|
||||||
('protocol', 'HTTP'),
|
('protocol', 'HTTP'),
|
||||||
('connection_limit', -1),
|
('connection_limit', -1),
|
||||||
('admin_state_up', True),
|
('admin_state_up', True),
|
||||||
('status', 'PENDING_CREATE')]
|
('status', 'PENDING_CREATE')]
|
||||||
with self.vip(name=name):
|
with self.vip(name=name) as vip:
|
||||||
|
keys.append(('subnet_id', vip['vip']['subnet_id']))
|
||||||
req = self.new_list_request('vips')
|
req = self.new_list_request('vips')
|
||||||
res = self.deserialize(self.fmt, req.get_response(self.ext_api))
|
res = self.deserialize(self.fmt, req.get_response(self.ext_api))
|
||||||
|
self.assertEqual(len(res), 1)
|
||||||
for k, v in keys:
|
for k, v in keys:
|
||||||
self.assertEqual(res['vips'][0][k], v)
|
self.assertEqual(res['vips'][0][k], v)
|
||||||
|
|
||||||
def test_list_vips_with_sort_emulated(self):
|
def test_list_vips_with_sort_emulated(self):
|
||||||
with contextlib.nested(self.vip(name='vip1', port=81),
|
with self.subnet() as subnet:
|
||||||
self.vip(name='vip2', port=82),
|
with contextlib.nested(
|
||||||
self.vip(name='vip3', port=82)
|
self.vip(name='vip1', subnet=subnet, protocol_port=81),
|
||||||
) as (vip1, vip2, vip3):
|
self.vip(name='vip2', subnet=subnet, protocol_port=82),
|
||||||
self._test_list_with_sort('vip', (vip1, vip3, vip2),
|
self.vip(name='vip3', subnet=subnet, protocol_port=82)
|
||||||
[('port', 'asc'), ('name', 'desc')])
|
) as (vip1, vip2, vip3):
|
||||||
|
self._test_list_with_sort(
|
||||||
|
'vip',
|
||||||
|
(vip1, vip3, vip2),
|
||||||
|
[('protocol_port', 'asc'), ('name', 'desc')]
|
||||||
|
)
|
||||||
|
|
||||||
def test_list_vips_with_pagination_emulated(self):
|
def test_list_vips_with_pagination_emulated(self):
|
||||||
with contextlib.nested(self.vip(name='vip1'),
|
with self.subnet() as subnet:
|
||||||
self.vip(name='vip2'),
|
with contextlib.nested(self.vip(name='vip1', subnet=subnet),
|
||||||
self.vip(name='vip3')
|
self.vip(name='vip2', subnet=subnet),
|
||||||
) as (vip1, vip2, vip3):
|
self.vip(name='vip3', subnet=subnet)
|
||||||
self._test_list_with_pagination('vip',
|
) as (vip1, vip2, vip3):
|
||||||
(vip1, vip2, vip3),
|
self._test_list_with_pagination('vip',
|
||||||
('name', 'asc'), 2, 2)
|
(vip1, vip2, vip3),
|
||||||
|
('name', 'asc'), 2, 2)
|
||||||
|
|
||||||
def test_list_vips_with_pagination_reverse_emulated(self):
|
def test_list_vips_with_pagination_reverse_emulated(self):
|
||||||
with contextlib.nested(self.vip(name='vip1'),
|
with self.subnet() as subnet:
|
||||||
self.vip(name='vip2'),
|
with contextlib.nested(self.vip(name='vip1', subnet=subnet),
|
||||||
self.vip(name='vip3')
|
self.vip(name='vip2', subnet=subnet),
|
||||||
) as (vip1, vip2, vip3):
|
self.vip(name='vip3', subnet=subnet)
|
||||||
self._test_list_with_pagination_reverse('vip',
|
) as (vip1, vip2, vip3):
|
||||||
(vip1, vip2, vip3),
|
self._test_list_with_pagination_reverse('vip',
|
||||||
('name', 'asc'), 2, 2)
|
(vip1, vip2, vip3),
|
||||||
|
('name', 'asc'), 2, 2)
|
||||||
|
|
||||||
def test_create_pool_with_invalid_values(self):
|
def test_create_pool_with_invalid_values(self):
|
||||||
name = 'pool3'
|
name = 'pool3'
|
||||||
@ -519,7 +503,7 @@ class TestLoadBalancer(LoadBalancerPluginDbTestCase):
|
|||||||
self.assertEqual(len(pool_updated['pool']['members']), 1)
|
self.assertEqual(len(pool_updated['pool']['members']), 1)
|
||||||
|
|
||||||
keys = [('address', '192.168.1.100'),
|
keys = [('address', '192.168.1.100'),
|
||||||
('port', 80),
|
('protocol_port', 80),
|
||||||
('weight', 1),
|
('weight', 1),
|
||||||
('pool_id', pool_id),
|
('pool_id', pool_id),
|
||||||
('admin_state_up', True),
|
('admin_state_up', True),
|
||||||
@ -584,10 +568,10 @@ class TestLoadBalancer(LoadBalancerPluginDbTestCase):
|
|||||||
with self.pool() as pool:
|
with self.pool() as pool:
|
||||||
pool_id = pool['pool']['id']
|
pool_id = pool['pool']['id']
|
||||||
with self.member(address='192.168.1.100',
|
with self.member(address='192.168.1.100',
|
||||||
port=80,
|
protocol_port=80,
|
||||||
pool_id=pool_id) as member1:
|
pool_id=pool_id) as member1:
|
||||||
with self.member(address='192.168.1.101',
|
with self.member(address='192.168.1.101',
|
||||||
port=80,
|
protocol_port=80,
|
||||||
pool_id=pool_id) as member2:
|
pool_id=pool_id) as member2:
|
||||||
req = self.new_show_request('pools',
|
req = self.new_show_request('pools',
|
||||||
pool_id,
|
pool_id,
|
||||||
@ -606,7 +590,7 @@ class TestLoadBalancer(LoadBalancerPluginDbTestCase):
|
|||||||
with self.pool(name="pool2") as pool2:
|
with self.pool(name="pool2") as pool2:
|
||||||
keys = [('address', "192.168.1.100"),
|
keys = [('address', "192.168.1.100"),
|
||||||
('tenant_id', self._tenant_id),
|
('tenant_id', self._tenant_id),
|
||||||
('port', 80),
|
('protocol_port', 80),
|
||||||
('weight', 10),
|
('weight', 10),
|
||||||
('pool_id', pool2['pool']['id']),
|
('pool_id', pool2['pool']['id']),
|
||||||
('admin_state_up', False),
|
('admin_state_up', False),
|
||||||
@ -686,7 +670,7 @@ class TestLoadBalancer(LoadBalancerPluginDbTestCase):
|
|||||||
with self.pool() as pool:
|
with self.pool() as pool:
|
||||||
keys = [('address', "192.168.1.100"),
|
keys = [('address', "192.168.1.100"),
|
||||||
('tenant_id', self._tenant_id),
|
('tenant_id', self._tenant_id),
|
||||||
('port', 80),
|
('protocol_port', 80),
|
||||||
('weight', 1),
|
('weight', 1),
|
||||||
('pool_id', pool['pool']['id']),
|
('pool_id', pool['pool']['id']),
|
||||||
('admin_state_up', True),
|
('admin_state_up', True),
|
||||||
@ -705,40 +689,40 @@ class TestLoadBalancer(LoadBalancerPluginDbTestCase):
|
|||||||
def test_list_members_with_sort_emulated(self):
|
def test_list_members_with_sort_emulated(self):
|
||||||
with self.pool() as pool:
|
with self.pool() as pool:
|
||||||
with contextlib.nested(self.member(pool_id=pool['pool']['id'],
|
with contextlib.nested(self.member(pool_id=pool['pool']['id'],
|
||||||
port=81),
|
protocol_port=81),
|
||||||
self.member(pool_id=pool['pool']['id'],
|
self.member(pool_id=pool['pool']['id'],
|
||||||
port=82),
|
protocol_port=82),
|
||||||
self.member(pool_id=pool['pool']['id'],
|
self.member(pool_id=pool['pool']['id'],
|
||||||
port=83)
|
protocol_port=83)
|
||||||
) as (m1, m2, m3):
|
) as (m1, m2, m3):
|
||||||
self._test_list_with_sort('member', (m3, m2, m1),
|
self._test_list_with_sort('member', (m3, m2, m1),
|
||||||
[('port', 'desc')])
|
[('protocol_port', 'desc')])
|
||||||
|
|
||||||
def test_list_members_with_pagination_emulated(self):
|
def test_list_members_with_pagination_emulated(self):
|
||||||
with self.pool() as pool:
|
with self.pool() as pool:
|
||||||
with contextlib.nested(self.member(pool_id=pool['pool']['id'],
|
with contextlib.nested(self.member(pool_id=pool['pool']['id'],
|
||||||
port=81),
|
protocol_port=81),
|
||||||
self.member(pool_id=pool['pool']['id'],
|
self.member(pool_id=pool['pool']['id'],
|
||||||
port=82),
|
protocol_port=82),
|
||||||
self.member(pool_id=pool['pool']['id'],
|
self.member(pool_id=pool['pool']['id'],
|
||||||
port=83)
|
protocol_port=83)
|
||||||
) as (m1, m2, m3):
|
) as (m1, m2, m3):
|
||||||
self._test_list_with_pagination('member',
|
self._test_list_with_pagination(
|
||||||
(m1, m2, m3),
|
'member', (m1, m2, m3), ('protocol_port', 'asc'), 2, 2
|
||||||
('port', 'asc'), 2, 2)
|
)
|
||||||
|
|
||||||
def test_list_members_with_pagination_reverse_emulated(self):
|
def test_list_members_with_pagination_reverse_emulated(self):
|
||||||
with self.pool() as pool:
|
with self.pool() as pool:
|
||||||
with contextlib.nested(self.member(pool_id=pool['pool']['id'],
|
with contextlib.nested(self.member(pool_id=pool['pool']['id'],
|
||||||
port=81),
|
protocol_port=81),
|
||||||
self.member(pool_id=pool['pool']['id'],
|
self.member(pool_id=pool['pool']['id'],
|
||||||
port=82),
|
protocol_port=82),
|
||||||
self.member(pool_id=pool['pool']['id'],
|
self.member(pool_id=pool['pool']['id'],
|
||||||
port=83)
|
protocol_port=83)
|
||||||
) as (m1, m2, m3):
|
) as (m1, m2, m3):
|
||||||
self._test_list_with_pagination_reverse('member',
|
self._test_list_with_pagination_reverse(
|
||||||
(m1, m2, m3),
|
'member', (m1, m2, m3), ('protocol_port', 'asc'), 2, 2
|
||||||
('port', 'asc'), 2, 2)
|
)
|
||||||
|
|
||||||
def test_create_healthmonitor(self):
|
def test_create_healthmonitor(self):
|
||||||
keys = [('type', "TCP"),
|
keys = [('type', "TCP"),
|
||||||
|
@ -93,7 +93,7 @@ class LoadBalancerExtensionTestCase(testlib_api.WebTestCase):
|
|||||||
'description': 'descr_vip1',
|
'description': 'descr_vip1',
|
||||||
'subnet_id': _uuid(),
|
'subnet_id': _uuid(),
|
||||||
'address': '127.0.0.1',
|
'address': '127.0.0.1',
|
||||||
'port': 80,
|
'protocol_port': 80,
|
||||||
'protocol': 'HTTP',
|
'protocol': 'HTTP',
|
||||||
'pool_id': _uuid(),
|
'pool_id': _uuid(),
|
||||||
'session_persistence': {'type': 'HTTP_COOKIE'},
|
'session_persistence': {'type': 'HTTP_COOKIE'},
|
||||||
@ -293,7 +293,7 @@ class LoadBalancerExtensionTestCase(testlib_api.WebTestCase):
|
|||||||
member_id = _uuid()
|
member_id = _uuid()
|
||||||
data = {'member': {'pool_id': _uuid(),
|
data = {'member': {'pool_id': _uuid(),
|
||||||
'address': '127.0.0.1',
|
'address': '127.0.0.1',
|
||||||
'port': 80,
|
'protocol_port': 80,
|
||||||
'weight': 1,
|
'weight': 1,
|
||||||
'admin_state_up': True,
|
'admin_state_up': True,
|
||||||
'tenant_id': _uuid()}}
|
'tenant_id': _uuid()}}
|
||||||
|
@ -19,8 +19,11 @@ import webob.exc as webexc
|
|||||||
|
|
||||||
import quantum
|
import quantum
|
||||||
from quantum.api import extensions
|
from quantum.api import extensions
|
||||||
|
from quantum.api.v2 import attributes
|
||||||
from quantum.api.v2 import router
|
from quantum.api.v2 import router
|
||||||
from quantum.common import config
|
from quantum.common import config
|
||||||
|
from quantum import context as q_context
|
||||||
|
from quantum.db import api as db
|
||||||
from quantum.db import db_base_plugin_v2
|
from quantum.db import db_base_plugin_v2
|
||||||
from quantum.db import l3_db
|
from quantum.db import l3_db
|
||||||
from quantum.db.loadbalancer import loadbalancer_db as lb_db
|
from quantum.db.loadbalancer import loadbalancer_db as lb_db
|
||||||
@ -171,6 +174,10 @@ class RouterServiceInsertionTestCase(testtools.TestCase):
|
|||||||
|
|
||||||
# Ensure 'stale' patched copies of the plugin are never returned
|
# Ensure 'stale' patched copies of the plugin are never returned
|
||||||
quantum.manager.QuantumManager._instance = None
|
quantum.manager.QuantumManager._instance = None
|
||||||
|
|
||||||
|
# Ensure the database is reset between tests
|
||||||
|
db._ENGINE = None
|
||||||
|
db._MAKER = None
|
||||||
# Ensure existing ExtensionManager is not used
|
# Ensure existing ExtensionManager is not used
|
||||||
|
|
||||||
ext_mgr = extensions.PluginAwareExtensionManager(
|
ext_mgr = extensions.PluginAwareExtensionManager(
|
||||||
@ -188,6 +195,48 @@ class RouterServiceInsertionTestCase(testtools.TestCase):
|
|||||||
res = self._do_request('GET', _get_path('service-types'))
|
res = self._do_request('GET', _get_path('service-types'))
|
||||||
self._service_type_id = res['service_types'][0]['id']
|
self._service_type_id = res['service_types'][0]['id']
|
||||||
|
|
||||||
|
self._setup_core_resources()
|
||||||
|
|
||||||
|
# FIXME (markmcclain): The test setup makes it difficult to add core
|
||||||
|
# via the api. In the interim we'll create directly using the plugin with
|
||||||
|
# the side effect of polluting the fixture database until tearDown.
|
||||||
|
|
||||||
|
def _setup_core_resources(self):
|
||||||
|
core_plugin = quantum.manager.QuantumManager.get_plugin()
|
||||||
|
|
||||||
|
self._network = core_plugin.create_network(
|
||||||
|
q_context.get_admin_context(),
|
||||||
|
{
|
||||||
|
'network':
|
||||||
|
{
|
||||||
|
'tenant_id': self._tenant_id,
|
||||||
|
'name': 'test net',
|
||||||
|
'admin_state_up': True,
|
||||||
|
'shared': False,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
self._subnet = core_plugin.create_subnet(
|
||||||
|
q_context.get_admin_context(),
|
||||||
|
{
|
||||||
|
'subnet':
|
||||||
|
{
|
||||||
|
'network_id': self._network['id'],
|
||||||
|
'name': 'test subnet',
|
||||||
|
'cidr': '192.168.1.0/24',
|
||||||
|
'ip_version': 4,
|
||||||
|
'gateway_ip': '192.168.1.1',
|
||||||
|
'allocation_pools': attributes.ATTR_NOT_SPECIFIED,
|
||||||
|
'dns_nameservers': attributes.ATTR_NOT_SPECIFIED,
|
||||||
|
'host_routes': attributes.ATTR_NOT_SPECIFIED,
|
||||||
|
'enable_dhcp': True,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
self._subnet_id = self._subnet['id']
|
||||||
|
|
||||||
def _do_request(self, method, path, data=None, params=None, action=None):
|
def _do_request(self, method, path, data=None, params=None, action=None):
|
||||||
content_type = 'application/json'
|
content_type = 'application/json'
|
||||||
body = None
|
body = None
|
||||||
@ -267,7 +316,6 @@ class RouterServiceInsertionTestCase(testtools.TestCase):
|
|||||||
'DELETE', _get_path('routers/{0}'.format(router['id'])))
|
'DELETE', _get_path('routers/{0}'.format(router['id'])))
|
||||||
|
|
||||||
def _test_lb_setup(self):
|
def _test_lb_setup(self):
|
||||||
self._subnet_id = _uuid()
|
|
||||||
router = self._router_create(self._service_type_id)
|
router = self._router_create(self._service_type_id)
|
||||||
self._router_id = router['id']
|
self._router_id = router['id']
|
||||||
|
|
||||||
@ -337,10 +385,10 @@ class RouterServiceInsertionTestCase(testtools.TestCase):
|
|||||||
"tenant_id": self._tenant_id,
|
"tenant_id": self._tenant_id,
|
||||||
"name": "test",
|
"name": "test",
|
||||||
"protocol": "HTTP",
|
"protocol": "HTTP",
|
||||||
"port": 80,
|
"protocol_port": 80,
|
||||||
"subnet_id": self._subnet_id,
|
"subnet_id": self._subnet_id,
|
||||||
"pool_id": self._pool_id,
|
"pool_id": self._pool_id,
|
||||||
"address": "192.168.1.101",
|
"address": "192.168.1.102",
|
||||||
"connection_limit": 100,
|
"connection_limit": 100,
|
||||||
"admin_state_up": True,
|
"admin_state_up": True,
|
||||||
"router_id": router_id
|
"router_id": router_id
|
||||||
@ -361,7 +409,6 @@ class RouterServiceInsertionTestCase(testtools.TestCase):
|
|||||||
|
|
||||||
def _test_resource_create(self, res):
|
def _test_resource_create(self, res):
|
||||||
getattr(self, "_test_{0}_setup".format(res))()
|
getattr(self, "_test_{0}_setup".format(res))()
|
||||||
obj = getattr(self, "_{0}_create".format(res))()
|
|
||||||
obj = getattr(self, "_{0}_create".format(res))(self._router_id)
|
obj = getattr(self, "_{0}_create".format(res))(self._router_id)
|
||||||
self.assertEqual(obj['router_id'], self._router_id)
|
self.assertEqual(obj['router_id'], self._router_id)
|
||||||
|
|
||||||
@ -389,12 +436,15 @@ class RouterServiceInsertionTestCase(testtools.TestCase):
|
|||||||
_get_path('lb/{0}s/{1}'.format(res, obj['id'])))
|
_get_path('lb/{0}s/{1}'.format(res, obj['id'])))
|
||||||
self.assertEqual(updated[res][update_attr], update_value)
|
self.assertEqual(updated[res][update_attr], update_value)
|
||||||
|
|
||||||
def _test_resource_delete(self, res):
|
def _test_resource_delete(self, res, with_router_id):
|
||||||
getattr(self, "_test_{0}_setup".format(res))()
|
getattr(self, "_test_{0}_setup".format(res))()
|
||||||
obj = getattr(self, "_{0}_create".format(res))()
|
|
||||||
self._do_request(
|
func = getattr(self, "_{0}_create".format(res))
|
||||||
'DELETE', _get_path('lb/{0}s/{1}'.format(res, obj['id'])))
|
|
||||||
obj = getattr(self, "_{0}_create".format(res))(self._router_id)
|
if with_router_id:
|
||||||
|
obj = func(self._router_id)
|
||||||
|
else:
|
||||||
|
obj = func()
|
||||||
self._do_request(
|
self._do_request(
|
||||||
'DELETE', _get_path('lb/{0}s/{1}'.format(res, obj['id'])))
|
'DELETE', _get_path('lb/{0}s/{1}'.format(res, obj['id'])))
|
||||||
|
|
||||||
@ -407,8 +457,11 @@ class RouterServiceInsertionTestCase(testtools.TestCase):
|
|||||||
def test_pool_update_without_router_id(self):
|
def test_pool_update_without_router_id(self):
|
||||||
self._test_resource_update('pool', False, 'name', _uuid())
|
self._test_resource_update('pool', False, 'name', _uuid())
|
||||||
|
|
||||||
def test_pool_delete(self):
|
def test_pool_delete_with_router_id(self):
|
||||||
self._test_resource_delete('pool')
|
self._test_resource_delete('pool', True)
|
||||||
|
|
||||||
|
def test_pool_delete_without_router_id(self):
|
||||||
|
self._test_resource_delete('pool', False)
|
||||||
|
|
||||||
def test_health_monitor_create(self):
|
def test_health_monitor_create(self):
|
||||||
self._test_resource_create('health_monitor')
|
self._test_resource_create('health_monitor')
|
||||||
@ -419,8 +472,11 @@ class RouterServiceInsertionTestCase(testtools.TestCase):
|
|||||||
def test_health_monitor_update_without_router_id(self):
|
def test_health_monitor_update_without_router_id(self):
|
||||||
self._test_resource_update('health_monitor', False, 'timeout', 2)
|
self._test_resource_update('health_monitor', False, 'timeout', 2)
|
||||||
|
|
||||||
def test_health_monitor_delete(self):
|
def test_health_monitor_delete_with_router_id(self):
|
||||||
self._test_resource_delete('health_monitor')
|
self._test_resource_delete('health_monitor', True)
|
||||||
|
|
||||||
|
def test_health_monitor_delete_without_router_id(self):
|
||||||
|
self._test_resource_delete('health_monitor', False)
|
||||||
|
|
||||||
def test_vip_create(self):
|
def test_vip_create(self):
|
||||||
self._test_resource_create('vip')
|
self._test_resource_create('vip')
|
||||||
@ -431,5 +487,8 @@ class RouterServiceInsertionTestCase(testtools.TestCase):
|
|||||||
def test_vip_update_without_router_id(self):
|
def test_vip_update_without_router_id(self):
|
||||||
self._test_resource_update('vip', False, 'name', _uuid())
|
self._test_resource_update('vip', False, 'name', _uuid())
|
||||||
|
|
||||||
def test_vip_delete(self):
|
def test_vip_delete_with_router_id(self):
|
||||||
self._test_resource_delete('vip')
|
self._test_resource_delete('vip', True)
|
||||||
|
|
||||||
|
def test_vip_delete_without_router_id(self):
|
||||||
|
self._test_resource_delete('vip', False)
|
||||||
|
Loading…
Reference in New Issue
Block a user