Merge "In Arista ML2 driver Reconfigure VLAN on VM migration" into stable/kilo
This commit is contained in:
commit
bef4e48982
|
@ -267,6 +267,22 @@ class AristaDriver(driver_api.MechanismDriver):
|
|||
orig_port = context.original
|
||||
if new_port['name'] != orig_port['name']:
|
||||
LOG.info(_LI('Port name changed to %s'), new_port['name'])
|
||||
new_port = context.current
|
||||
device_id = new_port['device_id']
|
||||
device_owner = new_port['device_owner']
|
||||
host = context.host
|
||||
|
||||
# device_id and device_owner are set on VM boot
|
||||
is_vm_boot = device_id and device_owner
|
||||
if host and host != orig_port['binding:host_id'] and is_vm_boot:
|
||||
port_id = new_port['id']
|
||||
network_id = new_port['network_id']
|
||||
tenant_id = new_port['tenant_id']
|
||||
if not tenant_id:
|
||||
tenant_id = context._plugin_context.tenant_id
|
||||
with self.eos_sync_lock:
|
||||
db_lib.update_vm_host(device_id, host, port_id,
|
||||
network_id, tenant_id)
|
||||
|
||||
def update_port_postcommit(self, context):
|
||||
"""Update the name of a given port in EOS.
|
||||
|
@ -276,9 +292,6 @@ class AristaDriver(driver_api.MechanismDriver):
|
|||
"""
|
||||
port = context.current
|
||||
orig_port = context.original
|
||||
if port['name'] == orig_port['name']:
|
||||
# nothing to do
|
||||
return
|
||||
|
||||
device_id = port['device_id']
|
||||
device_owner = port['device_owner']
|
||||
|
@ -310,6 +323,12 @@ class AristaDriver(driver_api.MechanismDriver):
|
|||
)
|
||||
if vm_provisioned and net_provisioned:
|
||||
try:
|
||||
orig_host = orig_port['binding:host_id']
|
||||
if host != orig_host:
|
||||
# The port moved to a different host. So delete the
|
||||
# old port on the old host before creating a new
|
||||
# port on the new host.
|
||||
self._delete_port(port, orig_host, tenant_id)
|
||||
self.rpc.plug_port_into_network(device_id,
|
||||
hostname,
|
||||
port_id,
|
||||
|
@ -348,30 +367,42 @@ class AristaDriver(driver_api.MechanismDriver):
|
|||
from appropriate network.
|
||||
"""
|
||||
port = context.current
|
||||
device_id = port['device_id']
|
||||
host = context.host
|
||||
port_id = port['id']
|
||||
network_id = port['network_id']
|
||||
tenant_id = port['tenant_id']
|
||||
if not tenant_id:
|
||||
tenant_id = context._plugin_context.tenant_id
|
||||
|
||||
with self.eos_sync_lock:
|
||||
self._delete_port(port, host, tenant_id)
|
||||
|
||||
def _delete_port(self, port, host, tenant_id):
|
||||
"""Deletes the port from EOS.
|
||||
|
||||
param port: Port which is to be deleted
|
||||
param host: The host on which the port existed
|
||||
param tenant_id: The tenant to which the port belongs to. Some times
|
||||
the tenant id in the port dict is not present (as in
|
||||
the case of HA router).
|
||||
"""
|
||||
device_id = port['device_id']
|
||||
port_id = port['id']
|
||||
network_id = port['network_id']
|
||||
device_owner = port['device_owner']
|
||||
|
||||
try:
|
||||
with self.eos_sync_lock:
|
||||
hostname = self._host_name(host)
|
||||
if device_owner == n_const.DEVICE_OWNER_DHCP:
|
||||
self.rpc.unplug_dhcp_port_from_network(device_id,
|
||||
hostname,
|
||||
port_id,
|
||||
network_id,
|
||||
tenant_id)
|
||||
else:
|
||||
self.rpc.unplug_host_from_network(device_id,
|
||||
hostname,
|
||||
port_id,
|
||||
network_id,
|
||||
tenant_id)
|
||||
hostname = self._host_name(host)
|
||||
if device_owner == n_const.DEVICE_OWNER_DHCP:
|
||||
self.rpc.unplug_dhcp_port_from_network(device_id,
|
||||
hostname,
|
||||
port_id,
|
||||
network_id,
|
||||
tenant_id)
|
||||
else:
|
||||
self.rpc.unplug_host_from_network(device_id,
|
||||
hostname,
|
||||
port_id,
|
||||
network_id,
|
||||
tenant_id)
|
||||
# if necessary, delete tenant as well.
|
||||
self.delete_tenant(tenant_id)
|
||||
except arista_exc.AristaRpcError:
|
||||
|
|
|
@ -253,6 +253,84 @@ class AristaDriverTestCase(testlib_api.SqlTestCase):
|
|||
|
||||
mechanism_arista.db_lib.assert_has_calls(expected_calls)
|
||||
|
||||
def test_update_port_precommit(self):
|
||||
tenant_id = 'ten-1'
|
||||
network_id = 'net1-id'
|
||||
segmentation_id = 1001
|
||||
vm_id = 'vm1'
|
||||
|
||||
network_context = self._get_network_context(tenant_id,
|
||||
network_id,
|
||||
segmentation_id,
|
||||
False)
|
||||
|
||||
port_context = self._get_port_context(tenant_id,
|
||||
network_id,
|
||||
vm_id,
|
||||
network_context)
|
||||
host_id = port_context.current['binding:host_id']
|
||||
port_context.original['binding:host_id'] = 'ubuntu0'
|
||||
port_id = port_context.current['id']
|
||||
self.drv.update_port_precommit(port_context)
|
||||
|
||||
expected_calls = [
|
||||
mock.call.update_vm_host(vm_id, host_id, port_id,
|
||||
network_id, tenant_id)
|
||||
]
|
||||
|
||||
mechanism_arista.db_lib.assert_has_calls(expected_calls)
|
||||
|
||||
def test_update_port_postcommit(self):
|
||||
tenant_id = 'ten-1'
|
||||
network_id = 'net1-id'
|
||||
segmentation_id = 1001
|
||||
vm_id = 'vm1'
|
||||
|
||||
network_context = self._get_network_context(tenant_id,
|
||||
network_id,
|
||||
segmentation_id,
|
||||
False)
|
||||
port_context = self._get_port_context(tenant_id,
|
||||
network_id,
|
||||
vm_id,
|
||||
network_context)
|
||||
|
||||
mechanism_arista.db_lib.is_vm_provisioned.return_value = True
|
||||
mechanism_arista.db_lib.is_network_provisioned.return_value = True
|
||||
mechanism_arista.db_lib.get_shared_network_owner_id.return_value = 1
|
||||
mechanism_arista.db_lib.get_segmentation_id.return_value = 1001
|
||||
mechanism_arista.db_lib.num_nets_provisioned.return_value = 1
|
||||
mechanism_arista.db_lib.num_vms_provisioned.return_value = 1
|
||||
|
||||
port = port_context.current
|
||||
device_id = port['device_id']
|
||||
device_owner = port['device_owner']
|
||||
host_id = port['binding:host_id']
|
||||
orig_host_id = 'ubuntu0'
|
||||
port_context.original['binding:host_id'] = orig_host_id
|
||||
port_id = port['id']
|
||||
port_name = port['name']
|
||||
|
||||
self.drv.update_port_postcommit(port_context)
|
||||
|
||||
expected_calls = [
|
||||
mock.call.NeutronNets(),
|
||||
mock.call.get_segmentation_id(tenant_id, network_id),
|
||||
mock.call.is_vm_provisioned(device_id, host_id, port_id,
|
||||
network_id, tenant_id),
|
||||
mock.call.is_network_provisioned(tenant_id, network_id,
|
||||
segmentation_id),
|
||||
mock.call.unplug_host_from_network(device_id, orig_host_id,
|
||||
port_id, network_id, tenant_id),
|
||||
mock.call.num_nets_provisioned(tenant_id),
|
||||
mock.call.num_vms_provisioned(tenant_id),
|
||||
mock.call.plug_port_into_network(device_id, host_id, port_id,
|
||||
network_id, tenant_id,
|
||||
port_name, device_owner)
|
||||
]
|
||||
|
||||
mechanism_arista.db_lib.assert_has_calls(expected_calls)
|
||||
|
||||
def _get_network_context(self, tenant_id, net_id, seg_id, shared):
|
||||
network = {'id': net_id,
|
||||
'tenant_id': tenant_id,
|
||||
|
@ -270,7 +348,7 @@ class AristaDriverTestCase(testlib_api.SqlTestCase):
|
|||
'id': 101,
|
||||
'network_id': net_id
|
||||
}
|
||||
return FakePortContext(port, port, network)
|
||||
return FakePortContext(port, dict(port), network)
|
||||
|
||||
|
||||
class fake_keystone_info_class(object):
|
||||
|
|
Loading…
Reference in New Issue