diff --git a/senlin/drivers/openstack/lbaas.py b/senlin/drivers/openstack/lbaas.py index 0bd11dda6..ada20fd78 100644 --- a/senlin/drivers/openstack/lbaas.py +++ b/senlin/drivers/openstack/lbaas.py @@ -13,9 +13,9 @@ import eventlet import six +from oslo_context import context as oslo_context from oslo_log import log as logging -from senlin.common import context from senlin.common.i18n import _ from senlin.common.i18n import _LE from senlin.drivers import base @@ -174,7 +174,8 @@ class LoadBalancerDriver(base.DriverBase): return None address = addresses[net_name] - member = self.nc().pool_member_create(pool_id, address, port, subnet) + member = self.nc().pool_member_create(pool_id, address, port, + subnet_obj['id']) self._wait_for_lb_ready(lb_id) return member.id @@ -201,10 +202,11 @@ class LoadBalancerDriver(base.DriverBase): def _get_node_address(self, node, version=4): """Get IP address of node with specific version""" - node_detail = node.get_details(context.get_current()) - node_addresses = node_detail.get('addresses') + node_detail = node.get_details(oslo_context.get_current()) + node_addresses = node_detail.get('addresses', {}) address = {} + for network in node_addresses: for addr in node_addresses[network]: if addr['version'] == version: diff --git a/senlin/tests/unit/driver/test_lbaas_driver.py b/senlin/tests/unit/driver/test_lbaas_driver.py index e3a40d65d..4ddea4438 100644 --- a/senlin/tests/unit/driver/test_lbaas_driver.py +++ b/senlin/tests/unit/driver/test_lbaas_driver.py @@ -13,6 +13,8 @@ import eventlet import mock +from oslo_context import context as oslo_context + from senlin.common.i18n import _ from senlin.drivers.openstack import lbaas from senlin.drivers.openstack import neutron_v2 @@ -100,7 +102,7 @@ class TestNeutronLBaaSDriver(base.SenlinTestCase): self.assertFalse(res) mock_sleep.assert_called_once_with(2) - def test_lb_create_succeed(self): + def test_lb_create_succeeded(self): lb_obj = mock.Mock() listener_obj = mock.Mock() pool_obj = mock.Mock() @@ -233,3 +235,143 @@ class TestNeutronLBaaSDriver(base.SenlinTestCase): calls = [mock.call('LB_ID') for i in range(1, 4)] self.lb_driver._wait_for_lb_ready.assert_has_calls( calls, any_order=False) + + @mock.patch.object(oslo_context, 'get_current') + def test_get_node_address(self, mock_get_current): + node = mock.Mock() + node_detail = { + 'name': 'node-01', + 'addresses': { + 'network1': [ + { + 'version': 4, + 'addr': 'ip_addr1' + }, + { + 'version': 6, + 'addr': 'ip_addr3' + } + ], + 'network2': [ + { + 'version': 4, + 'addr': 'ip_addr2' + }, + ] + } + } + node.get_details.return_value = node_detail + + res = self.lb_driver._get_node_address(node, version=4) + expected_addr = { + 'network1': 'ip_addr1', + 'network2': 'ip_addr2' + } + self.assertEqual(expected_addr, res) + + res = self.lb_driver._get_node_address(node, version=6) + expected_addr = { + 'network1': 'ip_addr3', + } + self.assertEqual(expected_addr, res) + + node_detail['addresses'] = {} + res = self.lb_driver._get_node_address(node, version=4) + self.assertEqual({}, res) + + node_detail.pop('addresses') + res = self.lb_driver._get_node_address(node, version=4) + self.assertEqual({}, res) + + @mock.patch.object(lbaas.LoadBalancerDriver, '_get_node_address') + def test_member_add_succeeded(self, mock_get_node_address): + node = mock.Mock() + lb_id = 'LB_ID' + pool_id = 'POOL_ID' + port = '80' + subnet = 'subnet1' + subnet_obj = {'name': 'subnet1', 'id': 'SUBNET_ID', + 'network_id': 'NETWORK_ID'} + network_obj = {'name': 'network1', 'id': 'NETWORK_ID'} + addresses = {'network1': 'ipaddr_net1', 'network2': 'ipaddr_net2'} + member = mock.Mock() + member.id = 'MEMBER_ID' + + mock_get_node_address.return_value = addresses + self.nc.subnet_get.return_value = subnet_obj + self.nc.network_get.return_value = network_obj + self.nc.pool_member_create.return_value = member + self.lb_driver._wait_for_lb_ready = mock.Mock() + self.lb_driver._wait_for_lb_ready.return_value = True + + res = self.lb_driver.member_add(node, lb_id, pool_id, port, subnet) + self.assertEqual('MEMBER_ID', res) + mock_get_node_address.assert_called_once_with(node, version=4) + self.nc.subnet_get.assert_called_once_with(subnet) + self.nc.network_get.assert_called_once_with('NETWORK_ID') + self.nc.pool_member_create.assert_called_once_with( + pool_id, 'ipaddr_net1', port, 'SUBNET_ID') + + @mock.patch.object(lbaas.LoadBalancerDriver, '_get_node_address') + def test_member_add_node_no_address(self, mock_get_node_address): + node = mock.Mock() + lb_id = 'LB_ID' + pool_id = 'POOL_ID' + port = '80' + subnet = 'subnet1' + + mock_get_node_address.return_value = {} + self.lb_driver._wait_for_lb_ready = mock.Mock() + self.lb_driver._wait_for_lb_ready.return_value = True + + res = self.lb_driver.member_add(node, lb_id, pool_id, port, subnet) + self.assertIsNone(res) + + @mock.patch.object(lbaas.LoadBalancerDriver, '_get_node_address') + def test_member_add_node_not_in_subnet(self, mock_get_node_address): + node = mock.Mock() + lb_id = 'LB_ID' + pool_id = 'POOL_ID' + port = '80' + subnet = 'subnet1' + network_obj = {'name': 'network3', 'id': 'NETWORK_ID'} + addresses = {'network1': 'ipaddr_net1', 'network2': 'ipaddr_net2'} + + self.nc.network_get.return_value = network_obj + mock_get_node_address.return_value = addresses + self.lb_driver._wait_for_lb_ready = mock.Mock() + self.lb_driver._wait_for_lb_ready.return_value = True + + res = self.lb_driver.member_add(node, lb_id, pool_id, port, subnet) + self.assertIsNone(res) + + def test_member_remove_succeeded(self): + lb_id = 'LB_ID' + pool_id = 'POOL_ID' + member_id = 'MEMBER_ID' + + self.lb_driver._wait_for_lb_ready = mock.Mock() + self.lb_driver._wait_for_lb_ready.return_value = True + + res = self.lb_driver.member_remove(lb_id, pool_id, member_id) + self.assertTrue(res) + self.nc.pool_member_delete.assert_called_once_with(pool_id, member_id) + self.lb_driver._wait_for_lb_ready.assert_called_once_with(lb_id) + + def test_member_remove_failed(self): + lb_id = 'LB_ID' + pool_id = 'POOL_ID' + member_id = 'MEMBER_ID' + + self.lb_driver._wait_for_lb_ready = mock.Mock() + self.lb_driver._wait_for_lb_ready.return_value = True + self.nc.pool_member_delete.side_effect = Exception('') + res = self.lb_driver.member_remove(lb_id, pool_id, member_id) + self.assertFalse(res) + self.nc.pool_member_delete.assert_called_once_with(pool_id, member_id) + + self.nc.pool_member_delete.side_effect = None + self.lb_driver._wait_for_lb_ready.side_effect = Exception('') + res = self.lb_driver.member_remove(lb_id, pool_id, member_id) + self.assertFalse(res) + self.lb_driver._wait_for_lb_ready.assert_called_once_with(lb_id)