From 01f8e67fdb2964931f2489d14b112519c36de875 Mon Sep 17 00:00:00 2001 From: Sergey Kraynev Date: Thu, 17 Jul 2014 07:16:50 -0400 Subject: [PATCH] Fix updating for OS::Neutron::Port resource Updating of port resource should not lead to removing ip address. This patch includes next changes: - Fix update behavior for Port resource. - Using properties names instead of constant names. - New test was added for port create/update actions. Change-Id: Iff73aaaa433ac56515a931f83ad201d15fca2bd8 Closes-Bug: #1343166 --- heat/engine/resources/neutron/port.py | 7 ++-- heat/tests/test_neutron.py | 54 +++++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 4 deletions(-) diff --git a/heat/engine/resources/neutron/port.py b/heat/engine/resources/neutron/port.py index 9204a4606..c052ffce9 100644 --- a/heat/engine/resources/neutron/port.py +++ b/heat/engine/resources/neutron/port.py @@ -229,9 +229,6 @@ class Port(neutron.NeutronResource): props, self.NETWORK, 'network_id') self._prepare_list_properties(props) - if not props['fixed_ips']: - del(props['fixed_ips']) - port = self.neutron().create_port({'port': props})['port'] self.resource_id_set(port['id']) @@ -257,6 +254,9 @@ class Port(neutron.NeutronResource): else: props.pop(self.SECURITY_GROUPS, None) + if not props[self.FIXED_IPS]: + del(props[self.FIXED_IPS]) + def _show_resource(self): return self.neutron().show_port( self.resource_id)['port'] @@ -284,7 +284,6 @@ class Port(neutron.NeutronResource): props = self.prepare_update_properties(json_snippet) self._prepare_list_properties(props) - LOG.debug('updating port with %s' % props) self.neutron().update_port(self.resource_id, {'port': props}) diff --git a/heat/tests/test_neutron.py b/heat/tests/test_neutron.py index b28c0c76a..ed811207f 100644 --- a/heat/tests/test_neutron.py +++ b/heat/tests/test_neutron.py @@ -2158,6 +2158,7 @@ class NeutronPortTest(HeatTestCase): super(NeutronPortTest, self).setUp() self.m.StubOutWithMock(neutronclient.Client, 'create_port') self.m.StubOutWithMock(neutronclient.Client, 'show_port') + self.m.StubOutWithMock(neutronclient.Client, 'update_port') self.m.StubOutWithMock(neutron_utils.neutronV20, 'find_resourceid_by_name_or_id') self.stub_keystoneclient() @@ -2390,6 +2391,59 @@ class NeutronPortTest(HeatTestCase): self.m.VerifyAll() + def test_create_and_update_port(self): + props = {'network_id': u'net1234', + 'name': utils.PhysName('test_stack', 'port'), + 'admin_state_up': True, + 'device_owner': u'network:dhcp'} + new_props = props.copy() + new_props['name'] = "new_name" + new_props_update = new_props.copy() + new_props_update.pop('network_id') + + neutron_utils.neutronV20.find_resourceid_by_name_or_id( + mox.IsA(neutronclient.Client), + 'network', + 'net1234' + ).AndReturn('net1234') + neutronclient.Client.create_port( + {'port': props} + ).AndReturn({'port': { + "status": "BUILD", + "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766" + }}) + neutronclient.Client.show_port( + 'fc68ea2c-b60b-4b4f-bd82-94ec81110766' + ).AndReturn({'port': { + "status": "ACTIVE", + "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766", + "fixed_ips": { + "subnet_id": "d0e971a6-a6b4-4f4c-8c88-b75e9c120b7e", + "ip_address": "10.0.0.2" + } + }}) + neutronclient.Client.update_port( + 'fc68ea2c-b60b-4b4f-bd82-94ec81110766', + {'port': new_props_update} + ).AndReturn(None) + + self.m.ReplayAll() + + # create port + t = template_format.parse(neutron_port_template) + t['Resources']['port']['Properties'].pop('fixed_ips') + stack = utils.parse_stack(t) + + port = stack['port'] + scheduler.TaskRunner(port.create)() + + # update port + update_snippet = rsrc_defn.ResourceDefinition(port.name, port.type(), + new_props) + self.assertIsNone(port.handle_update(update_snippet, {}, {})) + + self.m.VerifyAll() + class NetworkConstraintTest(HeatTestCase):