Merge "In Arista ML2 driver Reconfigure VLAN on VM migration" into stable/kilo

This commit is contained in:
Jenkins 2015-07-13 17:09:01 +00:00 committed by Gerrit Code Review
commit bef4e48982
2 changed files with 130 additions and 21 deletions

View File

@ -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:

View File

@ -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):