From 75e39db48c173655838cb0c77a58f9a948cef33a Mon Sep 17 00:00:00 2001 From: Rabi Mishra Date: Thu, 27 Feb 2014 11:30:45 +0530 Subject: [PATCH] Adds option to select a different subnet when adding 'vip' With this fix, 'AddVip' from the dashboard gives user an option to select a different subnet than the 'pool' subnet and then creates a 'vip' with an ip (provided/next available) from the selected subnet. Change-Id: I25f36090c5fb739256b62a88915f6414e39a915f Closes-Bug: #1285504 --- .../dashboards/project/loadbalancers/tests.py | 62 ++++++++++++++----- .../project/loadbalancers/workflows.py | 53 ++++++++++------ 2 files changed, 81 insertions(+), 34 deletions(-) diff --git a/openstack_dashboard/dashboards/project/loadbalancers/tests.py b/openstack_dashboard/dashboards/project/loadbalancers/tests.py index d38d8a9c4b..84629129b9 100644 --- a/openstack_dashboard/dashboards/project/loadbalancers/tests.py +++ b/openstack_dashboard/dashboards/project/loadbalancers/tests.py @@ -67,7 +67,7 @@ class LoadBalancerTests(test.TestCase): # retrieves monitors api.lbaas.pool_health_monitor_list( IsA(http.HttpRequest), tenant_id=self.tenant.id).MultipleTimes() \ - .AndReturn(self.monitors.list()) + .AndReturn(self.monitors.list()) def set_up_expect_with_exception(self): api.lbaas.pool_list( @@ -108,7 +108,7 @@ class LoadBalancerTests(test.TestCase): % self.DASHBOARD) self.assertTemplateUsed(res, 'horizon/common/_detail_table.html') self.assertEqual(len(res.context['memberstable_table'].data), - len(self.members.list())) + len(self.members.list())) @test.create_stubs({api.lbaas: ('pool_list', 'member_list', 'pool_health_monitor_list')}) @@ -123,7 +123,7 @@ class LoadBalancerTests(test.TestCase): % self.DASHBOARD) self.assertTemplateUsed(res, 'horizon/common/_detail_table.html') self.assertEqual(len(res.context['monitorstable_table'].data), - len(self.monitors.list())) + len(self.monitors.list())) @test.create_stubs({api.lbaas: ('pool_list', 'member_list', 'pool_health_monitor_list')}) @@ -269,28 +269,34 @@ class LoadBalancerTests(test.TestCase): def test_add_vip_post_no_connection_limit(self): self._test_add_vip_post(with_conn_limit=False) + def test_add_vip_post_with_diff_subnet(self): + self._test_add_vip_post(with_diff_subnet=True) + @test.create_stubs({api.lbaas: ('pool_get', 'vip_create'), - api.neutron: ('subnet_get', )}) - def _test_add_vip_post(self, with_conn_limit=True): + api.neutron: ( + 'network_list_for_tenant', 'subnet_get', )}) + def _test_add_vip_post(self, with_diff_subnet=False, with_conn_limit=True): vip = self.vips.first() subnet = self.subnets.first() pool = self.pools.first() - + networks = [{'subnets': [subnet, ]}, ] api.lbaas.pool_get( IsA(http.HttpRequest), pool.id).MultipleTimes().AndReturn(pool) api.neutron.subnet_get( IsA(http.HttpRequest), subnet.id).AndReturn(subnet) + api.neutron.network_list_for_tenant( + IsA(http.HttpRequest), self.tenant.id).AndReturn(networks) + params = {'name': vip.name, 'description': vip.description, 'pool_id': vip.pool_id, 'address': vip.address, 'floatip_address': vip.floatip_address, 'other_address': vip.other_address, - 'subnet': vip.subnet, - 'subnet_id': vip.subnet_id, + 'subnet_id': pool.subnet_id, 'protocol_port': vip.protocol_port, 'protocol': vip.protocol, 'session_persistence': vip.session_persistence['type'], @@ -299,6 +305,8 @@ class LoadBalancerTests(test.TestCase): } if with_conn_limit: params['connection_limit'] = vip.connection_limit + if with_diff_subnet: + params['subnet_id'] = vip.subnet_id api.lbaas.vip_create( IsA(http.HttpRequest), **params).AndReturn(vip) @@ -311,8 +319,7 @@ class LoadBalancerTests(test.TestCase): 'address': vip.address, 'floatip_address': vip.floatip_address, 'other_address': vip.other_address, - 'subnet_id': vip.subnet_id, - 'subnet': vip.subnet, + 'subnet_id': pool.subnet_id, 'protocol_port': vip.protocol_port, 'protocol': vip.protocol, 'session_persistence': vip.session_persistence['type'].lower(), @@ -321,6 +328,9 @@ class LoadBalancerTests(test.TestCase): if with_conn_limit: form_data['connection_limit'] = vip.connection_limit + if with_diff_subnet: + params['subnet_id'] = vip.subnet_id + res = self.client.post( reverse(self.ADDVIP_PATH, args=(pool.id,)), form_data) @@ -328,17 +338,22 @@ class LoadBalancerTests(test.TestCase): self.assertRedirectsNoFollow(res, str(self.INDEX_URL)) @test.create_stubs({api.lbaas: ('pool_get', ), - api.neutron: ('subnet_get', )}) + api.neutron: ( + 'network_list_for_tenant', 'subnet_get', )}) def test_add_vip_post_with_error(self): vip = self.vips.first() subnet = self.subnets.first() pool = self.pools.first() + networks = [{'subnets': [subnet, ]}, ] api.lbaas.pool_get(IsA(http.HttpRequest), pool.id).AndReturn(pool) api.neutron.subnet_get( IsA(http.HttpRequest), subnet.id).AndReturn(subnet) + api.neutron.network_list_for_tenant( + IsA(http.HttpRequest), self.tenant.id).AndReturn(networks) + self.mox.ReplayAll() form_data = { @@ -346,7 +361,7 @@ class LoadBalancerTests(test.TestCase): 'description': vip.description, 'pool_id': vip.pool_id, 'address': vip.address, - 'subnet_id': vip.subnet_id, + 'subnet_id': pool.subnet_id, 'protocol_port': 65536, 'protocol': vip.protocol, 'session_persistence': vip.session_persistence['type'].lower(), @@ -359,16 +374,27 @@ class LoadBalancerTests(test.TestCase): self.assertFormErrors(res, 2) - @test.create_stubs({api.lbaas: ('pool_get', ), - api.neutron: ('subnet_get', )}) def test_add_vip_get(self): + self._test_add_vip_get() + + def test_add_vip_get_with_diff_subnet(self): + self._test_add_vip_get(with_diff_subnet=True) + + @test.create_stubs({api.lbaas: ('pool_get', ), + api.neutron: ( + 'network_list_for_tenant', 'subnet_get', )}) + def _test_add_vip_get(self, with_diff_subnet=False): subnet = self.subnets.first() pool = self.pools.first() + networks = [{'subnets': [subnet, ]}, ] api.lbaas.pool_get(IsA(http.HttpRequest), pool.id).AndReturn(pool) api.neutron.subnet_get( IsA(http.HttpRequest), subnet.id).AndReturn(subnet) + api.neutron.network_list_for_tenant( + IsA(http.HttpRequest), self.tenant.id).AndReturn(networks) + self.mox.ReplayAll() res = self.client.get(reverse(self.ADDVIP_PATH, args=(pool.id,))) @@ -380,6 +406,9 @@ class LoadBalancerTests(test.TestCase): expected_objs = ['', ] self.assertQuerysetEqual(workflow.steps, expected_objs) + if with_diff_subnet: + self.assertNotEqual(networks[0], pool.subnet_id) + @test.create_stubs({api.lbaas: ('pool_health_monitor_create', )}) def test_add_monitor_post(self): monitor = self.monitors.first() @@ -519,7 +548,7 @@ class LoadBalancerTests(test.TestCase): api.nova.server_list(IsA(http.HttpRequest)).AndReturn([[server1, server2], - False]) + False]) self.mox.ReplayAll() @@ -699,7 +728,8 @@ class LoadBalancerTests(test.TestCase): 'max_retries': monitor.max_retries, 'admin_state_up': monitor.admin_state_up} - api.lbaas.pool_health_monitor_update(IsA(http.HttpRequest), + api.lbaas.pool_health_monitor_update( + IsA(http.HttpRequest), monitor.id, health_monitor=data).AndReturn(monitor) self.mox.ReplayAll() diff --git a/openstack_dashboard/dashboards/project/loadbalancers/workflows.py b/openstack_dashboard/dashboards/project/loadbalancers/workflows.py index 90cfc88a4b..d07ccdf37b 100644 --- a/openstack_dashboard/dashboards/project/loadbalancers/workflows.py +++ b/openstack_dashboard/dashboards/project/loadbalancers/workflows.py @@ -39,7 +39,7 @@ class AddPoolAction(workflows.Action): protocol = forms.ChoiceField(label=_("Protocol")) lb_method = forms.ChoiceField(label=_("Load Balancing Method")) admin_state_up = forms.BooleanField(label=_("Admin State"), - initial=True, required=False) + initial=True, required=False) def __init__(self, request, *args, **kwargs): super(AddPoolAction, self).__init__(request, *args, **kwargs) @@ -153,14 +153,18 @@ class AddVipAction(workflows.Action): label=_("VIP Address from Floating IPs"), widget=forms.Select(attrs={'disabled': 'disabled'}), required=False) + subnet_id = forms.ChoiceField(label=_("VIP Subnet"), + initial="", + required=False) other_address = forms.IPField(required=False, initial="", version=forms.IPv4, mask=False) - protocol_port = forms.IntegerField(label=_("Protocol Port"), min_value=1, - help_text=_("Enter an integer value " - "between 1 and 65535."), - validators=[validators.validate_port_range]) + protocol_port = forms.IntegerField( + label=_("Protocol Port"), min_value=1, + help_text=_("Enter an integer value " + "between 1 and 65535."), + validators=[validators.validate_port_range]) protocol = forms.ChoiceField(label=_("Protocol")) session_persistence = forms.ChoiceField( required=False, initial={}, label=_("Session Persistence"), @@ -187,10 +191,20 @@ class AddVipAction(workflows.Action): def __init__(self, request, *args, **kwargs): super(AddVipAction, self).__init__(request, *args, **kwargs) - - self.fields['other_address'].label = _("Specify a free IP address" - " from %s") % args[0]['subnet'] - + tenant_id = request.user.tenant_id + subnet_id_choices = [('', _("Select a Subnet"))] + try: + networks = api.neutron.network_list_for_tenant(request, tenant_id) + except Exception: + exceptions.handle(request, + _('Unable to retrieve networks list.')) + networks = [] + for n in networks: + for s in n['subnets']: + subnet_id_choices.append((s.id, s.cidr)) + self.fields['subnet_id'].choices = subnet_id_choices + self.fields['other_address'].label = _("Specify a free IP address " + "from the selected subnet") protocol_choices = [('', _("Select a Protocol"))] [protocol_choices.append((p, p)) for p in AVAILABLE_PROTOCOLS] self.fields['protocol'].choices = protocol_choices @@ -230,7 +244,7 @@ class AddVipAction(workflows.Action): class AddVipStep(workflows.Step): action_class = AddVipAction depends_on = ("pool_id", "subnet") - contributes = ("name", "description", "floatip_address", + contributes = ("name", "description", "floatip_address", "subnet_id", "other_address", "protocol_port", "protocol", "session_persistence", "cookie_name", "connection_limit", "admin_state_up") @@ -254,6 +268,17 @@ class AddVip(workflows.Workflow): return message % name def handle(self, request, context): + if context['subnet_id'] == '': + try: + pool = api.lbaas.pool_get(request, context['pool_id']) + context['subnet_id'] = pool['subnet_id'] + except Exception: + context['subnet_id'] = None + self.failure_message = _( + 'Unable to retrieve the specified pool. ' + 'Unable to add VIP "%s".') + return False + if context['other_address'] == '': context['address'] = context['floatip_address'] else: @@ -263,14 +288,6 @@ class AddVip(workflows.Workflow): return False else: context['address'] = context['other_address'] - try: - pool = api.lbaas.pool_get(request, context['pool_id']) - context['subnet_id'] = pool['subnet_id'] - except Exception: - context['subnet_id'] = None - self.failure_message = _('Unable to retrieve the specified pool. ' - 'Unable to add VIP "%s".') - return False if context['session_persistence']: stype = context['session_persistence']