diff --git a/heat/engine/resources/openstack/neutron/port.py b/heat/engine/resources/openstack/neutron/port.py index 3103c28752..78af5a8321 100644 --- a/heat/engine/resources/openstack/neutron/port.py +++ b/heat/engine/resources/openstack/neutron/port.py @@ -222,10 +222,12 @@ class Port(neutron.NeutronResource): ), MAC_ADDRESS: properties.Schema( properties.Schema.STRING, - _('MAC address to give to this port.'), + _('MAC address to give to this port. The default update policy ' + 'of this property in neutron is that allow admin role only.'), constraints=[ constraints.CustomConstraint('mac_addr') - ] + ], + update_allowed=True, ), ALLOWED_ADDRESS_PAIRS: properties.Schema( properties.Schema.LIST, diff --git a/heat_integrationtests/functional/test_create_update_neutron_port.py b/heat_integrationtests/functional/test_create_update_neutron_port.py index 2109012011..4e41b359e4 100644 --- a/heat_integrationtests/functional/test_create_update_neutron_port.py +++ b/heat_integrationtests/functional/test_create_update_neutron_port.py @@ -46,117 +46,53 @@ resources: outputs: port_ip: value: {get_attr: [port, fixed_ips, 0, ip_address]} + mac_address: + value: {get_attr: [port, mac_address]} ''' class UpdatePortTest(functional_base.FunctionalTestsBase): - def get_port_id_and_ip(self, stack_identifier): + def get_port_id_and_outputs(self, stack_identifier): resources = self.client.resources.list(stack_identifier) port_id = [res.physical_resource_id for res in resources if res.resource_name == 'port'] stack = self.client.stacks.get(stack_identifier) port_ip = self._stack_output(stack, 'port_ip') - return port_id[0], port_ip + port_mac = self._stack_output(stack, 'mac_address') + return port_id[0], port_ip, port_mac - def test_stack_update_replace_no_ip(self): - templ_no_ip = test_template.replace('ip_address: 11.11.11.11', '') - # create with default 'mac' parameter - stack_identifier = self.stack_create(template=templ_no_ip) - _id, _ip = self.get_port_id_and_ip(stack_identifier) - - # Update with another 'mac' parameter - parameters = {'mac': '00-00-00-00-AA-AA'} - self.update_stack(stack_identifier, templ_no_ip, - parameters=parameters) - - new_id, _ = self.get_port_id_and_ip(stack_identifier) - # port id should be different - self.assertNotEqual(_id, new_id) - - def test_stack_update_replace_with_ip(self): - # create with default 'mac' parameter + def test_update_remove_ip(self): + # create with defined ip_address stack_identifier = self.stack_create(template=test_template) - - _id, _ip = self.get_port_id_and_ip(stack_identifier) - - # Update with another 'mac' parameter - parameters = {'mac': '00-00-00-00-AA-AA'} - - # port should be replaced with same ip - self.update_stack(stack_identifier, test_template, - parameters=parameters) - - new_id, new_ip = self.get_port_id_and_ip(stack_identifier) - # port id should be different, ip should be the same - self.assertEqual(_ip, new_ip) - self.assertNotEqual(_id, new_id) - - def test_stack_update_replace_with_ip_rollback(self): - # create with default 'mac' parameter - stack_identifier = self.stack_create(template=test_template) - - _id, _ip = self.get_port_id_and_ip(stack_identifier) - - # Update with another 'mac' parameter - parameters = {'mac': '00-00-00-00-AA-AA'} - - # make test resource failing during update - fail_template = test_template.replace('fail: False', - 'fail: True') - fail_template = fail_template.replace('value: Test1', - 'value: Rollback') - - # port should be replaced with same ip - self.update_stack(stack_identifier, fail_template, - parameters=parameters, - expected_status='ROLLBACK_COMPLETE', - disable_rollback=False) - - new_id, new_ip = self.get_port_id_and_ip(stack_identifier) - # port id and ip should be the same after rollback - self.assertEqual(_ip, new_ip) - self.assertEqual(_id, new_id) - - def test_stack_update_replace_with_ip_after_failed_update(self): - # create with default 'mac' parameter - stack_identifier = self.stack_create(template=test_template) - - _id, _ip = self.get_port_id_and_ip(stack_identifier) - - # Update with another 'mac' parameter - parameters = {'mac': '00-00-00-00-AA-AA'} - - # make test resource failing during update - fail_template = test_template.replace('fail: False', - 'fail: True') - fail_template = fail_template.replace('value: Test1', - 'value: Rollback') - - # port should be replaced with same ip - self.update_stack(stack_identifier, fail_template, - parameters=parameters, - expected_status='UPDATE_FAILED') - - # port should be replaced with same ip - self.update_stack(stack_identifier, test_template, - parameters=parameters) - - new_id, new_ip = self.get_port_id_and_ip(stack_identifier) - # ip should be the same, but port id should be different, because it's - # restore replace - self.assertEqual(_ip, new_ip) - self.assertNotEqual(_id, new_id) - - def test_stack_update_in_place_remove_ip(self): - # create with default 'mac' parameter and defined ip_address - stack_identifier = self.stack_create(template=test_template) - _id, _ip = self.get_port_id_and_ip(stack_identifier) + _id, _ip, _mac = self.get_port_id_and_outputs(stack_identifier) # remove ip_address property and update stack templ_no_ip = test_template.replace('ip_address: 11.11.11.11', '') self.update_stack(stack_identifier, templ_no_ip) - new_id, new_ip = self.get_port_id_and_ip(stack_identifier) + new_id, new_ip, new_mac = self.get_port_id_and_outputs( + stack_identifier) # port should be updated with the same id self.assertEqual(_id, new_id) + self.assertEqual(_mac, new_mac) + + def test_update_with_mac_address(self): + # Setup admin clients for updating mac_address + self.setup_clients_for_admin() + + # Create with default mac_address and defined ip_address + stack_identifier = self.stack_create(template=test_template) + _id, _ip, _mac = self.get_port_id_and_outputs(stack_identifier) + + # Update with another 'mac' parameter + parameters = {'mac': '00-00-00-00-AA-AA'} + self.update_stack(stack_identifier, test_template, + parameters=parameters) + + new_id, new_ip, new_mac = self.get_port_id_and_outputs( + stack_identifier) + # mac_address should be different + self.assertEqual(_id, new_id) + self.assertEqual(_ip, new_ip) + self.assertNotEqual(_mac, new_mac)