Cisco plugin cleanup follow up commit

A commit was made by Alex Xu (https://review.openstack.org/#/c/20073) a day before the Cisco plugin
cleanup that led to some deleted files creeping back into the Cisco plugin. This commit backs out
the deleted files again.

Blueprint cisco-plugin-cleanup

Change-Id: Ibad452dc0497dad452a33d6f41c1785231cd5d5b
This commit is contained in:
Arvind Somya 2013-02-05 17:22:50 -05:00
parent 5c82b75576
commit 00ff102b21
7 changed files with 0 additions and 2059 deletions

View File

@ -1,74 +0,0 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2011, Cisco Systems, Inc.
#
# 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.
#
# @author: Edgar Magana, Cisco Systems, Inc.
import logging as LOG
from sqlalchemy.orm import exc
import quantum.plugins.cisco.db.api as db
from quantum.plugins.cisco.db import services_models
def get_all_services_bindings():
"""Lists all the services bindings"""
LOG.debug(_("get_all_services_bindings() called"))
session = db.get_session()
try:
bindings = session.query(services_models.ServicesBinding).all()
return bindings
except exc.NoResultFound:
return []
def get_service_bindings(service_id):
"""Lists services bindings for a service_id"""
LOG.debug(_("get_service_bindings() called"))
session = db.get_session()
try:
bindings = (session.query(services_models.ServicesBinding).
filter_by(service_id=service_id).one())
return bindings
except exc.NoResultFound:
return []
def add_services_binding(service_id, mngnet_id, nbnet_id, sbnet_id):
"""Adds a services binding"""
LOG.debug(_("add_services_binding() called"))
session = db.get_session()
binding = services_models.ServicesBinding(service_id, mngnet_id,
nbnet_id, sbnet_id)
session.add(binding)
session.flush()
return binding
def remove_services_binding(service_id):
"""Removes a services binding"""
LOG.debug(_("remove_services_binding() called"))
session = db.get_session()
try:
binding = (session.query(services_models.ServicesBinding).
filter_by(service_id=service_id).all())
for bind in binding:
session.delete(bind)
session.flush()
return binding
except exc.NoResultFound:
pass

View File

@ -1,155 +0,0 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2012, Cisco Systems, Inc.
#
# 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.
# @author: Rohit Agarwalla, Cisco Systems, Inc.
import logging as LOG
from sqlalchemy.orm import exc
from quantum.db import api as db
from quantum.plugins.cisco.common import cisco_exceptions as c_exc
from quantum.plugins.cisco.db import ucs_models_v2 as ucs_models
def get_all_portbindings():
"""Lists all the port bindings"""
LOG.debug(_("DB get_all_portbindings() called"))
session = db.get_session()
try:
port_bindings = session.query(ucs_models.PortBinding).all()
return port_bindings
except exc.NoResultFound:
return []
def get_portbinding(port_id):
"""Lists a port binding"""
LOG.debug(_("get_portbinding() called"))
session = db.get_session()
try:
port_binding = (session.query(ucs_models.PortBinding).
filter_by(port_id=port_id).one())
return port_binding
except exc.NoResultFound:
raise c_exc.PortVnicNotFound(port_id=port_id)
def add_portbinding(port_id, blade_intf_dn, portprofile_name,
vlan_name, vlan_id, qos):
"""Adds a port binding"""
LOG.debug(_("add_portbinding() called"))
session = db.get_session()
try:
port_binding = (session.query(ucs_models.PortBinding).
filter_by(port_id=port_id).one())
raise c_exc.PortVnicBindingAlreadyExists(port_id=port_id)
except exc.NoResultFound:
port_binding = ucs_models.PortBinding(port_id, blade_intf_dn,
portprofile_name, vlan_name,
vlan_id, qos)
session.add(port_binding)
session.flush()
return port_binding
def remove_portbinding(port_id):
"""Removes a port binding"""
LOG.debug(_("DB remove_portbinding() called"))
session = db.get_session()
try:
port_binding = (session.query(ucs_models.PortBinding).
filter_by(port_id=port_id).one())
session.delete(port_binding)
session.flush()
return port_binding
except exc.NoResultFound:
pass
def update_portbinding(port_id, blade_intf_dn=None, portprofile_name=None,
vlan_name=None, vlan_id=None, qos=None,
tenant_id=None, instance_id=None,
vif_id=None):
"""Updates port binding"""
LOG.debug(_("DB update_portbinding() called"))
session = db.get_session()
try:
port_binding = (session.query(ucs_models.PortBinding).
filter_by(port_id=port_id).one())
if blade_intf_dn:
port_binding.blade_intf_dn = blade_intf_dn
if portprofile_name:
port_binding.portprofile_name = portprofile_name
if vlan_name:
port_binding.vlan_name = vlan_name
if vlan_name:
port_binding.vlan_id = vlan_id
if qos:
port_binding.qos = qos
if tenant_id:
port_binding.tenant_id = tenant_id
if instance_id:
port_binding.instance_id = instance_id
if vif_id:
port_binding.vif_id = vif_id
session.merge(port_binding)
session.flush()
return port_binding
except exc.NoResultFound:
raise c_exc.PortVnicNotFound(port_id=port_id)
def update_portbinding_instance_id(port_id, instance_id):
"""Updates port binding for the instance ID"""
LOG.debug(_("DB update_portbinding_instance_id() called"))
session = db.get_session()
try:
port_binding = (session.query(ucs_models.PortBinding).
filter_by(port_id=port_id).one())
port_binding.instance_id = instance_id
session.merge(port_binding)
session.flush()
return port_binding
except exc.NoResultFound:
raise c_exc.PortVnicNotFound(port_id=port_id)
def update_portbinding_vif_id(port_id, vif_id):
"""Updates port binding for the VIF ID"""
LOG.debug(_("DB update_portbinding_vif_id() called"))
session = db.get_session()
try:
port_binding = (session.query(ucs_models.PortBinding).
filter_by(port_id=port_id).one())
port_binding.vif_id = vif_id
session.merge(port_binding)
session.flush()
return port_binding
except exc.NoResultFound:
raise c_exc.PortVnicNotFound(port_id=port_id)
def get_portbinding_dn(blade_intf_dn):
"""Lists a port binding"""
LOG.debug(_("get_portbinding_dn() called"))
session = db.get_session()
try:
port_binding = (session.query(ucs_models.PortBinding).
filter_by(blade_intf_dn=blade_intf_dn).one())
return port_binding
except exc.NoResultFound:
return []

View File

@ -1,314 +0,0 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2012 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.
#
# @author: Sumit Naiksatam, Cisco Systems, Inc.
#
from copy import deepcopy
import inspect
import logging
from quantum.openstack.common import importutils
from quantum.plugins.cisco.common import cisco_constants as const
from quantum.plugins.cisco.common import cisco_credentials_v2 as cred
from quantum.plugins.cisco.db import network_db_v2 as cdb
from quantum.plugins.cisco import l2network_plugin_configuration as conf
from quantum import quantum_plugin_base_v2
LOG = logging.getLogger(__name__)
class NetworkMultiBladeV2(quantum_plugin_base_v2.QuantumPluginBaseV2):
"""
This implementation works with UCS and Nexus plugin for the
following topology:
One or more UCSM (each with one or more chasses connected),
All FICs connected to a single Nexus Switch.
"""
_plugins = {}
_inventory = {}
def __init__(self):
"""
Initialize the segmentation manager, check which device plugins are
configured, and load the inventories those device plugins for which the
inventory is configured
"""
cdb.initialize()
cred.Store.initialize()
self._vlan_mgr = importutils.import_object(conf.MANAGER_CLASS)
for key in conf.PLUGINS[const.PLUGINS].keys():
plugin_obj = conf.PLUGINS[const.PLUGINS][key]
self._plugins[key] = importutils.import_object(plugin_obj)
LOG.debug(_("Loaded device plugin %s"),
conf.PLUGINS[const.PLUGINS][key])
if key in conf.PLUGINS[const.INVENTORY].keys():
inventory_obj = conf.PLUGINS[const.INVENTORY][key]
self._inventory[key] = importutils.import_object(inventory_obj)
LOG.debug(_("Loaded device inventory %s"),
conf.PLUGINS[const.INVENTORY][key])
LOG.debug(_("%(module)s.%(name)s init done"),
{'module': __name__,
'name': self.__class__.__name__})
def _func_name(self, offset=0):
"""Get the name of the calling function"""
return inspect.stack()[1 + offset][3]
def _invoke_plugin_per_device(self, plugin_key, function_name, args):
"""
Invokes a device plugin's relevant functions (on the it's
inventory and plugin implementation) for completing this operation.
"""
if plugin_key not in self._plugins:
LOG.info(_("No %s Plugin loaded"), plugin_key)
LOG.info(_("%(plugin_key)s: %(function_name)s with args %(args)s "
"ignored"), locals())
return
device_params = self._invoke_inventory(plugin_key, function_name,
args)
device_ips = device_params[const.DEVICE_IP]
if not device_ips:
return [self._invoke_plugin(plugin_key, function_name, args,
device_params)]
else:
output = []
for device_ip in device_ips:
new_device_params = deepcopy(device_params)
new_device_params[const.DEVICE_IP] = device_ip
output.append(self._invoke_plugin(plugin_key, function_name,
args, new_device_params))
return output
def _invoke_inventory(self, plugin_key, function_name, args):
"""
Invokes the relevant function on a device plugin's
inventory for completing this operation.
"""
if plugin_key not in self._inventory:
LOG.info(_("No %s inventory loaded"), plugin_key)
LOG.info(_("%(plugin_key)s: %(function_name)s with args %(args)s "
"ignored"), locals())
return {const.DEVICE_IP: []}
else:
return getattr(self._inventory[plugin_key], function_name)(args)
def _invoke_plugin(self, plugin_key, function_name, args, kwargs):
"""
Invokes the relevant function on a device plugin's
implementation for completing this operation.
"""
func = getattr(self._plugins[plugin_key], function_name)
func_args_len = int(inspect.getargspec(func).args.__len__()) - 1
if args.__len__() > func_args_len:
func_args = args[:func_args_len]
extra_args = args[func_args_len:]
for dict_arg in extra_args:
for k, v in dict_arg.iteritems():
kwargs[k] = v
return func(*func_args, **kwargs)
else:
return func(*args, **kwargs)
def create_network(self, context, network):
"""
Perform this operation in the context of the configured device
plugins.
"""
n = network
try:
vlan_id = self._vlan_mgr.reserve_segmentation_id(n['tenant_id'],
n['name'])
vlan_name = self._vlan_mgr.get_vlan_name(n['id'], str(vlan_id))
args = [n['tenant_id'], n['name'], n['id'], vlan_name, vlan_id]
output = []
ucs_output = self._invoke_plugin_per_device(const.UCS_PLUGIN,
self._func_name(),
args)
nexus_output = self._invoke_plugin_per_device(const.NEXUS_PLUGIN,
self._func_name(),
args)
output.extend(ucs_output or [])
output.extend(nexus_output or [])
cdb.add_vlan_binding(vlan_id, vlan_name, n['id'])
return output
except:
# TODO (Sumit): Check if we need to perform any rollback here
raise
def get_network(self, context, id, fields=None):
"""Currently there is no processing required for the device plugins"""
pass
def get_networks(self, context, filters=None, fields=None):
"""Currently there is no processing required for the device plugins"""
pass
def update_network(self, context, id, network):
"""
Perform this operation in the context of the configured device
plugins.
"""
n = network
vlan = cdb.get_vlan_binding(id)
args = [n['tenant_id'], id, {'vlan_id': vlan.vlan_id},
{'net_admin_state': n['admin_state_up']},
{'vlan_ids': ''}]
nexus_output = self._invoke_plugin_per_device(const.NEXUS_PLUGIN,
self._func_name(),
args)
return nexus_output
def delete_network(self, context, id, kwargs):
"""
Perform this operation in the context of the configured device
plugins.
"""
try:
base_plugin_ref = kwargs[const.BASE_PLUGIN_REF]
n = kwargs[const.NETWORK]
tenant_id = n['tenant_id']
args = [tenant_id, id, {const.CONTEXT: context},
{const.BASE_PLUGIN_REF: base_plugin_ref}]
# TODO (Sumit): Might first need to check here if there are active
# ports
output = []
ucs_output = self._invoke_plugin_per_device(const.UCS_PLUGIN,
self._func_name(),
args)
nexus_output = self._invoke_plugin_per_device(const.NEXUS_PLUGIN,
self._func_name(),
args)
output.extend(ucs_output or [])
output.extend(nexus_output or [])
self._vlan_mgr.release_segmentation_id(tenant_id, id)
cdb.remove_vlan_binding(id)
return output
except:
# TODO (Sumit): Check if we need to perform any rollback here
raise
def create_port(self, context, port):
"""
Perform this operation in the context of the configured device
plugins.
"""
try:
tenant_id = port['tenant_id']
net_id = port['network_id']
port_state = port['admin_state_up']
port_id_string = port['id']
args = [tenant_id, net_id, port_state, port_id_string]
ret_val = self._invoke_plugin_per_device(const.UCS_PLUGIN,
self._func_name(), args)
new_args = [tenant_id, net_id, port['id'], port['id']]
self._invoke_plugin_per_device(const.UCS_PLUGIN,
"plug_interface", new_args)
return ret_val
except:
# TODO (Sumit): Check if we need to perform any rollback here
raise
def get_port(self, context, id, fields=None):
"""Currently there is no processing required for the device plugins"""
pass
def get_ports(self, context, filters=None, fields=None):
"""Currently there is no processing required for the device plugins"""
pass
def update_port(self, context, id, port):
"""Currently there is no processing required for the device plugins"""
pass
def delete_port(self, context, id, kwargs):
"""
Perform this operation in the context of the configured device
plugins.
"""
try:
p = kwargs['port']
args = [p['tenant_id'], p['network_id'], p['id']]
return self._invoke_plugin_per_device(const.UCS_PLUGIN,
self._func_name(), args)
except:
# TODO (Sumit): Check if we need to perform any rollback here
raise
def create_subnet(self, context, subnet):
"""Currently there is no processing required for the device plugins"""
pass
def update_subnet(self, context, id, subnet):
"""Currently there is no processing required for the device plugins"""
pass
def get_subnet(self, context, id, fields=None):
"""Currently there is no processing required for the device plugins"""
pass
def delete_subnet(self, context, id, kwargs):
"""Currently there is no processing required for the device plugins"""
pass
def get_subnets(self, context, filters=None, fields=None):
"""Currently there is no processing required for the device plugins"""
pass
"""
Extensions' implementation in device plugins
"""
def schedule_host(self, args):
"""Provides the hostname on which a dynamic vnic is reserved"""
try:
return self._invoke_inventory(const.UCS_PLUGIN, self._func_name(),
args)
except:
# TODO (Sumit): Check if we need to perform any rollback here
raise
def associate_port(self, args):
"""Get the portprofile name and the device name for the dynamic vnic"""
try:
return self._invoke_inventory(const.UCS_PLUGIN, self._func_name(),
args)
except:
# TODO (Sumit): Check if we need to perform any rollback here
raise
def detach_port(self, args):
"""Remove the association of the VIF with the dynamic vnic """
try:
return self._invoke_plugin_per_device(const.UCS_PLUGIN,
self._func_name(), args)
except:
# TODO (Sumit): Check if we need to perform any rollback here
raise
def create_multiport(self, args):
"""
Makes a call to the UCS device plugin to create ports on the same
host.
"""
try:
self._invoke_plugin_per_device(const.UCS_PLUGIN, self._func_name(),
args)
except:
# TODO (Sumit): Check if we need to perform any rollback here
raise

View File

@ -1,342 +0,0 @@
#!/usr/bin/env python
# vim: tabstop=4 shiftwidth=4 softtabstop=4
#
# Copyright 2011 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.
#
# @author: Edgar Magana, Cisco Systems
#
"""
Network Library to insert services using Quantum APIs
Currently has four functionalities:
1. insert_inpath_service <tenant_id> <service_image_id>
<management_net_name> <northbound_net_name> <southbound_net_name>
2. delete_service <tenant_id> <service_instance_id>
3. connect_vm <tenant_id> <vm_image_id> <service_instance_id>
4. disconnect_vm <vm_instance_id>
"""
import logging
import logging.handlers
from optparse import OptionParser
import os
import re
import subprocess
import sys
from quantum.common import constants
from quantum.common import utils
from quantum.plugins.cisco.common import cisco_constants as const
from quantum.plugins.cisco.db import api as db
from quantum.plugins.cisco.db import l2network_db as l2db
from quantum.plugins.cisco.db import services_db as sdb
from quantum.plugins.cisco.services import services_constants as servconts
from quantum.plugins.cisco.services import services_logistics as servlogcs
from quantumclient import Client
LOG = logging.getLogger(__name__)
def insert_inpath_service(tenant_id, service_image_id,
management_net_name, northbound_net_name,
southbound_net_name, *args):
"""Inserting a network service between two networks"""
print _("Creating Network for Services and Servers")
service_logic = servlogcs.ServicesLogistics()
net_list = {}
multiport_net_list = []
networks_name_list = [management_net_name, northbound_net_name,
southbound_net_name]
client = Client(HOST, PORT, USE_SSL, format='json', tenant=tenant_id)
for net in networks_name_list:
data = {servconts.NETWORK: {servconts.NAME: net}}
net_list[net] = client.create_network(data)
net_list[net][servconts.PORTS] = []
LOG.debug(_("Network %(net)s Created with ID: %(id)s "),
{'net': net,
'id': net_list[net][servconts.NETWORK][servconts.ID]})
print _("Completed")
print _("Creating Ports on Services and Server Networks")
LOG.debug(_("Operation 'create_port' executed."))
if not service_logic.verify_plugin(const.UCS_PLUGIN):
for net in networks_name_list:
net_list[net][servconts.PORTS].append
(client.create_port
(net_list[net][servconts.NETWORK][servconts.ID]))
LOG.debug(_("Operation 'create_port' executed."))
else:
for net in networks_name_list:
nets = net_list[net][servconts.NETWORK][servconts.ID]
multiport_net_list.append(nets)
data = create_multiport(tenant_id, multiport_net_list)
net_idx = 0
for net in networks_name_list:
port_id = data[servconts.PORTS][net_idx][servconts.ID]
net_list[net][servconts.PORTS].append(port_id)
LOG.debug(_("Port UUID: %(id)s on network: %(net)s"),
{'id': data[servconts.PORTS][net_idx][servconts.ID],
'net': net})
net_idx = net_idx + 1
print _("Completed")
try:
create_vm_args = []
create_vm_args.append(servconts.CREATE_VM_CMD)
create_vm_args.append(service_image_id)
print _("Creating VM with image: %s") % (service_image_id)
process = utils.subprocess_popen(create_vm_args,
stdout=subprocess.PIPE)
result = process.stdout.readlines()
tokens = re.search("i-[a-f0-9]*", str(result[1]))
service_vm_name = tokens.group(0)
print _("Image: %s instantiated successfully") % (service_vm_name)
except Exception as exc:
print exc
service_logic.image_status(service_vm_name)
print _("Completed")
print _("Attaching Ports To VM Service interfaces")
try:
idx = 0
for net in networks_name_list:
network_id = net_list[net][servconts.NETWORK][servconts.ID]
port_id = net_list[net][servconts.PORTS][idx]
attachment = client.show_port_attachment(network_id, port_id)
attachment = attachment[servconts.ATTACHMENT][servconts.ID][:36]
LOG.debug(_("Plugging virtual interface: %(attachment)s of VM "
"%(service_vm_name)s into port: %(port_id)s on "
"network: %(net)s"), locals())
attach_data = {servconts.ATTACHMENT: {servconts.ID: '%s' %
attachment}}
client.attach_resource(network_id, port_id, attach_data)
except Exception as exc:
print exc
print _("Completed")
try:
LOG.debug(_("Registering Service in DB"))
l2db.initialize()
for uuid_net in db.network_id(networks_name_list[0]):
mngnet_id = str(uuid_net.uuid)
for uuid_net in db.network_id(networks_name_list[1]):
nbnet_id = str(uuid_net.uuid)
for uuid_net in db.network_id(networks_name_list[2]):
sbnet_id = str(uuid_net.uuid)
sdb.add_services_binding(service_vm_name, mngnet_id, nbnet_id,
sbnet_id)
except Exception as exc:
print exc
def delete_service(tenant_id, service_instance_id, *args):
"""
Removes a service and all the network configuration
"""
l2db.initialize()
print _("Terminating Service VM")
service_logic = servlogcs.ServicesLogistics()
vms_list = []
vms_list.append(servconts.DELETE_VM_CMD)
vms_list.append(service_instance_id)
if not service_logic.image_exist(service_instance_id):
print _("Service VM does not exist")
sys.exit()
result = subprocess.call(vms_list)
service_logic.image_shutdown_verification(service_instance_id)
client = Client(HOST, PORT, USE_SSL, format='json', tenant=tenant_id)
service_nets = sdb.get_service_bindings(service_instance_id)
print _("Terminating Ports and Networks")
network_name = db.network_get(service_nets.mngnet_id)
port_id_net = db.port_list(service_nets.mngnet_id)
for ports_uuid in port_id_net:
client.delete_port(service_nets.mngnet_id, ports_uuid.uuid)
client.delete_network(service_nets.mngnet_id)
network_name = db.network_get(service_nets.nbnet_id)
port_id_net = db.port_list(service_nets.nbnet_id)
for ports_uuid in port_id_net:
client.delete_port(service_nets.nbnet_id, ports_uuid.uuid)
client.delete_network(service_nets.nbnet_id)
network_name = db.network_get(service_nets.sbnet_id)
port_id_net = db.port_list(service_nets.sbnet_id)
for ports_uuid in port_id_net:
client.delete_port(service_nets.sbnet_id, ports_uuid.uuid)
client.delete_network(service_nets.sbnet_id)
service_list = sdb.remove_services_binding(service_instance_id)
print _("Configuration Removed Successfully")
def disconnect_vm(vm_instance_id, *args):
"""
Deletes VMs and Port connection
"""
l2db.initialize()
print _("Terminating Service VM")
service_logic = servlogcs.ServicesLogistics()
vms_list = []
vms_list.append(servconts.DELETE_VM_CMD)
vms_list.append(vm_instance_id)
result = subprocess.call(vms_list)
service_logic.image_shutdown_verification(vm_instance_id)
print _("VM Server Off")
def connect_vm(tenant_id, vm_image_id, service_instance_id, *args):
"""
Starts a VMs and is connected to southbound network
"""
l2db.initialize()
client = Client(HOST, PORT, USE_SSL, format='json', tenant=tenant_id)
print (_("Connecting %(vm_image_id)s to Service "
"%(service_instance_id)s") % locals())
service_logic = servlogcs.ServicesLogistics()
service_nets = sdb.get_service_bindings(service_instance_id)
client.create_port(service_nets.mngnet_id)
client.create_port(service_nets.nbnet_id)
sb_port_id = client.create_port(service_nets.sbnet_id)
LOG.debug(_("Operation 'create_port' executed."))
new_port_id = sb_port_id[servconts.PORT][servconts.ID]
try:
create_vm_args = []
create_vm_args.append(servconts.CREATE_VM_CMD)
create_vm_args.append(vm_image_id)
print _("Creating VM with image: %s") % (vm_image_id)
process = utils.subprocess_popen(create_vm_args,
stdout=subprocess.PIPE)
result = process.stdout.readlines()
tokens = re.search("i-[a-f0-9]*", str(result[1]))
vm_name = tokens.group(0)
print _("Image: %s instantiated successfully") % (vm_name)
except Exception as exc:
print exc
service_logic.image_status(vm_name)
print _("Completed")
print _("Attaching Ports To VM Service interfaces")
south_net = service_nets.sbnet_id
attachment = client.show_port_attachment(south_net, new_port_id)
attachment = attachment[servconts.ATTACHMENT][servconts.ID][:36]
LOG.debug(_("Plugging virtual interface: %(attachment)s of VM "
"%(vm_name)s into port: %(new_port_id)s on network: "
"%(sbnet_id)s"), {'attachment': attachment,
'vm_name': vm_name,
'new_port_id': new_port_id,
'sbnet_id': service_nets.sbnet_id})
attach_data = {servconts.ATTACHMENT: {servconts.ID: '%s' % attachment}}
client.attach_resource(service_nets.sbnet_id, new_port_id, attach_data)
print _("Connect VM Ended")
def create_multiport(tenant_id, networks_list, *args):
"""Creates ports on a single host"""
ports_info = {'multiport':
{'status': constants.PORT_STATUS_ACTIVE,
'net_id_list': networks_list,
'ports_desc': {'key': 'value'}}}
request_url = "/multiport"
client = Client(HOST, PORT, USE_SSL, format='json', tenant=tenant_id,
action_prefix=servconts.ACTION_PREFIX_CSCO)
data = client.do_request('POST', request_url, body=ports_info)
return data
def build_args(cmd, cmdargs, arglist):
"""Building the list of args for a particular CLI"""
args = []
orig_arglist = arglist[:]
try:
for cmdarg in cmdargs:
args.append(arglist[0])
del arglist[0]
except:
LOG.debug(_("Not enough arguments for '%(cmd)s' "
"(expected: %(len_cmd)d, got: %(len_args)d)",
{'cmd': cmd, 'len_cmd': len(cmdargs),
'len_args': len(orig_arglist)}))
print (_("Service Insertion Usage:\n %(cmd)s %(usage)s") %
{'cmd': cmd,
'usage': " ".join(["<%s>" % y
for y in SERVICE_COMMANDS[cmd]["args"]])})
sys.exit()
if len(arglist) > 0:
LOG.debug(_("Too many arguments for '%(cmd)s' (expected: %(len)d, "
"got: %(len_args)d)"),
{'cmd': cmd, 'len_cmd': len(cmdargs),
'len_args': len(orig_arglist)})
print (_("Service Insertion Usage:\n %(cmd)s %(usage)s") %
{'cmd': cmd,
'usage': " ".join(["<%s>" % y
for y in SERVICE_COMMANDS[cmd]["args"]])})
sys.exit()
return args
SERVICE_COMMANDS = {
"insert_inpath_service": {
"func": insert_inpath_service,
"args": ["tenant_id", "service_image_id", "management_net_name",
"northbound_net_name", "southbound_net_name"],
},
"delete_service": {
"func": delete_service,
"args": ["tenant_id", "service_instance_id"],
},
"connect_vm": {
"func": connect_vm,
"args": ["tenant_id", "vm_image_id", "service_instance_id"],
},
"disconnect_vm": {
"func": disconnect_vm,
"args": ["vm_instance_id"],
},
}
if __name__ == "__main__":
os.system("clear")
usagestr = _("Usage: %prog [OPTIONS] <command> [args]")
PARSER = OptionParser(usage=usagestr)
PARSER.add_option("-H", "--host", dest="host",
type="string", default="127.0.0.1",
help=_("IP address of api host"))
PARSER.add_option("-p", "--port", dest="port",
type="int", default=9696, help=_("Api port"))
PARSER.add_option("-s", "--ssl", dest="ssl",
action="store_true", default=False, help=_("Use ssl"))
PARSER.add_option("-v", "--verbose", dest="verbose",
action="store_true", default=False,
help=_("Turn on verbose logging"))
PARSER.add_option("-f", "--logfile", dest="logfile",
type="string", default="syslog",
help=_("Log file path"))
options, args = PARSER.parse_args()
if options.verbose:
LOG.setLevel(logging.DEBUG)
else:
LOG.setLevel(logging.WARN)
if options.logfile == "syslog":
LOG.addHandler(logging.handlers.SysLogHandler(address='/dev/log'))
else:
LOG.addHandler(logging.handlers.WatchedFileHandler(options.logfile))
os.chmod(options.logfile, 0644)
service_logic = servlogcs.ServicesLogistics()
HOST = options.host
PORT = options.port
USE_SSL = options.ssl
CMD = args[0]
args = build_args(CMD, SERVICE_COMMANDS[CMD]["args"], args[1:])
SERVICE_COMMANDS[CMD]["func"](*args)
sys.exit(0)

View File

@ -1,127 +0,0 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2011 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.
#
# @author: Edgar Magana, Cisco Systems
#
"""
Logistic components for Service Insertion utility
"""
import logging
import re
import subprocess
import time
from quantum.common import utils
from quantum.openstack.common import importutils
from quantum.plugins.cisco.common import cisco_constants as const
from quantum.plugins.cisco.db import services_db as sdb
from quantum.plugins.cisco import l2network_plugin_configuration as conf
from quantum.plugins.cisco.services import services_constants as servconts
LOG = logging.getLogger(__name__)
class ServicesLogistics():
"""
Services Logistics Modules
"""
def __init__(self):
pass
def image_shutdown_verification(self, image_name):
"""
Verifies that the VM has been properly shutdown
"""
try:
service_args = []
service_args.append(servconts.DESCRIBE_VM_CMD)
service_args.append(image_name)
counter = 0
flag = False
while not flag and counter <= 5:
counter = counter + 1
time.sleep(2.5)
process = utils.subprocess_popen(service_args,
stdout=subprocess.PIPE)
result = process.stdout.readlines()
if not result:
flag = True
except Exception, exc:
print exc
def image_status(self, image_name):
"""
Checks the status of the image
"""
try:
service_args = []
service_args.append(servconts.DESCRIBE_VM_CMD)
service_args.append(image_name)
counter = 0
flag = False
while not flag and counter <= 10:
counter = counter + 1
time.sleep(2.5)
process = utils.subprocess_popen(service_args,
stdout=subprocess.PIPE)
result = process.stdout.readlines()
if result:
tokens = re.search("running", str(result[1]))
if tokens:
service_status = tokens.group(0)
if service_status == "running":
flag = True
except Exception as exc:
print exc
def image_exist(self, image_name):
"""
Verifies that the image id is available
"""
try:
service_vm = sdb.get_service_bindings(image_name)
if service_vm:
return True
else:
return False
except Exception as exc:
print exc
def verify_plugin(self, plugin_key):
"""
Verifies the PlugIn available
"""
_plugins = {}
for key in conf.PLUGINS[const.PLUGINS].keys():
plugin_obj = conf.PLUGINS[const.PLUGINS][key]
_plugins[key] = importutils.import_object(plugin_obj)
if plugin_key not in _plugins:
LOG.debug(_("No %s Plugin loaded"), plugin_key)
return False
else:
LOG.debug(_("Plugin %s founded"), const.UCS_PLUGIN)
return True
def press_key(self):
"""
Waits for en external input
"""
key = raw_input(_("Press any key to continue"))
return key

View File

@ -1,710 +0,0 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
#
# Copyright 2012 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.
#
# @author: Sumit Naiksatam, Cisco Systems, Inc.
"""
The _inventory data strcuture contains a nested disctioary:
{"UCSM_IP: {"Chassis-ID": [Balde-ID, Blade-ID],
"Chassis-ID": [Blade-ID, Blade-ID, Blade-ID]]},
"UCSM_IP: {"Chassis-ID": [Balde-ID]}
}
"""
"""
_inventory_state data structure is organized as below:
{ucsm_ip:
{chassis_id:
{blade_id:
{'blade-data':
{blade-dn-1: {blade-intf-data},
blade-dn-2: {blade-intf-data}
}
}
}
}
}
'blade-data': Blade Data dictionary has the following keys:
===========================================================
const.BLADE_INTF_DATA: This is a dictionary, with the key as the
dn of the interface, and the value as the
Blade Interface Dictionary described next
const.BLADE_UNRESERVED_INTF_COUNT: Number of unreserved interfaces
on this blade
'blade-intf-data': Blade Interface dictionary has the following keys:
=====================================================================
const.BLADE_INTF_DN
const.BLADE_INTF_ORDER
const.BLADE_INTF_LINK_STATE
const.BLADE_INTF_OPER_STATE
const.BLADE_INTF_INST_TYPE
const.BLADE_INTF_RHEL_DEVICE_NAME
const.BLADE_INTF_RESERVATION
const.TENANTID
const.PORTID
const.PROFILE_ID
const.INSTANCE_ID
const.VIF_ID
"""
from copy import deepcopy
import logging
from quantum.common import exceptions as exc
from quantum.openstack.common import importutils
from quantum.plugins.cisco.common import cisco_constants as const
from quantum.plugins.cisco.common import cisco_credentials_v2 as cred
from quantum.plugins.cisco.common import cisco_exceptions as cexc
from quantum.plugins.cisco.db import ucs_db_v2 as udb
from quantum.plugins.cisco.l2device_inventory_base import (
L2NetworkDeviceInventoryBase,
)
from quantum.plugins.cisco.ucs import (
cisco_ucs_inventory_configuration as conf,
)
LOG = logging.getLogger(__name__)
class UCSInventory(L2NetworkDeviceInventoryBase):
"""
Manages the state of all the UCS chasses, and blades in
the system
"""
_inventory = {}
_host_names = {}
_inventory_state = {}
def __init__(self):
self._client = importutils.import_object(conf.UCSM_DRIVER)
self._load_inventory()
def _load_inventory(self):
"""Load the inventory from a config file"""
inventory = deepcopy(conf.INVENTORY)
LOG.info(_("Loaded UCS inventory: %s"), inventory)
LOG.info(_("Building UCS inventory state (this may take a while)..."))
for ucsm in inventory.keys():
ucsm_ip = inventory[ucsm][const.IP_ADDRESS]
inventory[ucsm].pop(const.IP_ADDRESS)
chassis_dict = {}
for chassis in inventory[ucsm].keys():
chassis_id = inventory[ucsm][chassis][const.CHASSIS_ID]
inventory[ucsm][chassis].pop(const.CHASSIS_ID)
blade_list = []
for blade in inventory[ucsm][chassis].keys():
blade_id = (
inventory[ucsm][chassis][blade][const.BLADE_ID])
host_name = (
inventory[ucsm][chassis][blade][const.HOST_NAME])
host_key = ucsm_ip + "-" + chassis_id + "-" + blade_id
self._host_names[host_key] = host_name
blade_list.append(blade_id)
chassis_dict[chassis_id] = blade_list
self._inventory[ucsm_ip] = chassis_dict
self._build_inventory_state()
def _build_inventory_state(self):
"""Populate the state of all the blades"""
for ucsm_ip in self._inventory.keys():
self._inventory_state[ucsm_ip] = {ucsm_ip: {}}
ucsm_username = cred.Store.get_username(ucsm_ip)
ucsm_password = cred.Store.get_password(ucsm_ip)
chasses_state = {}
self._inventory_state[ucsm_ip] = chasses_state
ucsm = self._inventory[ucsm_ip]
for chassis_id in ucsm.keys():
blades_dict = {}
chasses_state[chassis_id] = blades_dict
for blade_id in ucsm[chassis_id]:
blade_data = self._get_initial_blade_state(chassis_id,
blade_id,
ucsm_ip,
ucsm_username,
ucsm_password)
blades_dict[blade_id] = blade_data
LOG.debug(_("UCS Inventory state is: %s"), self._inventory_state)
return True
def _get_host_name(self, ucsm_ip, chassis_id, blade_id):
"""Get the hostname based on the blade info"""
host_key = ucsm_ip + "-" + chassis_id + "-" + blade_id
return self._host_names[host_key]
def _get_initial_blade_state(self, chassis_id, blade_id, ucsm_ip,
ucsm_username, ucsm_password):
"""Get the initial blade state"""
blade_intf_data = self._client.get_blade_data(chassis_id, blade_id,
ucsm_ip, ucsm_username,
ucsm_password)
unreserved_counter = 0
for blade_intf in blade_intf_data.keys():
dist_name = blade_intf_data[blade_intf][const.BLADE_INTF_DN]
# We first make a pass through the state in UCSM
# If a particular interface is showing as being allocated in
# UCSM then it is definitely being used and so should be
# marked as reserved, else we temporarily mark it as unreserved
# based on the UCSM state, but may later change it if a port
# association is found in the DB
if const.TENANTID not in blade_intf_data[blade_intf].keys():
blade_intf_data[blade_intf][const.TENANTID] = None
if const.PORTID not in blade_intf_data[blade_intf].keys():
blade_intf_data[blade_intf][const.PORTID] = None
if const.PROFILE_ID not in blade_intf_data[blade_intf].keys():
blade_intf_data[blade_intf][const.PROFILE_ID] = None
if const.INSTANCE_ID not in blade_intf_data[blade_intf].keys():
blade_intf_data[blade_intf][const.INSTANCE_ID] = None
if const.VIF_ID not in blade_intf_data[blade_intf].keys():
blade_intf_data[blade_intf][const.VIF_ID] = None
if (blade_intf_data[blade_intf][const.BLADE_INTF_LINK_STATE] ==
const.BLADE_INTF_STATE_UNALLOCATED or
blade_intf_data[blade_intf][const.BLADE_INTF_LINK_STATE] ==
const.BLADE_INTF_STATE_UNKNOWN) and (
blade_intf_data[blade_intf][const.BLADE_INTF_OPER_STATE] ==
const.BLADE_INTF_STATE_UNKNOWN):
blade_intf_data[blade_intf][const.BLADE_INTF_RESERVATION] = (
const.BLADE_INTF_UNRESERVED)
unreserved_counter += 1
else:
blade_intf_data[blade_intf][const.BLADE_INTF_RESERVATION] = (
const.BLADE_INTF_RESERVED)
port_binding = udb.get_portbinding_dn(dist_name)
if port_binding:
# We have found a port binding for this interface in the DB,
# so we have earlier marked this interface as unreserved, we
# need to change it, and also load the state from the DB for
# other associations
intf_data = blade_intf_data[blade_intf]
if ((intf_data[const.BLADE_INTF_RESERVATION] == const.
BLADE_INTF_UNRESERVED)):
unreserved_counter -= 1
intf_data[const.BLADE_INTF_RESERVATION] = (
const.BLADE_INTF_RESERVED)
intf_data[const.TENANTID] = port_binding[const.TENANTID]
intf_data[const.PORTID] = port_binding[const.PORTID]
intf_data[const.PROFILE_ID] = (
port_binding[const.PORTPROFILENAME])
intf_data[const.INSTANCE_ID] = port_binding[const.INSTANCE_ID]
intf_data[const.VIF_ID] = port_binding[const.VIF_ID]
host_name = self._get_host_name(ucsm_ip, chassis_id, blade_id)
blade_data = {const.BLADE_INTF_DATA: blade_intf_data,
const.BLADE_UNRESERVED_INTF_COUNT: unreserved_counter,
const.HOST_NAME: host_name}
return blade_data
def _get_blade_state(self, chassis_id, blade_id, ucsm_ip,
ucsm_username, ucsm_password):
"""Get the blade state"""
blade_intf_data = self._client.get_blade_data(chassis_id, blade_id,
ucsm_ip, ucsm_username,
ucsm_password)
unreserved_counter = 0
for blade_intf in blade_intf_data.keys():
if (blade_intf_data[blade_intf][const.BLADE_INTF_LINK_STATE] ==
const.BLADE_INTF_STATE_UNALLOCATED or
blade_intf_data[blade_intf][const.BLADE_INTF_LINK_STATE] ==
const.BLADE_INTF_STATE_UNKNOWN) and (
blade_intf_data[blade_intf][const.BLADE_INTF_OPER_STATE] ==
const.BLADE_INTF_STATE_UNKNOWN):
blade_intf_data[blade_intf][const.BLADE_INTF_RESERVATION] = (
const.BLADE_INTF_UNRESERVED)
unreserved_counter += 1
else:
blade_intf_data[blade_intf][const.BLADE_INTF_RESERVATION] = (
const.BLADE_INTF_RESERVED)
blade_data = {const.BLADE_INTF_DATA: blade_intf_data,
const.BLADE_UNRESERVED_INTF_COUNT: unreserved_counter}
return blade_data
def _get_all_ucsms(self):
"""Return a list of the IPs of all the UCSMs in the system"""
return {const.DEVICE_IP: self._inventory.keys()}
def _get_blade_for_port(self, args):
"""
Return the a dict with IP address of the blade
on which a dynamic vnic was reserved for this port
"""
tenant_id = args[0]
net_id = args[1]
port_id = args[2]
rsvd_info = self._get_rsvd_blade_intf_by_port(tenant_id, port_id)
if not rsvd_info:
raise exc.PortNotFound(net_id=net_id, port_id=port_id)
device_params = {const.DEVICE_IP: [rsvd_info[const.UCSM_IP]]}
return device_params
def _get_host_name_for_rsvd_intf(self, tenant_id, instance_id):
"""
Return the hostname of the blade with a reserved instance
for this tenant
"""
for ucsm_ip in self._inventory_state.keys():
ucsm = self._inventory_state[ucsm_ip]
for chassis_id in ucsm.keys():
for blade_id in ucsm[chassis_id]:
blade_data = ucsm[chassis_id][blade_id]
blade_intf_data = blade_data[const.BLADE_INTF_DATA]
for blade_intf in blade_intf_data.keys():
tmp = deepcopy(blade_intf_data[blade_intf])
intf_data = blade_intf_data[blade_intf]
if (intf_data[const.BLADE_INTF_RESERVATION] ==
const.BLADE_INTF_RESERVED and
intf_data[const.TENANTID] == tenant_id and
intf_data[const.INSTANCE_ID] is None):
intf_data[const.INSTANCE_ID] = instance_id
host_name = self._get_host_name(ucsm_ip,
chassis_id,
blade_id)
port_binding = udb.get_portbinding_dn(blade_intf)
port_id = port_binding[const.PORTID]
udb.update_portbinding(port_id,
instance_id=instance_id)
return host_name
LOG.warn(_("Could not find a reserved dynamic nic for tenant: %s"),
tenant_id)
return None
def _get_instance_port(self, tenant_id, instance_id, vif_id):
"""
Return the device name for a reserved interface
"""
found_blade_intf_data = None
for ucsm_ip in self._inventory_state.keys():
ucsm = self._inventory_state[ucsm_ip]
for chassis_id in ucsm.keys():
for blade_id in ucsm[chassis_id]:
blade_data = ucsm[chassis_id][blade_id]
blade_intf_data = blade_data[const.BLADE_INTF_DATA]
for blade_intf in blade_intf_data.keys():
intf_data = blade_intf_data[blade_intf]
if (intf_data[const.BLADE_INTF_RESERVATION] ==
const.BLADE_INTF_RESERVED and
intf_data[const.TENANTID] == tenant_id and
intf_data[const.INSTANCE_ID] == instance_id):
found_blade_intf_data = blade_intf_data
LOG.debug(_("Found blade %(blade_id)s "
"associated with this"
" instance: %(instance_id)s"),
locals())
break
if found_blade_intf_data:
blade_intf_data = found_blade_intf_data
for blade_intf in blade_intf_data.keys():
intf_data = blade_intf_data[blade_intf]
if (intf_data[const.BLADE_INTF_RESERVATION] ==
const.BLADE_INTF_RESERVED and
intf_data[const.TENANTID] == tenant_id and
(not intf_data[const.VIF_ID])):
intf_data[const.VIF_ID] = vif_id
intf_data[const.INSTANCE_ID] = instance_id
port_binding = udb.get_portbinding_dn(blade_intf)
port_id = port_binding[const.PORTID]
udb.update_portbinding(port_id, instance_id=instance_id,
vif_id=vif_id)
device_name = intf_data[const.BLADE_INTF_RHEL_DEVICE_NAME]
profile_name = port_binding[const.PORTPROFILENAME]
dynamicnic_details = {
const.DEVICENAME: device_name,
const.UCSPROFILE: profile_name,
}
LOG.debug(_("Found reserved dynamic nic: %(intf_data)s"
"associated with port %(port_id)s"), locals())
LOG.debug(_("Returning dynamic nic details: %s"),
dynamicnic_details)
return dynamicnic_details
LOG.warn(_("Could not find a reserved dynamic nic for tenant: %s"),
tenant_id)
return None
def _disassociate_vifid_from_port(self, tenant_id, instance_id, vif_id):
"""
Disassociate a VIF-ID from a port, this happens when a
VM is destroyed
"""
for ucsm_ip in self._inventory_state.keys():
ucsm = self._inventory_state[ucsm_ip]
for chassis_id in ucsm.keys():
for blade_id in ucsm[chassis_id]:
blade_data = ucsm[chassis_id][blade_id]
blade_intf_data = blade_data[const.BLADE_INTF_DATA]
for blade_intf in blade_intf_data.keys():
intf_data = blade_intf_data[blade_intf]
if (intf_data[const.BLADE_INTF_RESERVATION] ==
const.BLADE_INTF_RESERVED and
intf_data[const.TENANTID] == tenant_id and
blade_intf_data[blade_intf][const.INSTANCE_ID]
== instance_id and
intf_data[const.VIF_ID][:const.UUID_LENGTH] ==
vif_id):
intf_data[const.VIF_ID] = None
intf_data[const.INSTANCE_ID] = None
port_binding = udb.get_portbinding_dn(blade_intf)
port_id = port_binding[const.PORTID]
udb.update_portbinding(port_id, instance_id=None,
vif_id=None)
LOG.debug(
_("Disassociated VIF-ID: %(vif_id)s "
"from port: %(port_id)s"
"in UCS inventory state for blade: "
"%(intf_data)s"), locals())
device_params = {const.DEVICE_IP: [ucsm_ip],
const.PORTID: port_id}
return device_params
LOG.warn(_("Disassociating VIF-ID in UCS inventory failed. "
"Could not find a reserved dynamic nic for tenant: %s"),
tenant_id)
return None
def _get_rsvd_blade_intf_by_port(self, tenant_id, port_id):
"""
Lookup a reserved blade interface based on tenant_id and port_id
and return the blade interface info
"""
for ucsm_ip in self._inventory_state.keys():
ucsm = self._inventory_state[ucsm_ip]
for chassis_id in ucsm.keys():
for blade_id in ucsm[chassis_id]:
blade_data = ucsm[chassis_id][blade_id]
blade_intf_data = blade_data[const.BLADE_INTF_DATA]
for blade_intf in blade_intf_data.keys():
if ((not blade_intf_data[blade_intf][const.PORTID] or
not blade_intf_data[blade_intf][const.TENANTID])):
continue
intf_data = blade_intf_data[blade_intf]
if (intf_data[const.BLADE_INTF_RESERVATION] ==
const.BLADE_INTF_RESERVED and
intf_data[const.TENANTID] == tenant_id and
intf_data[const.PORTID] == port_id):
interface_dn = intf_data[const.BLADE_INTF_DN]
blade_intf_info = {const.UCSM_IP: ucsm_ip,
const.CHASSIS_ID: chassis_id,
const.BLADE_ID: blade_id,
const.BLADE_INTF_DN:
interface_dn}
return blade_intf_info
LOG.warn(_("Could not find a reserved nic for tenant: %(tenant_id)s "
"port: %(port_id)s"), locals())
return None
def _get_least_reserved_blade(self, intf_count=1):
"""Return the blade with least number of dynamic nics reserved"""
unreserved_interface_count = 0
least_reserved_blade_ucsm = None
least_reserved_blade_chassis = None
least_reserved_blade_id = None
least_reserved_blade_data = None
for ucsm_ip in self._inventory_state.keys():
ucsm = self._inventory_state[ucsm_ip]
for chassis_id in ucsm.keys():
for blade_id in ucsm[chassis_id]:
blade_data = ucsm[chassis_id][blade_id]
if ((blade_data[const.BLADE_UNRESERVED_INTF_COUNT] >
unreserved_interface_count)):
unreserved_interface_count = (
blade_data[const.BLADE_UNRESERVED_INTF_COUNT])
least_reserved_blade_ucsm = ucsm_ip
least_reserved_blade_chassis = chassis_id
least_reserved_blade_id = blade_id
least_reserved_blade_data = blade_data
if unreserved_interface_count < intf_count:
LOG.warn(_("Not enough dynamic nics available on a single host."
" Requested: %(intf_count)s, Maximum available: "
"%(unreserved_interface_count)s"), locals())
return False
least_reserved_blade_dict = {
const.LEAST_RSVD_BLADE_UCSM: least_reserved_blade_ucsm,
const.LEAST_RSVD_BLADE_CHASSIS: least_reserved_blade_chassis,
const.LEAST_RSVD_BLADE_ID: least_reserved_blade_id,
const.LEAST_RSVD_BLADE_DATA: least_reserved_blade_data,
}
LOG.debug(_("Found dynamic nic %s available for reservation"),
least_reserved_blade_dict)
return least_reserved_blade_dict
def reload_inventory(self):
"""Reload the inventory from a conf file"""
self._load_inventory()
def reserve_blade_interface(self, ucsm_ip, chassis_id, blade_id,
blade_data_dict, tenant_id, port_id,
portprofile_name):
"""Reserve an interface on a blade"""
ucsm_username = cred.Store.get_username(ucsm_ip)
ucsm_password = cred.Store.get_password(ucsm_ip)
"""
We are first getting the updated UCSM-specific blade
interface state
"""
blade_data = self._get_blade_state(chassis_id, blade_id, ucsm_ip,
ucsm_username, ucsm_password)
blade_intf_data = blade_data[const.BLADE_INTF_DATA]
chassis_data = self._inventory_state[ucsm_ip][chassis_id]
old_blade_intf_data = chassis_data[blade_id][const.BLADE_INTF_DATA]
"""
We will now copy the older non-UCSM-specific blade
interface state
"""
for blade_intf in blade_intf_data.keys():
old_intf_data = old_blade_intf_data[blade_intf]
blade_intf_data[blade_intf][const.BLADE_INTF_RESERVATION] = (
old_intf_data[const.BLADE_INTF_RESERVATION])
blade_intf_data[blade_intf][const.TENANTID] = (
old_intf_data[const.TENANTID])
blade_intf_data[blade_intf][const.PORTID] = (
old_intf_data[const.PORTID])
blade_intf_data[blade_intf][const.PROFILE_ID] = (
old_intf_data[const.PROFILE_ID])
blade_intf_data[blade_intf][const.INSTANCE_ID] = (
old_intf_data[const.INSTANCE_ID])
blade_intf_data[blade_intf][const.VIF_ID] = (
old_intf_data[const.VIF_ID])
blade_data[const.BLADE_UNRESERVED_INTF_COUNT] = (
chassis_data[blade_id][const.BLADE_UNRESERVED_INTF_COUNT])
"""
Now we will reserve an interface if its available
"""
for blade_intf in blade_intf_data.keys():
intf_data = blade_intf_data[blade_intf]
if (intf_data[const.BLADE_INTF_RESERVATION] ==
const.BLADE_INTF_UNRESERVED):
intf_data[const.BLADE_INTF_RESERVATION] = (
const.BLADE_INTF_RESERVED)
intf_data[const.TENANTID] = tenant_id
intf_data[const.PORTID] = port_id
intf_data[const.INSTANCE_ID] = None
dev_eth_name = intf_data[const.BLADE_INTF_RHEL_DEVICE_NAME]
"""
We are replacing the older blade interface state with new
"""
chassis_data[blade_id][const.BLADE_INTF_DATA] = blade_intf_data
chassis_data[blade_id][const.BLADE_UNRESERVED_INTF_COUNT] -= 1
host_name = self._get_host_name(ucsm_ip, chassis_id, blade_id)
reserved_nic_dict = {
const.RESERVED_NIC_HOSTNAME: host_name,
const.RESERVED_NIC_NAME: dev_eth_name,
const.BLADE_INTF_DN: blade_intf,
}
port_binding = udb.add_portbinding(port_id, blade_intf, None,
None, None, None)
udb.update_portbinding(port_id,
tenant_id=intf_data[const.TENANTID])
LOG.debug(_("Reserved blade interface: %s"),
reserved_nic_dict)
return reserved_nic_dict
LOG.warn(_("Dynamic nic %(blade_data)s could not be reserved for "
"port-id: %(port_id)s"), locals())
return False
def unreserve_blade_interface(self, ucsm_ip, chassis_id, blade_id,
interface_dn):
"""Unreserve a previously reserved interface on a blade"""
ucsm_username = cred.Store.get_username(ucsm_ip)
ucsm_password = cred.Store.get_password(ucsm_ip)
blade_data = self._inventory_state[ucsm_ip][chassis_id][blade_id]
blade_data[const.BLADE_UNRESERVED_INTF_COUNT] += 1
blade_intf = blade_data[const.BLADE_INTF_DATA][interface_dn]
blade_intf[const.BLADE_INTF_RESERVATION] = const.BLADE_INTF_UNRESERVED
blade_intf[const.TENANTID] = None
blade_intf[const.PORTID] = None
blade_intf[const.PROFILE_ID] = None
blade_intf[const.INSTANCE_ID] = None
blade_intf[const.VIF_ID] = None
LOG.debug(_("Unreserved blade interface %s"), interface_dn)
def add_blade(self, ucsm_ip, chassis_id, blade_id):
"""Add a blade to the inventory"""
# TODO (Sumit)
pass
def get_all_networks(self, args):
"""Return all UCSM IPs"""
LOG.debug(_("get_all_networks() called"))
return self._get_all_ucsms()
def create_network(self, args):
"""Return all UCSM IPs"""
LOG.debug(_("create_network() called"))
return self._get_all_ucsms()
def delete_network(self, args):
"""Return all UCSM IPs"""
LOG.debug(_("delete_network() called"))
return self._get_all_ucsms()
def get_network_details(self, args):
"""Return all UCSM IPs"""
LOG.debug(_("get_network_details() called"))
return self._get_all_ucsms()
def update_network(self, args):
"""Return all UCSM IPs"""
LOG.debug(_("update_network() called"))
return self._get_all_ucsms()
def get_all_ports(self, args):
"""Return all UCSM IPs"""
LOG.debug(_("get_all_ports() called"))
return self._get_all_ucsms()
def create_port(self, args):
"""
Return the a dict with information of the blade
on which a dynamic vnic is available
"""
LOG.debug(_("create_port() called"))
least_reserved_blade_dict = self._get_least_reserved_blade()
if not least_reserved_blade_dict:
raise cexc.NoMoreNics()
ucsm_ip = least_reserved_blade_dict[const.LEAST_RSVD_BLADE_UCSM]
device_params = {
const.DEVICE_IP: [ucsm_ip],
const.UCS_INVENTORY: self,
const.LEAST_RSVD_BLADE_DICT: least_reserved_blade_dict,
}
return device_params
def delete_port(self, args):
"""
Return the a dict with information of the blade
on which a dynamic vnic was reserved for this port
"""
LOG.debug(_("delete_port() called"))
tenant_id = args[0]
net_id = args[1]
port_id = args[2]
rsvd_info = self._get_rsvd_blade_intf_by_port(tenant_id, port_id)
if not rsvd_info:
LOG.warn(_("UCSInventory: Port not found: net_id: %(net_id)s, "
"port_id: %(port_id)s"), locals())
return {const.DEVICE_IP: []}
device_params = {
const.DEVICE_IP: [rsvd_info[const.UCSM_IP]],
const.UCS_INVENTORY: self,
const.CHASSIS_ID: rsvd_info[const.CHASSIS_ID],
const.BLADE_ID: rsvd_info[const.BLADE_ID],
const.BLADE_INTF_DN: rsvd_info[const.BLADE_INTF_DN],
}
return device_params
def update_port(self, args):
"""
Return the a dict with IP address of the blade
on which a dynamic vnic was reserved for this port
"""
LOG.debug(_("update_port() called"))
return self._get_blade_for_port(args)
def get_port_details(self, args):
"""
Return the a dict with IP address of the blade
on which a dynamic vnic was reserved for this port
"""
LOG.debug(_("get_port_details() called"))
return self._get_blade_for_port(args)
def plug_interface(self, args):
"""
Return the a dict with IP address of the blade
on which a dynamic vnic was reserved for this port
"""
LOG.debug(_("plug_interface() called"))
return self._get_blade_for_port(args)
def unplug_interface(self, args):
"""
Return the a dict with IP address of the blade
on which a dynamic vnic was reserved for this port
"""
LOG.debug(_("unplug_interface() called"))
return self._get_blade_for_port(args)
def schedule_host(self, args):
"""Provides the hostname on which a dynamic vnic is reserved"""
LOG.debug(_("schedule_host() called"))
instance_id = args[1]
tenant_id = args[2][const.PROJECT_ID]
host_name = self._get_host_name_for_rsvd_intf(tenant_id, instance_id)
host_list = {const.HOST_LIST: {const.HOST_1: host_name}}
LOG.debug(_("host_list is: %s"), host_list)
return host_list
def associate_port(self, args):
"""
Get the portprofile name and the device name for the dynamic vnic
"""
LOG.debug(_("associate_port() called"))
instance_id = args[1]
tenant_id = args[2][const.PROJECT_ID]
vif_id = args[2][const.VIF_ID]
vif_info = self._get_instance_port(tenant_id, instance_id, vif_id)
vif_desc = {const.VIF_DESC: vif_info}
LOG.debug(_("vif_desc is: %s"), vif_desc)
return vif_desc
def detach_port(self, args):
"""
Remove the VIF-ID and instance name association
with the port
"""
LOG.debug(_("detach_port() called"))
instance_id = args[1]
tenant_id = args[2][const.PROJECT_ID]
vif_id = args[2][const.VIF_ID]
device_params = self._disassociate_vifid_from_port(tenant_id,
instance_id,
vif_id)
return device_params
def create_multiport(self, args):
"""
Create multiple ports for a VM
"""
LOG.debug(_("create_ports() called"))
tenant_id = args[0]
ports_num = args[2]
least_reserved_blade_dict = self._get_least_reserved_blade(ports_num)
if not least_reserved_blade_dict:
raise cexc.NoMoreNics()
ucsm_ip = least_reserved_blade_dict[const.LEAST_RSVD_BLADE_UCSM]
device_params = {
const.DEVICE_IP: [ucsm_ip],
const.UCS_INVENTORY: self,
const.LEAST_RSVD_BLADE_DICT:
least_reserved_blade_dict,
}
return device_params

View File

@ -1,337 +0,0 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
#
# Copyright 2012 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.
#
# @author: Sumit Naiksatam, Cisco Systems, Inc.
#
import logging
from quantum.db import api as db
from quantum.openstack.common import importutils
from quantum.plugins.cisco.common import cisco_constants as const
from quantum.plugins.cisco.common import cisco_credentials_v2 as cred
from quantum.plugins.cisco.common import cisco_exceptions as cexc
from quantum.plugins.cisco.common import cisco_utils as cutil
from quantum.plugins.cisco.db import network_db_v2 as cdb
from quantum.plugins.cisco.db import ucs_db_v2 as udb
from quantum.plugins.cisco.l2device_plugin_base import L2DevicePluginBase
from quantum.plugins.cisco.ucs import cisco_ucs_configuration as conf
LOG = logging.getLogger(__name__)
class UCSVICPlugin(L2DevicePluginBase):
"""UCS Device Plugin"""
def __init__(self):
self._driver = importutils.import_object(conf.UCSM_DRIVER)
LOG.debug(_("Loaded driver %s"), conf.UCSM_DRIVER)
# TODO (Sumit) Make the counter per UCSM
self._port_profile_counter = 0
def get_all_networks(self, tenant_id, **kwargs):
"""
Returns a dictionary containing all
<network_uuid, network_name> for
the specified tenant.
"""
LOG.debug(_("UCSVICPlugin:get_all_networks() called"))
self._set_ucsm(kwargs[const.DEVICE_IP])
networks_list = db.network_list(tenant_id)
new_networks_list = []
for network in networks_list:
new_network_dict = cutil.make_net_dict(network[const.UUID],
network[const.NETWORKNAME],
[])
new_networks_list.append(new_network_dict)
return new_networks_list
def create_network(self, tenant_id, net_name, net_id, vlan_name, vlan_id,
**kwargs):
"""
Creates a new Virtual Network, and assigns it
a symbolic name.
"""
LOG.debug(_("UCSVICPlugin:create_network() called"))
self._set_ucsm(kwargs[const.DEVICE_IP])
self._driver.create_vlan(vlan_name, str(vlan_id), self._ucsm_ip,
self._ucsm_username, self._ucsm_password)
ports_on_net = []
new_network_dict = cutil.make_net_dict(net_id,
net_name,
ports_on_net)
return new_network_dict
def delete_network(self, tenant_id, net_id, **kwargs):
"""
Deletes the network with the specified network identifier
belonging to the specified tenant.
"""
LOG.debug(_("UCSVICPlugin:delete_network() called"))
self._set_ucsm(kwargs[const.DEVICE_IP])
vlan_binding = cdb.get_vlan_binding(net_id)
vlan_name = vlan_binding[const.VLANNAME]
self._driver.delete_vlan(vlan_name, self._ucsm_ip,
self._ucsm_username, self._ucsm_password)
#Rohit:passing empty network name, might not need fixing
net_dict = cutil.make_net_dict(net_id,
"",
[])
return net_dict
def get_network_details(self, tenant_id, net_id, **kwargs):
"""
Deletes the Virtual Network belonging to a the
spec
"""
LOG.debug(_("UCSVICPlugin:get_network_details() called"))
self._set_ucsm(kwargs[const.DEVICE_IP])
network = db.network_get(net_id)
ports_list = network[const.NETWORKPORTS]
ports_on_net = []
for port in ports_list:
new_port = cutil.make_port_dict(port[const.UUID],
port[const.PORTSTATE],
port[const.NETWORKID],
port[const.INTERFACEID])
ports_on_net.append(new_port)
new_network = cutil.make_net_dict(network[const.UUID],
network[const.NETWORKNAME],
ports_on_net)
return new_network
def update_network(self, tenant_id, net_id, **kwargs):
"""
Updates the symbolic name belonging to a particular
Virtual Network.
"""
LOG.debug(_("UCSVICPlugin:update_network() called"))
self._set_ucsm(kwargs[const.DEVICE_IP])
network = db.network_get(net_id)
net_dict = cutil.make_net_dict(network[const.UUID],
network[const.NETWORKNAME],
[])
return net_dict
def get_all_ports(self, tenant_id, net_id, **kwargs):
"""
Retrieves all port identifiers belonging to the
specified Virtual Network.
"""
LOG.debug(_("UCSVICPlugin:get_all_ports() called"))
self._set_ucsm(kwargs[const.DEVICE_IP])
network = db.network_get(net_id)
ports_list = network[const.NETWORKPORTS]
ports_on_net = []
for port in ports_list:
port_binding = udb.get_portbinding(port[const.UUID])
ports_on_net.append(port_binding)
return ports_on_net
def create_port(self, tenant_id, net_id, port_state, port_id, **kwargs):
"""
Creates a port on the specified Virtual Network.
"""
LOG.debug(_("UCSVICPlugin:create_port() called"))
self._set_ucsm(kwargs[const.DEVICE_IP])
qos = None
ucs_inventory = kwargs[const.UCS_INVENTORY]
least_rsvd_blade_dict = kwargs[const.LEAST_RSVD_BLADE_DICT]
chassis_id = least_rsvd_blade_dict[const.LEAST_RSVD_BLADE_CHASSIS]
blade_id = least_rsvd_blade_dict[const.LEAST_RSVD_BLADE_ID]
blade_data_dict = least_rsvd_blade_dict[const.LEAST_RSVD_BLADE_DATA]
new_port_profile = self._create_port_profile(tenant_id, net_id,
port_id,
conf.DEFAULT_VLAN_NAME,
conf.DEFAULT_VLAN_ID)
profile_name = new_port_profile[const.PROFILE_NAME]
rsvd_nic_dict = ucs_inventory.reserve_blade_interface(
self._ucsm_ip, chassis_id,
blade_id, blade_data_dict,
tenant_id, port_id,
profile_name)
port_binding = udb.update_portbinding(port_id,
portprofile_name=profile_name,
vlan_name=conf.DEFAULT_VLAN_NAME,
vlan_id=conf.DEFAULT_VLAN_ID,
qos=qos)
return port_binding
def delete_port(self, tenant_id, net_id, port_id, **kwargs):
"""
Deletes a port on a specified Virtual Network,
if the port contains a remote interface attachment,
the remote interface should first be un-plugged and
then the port can be deleted.
"""
LOG.debug(_("UCSVICPlugin:delete_port() called"))
self._set_ucsm(kwargs[const.DEVICE_IP])
ucs_inventory = kwargs[const.UCS_INVENTORY]
chassis_id = kwargs[const.CHASSIS_ID]
blade_id = kwargs[const.BLADE_ID]
interface_dn = kwargs[const.BLADE_INTF_DN]
port_binding = udb.get_portbinding(port_id)
profile_name = port_binding[const.PORTPROFILENAME]
self._delete_port_profile(port_id, profile_name)
ucs_inventory.unreserve_blade_interface(self._ucsm_ip, chassis_id,
blade_id, interface_dn)
return udb.remove_portbinding(port_id)
def update_port(self, tenant_id, net_id, port_id, **kwargs):
"""
Updates the state of a port on the specified Virtual Network.
"""
LOG.debug(_("UCSVICPlugin:update_port() called"))
self._set_ucsm(kwargs[const.DEVICE_IP])
pass
def get_port_details(self, tenant_id, net_id, port_id, **kwargs):
"""
This method allows the user to retrieve a remote interface
that is attached to this particular port.
"""
LOG.debug(_("UCSVICPlugin:get_port_details() called"))
self._set_ucsm(kwargs[const.DEVICE_IP])
port_binding = udb.get_portbinding(port_id)
return port_binding
def plug_interface(self, tenant_id, net_id, port_id, remote_interface_id,
**kwargs):
"""
Attaches a remote interface to the specified port on the
specified Virtual Network.
"""
LOG.debug(_("UCSVICPlugin:plug_interface() called"))
self._set_ucsm(kwargs[const.DEVICE_IP])
port_binding = udb.get_portbinding(port_id)
profile_name = port_binding[const.PORTPROFILENAME]
old_vlan_name = port_binding[const.VLANNAME]
new_vlan_name = self._get_vlan_name_for_network(tenant_id, net_id)
new_vlan_id = self._get_vlan_id_for_network(tenant_id, net_id)
self._driver.change_vlan_in_profile(profile_name, old_vlan_name,
new_vlan_name, self._ucsm_ip,
self._ucsm_username,
self._ucsm_password)
return udb.update_portbinding(port_id, vlan_name=new_vlan_name,
vlan_id=new_vlan_id)
def unplug_interface(self, tenant_id, net_id, port_id, **kwargs):
"""
Detaches a remote interface from the specified port on the
specified Virtual Network.
"""
LOG.debug(_("UCSVICPlugin:unplug_interface() called"))
self._set_ucsm(kwargs[const.DEVICE_IP])
port_binding = udb.get_portbinding(port_id)
profile_name = port_binding[const.PORTPROFILENAME]
old_vlan_name = port_binding[const.VLANNAME]
new_vlan_name = conf.DEFAULT_VLAN_NAME
self._driver.change_vlan_in_profile(profile_name, old_vlan_name,
new_vlan_name, self._ucsm_ip,
self._ucsm_username,
self._ucsm_password)
return udb.update_portbinding(port_id, vlan_name=new_vlan_name,
vlan_id=conf.DEFAULT_VLAN_ID)
def create_multiport(self, tenant_id, net_id_list, ports_num,
port_id_list, **kwargs):
"""
Creates a port on the specified Virtual Network.
"""
LOG.debug(_("UCSVICPlugin:create_multiport() called"))
self._set_ucsm(kwargs[const.DEVICE_IP])
qos = None
ucs_inventory = kwargs[const.UCS_INVENTORY]
least_rsvd_blade_dict = kwargs[const.LEAST_RSVD_BLADE_DICT]
chassis_id = least_rsvd_blade_dict[const.LEAST_RSVD_BLADE_CHASSIS]
blade_id = least_rsvd_blade_dict[const.LEAST_RSVD_BLADE_ID]
blade_data_dict = least_rsvd_blade_dict[const.LEAST_RSVD_BLADE_DATA]
port_binding_list = []
for port_id, net_id in zip(port_id_list, net_id_list):
new_port_profile = self._create_port_profile(
tenant_id, net_id, port_id,
conf.DEFAULT_VLAN_NAME,
conf.DEFAULT_VLAN_ID)
profile_name = new_port_profile[const.PROFILE_NAME]
rsvd_nic_dict = ucs_inventory.reserve_blade_interface(
self._ucsm_ip, chassis_id,
blade_id, blade_data_dict,
tenant_id, port_id,
profile_name)
port_binding = udb.update_portbinding(
port_id,
portprofile_name=profile_name,
vlan_name=conf.DEFAULT_VLAN_NAME,
vlan_id=conf.DEFAULT_VLAN_ID,
qos=qos)
port_binding_list.append(port_binding)
return port_binding_list
def detach_port(self, tenant_id, instance_id, instance_desc, **kwargs):
"""
Remove the association of the VIF with the dynamic vnic
"""
LOG.debug(_("detach_port() called"))
port_id = kwargs[const.PORTID]
kwargs.pop(const.PORTID)
return self.unplug_interface(tenant_id, None, port_id, **kwargs)
def _get_profile_name(self, port_id):
"""Returns the port profile name based on the port UUID"""
profile_name = conf.PROFILE_NAME_PREFIX + cutil.get16ByteUUID(port_id)
return profile_name
def _get_vlan_name_for_network(self, tenant_id, network_id):
"""Return the VLAN name as set by the L2 network plugin"""
vlan_binding = cdb.get_vlan_binding(network_id)
return vlan_binding[const.VLANNAME]
def _get_vlan_id_for_network(self, tenant_id, network_id):
"""Return the VLAN id as set by the L2 network plugin"""
vlan_binding = cdb.get_vlan_binding(network_id)
return vlan_binding[const.VLANID]
def _create_port_profile(self, tenant_id, net_id, port_id, vlan_name,
vlan_id):
"""Create port profile in UCSM"""
if self._port_profile_counter >= int(conf.MAX_UCSM_PORT_PROFILES):
raise cexc.UCSMPortProfileLimit(net_id=net_id, port_id=port_id)
profile_name = self._get_profile_name(port_id)
self._driver.create_profile(profile_name, vlan_name, self._ucsm_ip,
self._ucsm_username, self._ucsm_password)
self._port_profile_counter += 1
new_port_profile = {const.PROFILE_NAME: profile_name,
const.PROFILE_VLAN_NAME: vlan_name,
const.PROFILE_VLAN_ID: vlan_id}
return new_port_profile
def _delete_port_profile(self, port_id, profile_name):
"""Delete port profile in UCSM"""
self._driver.delete_profile(profile_name, self._ucsm_ip,
self._ucsm_username, self._ucsm_password)
self._port_profile_counter -= 1
def _set_ucsm(self, ucsm_ip):
"""Set the UCSM IP, username, and password"""
self._ucsm_ip = ucsm_ip
self._ucsm_username = cred.Store.get_username(conf.UCSM_IP_ADDRESS)
self._ucsm_password = cred.Store.get_password(conf.UCSM_IP_ADDRESS)