nova/nova/virt/vmwareapi/vif.py

133 lines
5.2 KiB
Python

# Copyright (c) 2011 Citrix Systems, Inc.
# Copyright 2011 OpenStack Foundation
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
"""VIF drivers for VMware."""
from oslo_log import log as logging
from oslo_utils import versionutils
from oslo_vmware import vim_util
import nova.conf
from nova import exception
from nova.i18n import _
from nova.network import model
from nova.virt.vmwareapi import constants
from nova.virt.vmwareapi import network_util
from nova.virt.vmwareapi import vm_util
LOG = logging.getLogger(__name__)
CONF = nova.conf.CONF
def _check_ovs_supported_version(session):
# The port type 'ovs' is only support by the VC version 5.5 onwards
min_version = versionutils.convert_version_to_int(
constants.MIN_VC_OVS_VERSION)
vc_version = versionutils.convert_version_to_int(
vim_util.get_vc_version(session))
if vc_version < min_version:
LOG.warning('VMware vCenter version less than %(version)s '
'does not support the \'ovs\' port type.',
{'version': constants.MIN_VC_OVS_VERSION})
def get_network_ref(session, cluster, vif):
if vif['type'] == model.VIF_TYPE_OVS:
_check_ovs_supported_version(session)
# Check if this is the NSX-MH plugin is used
if CONF.vmware.integration_bridge:
net_id = CONF.vmware.integration_bridge
use_external_id = False
network_type = 'opaque'
else:
# The NSX|V3 plugin will pass the nsx-logical-switch-id as part
# of the port details. This will enable the VC to connect to
# that specific opaque network
net_id = (vif.get('details') and
vif['details'].get('nsx-logical-switch-id'))
if not net_id:
# Make use of the original one, in the event that the
# plugin does not pass the aforementioned id
LOG.info('NSX Logical switch ID is not present. '
'Using network ID to attach to the '
'opaque network.')
net_id = vif['network']['id']
use_external_id = True
network_type = 'nsx.LogicalSwitch'
network_ref = {'type': 'OpaqueNetwork',
'network-id': net_id,
'network-type': network_type,
'use-external-id': use_external_id}
elif vif['type'] == model.VIF_TYPE_DVS:
# Port binding for DVS VIF types may pass the name
# of the port group, so use it if present
vif_details = vif.get('details', {})
dvs_uuid = vif_details.get('dvs_id')
dvs_port_group_key = vif_details.get('pg_id')
if dvs_uuid and dvs_port_group_key:
network_ref = {
'type': 'DistributedVirtualPortgroup',
'dvpg': dvs_port_group_key,
'dvsw': dvs_uuid
}
else:
network_id = vif_details.get('dvs_port_group_name')
if network_id is None:
# Make use of the original one, in the event that the
# port binding does not provide this key in VIF details
network_id = vif['network']['bridge']
network_ref = network_util.get_network_with_the_name(
session, network_id, cluster)
if not network_ref:
raise exception.NetworkNotFoundForBridge(bridge=network_id)
if vif_details.get('dvs_port_key'):
network_ref['dvs_port_key'] = vif_details['dvs_port_key']
else:
reason = _('vif type %s not supported') % vif['type']
raise exception.InvalidInput(reason=reason)
return network_ref
def get_vif_dict(session, cluster, vif_model, vif):
mac = vif['address']
name = vif['network']['bridge'] or CONF.vmware.integration_bridge
ref = get_network_ref(session, cluster, vif)
return {'network_name': name,
'mac_address': mac,
'network_ref': ref,
'iface_id': vif['id'],
'vif_model': vif_model}
def get_vif_info(session, cluster, vif_model, network_info):
vif_infos = []
if network_info is None:
return vif_infos
for vif in network_info:
vif_infos.append(get_vif_dict(session, cluster, vif_model, vif))
return vif_infos
def get_network_device(hardware_devices, mac_address):
"""Return the network device with MAC 'mac_address'."""
if hardware_devices.__class__.__name__ == "ArrayOfVirtualDevice":
hardware_devices = hardware_devices.VirtualDevice
for device in hardware_devices:
if device.__class__.__name__ in vm_util.ALL_SUPPORTED_NETWORK_DEVICES:
if hasattr(device, 'macAddress'):
if device.macAddress == mac_address:
return device