diff --git a/openstack_dashboard/dashboards/project/loadbalancers/tests.py b/openstack_dashboard/dashboards/project/loadbalancers/tests.py index 921550d5bb..9f3c0bbfc4 100644 --- a/openstack_dashboard/dashboards/project/loadbalancers/tests.py +++ b/openstack_dashboard/dashboards/project/loadbalancers/tests.py @@ -584,6 +584,37 @@ class LoadBalancerTests(test.TestCase): self.assertNoFormErrors(res) self.assertRedirectsNoFollow(res, str(self.INDEX_URL)) + @test.create_stubs({api.lbaas: ('pool_list', 'pool_get', 'member_create'), + api.neutron: ('port_list',), + api.nova: ('server_list',)}) + def test_add_member_no_ports(self): + member = self.members.first() + pools = self.pools.list() + server1 = self.AttributeDict({'id': + '12381d38-c3eb-4fee-9763-12de3338042e', + 'name': 'vm1'}) + api.lbaas.pool_list( + IsA(http.HttpRequest), tenant_id=self.tenant.id).AndReturn(pools) + api.nova.server_list( + IsA(http.HttpRequest)).AndReturn([[server1, ], False]) + api.lbaas.pool_get( + IsA(http.HttpRequest), pools[1].id).AndReturn(pools[1]) + api.neutron.port_list( + IsA(http.HttpRequest), device_id=server1.id).AndReturn([]) + + form_data = {'pool_id': member.pool_id, + 'protocol_port': member.protocol_port, + 'members': [server1.id], + 'admin_state_up': member.admin_state_up, + 'member_type': 'server_list'} + + self.mox.ReplayAll() + + res = self.client.post(reverse(self.ADDMEMBER_PATH), form_data) + + self.assertNoFormErrors(res) + self.assertRedirectsNoFollow(res, str(self.INDEX_URL)) + @test.create_stubs({api.lbaas: ('pool_list',), api.nova: ('server_list',)}) def test_add_member_post_with_error(self): diff --git a/openstack_dashboard/dashboards/project/loadbalancers/workflows.py b/openstack_dashboard/dashboards/project/loadbalancers/workflows.py index e058d88e56..385ba38c59 100644 --- a/openstack_dashboard/dashboards/project/loadbalancers/workflows.py +++ b/openstack_dashboard/dashboards/project/loadbalancers/workflows.py @@ -435,27 +435,31 @@ class AddMember(workflows.Workflow): # Sort port list for each member. This is needed to avoid # attachment of random ports in case of creation of several # members attached to several networks. - plist = sorted(plist, key=lambda port: port.network_id) - psubnet = [p for p in plist for ips in p.fixed_ips - if ips['subnet_id'] == subnet_id] + if plist: + plist = sorted(plist, key=lambda port: port.network_id) + psubnet = [p for p in plist for ips in p.fixed_ips + if ips['subnet_id'] == subnet_id] - # If possible, select a port on pool subnet. - if psubnet: - selected_port = psubnet[0] - elif plist: - selected_port = plist[0] + # If possible, select a port on pool subnet. + if psubnet: + selected_port = psubnet[0] + elif plist: + selected_port = plist[0] + else: + selected_port = None + + if selected_port: + context['address'] = \ + selected_port.fixed_ips[0]['ip_address'] + try: + api.lbaas.member_create(request, **context).id + except Exception as e: + msg = self.failure_message + LOG.info('%s: %s' % (msg, e)) + return False else: - selected_port = None - - if selected_port: - context['address'] = \ - selected_port.fixed_ips[0]['ip_address'] - try: - api.lbaas.member_create(request, **context).id - except Exception as e: - msg = self.failure_message - LOG.info('%s: %s' % (msg, e)) - return False + self.failure_message = _('No ports available.') + return False return True else: try: