diff --git a/heat/engine/resources/neutron/port.py b/heat/engine/resources/neutron/port.py index 3eeb520356a..4f49c8449cd 100644 --- a/heat/engine/resources/neutron/port.py +++ b/heat/engine/resources/neutron/port.py @@ -73,7 +73,7 @@ def handle_create(self): self.properties, self.physical_resource_name()) - for fixed_ip in props['fixed_ips']: + for fixed_ip in props.get('fixed_ips', []): for key, value in fixed_ip.items(): if value is None: fixed_ip.pop(key) diff --git a/heat/tests/test_neutron.py b/heat/tests/test_neutron.py index e1ed926f93e..391566eae5c 100644 --- a/heat/tests/test_neutron.py +++ b/heat/tests/test_neutron.py @@ -1123,3 +1123,31 @@ def test_missing_ip_address(self): port = stack['port'] scheduler.TaskRunner(port.create)() self.m.VerifyAll() + + def test_missing_fixed_ips(self): + clients.OpenStackClients.keystone().AndReturn( + fakes.FakeKeystoneClient()) + neutronclient.Client.create_port({'port': { + 'network_id': u'net1234', + 'name': utils.PhysName('test_stack', 'port'), + 'admin_state_up': True}} + ).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" + }}) + + self.m.ReplayAll() + + 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)() + self.m.VerifyAll()