From 3c6dc97bac5510c9299b540763cc75f7f62ccc2f Mon Sep 17 00:00:00 2001 From: huangtianhua Date: Thu, 14 Jan 2016 15:37:46 +0800 Subject: [PATCH] Don't pass both network_id and port_id when attach interface Nova doesn't allow to specify both network_id and port_id when attach interfaces for server. This change will refactor handler_kwargs for ServerUpdateProgress 'interface_detach'. Change-Id: I74eb115de520d8a66abd1621522f0c605201019a Closes-Bug: #1533570 --- .../openstack/nova/server_network_mixin.py | 33 +++++++++++-------- .../functional/test_nova_server_networks.py | 22 +++++++++++++ 2 files changed, 42 insertions(+), 13 deletions(-) diff --git a/heat/engine/resources/openstack/nova/server_network_mixin.py b/heat/engine/resources/openstack/nova/server_network_mixin.py index 02b9ad3476..76e6ff568e 100644 --- a/heat/engine/resources/openstack/nova/server_network_mixin.py +++ b/heat/engine/resources/openstack/nova/server_network_mixin.py @@ -401,31 +401,38 @@ class ServerNetworkMixin(object): # were mentioned above for idx, net in enumerate(new_nets): handler_kwargs = {'port_id': None, - 'net_id': self._get_network_id(net), + 'net_id': None, 'fip': None} - if handler_kwargs['net_id']: - handler_kwargs['fip'] = net.get('fixed_ip') + if net.get(self.NETWORK_PORT): handler_kwargs['port_id'] = net.get(self.NETWORK_PORT) elif self.is_using_neutron() and net.get(self.NETWORK_SUBNET): handler_kwargs['port_id'] = self._create_internal_port(net, idx) + + if not handler_kwargs['port_id']: + handler_kwargs['net_id'] = self._get_network_id(net) + if handler_kwargs['net_id']: + handler_kwargs['fip'] = net.get('fixed_ip') + floating_ip = net.get(self.NETWORK_FLOATING_IP) - self.update_floating_ip_association(floating_ip, handler_kwargs) + if floating_ip: + flip_associate = {'port_id': handler_kwargs.get('port_id')} + if net.get('fixed_ip'): + flip_associate['fixed_ip_address'] = net.get('fixed_ip') + + self.update_floating_ip_association(floating_ip, + flip_associate) add_nets.append(handler_kwargs) return remove_ports, add_nets - def update_floating_ip_association(self, floating_ip, handler_kwargs): - if floating_ip: - if self.is_using_neutron() and handler_kwargs.get('port_id'): - body = {'port_id': handler_kwargs['port_id']} - if handler_kwargs.get('fip'): - body['fixed_ip_address'] = handler_kwargs['fip'] - self._floating_ip_neutron_associate(floating_ip, body) - elif not self.is_using_neutron(): - self._floating_ip_nova_associate(floating_ip) + def update_floating_ip_association(self, floating_ip, flip_associate): + if self.is_using_neutron() and flip_associate.get('port_id'): + self._floating_ip_neutron_associate(floating_ip, flip_associate) + elif not self.is_using_neutron(): + self._floating_ip_nova_associate(floating_ip) def prepare_ports_for_replace(self): if not self.is_using_neutron(): diff --git a/heat_integrationtests/functional/test_nova_server_networks.py b/heat_integrationtests/functional/test_nova_server_networks.py index 99311d0ff2..ae550b282c 100644 --- a/heat_integrationtests/functional/test_nova_server_networks.py +++ b/heat_integrationtests/functional/test_nova_server_networks.py @@ -64,3 +64,25 @@ class CreateServerTest(functional_base.FunctionalTestsBase): parameters=parms) networks = self.get_outputs(stack_identifier, 'networks') self.assertEqual(['11.11.11.11'], networks['my_net']) + + def test_create_update_server_with_subnet(self): + parms = {'flavor': self.conf.minimal_instance_type, + 'image': self.conf.minimal_image_ref} + template = server_with_sub_fixed_ip_template.replace( + 'fixed_ip: 11.11.11.11', 'fixed_ip: 11.11.11.22') + stack_identifier = self.stack_create( + template=template, + stack_name='create_server_with_sub_ip', + parameters=parms) + networks = self.get_outputs(stack_identifier, 'networks') + self.assertEqual(['11.11.11.22'], networks['my_net']) + + # update the server only with subnet, we won't pass + # both port_id and net_id to attach interface, then update success + template_only_subnet = template.replace( + 'fixed_ip: 11.11.11.22', '') + self.update_stack(stack_identifier, + template_only_subnet, + parameters=parms) + new_networks = self.get_outputs(stack_identifier, 'networks') + self.assertNotEqual(['11.11.11.22'], new_networks['my_net'])