From 72cc3eab3b0a81578b84a3c253a6de711aa6ffd7 Mon Sep 17 00:00:00 2001 From: Praveen Yalagandula Date: Sat, 23 May 2015 00:03:58 +0000 Subject: [PATCH] neutron loadbalancer resource: provider property Neutron LBaaS data model allows the users to pick a specific provider to implement a given load balancer instance (described by Pool in LBaaS v1.0 API). This commit brings this option into the heat resources as a property and an attribute. Co-Authored-By: Magesh GV Change-Id: Id55b8e615516c2ffd9d06980fb60707b207c356e --- .../openstack/neutron/loadbalancer.py | 18 +++++-- .../neutron/test_neutron_loadbalancer.py | 50 +++++++++++++++++++ 2 files changed, 64 insertions(+), 4 deletions(-) diff --git a/heat/engine/resources/openstack/neutron/loadbalancer.py b/heat/engine/resources/openstack/neutron/loadbalancer.py index eeee3d6d1..984283392 100644 --- a/heat/engine/resources/openstack/neutron/loadbalancer.py +++ b/heat/engine/resources/openstack/neutron/loadbalancer.py @@ -184,10 +184,10 @@ class Pool(neutron.NeutronResource): PROPERTIES = ( PROTOCOL, SUBNET_ID, SUBNET, LB_METHOD, NAME, DESCRIPTION, - ADMIN_STATE_UP, VIP, MONITORS, + ADMIN_STATE_UP, VIP, MONITORS, PROVIDER, ) = ( 'protocol', 'subnet_id', 'subnet', 'lb_method', 'name', 'description', - 'admin_state_up', 'vip', 'monitors', + 'admin_state_up', 'vip', 'monitors', 'provider', ) _VIP_KEYS = ( @@ -208,10 +208,10 @@ class Pool(neutron.NeutronResource): ATTRIBUTES = ( ADMIN_STATE_UP_ATTR, NAME_ATTR, PROTOCOL_ATTR, SUBNET_ID_ATTR, - LB_METHOD_ATTR, DESCRIPTION_ATTR, TENANT_ID, VIP_ATTR, + LB_METHOD_ATTR, DESCRIPTION_ATTR, TENANT_ID, VIP_ATTR, PROVIDER_ATTR, ) = ( 'admin_state_up', 'name', 'protocol', 'subnet_id', - 'lb_method', 'description', 'tenant_id', 'vip', + 'lb_method', 'description', 'tenant_id', 'vip', 'provider', ) properties_schema = { @@ -268,6 +268,11 @@ class Pool(neutron.NeutronResource): default=True, update_allowed=True ), + PROVIDER: properties.Schema( + properties.Schema.STRING, + _('LBaaS provider to implement this load balancer instance.'), + support_status=support.SupportStatus(version='2015.2'), + ), VIP: properties.Schema( properties.Schema.MAP, _('IP address and port of the pool.'), @@ -376,6 +381,11 @@ class Pool(neutron.NeutronResource): _('Vip associated with the pool.'), type=attributes.Schema.MAP ), + PROVIDER_ATTR: attributes.Schema( + _('Provider implementing this load balancer instance.'), + support_status=support.SupportStatus(version='2015.2'), + type=attributes.Schema.STRING, + ), } def validate(self): diff --git a/heat/tests/neutron/test_neutron_loadbalancer.py b/heat/tests/neutron/test_neutron_loadbalancer.py index a42b625fd..d9ac10aaf 100644 --- a/heat/tests/neutron/test_neutron_loadbalancer.py +++ b/heat/tests/neutron/test_neutron_loadbalancer.py @@ -59,6 +59,22 @@ resources: subnet: sub9999 ''' +pool_template_with_provider = ''' +heat_template_version: 2015-04-30 +description: Template to test load balancer resources +resources: + pool: + type: OS::Neutron::Pool + properties: + protocol: HTTP + subnet: sub123 + lb_method: ROUND_ROBIN + provider: test_prov + vip: + protocol_port: 80 + +''' + pool_template = ''' heat_template_version: 2015-04-30 description: Template to test load balancer resources @@ -547,6 +563,40 @@ class PoolTest(common.HeatTestCase): self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state) self.m.VerifyAll() + def test_create_pool_with_provider(self): + neutronV20.find_resourceid_by_name_or_id( + mox.IsA(neutronclient.Client), + 'subnet', + 'sub123' + ).MultipleTimes().AndReturn('sub123') + neutronclient.Client.create_pool({ + 'pool': { + 'subnet_id': 'sub123', 'protocol': u'HTTP', + 'name': utils.PhysName('test_stack', 'pool'), + 'lb_method': 'ROUND_ROBIN', 'admin_state_up': True, + 'provider': 'test_prov'}} + ).AndReturn({'pool': {'id': '5678'}}) + neutronclient.Client.create_vip({ + 'vip': { + 'protocol': u'HTTP', 'name': 'pool.vip', + 'admin_state_up': True, 'subnet_id': u'sub123', + 'pool_id': '5678', 'protocol_port': 80}} + ).AndReturn({'vip': {'id': 'xyz'}}) + neutronclient.Client.show_pool('5678').MultipleTimes().AndReturn( + {'pool': {'status': 'ACTIVE', 'provider': 'test_prov'}}) + neutronclient.Client.show_vip('xyz').AndReturn( + {'vip': {'status': 'ACTIVE'}}) + snippet = template_format.parse(pool_template_with_provider) + self.stack = utils.parse_stack(snippet) + resource_defns = self.stack.t.resource_definitions(self.stack) + rsrc = loadbalancer.Pool( + 'pool', resource_defns['pool'], self.stack) + self.m.ReplayAll() + scheduler.TaskRunner(rsrc.create)() + self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state) + self.assertEqual("test_prov", rsrc.FnGetAtt("provider")) + self.m.VerifyAll() + def test_failing_validation_with_session_persistence(self): msg = _('Property cookie_name is required, when ' 'session_persistence type is set to APP_COOKIE.')