Don't update existing port if no change
This allows external service pre-create a neutron port with 'binding:host_id' populated before passing the port to kuryr. This is important because setting 'binding:host_id' is slow. This blocks the docker daemon for serving other requests, which blocks the whole system. We want to have this field pre-populated so that the docker daemon won't be blocked by this API call. This commit also allows the 'device_owner' field to be customized if users choose to pre-populate the 'binding:host_id' field. In addition, this commit skips the API call to update the neutron port if the 'binding:host_id' is pre-populated and 'admin_state_up' and 'mac_address' fields are unchanged. Closes-Bug: #1809306 Change-Id: I09c4a51410dffaec21ab0bb3db85df8c776c92e5
This commit is contained in:
parent
a9a70b3178
commit
5fb8275d12
|
@ -129,26 +129,29 @@ class Driver(object):
|
|||
python-neutronclient
|
||||
"""
|
||||
try:
|
||||
updated_port = {
|
||||
'device_owner': lib_const.DEVICE_OWNER,
|
||||
'binding:host_id': lib_utils.get_hostname(),
|
||||
'admin_state_up': True,
|
||||
}
|
||||
updated_port = {}
|
||||
hostname = lib_utils.get_hostname()
|
||||
if port['binding:host_id'] != hostname:
|
||||
updated_port['binding:host_id'] = hostname
|
||||
updated_port['device_owner'] = lib_const.DEVICE_OWNER
|
||||
if port['admin_state_up'] is not True:
|
||||
updated_port['admin_state_up'] = True
|
||||
if not tags:
|
||||
# rename the port if tagging is not supported
|
||||
updated_port['name'] = libnet_utils.get_neutron_port_name(
|
||||
endpoint_id)
|
||||
if not port.get('device_id'):
|
||||
updated_port['device_id'] = endpoint_id
|
||||
if interface_mac:
|
||||
if interface_mac and port['mac_address'] != interface_mac:
|
||||
updated_port['mac_address'] = interface_mac
|
||||
response_port = app.neutron.update_port(port['id'],
|
||||
{'port': updated_port})
|
||||
if updated_port:
|
||||
port = app.neutron.update_port(port['id'],
|
||||
{'port': updated_port})['port']
|
||||
except n_exceptions.NeutronClientException as ex:
|
||||
LOG.error("Error happened during updating a "
|
||||
"Neutron port: %s", ex)
|
||||
raise
|
||||
return response_port['port']
|
||||
return port
|
||||
|
||||
def __str__(self):
|
||||
return self.__class__.__name__
|
||||
|
|
|
@ -172,7 +172,9 @@ class TestKuryrBase(TestCase):
|
|||
neutron_trunk_id=None,
|
||||
tags=None,
|
||||
name=None,
|
||||
binding_profile=None):
|
||||
binding_profile=None,
|
||||
binding_host=None,
|
||||
admin_state_up=True):
|
||||
# The following fake response is retrieved from the Neutron doc:
|
||||
# http://developer.openstack.org/api-ref-networking-v2.html#createPort # noqa
|
||||
if not name:
|
||||
|
@ -182,7 +184,7 @@ class TestKuryrBase(TestCase):
|
|||
"status": neutron_port_status,
|
||||
"name": name,
|
||||
"allowed_address_pairs": [],
|
||||
"admin_state_up": True,
|
||||
"admin_state_up": admin_state_up,
|
||||
"network_id": neutron_network_id,
|
||||
"tenant_id": "d6700c0c9ffa4f1cb322cd4a1f3906fa",
|
||||
"device_owner": device_owner,
|
||||
|
@ -198,6 +200,9 @@ class TestKuryrBase(TestCase):
|
|||
if binding_profile is not None:
|
||||
fake_port['port']['binding:profile'] = binding_profile
|
||||
|
||||
if binding_host is not None:
|
||||
fake_port['port']['binding:host_id'] = binding_host
|
||||
|
||||
if neutron_subnet_v4_id:
|
||||
fake_port['port']['fixed_ips'].append({
|
||||
"subnet_id": neutron_subnet_v4_id,
|
||||
|
|
|
@ -100,7 +100,8 @@ class TestVethDriver(base.TestKuryrBase):
|
|||
fake_neutron_port_id, lib_const.PORT_STATUS_ACTIVE,
|
||||
fake_neutron_v4_subnet_id, fake_neutron_v6_subnet_id,
|
||||
'192.168.1.3', 'fe80::f816:3eff:fe1c:36a9',
|
||||
fake_mac_address1)['port']
|
||||
fake_mac_address1,
|
||||
admin_state_up=False, binding_host='')['port']
|
||||
fake_port_name = '-'.join([fake_endpoint_id, lib_utils.PORT_POSTFIX])
|
||||
mock_get_port_name.return_value = fake_port_name
|
||||
|
||||
|
@ -133,7 +134,8 @@ class TestVethDriver(base.TestKuryrBase):
|
|||
fake_endpoint_id, fake_neutron_net_id,
|
||||
fake_neutron_port_id, lib_const.PORT_STATUS_ACTIVE,
|
||||
fake_neutron_v4_subnet_id, fake_neutron_v6_subnet_id,
|
||||
'192.168.1.3', 'fe80::f816:3eff:fe1c:36a9')['port']
|
||||
'192.168.1.3', 'fe80::f816:3eff:fe1c:36a9',
|
||||
admin_state_up=False, binding_host='')['port']
|
||||
fake_port_name = '-'.join([fake_endpoint_id, lib_utils.PORT_POSTFIX])
|
||||
mock_get_port_name.return_value = fake_port_name
|
||||
|
||||
|
@ -167,7 +169,8 @@ class TestVethDriver(base.TestKuryrBase):
|
|||
fake_neutron_port_id, lib_const.PORT_STATUS_ACTIVE,
|
||||
fake_neutron_v4_subnet_id, fake_neutron_v6_subnet_id,
|
||||
'192.168.1.3', 'fe80::f816:3eff:fe1c:36a9',
|
||||
fake_mac_address1)['port']
|
||||
fake_mac_address1,
|
||||
admin_state_up=False, binding_host='')['port']
|
||||
fake_neutron_port.pop('device_id')
|
||||
fake_port_name = '-'.join([fake_endpoint_id, lib_utils.PORT_POSTFIX])
|
||||
mock_get_port_name.return_value = fake_port_name
|
||||
|
@ -188,3 +191,27 @@ class TestVethDriver(base.TestKuryrBase):
|
|||
}
|
||||
mock_update_port.assert_called_with(fake_neutron_port_id,
|
||||
expected_update_port)
|
||||
|
||||
@mock.patch('kuryr_libnetwork.app.neutron.update_port')
|
||||
@mock.patch.object(libnet_utils, 'get_neutron_port_name')
|
||||
def test_update_port_with_no_changes(self, mock_get_port_name,
|
||||
mock_update_port):
|
||||
fake_endpoint_id = lib_utils.get_hash()
|
||||
fake_neutron_port_id = uuidutils.generate_uuid()
|
||||
fake_neutron_net_id = uuidutils.generate_uuid()
|
||||
fake_neutron_v4_subnet_id = uuidutils.generate_uuid()
|
||||
fake_neutron_v6_subnet_id = uuidutils.generate_uuid()
|
||||
fake_neutron_port = self._get_fake_port(
|
||||
fake_endpoint_id, fake_neutron_net_id,
|
||||
fake_neutron_port_id, lib_const.PORT_STATUS_ACTIVE,
|
||||
fake_neutron_v4_subnet_id, fake_neutron_v6_subnet_id,
|
||||
'192.168.1.3', 'fe80::f816:3eff:fe1c:36a9',
|
||||
binding_host=lib_utils.get_hostname())['port']
|
||||
fake_port_name = '-'.join([fake_endpoint_id, lib_utils.PORT_POSTFIX])
|
||||
mock_get_port_name.return_value = fake_port_name
|
||||
|
||||
veth_driver = veth.VethDriver()
|
||||
veth_driver.update_port(fake_neutron_port, fake_endpoint_id, '')
|
||||
|
||||
mock_get_port_name.assert_called_with(fake_endpoint_id)
|
||||
mock_update_port.assert_not_called()
|
||||
|
|
|
@ -270,7 +270,8 @@ class TestVlanDriver(base.TestKuryrBase):
|
|||
fake_neutron_port_id, lib_const.PORT_STATUS_ACTIVE,
|
||||
fake_neutron_v4_subnet_id, fake_neutron_v6_subnet_id,
|
||||
'192.168.1.3', 'fe80::f816:3eff:fe1c:36a9',
|
||||
fake_neutron_mac_address1)['port']
|
||||
fake_neutron_mac_address1,
|
||||
binding_host='', admin_state_up=False)['port']
|
||||
fake_vm_port = self._get_fake_port(
|
||||
fake_endpoint_id, fake_neutron_net_id,
|
||||
fake_vm_port_id, lib_const.PORT_STATUS_ACTIVE,
|
||||
|
|
Loading…
Reference in New Issue