diff --git a/senlin/drivers/os/lbaas.py b/senlin/drivers/os/lbaas.py index 440219137..12503b29a 100644 --- a/senlin/drivers/os/lbaas.py +++ b/senlin/drivers/os/lbaas.py @@ -89,7 +89,7 @@ class LoadBalancerDriver(base.DriverBase): return False - def lb_create(self, vip, pool, hm=None, az=None): + def lb_create(self, vip, pool, hm=None, az=None, flavor_id=None): """Create a LBaaS instance :param vip: A dict containing the properties for the VIP; @@ -119,7 +119,8 @@ class LoadBalancerDriver(base.DriverBase): try: lb = self.oc().loadbalancer_create( subnet_id, network_id, vip.get('address', None), - vip['admin_state_up'], availability_zone=az) + vip['admin_state_up'], availability_zone=az, + flavor_id=flavor_id) except exception.InternalError as ex: msg = ('Failed in creating loadbalancer: %s.' % str(ex)) diff --git a/senlin/drivers/os/octavia_v2.py b/senlin/drivers/os/octavia_v2.py index a9b8d603c..c82e8ec06 100644 --- a/senlin/drivers/os/octavia_v2.py +++ b/senlin/drivers/os/octavia_v2.py @@ -37,7 +37,8 @@ class OctaviaClient(base.DriverBase): @sdk.translate_exception def loadbalancer_create(self, vip_subnet_id=None, vip_network_id=None, vip_address=None, admin_state_up=True, name=None, - description=None, availability_zone=None): + description=None, availability_zone=None, + flavor_id=None): kwargs = { 'admin_state_up': admin_state_up, @@ -55,6 +56,8 @@ class OctaviaClient(base.DriverBase): kwargs['description'] = description if availability_zone is not None: kwargs['availability_zone'] = availability_zone + if flavor_id is not None: + kwargs['flavor_id'] = flavor_id res = self.conn.load_balancer.create_load_balancer(**kwargs) return res @@ -172,3 +175,9 @@ class OctaviaClient(base.DriverBase): self.conn.load_balancer.delete_health_monitor( hm_id, ignore_missing=ignore_missing) return + + @sdk.translate_exception + def find_flavor(self, flavor_id, ignore_missing=False): + self.conn.load_balancer.find_flavor( + flavor_id, ignore_missing=ignore_missing) + return diff --git a/senlin/policies/lb_policy.py b/senlin/policies/lb_policy.py index 94396d158..b95ac69cb 100755 --- a/senlin/policies/lb_policy.py +++ b/senlin/policies/lb_policy.py @@ -80,10 +80,10 @@ class LoadBalancingPolicy(base.Policy): KEYS = ( POOL, VIP, HEALTH_MONITOR, LB_STATUS_TIMEOUT, LOADBALANCER, - AVAILABILITY_ZONE + AVAILABILITY_ZONE, FLAVOR_ID, ) = ( 'pool', 'vip', 'health_monitor', 'lb_status_timeout', 'loadbalancer', - 'availability_zone' + 'availability_zone', 'flavor_id', ) _POOL_KEYS = ( @@ -301,6 +301,11 @@ class LoadBalancingPolicy(base.Policy): _('Name of the loadbalancer availability zone to use for creation ' 'of the loadbalancer.'), default=None, + ), + FLAVOR_ID: schema.String( + _('ID of octavia loadbalancer flavor to use for creation ' + 'of the loadbalancer.'), + default=None, ) } @@ -311,6 +316,7 @@ class LoadBalancingPolicy(base.Policy): self.vip_spec = self.properties.get(self.VIP, {}) self.hm_spec = self.properties.get(self.HEALTH_MONITOR, None) self.az_spec = self.properties.get(self.AVAILABILITY_ZONE, None) + self.flavor_id_spec = self.properties.get(self.FLAVOR_ID, None) self.lb_status_timeout = self.properties.get(self.LB_STATUS_TIMEOUT) self.lb = self.properties.get(self.LOADBALANCER, None) @@ -332,6 +338,16 @@ class LoadBalancingPolicy(base.Policy): ) % {'key': self.POOL_SUBNET, 'value': name_or_id} raise exc.InvalidSpec(message=msg) + # validate loadbalancer flavor_id + flavor_id = self.flavor_id_spec + if flavor_id: + try: + oc.find_flavor(flavor_id) + except exc.InternalError: + msg = _("The specified %(key)s '%(value)s' could not be found." + ) % {'key': self.FLAVOR_ID, 'value': flavor_id} + raise exc.InvalidSpec(message=msg) + # validate VIP subnet or network subnet_name_or_id = self.vip_spec.get(self.VIP_SUBNET) network_name_or_id = self.vip_spec.get(self.VIP_NETWORK) @@ -398,7 +414,8 @@ class LoadBalancingPolicy(base.Policy): data['healthmonitor'] = self.hm_spec.get(self.HM_ID) else: res, data = lb_driver.lb_create(self.vip_spec, self.pool_spec, - self.hm_spec, self.az_spec) + self.hm_spec, self.az_spec, + self.flavor_id_spec) if res is False: return False, data diff --git a/senlin/tests/drivers/os_test/lbaas.py b/senlin/tests/drivers/os_test/lbaas.py index 4bd99d22a..a1d27601b 100644 --- a/senlin/tests/drivers/os_test/lbaas.py +++ b/senlin/tests/drivers/os_test/lbaas.py @@ -25,7 +25,7 @@ class LoadBalancerDriver(base.DriverBase): self.member_id = "9a7aff27-fd41-4ec1-ba4c-3eb92c629313" - def lb_create(self, vip, pool, hm=None, az=None): + def lb_create(self, vip, pool, hm=None, az=None, flavor_id=None): return True, self.lb_result def lb_delete(self, **kwargs): diff --git a/senlin/tests/unit/drivers/test_lbaas.py b/senlin/tests/unit/drivers/test_lbaas.py index c177ddcb3..a6bff4180 100644 --- a/senlin/tests/unit/drivers/test_lbaas.py +++ b/senlin/tests/unit/drivers/test_lbaas.py @@ -64,6 +64,7 @@ class TestOctaviaLBaaSDriver(base.SenlinTestCase): "expected_codes": "200,201,202" } self.availability_zone = 'my_fake_az' + self.flavor_id = 'my_fake_flavor_id' def test_init(self): conn_params = self.context.to_dict() @@ -152,12 +153,13 @@ class TestOctaviaLBaaSDriver(base.SenlinTestCase): self.lb_driver._wait_for_lb_ready = mock.Mock() self.lb_driver._wait_for_lb_ready.return_value = True status, res = self.lb_driver.lb_create(self.vip, self.pool, self.hm, - self.availability_zone) + self.availability_zone, + self.flavor_id) self.assertTrue(status) self.oc.loadbalancer_create.assert_called_once_with( 'SUBNET_ID', None, self.vip['address'], self.vip['admin_state_up'], - availability_zone=self.availability_zone) + availability_zone=self.availability_zone, flavor_id=self.flavor_id) self.assertEqual('LB_ID', res['loadbalancer']) self.assertEqual('192.168.1.100', res['vip_address']) self.oc.listener_create.assert_called_once_with( @@ -215,7 +217,8 @@ class TestOctaviaLBaaSDriver(base.SenlinTestCase): self.assertTrue(status) self.oc.loadbalancer_create.assert_called_once_with( None, 'NETWORK_ID', vip['address'], vip['admin_state_up'], - availability_zone=self.availability_zone) + availability_zone=self.availability_zone, + flavor_id=None) self.assertEqual('LB_ID', res['loadbalancer']) self.assertEqual('192.168.1.100', res['vip_address']) self.oc.listener_create.assert_called_once_with( @@ -257,7 +260,7 @@ class TestOctaviaLBaaSDriver(base.SenlinTestCase): self.assertEqual(msg, res) self.oc.loadbalancer_create.assert_called_once_with( 'SUBNET_ID', None, self.vip['address'], self.vip['admin_state_up'], - availability_zone=None) + availability_zone=None, flavor_id=None) self.lb_driver._wait_for_lb_ready.assert_called_once_with('LB_ID') self.lb_driver.lb_delete.assert_called_once_with( loadbalancer='LB_ID') @@ -303,7 +306,7 @@ class TestOctaviaLBaaSDriver(base.SenlinTestCase): self.assertEqual(msg, res) self.oc.loadbalancer_create.assert_called_once_with( 'SUBNET_ID', None, self.vip['address'], self.vip['admin_state_up'], - availability_zone=None) + availability_zone=None, flavor_id=None) self.oc.listener_create.assert_called_once_with( 'LB_ID', self.vip['protocol'], self.vip['protocol_port'], self.vip['connection_limit'], self.vip['admin_state_up']) @@ -348,7 +351,7 @@ class TestOctaviaLBaaSDriver(base.SenlinTestCase): self.assertEqual(msg, res) self.oc.loadbalancer_create.assert_called_once_with( 'SUBNET_ID', None, self.vip['address'], self.vip['admin_state_up'], - availability_zone=None) + availability_zone=None, flavor_id=None) self.oc.listener_create.assert_called_once_with( 'LB_ID', self.vip['protocol'], self.vip['protocol_port'], self.vip['connection_limit'], self.vip['admin_state_up']) diff --git a/senlin/tests/unit/policies/test_lb_policy.py b/senlin/tests/unit/policies/test_lb_policy.py index 0b6569790..c09e1ead3 100644 --- a/senlin/tests/unit/policies/test_lb_policy.py +++ b/senlin/tests/unit/policies/test_lb_policy.py @@ -68,7 +68,8 @@ class TestLoadBalancingPolicy(base.SenlinTestCase): 'expected_codes': '200,201,202' }, 'lb_status_timeout': 300, - 'availability_zone': 'test_az' + 'availability_zone': 'test_az', + 'flavor_id': 'test_flavor_id' } } self.sd = mock.Mock() @@ -389,7 +390,8 @@ class TestLoadBalancingPolicy(base.SenlinTestCase): self.lb_driver.lb_create.assert_called_once_with(policy.vip_spec, policy.pool_spec, policy.hm_spec, - policy.az_spec) + policy.az_spec, + policy.flavor_id_spec) member_add_calls = [ mock.call(node1, 'LB_ID', 'POOL_ID', 80, 'internal-subnet'), mock.call(node2, 'LB_ID', 'POOL_ID', 80, 'internal-subnet')