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
|
python-neutronclient
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
updated_port = {
|
updated_port = {}
|
||||||
'device_owner': lib_const.DEVICE_OWNER,
|
hostname = lib_utils.get_hostname()
|
||||||
'binding:host_id': lib_utils.get_hostname(),
|
if port['binding:host_id'] != hostname:
|
||||||
'admin_state_up': True,
|
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:
|
if not tags:
|
||||||
# rename the port if tagging is not supported
|
# rename the port if tagging is not supported
|
||||||
updated_port['name'] = libnet_utils.get_neutron_port_name(
|
updated_port['name'] = libnet_utils.get_neutron_port_name(
|
||||||
endpoint_id)
|
endpoint_id)
|
||||||
if not port.get('device_id'):
|
if not port.get('device_id'):
|
||||||
updated_port['device_id'] = endpoint_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
|
updated_port['mac_address'] = interface_mac
|
||||||
response_port = app.neutron.update_port(port['id'],
|
if updated_port:
|
||||||
{'port': updated_port})
|
port = app.neutron.update_port(port['id'],
|
||||||
|
{'port': updated_port})['port']
|
||||||
except n_exceptions.NeutronClientException as ex:
|
except n_exceptions.NeutronClientException as ex:
|
||||||
LOG.error("Error happened during updating a "
|
LOG.error("Error happened during updating a "
|
||||||
"Neutron port: %s", ex)
|
"Neutron port: %s", ex)
|
||||||
raise
|
raise
|
||||||
return response_port['port']
|
return port
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.__class__.__name__
|
return self.__class__.__name__
|
||||||
|
|
|
@ -172,7 +172,9 @@ class TestKuryrBase(TestCase):
|
||||||
neutron_trunk_id=None,
|
neutron_trunk_id=None,
|
||||||
tags=None,
|
tags=None,
|
||||||
name=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:
|
# The following fake response is retrieved from the Neutron doc:
|
||||||
# http://developer.openstack.org/api-ref-networking-v2.html#createPort # noqa
|
# http://developer.openstack.org/api-ref-networking-v2.html#createPort # noqa
|
||||||
if not name:
|
if not name:
|
||||||
|
@ -182,7 +184,7 @@ class TestKuryrBase(TestCase):
|
||||||
"status": neutron_port_status,
|
"status": neutron_port_status,
|
||||||
"name": name,
|
"name": name,
|
||||||
"allowed_address_pairs": [],
|
"allowed_address_pairs": [],
|
||||||
"admin_state_up": True,
|
"admin_state_up": admin_state_up,
|
||||||
"network_id": neutron_network_id,
|
"network_id": neutron_network_id,
|
||||||
"tenant_id": "d6700c0c9ffa4f1cb322cd4a1f3906fa",
|
"tenant_id": "d6700c0c9ffa4f1cb322cd4a1f3906fa",
|
||||||
"device_owner": device_owner,
|
"device_owner": device_owner,
|
||||||
|
@ -198,6 +200,9 @@ class TestKuryrBase(TestCase):
|
||||||
if binding_profile is not None:
|
if binding_profile is not None:
|
||||||
fake_port['port']['binding:profile'] = binding_profile
|
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:
|
if neutron_subnet_v4_id:
|
||||||
fake_port['port']['fixed_ips'].append({
|
fake_port['port']['fixed_ips'].append({
|
||||||
"subnet_id": neutron_subnet_v4_id,
|
"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_port_id, lib_const.PORT_STATUS_ACTIVE,
|
||||||
fake_neutron_v4_subnet_id, fake_neutron_v6_subnet_id,
|
fake_neutron_v4_subnet_id, fake_neutron_v6_subnet_id,
|
||||||
'192.168.1.3', 'fe80::f816:3eff:fe1c:36a9',
|
'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])
|
fake_port_name = '-'.join([fake_endpoint_id, lib_utils.PORT_POSTFIX])
|
||||||
mock_get_port_name.return_value = fake_port_name
|
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_endpoint_id, fake_neutron_net_id,
|
||||||
fake_neutron_port_id, lib_const.PORT_STATUS_ACTIVE,
|
fake_neutron_port_id, lib_const.PORT_STATUS_ACTIVE,
|
||||||
fake_neutron_v4_subnet_id, fake_neutron_v6_subnet_id,
|
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])
|
fake_port_name = '-'.join([fake_endpoint_id, lib_utils.PORT_POSTFIX])
|
||||||
mock_get_port_name.return_value = fake_port_name
|
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_port_id, lib_const.PORT_STATUS_ACTIVE,
|
||||||
fake_neutron_v4_subnet_id, fake_neutron_v6_subnet_id,
|
fake_neutron_v4_subnet_id, fake_neutron_v6_subnet_id,
|
||||||
'192.168.1.3', 'fe80::f816:3eff:fe1c:36a9',
|
'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_neutron_port.pop('device_id')
|
||||||
fake_port_name = '-'.join([fake_endpoint_id, lib_utils.PORT_POSTFIX])
|
fake_port_name = '-'.join([fake_endpoint_id, lib_utils.PORT_POSTFIX])
|
||||||
mock_get_port_name.return_value = fake_port_name
|
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,
|
mock_update_port.assert_called_with(fake_neutron_port_id,
|
||||||
expected_update_port)
|
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_port_id, lib_const.PORT_STATUS_ACTIVE,
|
||||||
fake_neutron_v4_subnet_id, fake_neutron_v6_subnet_id,
|
fake_neutron_v4_subnet_id, fake_neutron_v6_subnet_id,
|
||||||
'192.168.1.3', 'fe80::f816:3eff:fe1c:36a9',
|
'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_vm_port = self._get_fake_port(
|
||||||
fake_endpoint_id, fake_neutron_net_id,
|
fake_endpoint_id, fake_neutron_net_id,
|
||||||
fake_vm_port_id, lib_const.PORT_STATUS_ACTIVE,
|
fake_vm_port_id, lib_const.PORT_STATUS_ACTIVE,
|
||||||
|
|
Loading…
Reference in New Issue