Merge "Add support for loadbalancer providers"

This commit is contained in:
Jenkins 2013-09-28 15:29:23 +00:00 committed by Gerrit Code Review
commit dc284d154f
8 changed files with 116 additions and 10 deletions

View File

@ -32,6 +32,8 @@ class Pool(neutron.NeutronAPIDictWrapper):
"""Wrapper for neutron load balancer pool"""
def __init__(self, apiresource):
if 'provider' not in apiresource:
apiresource['provider'] = None
super(Pool, self).__init__(apiresource)
class AttributeDict(dict):
@ -46,7 +48,8 @@ class Pool(neutron.NeutronAPIDictWrapper):
'name': self.name,
'description': self.description,
'protocol': self.protocol,
'health_monitors': self.health_monitors}
'health_monitors': self.health_monitors,
'provider': self.provider}
try:
pFormatted['subnet_id'] = self.subnet_id
pFormatted['subnet_name'] = neutron.subnet_get(
@ -173,7 +176,8 @@ def pool_create(request, **kwargs):
'subnet_id': kwargs['subnet_id'],
'protocol': kwargs['protocol'],
'lb_method': kwargs['lb_method'],
'admin_state_up': kwargs['admin_state_up']
'admin_state_up': kwargs['admin_state_up'],
'provider': kwargs['provider'],
}}
pool = neutronclient(request).create_pool(body).get('pool')
return Pool(pool)

View File

@ -722,6 +722,11 @@ def agent_list(request):
return [Agent(a) for a in agents['agents']]
def provider_list(request):
providers = neutronclient(request).list_service_providers()
return providers['service_providers']
@memoized
def list_extensions(request):
extensions_list = neutronclient(request).list_extensions()

View File

@ -16,6 +16,7 @@
from django.core.urlresolvers import reverse # noqa
from django.template import defaultfilters as filters
from django.utils import http
from django.utils.translation import ugettext_lazy as _ # noqa
@ -190,6 +191,8 @@ class PoolsTable(tables.DataTable):
verbose_name=_("Name"),
link="horizon:project:loadbalancers:pooldetails")
description = tables.Column('description', verbose_name=_("Description"))
provider = tables.Column('provider', verbose_name=_("Provider"),
filters=(lambda v: filters.default(v, _('N/A')),))
subnet_name = tables.Column('subnet_name', verbose_name=_("Subnet"))
protocol = tables.Column('protocol', verbose_name=_("Protocol"))
vip_name = tables.Column('vip_name', verbose_name=_("VIP"),

View File

@ -18,6 +18,9 @@
<dt>{% trans "VIP ID" %}</dt>
<dd>{{ pool.vip_id|default:_("-") }}</dd>
<dt>{% trans "Provider" %}</dt>
<dd>{{ pool.provider|default:_("N/A") }}</dd>
<dt>{% trans "Subnet ID" %}</dt>
<dd>{{ pool.subnet_id }}</dd>

View File

@ -180,7 +180,9 @@ class LoadBalancerTests(test.TestCase):
'horizon/common/_detail_table.html')
self.assertEqual(len(res.context['monitorstable_table'].data), 0)
@test.create_stubs({api.neutron: ('network_list_for_tenant',),
@test.create_stubs({api.neutron: ('network_list_for_tenant',
'provider_list',
'is_extension_supported'),
api.lbaas: ('pool_create', )})
def test_add_pool_post(self):
pool = self.pools.first()
@ -188,8 +190,12 @@ class LoadBalancerTests(test.TestCase):
subnet = self.subnets.first()
networks = [{'subnets': [subnet, ]}, ]
api.neutron.is_extension_supported(
IsA(http.HttpRequest), 'service-type').AndReturn(True)
api.neutron.network_list_for_tenant(
IsA(http.HttpRequest), subnet.tenant_id).AndReturn(networks)
api.neutron.provider_list(IsA(http.HttpRequest)) \
.AndReturn(self.providers.list())
api.lbaas.pool_create(
IsA(http.HttpRequest),
@ -198,7 +204,8 @@ class LoadBalancerTests(test.TestCase):
subnet_id=pool.subnet_id,
protocol=pool.protocol,
lb_method=pool.lb_method,
admin_state_up=pool.admin_state_up).AndReturn(lbaas.Pool(pool))
admin_state_up=pool.admin_state_up,
provider=pool.provider).AndReturn(pool)
self.mox.ReplayAll()
@ -214,14 +221,40 @@ class LoadBalancerTests(test.TestCase):
self.assertNoFormErrors(res)
self.assertRedirectsNoFollow(res, str(self.INDEX_URL))
@test.create_stubs({api.neutron: ('network_list_for_tenant',)})
@test.create_stubs({api.neutron: ('network_list_for_tenant',
'provider_list',
'is_extension_supported')})
def test_add_pool_get(self):
self._test_add_pool_get(with_service_type=True)
@test.create_stubs({api.neutron: ('network_list_for_tenant',
'provider_list',
'is_extension_supported')})
def test_add_pool_get_provider_list_exception(self):
self._test_add_pool_get(with_service_type=True)
@test.create_stubs({api.neutron: ('network_list_for_tenant',
'is_extension_supported')})
def test_add_pool_get_without_service_type_support(self):
self._test_add_pool_get(with_service_type=False)
def _test_add_pool_get(self, with_service_type=True,
with_provider_exception=False):
subnet = self.subnets.first()
default_provider = self.providers.first()['name']
networks = [{'subnets': [subnet, ]}, ]
api.neutron.is_extension_supported(
IsA(http.HttpRequest), 'service-type').AndReturn(with_service_type)
api.neutron.network_list_for_tenant(
IsA(http.HttpRequest), subnet.tenant_id).AndReturn(networks)
if with_service_type:
prov_list = api.neutron.provider_list(IsA(http.HttpRequest))
if with_provider_exception:
prov_list.AndRaise(self.exceptions.neutron)
else:
prov_list.AndReturn(self.providers.list())
self.mox.ReplayAll()
@ -234,6 +267,16 @@ class LoadBalancerTests(test.TestCase):
expected_objs = ['<AddPoolStep: addpoolaction>', ]
self.assertQuerysetEqual(workflow.steps, expected_objs)
if not with_service_type:
self.assertNotContains(res, default_provider)
self.assertContains(res, ('Provider for Load Balancer '
'is not supported.'))
elif with_provider_exception:
self.assertNotContains(res, default_provider)
self.assertContains(res, 'No provider is available.')
else:
self.assertContains(res, default_provider)
@test.create_stubs({api.lbaas: ('pool_get', 'vip_create'),
api.neutron: ('subnet_get', )})
def test_add_vip_post(self):
@ -263,7 +306,7 @@ class LoadBalancerTests(test.TestCase):
session_persistence=vip.session_persistence['type'],
cookie_name=vip.session_persistence['cookie_name'],
connection_limit=vip.connection_limit,
admin_state_up=vip.admin_state_up).AndReturn(lbaas.Vip(vip))
admin_state_up=vip.admin_state_up).AndReturn(vip)
self.mox.ReplayAll()

View File

@ -35,6 +35,9 @@ class AddPoolAction(workflows.Action):
description = forms.CharField(
initial="", required=False,
max_length=80, label=_("Description"))
# provider is optional because some LBaaS implemetation does
# not support service-type extension.
provider = forms.ChoiceField(label=_("Provider"), required=False)
subnet_id = forms.ChoiceField(label=_("Subnet"))
protocol = forms.ChoiceField(label=_("Protocol"))
lb_method = forms.ChoiceField(label=_("Load Balancing Method"))
@ -69,6 +72,40 @@ class AddPoolAction(workflows.Action):
lb_method_choices.append(('SOURCE_IP', 'SOURCE_IP'))
self.fields['lb_method'].choices = lb_method_choices
# provider choice
try:
if api.neutron.is_extension_supported(request, 'service-type'):
provider_list = api.neutron.provider_list(request)
providers = [p for p in provider_list
if p['service_type'] == 'LOADBALANCER']
else:
providers = None
except Exception:
exceptions.handle(request,
_('Unable to retrieve providers list.'))
providers = []
if providers:
default_providers = [p for p in providers if p.get('default')]
if default_providers:
default_provider = default_providers[0]['name']
else:
default_provider = None
provider_choices = [(p['name'], p['name']) for p in providers
if p['name'] != default_provider]
if default_provider:
provider_choices.insert(
0, (default_provider,
_("%s (default)") % default_provider))
else:
if providers is None:
msg = _("Provider for Load Balancer is not supported.")
else:
msg = _("No provider is available.")
provider_choices = [('', msg)]
self.fields['provider'].widget.attrs['readonly'] = True
self.fields['provider'].choices = provider_choices
class Meta:
name = _("Add New Pool")
permissions = ('openstack.services.network',)
@ -83,7 +120,7 @@ class AddPoolAction(workflows.Action):
class AddPoolStep(workflows.Step):
action_class = AddPoolAction
contributes = ("name", "description", "subnet_id",
contributes = ("name", "description", "subnet_id", "provider",
"protocol", "lb_method", "admin_state_up")
def contribute(self, data, context):

View File

@ -122,7 +122,8 @@ class LbaasApiTests(test.APITestCase):
'subnet_id': '12381d38-c3eb-4fee-9763-12de3338041e',
'protocol': 'HTTP',
'lb_method': 'ROUND_ROBIN',
'admin_state_up': True
'admin_state_up': True,
'provider': 'dummy'
}
pool = {'pool': {'id': 'abcdef-c3eb-4fee-9763-12de3338041e',
@ -131,7 +132,8 @@ class LbaasApiTests(test.APITestCase):
'subnet_id': '12381d38-c3eb-4fee-9763-12de3338041e',
'protocol': 'HTTP',
'lb_method': 'ROUND_ROBIN',
'admin_state_up': True
'admin_state_up': True,
'provider': 'dummy'
}}
neutronclient.create_pool({'pool': form_data}).AndReturn(pool)
self.mox.ReplayAll()

View File

@ -34,6 +34,7 @@ def data(TEST):
TEST.q_floating_ips = utils.TestDataContainer()
TEST.q_secgroups = utils.TestDataContainer()
TEST.q_secgroup_rules = utils.TestDataContainer()
TEST.providers = utils.TestDataContainer()
TEST.pools = utils.TestDataContainer()
TEST.vips = utils.TestDataContainer()
TEST.members = utils.TestDataContainer()
@ -411,7 +412,8 @@ def data(TEST):
'protocol': 'HTTP',
'lb_method': 'ROUND_ROBIN',
'health_monitors': ['d4a0500f-db2b-4cc4-afcf-ec026febff96'],
'admin_state_up': True}
'admin_state_up': True,
'provider': 'haproxy'}
TEST.api_pools.add(pool_dict)
TEST.pools.add(lbaas.Pool(pool_dict))
@ -576,6 +578,13 @@ def data(TEST):
TEST.api_agents.add(agent_dict)
TEST.agents.add(neutron.Agent(agent_dict))
#------------------------------------------------------------
# Service providers
provider_1 = {"service_type": "LOADBALANCER",
"name": "haproxy",
"default": True}
TEST.providers.add(provider_1)
#------------------------------------------------------------
# VPNaaS