Cisco UCS Manager ML2 Mechanism Driver
Introduces a ML2 based Mechanism Driver for Cisco UCS Manager. The vendor specific driver code referenced by this MD resides in stackforge repo networking-cisco. This MD did not exist in the Neutron tree before so no files have to be removed as part of this change. DocImpact Partially-implements: blueprint core-vendor-decomposition Implements: blueprint ml2-ucs-manager-mechanism-driver Closes-Bug: #1434401 Conflicts: etc/neutron/plugins/ml2/ml2_conf_cisco.ini neutron/db/migration/alembic_migrations/versions/HEAD setup.cfg Change-Id: I5a32b18f0d4e3ef55738c51e65e3e81d8f415da4
This commit is contained in:
parent
81ac74359c
commit
c96b4f0f6e
|
@ -207,20 +207,6 @@
|
|||
# cidr_exposed=10.10.40.2/16
|
||||
# gateway_ip=10.10.40.1
|
||||
|
||||
[ml2_cisco_ucsm]
|
||||
|
||||
# Cisco UCS Manager IP address
|
||||
# ucsm_ip=1.1.1.1
|
||||
|
||||
# Username to connect to UCS Manager
|
||||
# ucsm_username=user
|
||||
|
||||
# Password to connect to UCS Manager
|
||||
# ucsm_password=password
|
||||
|
||||
# SR-IOV and VM-FEX vendors supported by this plugin
|
||||
# xxxx:yyyy represents vendor_id:product_id
|
||||
# supported_pci_devs = ['2222:3333', '4444:5555']
|
||||
|
||||
[ml2_cisco_n1kv]
|
||||
|
||||
|
@ -259,3 +245,22 @@
|
|||
# n1kv_vsm_ips = 1.1.1.1,1.1.1.2
|
||||
# username = user
|
||||
# password = password
|
||||
|
||||
[ml2_cisco_ucsm]
|
||||
|
||||
# Cisco UCS Manager IP address
|
||||
# ucsm_ip=1.1.1.1
|
||||
|
||||
# Username to connect to UCS Manager
|
||||
# ucsm_username=user
|
||||
|
||||
# Password to connect to UCS Manager
|
||||
# ucsm_password=password
|
||||
|
||||
# SR-IOV and VM-FEX vendors supported by this plugin
|
||||
# xxxx:yyyy represents vendor_id:product_id
|
||||
# supported_pci_devs = ['2222:3333', '4444:5555']
|
||||
|
||||
# Hostname to Service profile mapping for UCS Manager
|
||||
# controlled compute hosts
|
||||
# ucsm_host_list=Hostname1:Serviceprofile1, Hostname2:Serviceprofile2
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
# Copyright 2015 Cisco Systems, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
"""Cisco UCS Manager Mechanism Driver
|
||||
|
||||
Revision ID: 20b99fd19d4f
|
||||
Revises: 589f9237ca0e
|
||||
Create Date: 2014-07-30 21:01:13.754637
|
||||
|
||||
"""
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = '20b99fd19d4f'
|
||||
down_revision = '589f9237ca0e'
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
def upgrade():
|
||||
op.create_table(
|
||||
'ml2_ucsm_port_profiles',
|
||||
sa.Column('vlan_id', sa.Integer(), nullable=False),
|
||||
sa.Column('profile_id', sa.String(length=64), nullable=False),
|
||||
sa.Column('created_on_ucs', sa.Boolean(), nullable=False),
|
||||
sa.PrimaryKeyConstraint('vlan_id')
|
||||
)
|
|
@ -1 +1 @@
|
|||
589f9237ca0e
|
||||
20b99fd19d4f
|
||||
|
|
|
@ -57,6 +57,7 @@ from neutron.plugins.ml2.drivers.cisco.apic import apic_model # noqa
|
|||
from neutron.plugins.ml2.drivers.cisco.n1kv import n1kv_models # noqa
|
||||
from neutron.plugins.ml2.drivers.cisco.nexus import ( # noqa
|
||||
nexus_models_v2 as ml2_nexus_models_v2)
|
||||
from neutron.plugins.ml2.drivers.cisco.ucsm import ucsm_model # noqa
|
||||
from neutron.plugins.ml2.drivers import type_flat # noqa
|
||||
from neutron.plugins.ml2.drivers import type_gre # noqa
|
||||
from neutron.plugins.ml2.drivers import type_vlan # noqa
|
||||
|
|
|
@ -0,0 +1,218 @@
|
|||
# Copyright 2015 Cisco Systems, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# 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.
|
||||
|
||||
from networking_cisco.plugins.ml2.drivers.cisco.ucsm import constants as const
|
||||
from networking_cisco.plugins.ml2.drivers.cisco.ucsm import ucsm_db
|
||||
from networking_cisco.plugins.ml2.drivers.cisco.ucsm import ucsm_network_driver
|
||||
|
||||
from oslo_log import log as logging
|
||||
|
||||
from neutron.common import constants
|
||||
from neutron.extensions import portbindings
|
||||
from neutron.i18n import _LE, _LW
|
||||
from neutron.plugins.common import constants as p_const
|
||||
from neutron.plugins.ml2 import driver_api as api
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class CiscoUcsmMechanismDriver(api.MechanismDriver):
|
||||
|
||||
"""ML2 Mechanism Driver for Cisco UCS Manager."""
|
||||
|
||||
def initialize(self):
|
||||
self.vif_type = portbindings.VIF_TYPE_802_QBH
|
||||
self.vif_details = {portbindings.CAP_PORT_FILTER: False}
|
||||
self.driver = ucsm_network_driver.CiscoUcsmDriver()
|
||||
self.ucsm_db = ucsm_db.UcsmDbModel()
|
||||
|
||||
def _get_vlanid(self, context):
|
||||
"""Returns vlan_id associated with a bound VLAN segment."""
|
||||
segment = context.bottom_bound_segment
|
||||
if segment and self.check_segment(segment):
|
||||
return segment.get(api.SEGMENTATION_ID)
|
||||
|
||||
def update_port_precommit(self, context):
|
||||
"""Adds port profile and vlan information to the DB.
|
||||
|
||||
Assign a port profile to this port. To do that:
|
||||
1. Get the vlan_id associated with the bound segment
|
||||
2. Check if a port profile already exists for this vlan_id
|
||||
3. If yes, associate that port profile with this port.
|
||||
4. If no, create a new port profile with this vlan_id and
|
||||
associate with this port
|
||||
"""
|
||||
LOG.debug("Inside update_port_precommit")
|
||||
vnic_type = context.current.get(portbindings.VNIC_TYPE,
|
||||
portbindings.VNIC_NORMAL)
|
||||
|
||||
profile = context.current.get(portbindings.PROFILE, {})
|
||||
|
||||
if not self.driver.check_vnic_type_and_vendor_info(vnic_type,
|
||||
profile):
|
||||
LOG.debug("update_port_precommit encountered a non-SR-IOV port")
|
||||
return
|
||||
|
||||
# If this is an Intel SR-IOV vnic, then no need to create port
|
||||
# profile on the UCS manager. So no need to update the DB.
|
||||
if not self.driver.is_vmfex_port(profile):
|
||||
LOG.debug("update_port_precommit has nothing to do for this "
|
||||
"sr-iov port")
|
||||
return
|
||||
|
||||
vlan_id = self._get_vlanid(context)
|
||||
|
||||
if not vlan_id:
|
||||
LOG.warn(_LW("update_port_precommit: vlan_id is None."))
|
||||
return
|
||||
|
||||
p_profile_name = self.make_profile_name(vlan_id)
|
||||
LOG.debug("update_port_precommit: Profile: %s, VLAN_id: %d",
|
||||
p_profile_name, vlan_id)
|
||||
|
||||
# Create a new port profile entry in the db
|
||||
self.ucsm_db.add_port_profile(p_profile_name, vlan_id)
|
||||
|
||||
def update_port_postcommit(self, context):
|
||||
"""Creates a port profile on UCS Manager.
|
||||
|
||||
Creates a Port Profile for this VLAN if it does not already
|
||||
exist.
|
||||
"""
|
||||
LOG.debug("Inside update_port_postcommit")
|
||||
vlan_id = self._get_vlanid(context)
|
||||
|
||||
if not vlan_id:
|
||||
LOG.warn(_LW("update_port_postcommit: vlan_id is None."))
|
||||
return
|
||||
|
||||
# Check if UCS Manager needs to create a Port Profile.
|
||||
# 1. Make sure this is a vm_fex_port.(Port profiles are created
|
||||
# only for VM-FEX ports.)
|
||||
# 2. Make sure update_port_precommit added an entry in the DB
|
||||
# for this port profile
|
||||
# 3. Make sure that the Port Profile hasn't already been created.
|
||||
|
||||
profile = context.current.get(portbindings.PROFILE, {})
|
||||
vnic_type = context.current.get(portbindings.VNIC_TYPE,
|
||||
portbindings.VNIC_NORMAL)
|
||||
|
||||
if (self.driver.check_vnic_type_and_vendor_info(vnic_type, profile) and
|
||||
self.driver.is_vmfex_port(profile)):
|
||||
|
||||
LOG.debug("update_port_postcommit: VM-FEX port updated for "
|
||||
"vlan_id %d", vlan_id)
|
||||
|
||||
profile_name = self.ucsm_db.get_port_profile_for_vlan(vlan_id)
|
||||
if self.ucsm_db.is_port_profile_created(vlan_id):
|
||||
LOG.debug("update_port_postcommit: Port Profile %s for "
|
||||
"vlan_id %d already exists. Nothing to do.",
|
||||
profile_name, vlan_id)
|
||||
return
|
||||
|
||||
# Ask the UCS Manager driver to create the above Port Profile.
|
||||
# Connection to the UCS Manager is managed from within the driver.
|
||||
if self.driver.create_portprofile(profile_name, vlan_id,
|
||||
vnic_type):
|
||||
# Port profile created on UCS, record that in the DB.
|
||||
self.ucsm_db.set_port_profile_created(vlan_id, profile_name)
|
||||
return
|
||||
|
||||
else:
|
||||
# Enable vlan-id for this regular Neutron virtual port.
|
||||
host_id = context.current.get(portbindings.HOST_ID)
|
||||
LOG.debug("update_port_postcommit: Host_id is %s", host_id)
|
||||
self.driver.update_serviceprofile(host_id, vlan_id)
|
||||
|
||||
def delete_network_precommit(self, context):
|
||||
"""Delete entry corresponding to Network's VLAN in the DB."""
|
||||
|
||||
segments = context.network_segments
|
||||
vlan_id = segments[0]['segmentation_id']
|
||||
|
||||
if vlan_id:
|
||||
self.ucsm_db.delete_vlan_entry(vlan_id)
|
||||
|
||||
def delete_network_postcommit(self, context):
|
||||
"""Delete all configuration added to UCS Manager for the vlan_id."""
|
||||
|
||||
segments = context.network_segments
|
||||
vlan_id = segments[0]['segmentation_id']
|
||||
port_profile = self.make_profile_name(vlan_id)
|
||||
|
||||
if vlan_id:
|
||||
self.driver.delete_all_config_for_vlan(vlan_id, port_profile)
|
||||
|
||||
def bind_port(self, context):
|
||||
"""Binds port to current network segment.
|
||||
|
||||
Binds port only if the vnic_type is direct or macvtap and
|
||||
the port is from a supported vendor. While binding port set it
|
||||
in ACTIVE state and provide the Port Profile or Vlan Id as part
|
||||
vif_details.
|
||||
"""
|
||||
vnic_type = context.current.get(portbindings.VNIC_TYPE,
|
||||
portbindings.VNIC_NORMAL)
|
||||
|
||||
LOG.debug("Attempting to bind port %(port)s with vnic_type "
|
||||
"%(vnic_type)s on network %(network)s",
|
||||
{'port': context.current['id'],
|
||||
'vnic_type': vnic_type,
|
||||
'network': context.network.current['id']})
|
||||
|
||||
profile = context.current.get(portbindings.PROFILE, {})
|
||||
|
||||
if not self.driver.check_vnic_type_and_vendor_info(vnic_type,
|
||||
profile):
|
||||
return
|
||||
|
||||
for segment in context.network.network_segments:
|
||||
if self.check_segment(segment):
|
||||
vlan_id = segment[api.SEGMENTATION_ID]
|
||||
|
||||
if not vlan_id:
|
||||
LOG.warn(_LW("Bind port: vlan_id is None."))
|
||||
return
|
||||
|
||||
LOG.debug("Port binding to Vlan_id: %s", str(vlan_id))
|
||||
|
||||
# Check if this is a Cisco VM-FEX port or Intel SR_IOV port
|
||||
if self.driver.is_vmfex_port(profile):
|
||||
profile_name = self.make_profile_name(vlan_id)
|
||||
self.vif_details[
|
||||
const.VIF_DETAILS_PROFILEID] = profile_name
|
||||
else:
|
||||
self.vif_details[
|
||||
portbindings.VIF_DETAILS_VLAN] = str(vlan_id)
|
||||
|
||||
context.set_binding(segment[api.ID],
|
||||
self.vif_type,
|
||||
self.vif_details,
|
||||
constants.PORT_STATUS_ACTIVE)
|
||||
return
|
||||
|
||||
LOG.error(_LE("UCS Mech Driver: Failed binding port ID %(id)s "
|
||||
"on any segment of network %(network)s"),
|
||||
{'id': context.current['id'],
|
||||
'network': context.network.current['id']})
|
||||
|
||||
@staticmethod
|
||||
def check_segment(segment):
|
||||
network_type = segment[api.NETWORK_TYPE]
|
||||
return network_type == p_const.TYPE_VLAN
|
||||
|
||||
@staticmethod
|
||||
def make_profile_name(vlan_id):
|
||||
return const.PORT_PROFILE_NAME_PREFIX + str(vlan_id)
|
|
@ -0,0 +1,29 @@
|
|||
# Copyright 2015 Cisco Systems, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# 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.
|
||||
|
||||
import sqlalchemy as sa
|
||||
|
||||
from neutron.db import model_base
|
||||
|
||||
|
||||
class PortProfile(model_base.BASEV2):
|
||||
|
||||
"""Port profiles created on the UCS Manager."""
|
||||
|
||||
__tablename__ = 'ml2_ucsm_port_profiles'
|
||||
|
||||
vlan_id = sa.Column(sa.Integer(), nullable=False, primary_key=True)
|
||||
profile_id = sa.Column(sa.String(64), nullable=False)
|
||||
created_on_ucs = sa.Column(sa.Boolean(), nullable=False)
|
|
@ -180,6 +180,7 @@ neutron.ml2.mechanism_drivers =
|
|||
cisco_nexus = neutron.plugins.ml2.drivers.cisco.nexus.mech_cisco_nexus:CiscoNexusMechanismDriver
|
||||
cisco_apic = neutron.plugins.ml2.drivers.cisco.apic.mechanism_apic:APICMechanismDriver
|
||||
cisco_n1kv = neutron.plugins.ml2.drivers.cisco.n1kv.mech_cisco_n1kv:N1KVMechanismDriver
|
||||
cisco_ucsm = neutron.plugins.ml2.drivers.cisco.ucsm.mech_cisco_ucsm:CiscoUcsmMechanismDriver
|
||||
l2population = neutron.plugins.ml2.drivers.l2pop.mech_driver:L2populationMechanismDriver
|
||||
bigswitch = neutron.plugins.ml2.drivers.mech_bigswitch.driver:BigSwitchMechanismDriver
|
||||
ofagent = neutron.plugins.ml2.drivers.ofagent.driver:OfagentMechanismDriver
|
||||
|
|
Loading…
Reference in New Issue