Merge "Add support for loadbalancer providers"
This commit is contained in:
commit
dc284d154f
@ -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)
|
||||
|
@ -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()
|
||||
|
@ -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"),
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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()
|
||||
|
||||
|
@ -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):
|
||||
|
@ -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()
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user