Merge "Accept ucsm_host_list as part of Multi-UCSM config"

This commit is contained in:
Jenkins 2017-03-14 19:17:17 +00:00 committed by Gerrit Code Review
commit 5d93dafd7c
5 changed files with 70 additions and 37 deletions

View File

@ -234,6 +234,11 @@
# ucsm_password = password
# ucsm_virtio_eth_ports = eth0, eth1
# Hostname to Service Profile mapping for Compute hosts managed by
# this UCS Manager. This config should be specified for hosts configured
# with only Service Profiles and not Service Profile Templates.
# ucsm_host_list=Hostname1:Serviceprofile1, Hostname2:Serviceprofile2
# Service Profile Template config per UCSM. This is a mapping of Service Profile
# Template to the list of UCS Servers controlled by this template.
# sp_template_list = SP_Template1_path:SP_Template1:S1,S2 SP_Template2_path:SP_Template2:S3,S4

View File

@ -13,8 +13,6 @@
# License for the specific language governing permissions and limitations
# under the License.
import debtcollector
from oslo_config import cfg
from oslo_log import log as logging
@ -82,38 +80,35 @@ def parse_pci_vendor_config():
return vendor_list
@debtcollector.removals.remove(message=DEPRECATION_MESSAGE)
def parse_ucsm_host_config():
def parse_ucsm_host_config(ucsm_ip, ucsm_host_list):
sp_dict = {}
host_dict = {}
if cfg.CONF.ml2_cisco_ucsm.ucsm_host_list:
host_config_list = cfg.CONF.ml2_cisco_ucsm.ucsm_host_list
for host in host_config_list:
hostname, sep, service_profile = host.partition(':')
if not sep or not service_profile:
raise cfg.Error(_("UCS Mech Driver: Invalid Host Service "
"Profile config: %s") % host)
key = (cfg.CONF.ml2_cisco_ucsm.ucsm_ip, hostname)
if '/' not in service_profile:
# Assuming the service profile is at the root level
# and the path is not specified. This option
# allows backward compatability with earlier config
# format
sp_dict[key] = (const.SERVICE_PROFILE_PATH_PREFIX +
service_profile.strip())
else:
# Assuming the complete path to Service Profile has
# been provided in the config. The Service Profile
# could be in an sub-org.
sp_dict[key] = service_profile.strip()
for host in ucsm_host_list:
host = host.strip()
hostname, sep, service_profile = host.partition(':')
if not sep or not service_profile:
raise cfg.Error(_("UCS Mech Driver: Invalid Host Service "
"Profile config: %s") % host)
key = (ucsm_ip, hostname)
if '/' not in service_profile:
# Assuming the service profile is at the root level
# and the path is not specified. This option
# allows backward compatability with earlier config
# format
sp_dict[key] = (const.SERVICE_PROFILE_PATH_PREFIX +
service_profile.strip())
else:
# Assuming the complete path to Service Profile has
# been provided in the config. The Service Profile
# could be in an sub-org.
sp_dict[key] = service_profile.strip()
LOG.debug('Service Profile for %s is %s',
hostname, sp_dict.get(key))
host_dict[hostname] = cfg.CONF.ml2_cisco_ucsm.ucsm_ip
return sp_dict, host_dict
LOG.debug('Service Profile for %s is %s',
hostname, sp_dict.get(key))
host_dict[hostname] = ucsm_ip
return sp_dict, host_dict
@debtcollector.removals.remove(message=DEPRECATION_MESSAGE)
def parse_virtio_eth_ports():
eth_port_list = []
if not cfg.CONF.ml2_cisco_ucsm.ucsm_virtio_eth_ports:
@ -130,6 +125,8 @@ def parse_virtio_eth_ports():
class UcsmConfig(object):
"""ML2 Cisco UCSM Mechanism Driver Configuration class."""
ucsm_dict = {}
ucsm_sp_dict = {}
ucsm_host_dict = {}
ucsm_port_dict = {}
sp_template_dict = {}
vnic_template_dict = {}
@ -149,7 +146,6 @@ class UcsmConfig(object):
raise cfg.Error(_('Insufficient UCS Manager configuration has '
'been provided to the plugin'))
@debtcollector.removals.remove(message=DEPRECATION_MESSAGE)
def _create_single_ucsm_dicts(self):
"""Creates a dictionary of UCSM data for 1 UCS Manager."""
ucsm_info = []
@ -166,6 +162,8 @@ class UcsmConfig(object):
"""Creates a dictionary of all UCS Manager data from config."""
username = None
password = None
local_sp_dict = {}
local_host_dict = {}
multi_parser = cfg.MultiConfigParser()
read_ok = multi_parser.read(cfg.CONF.config_file)
@ -181,7 +179,13 @@ class UcsmConfig(object):
eth_port_list = []
for dev_key, value in parsed_file[parsed_item].items():
config_item = dev_key.lower()
if config_item == 'ucsm_virtio_eth_ports':
if config_item == 'ucsm_host_list':
local_sp_dict, local_host_dict = (
parse_ucsm_host_config(dev_ip,
value[0].split(',')))
self.ucsm_sp_dict.update(local_sp_dict)
self.ucsm_host_dict.update(local_host_dict)
elif config_item == 'ucsm_virtio_eth_ports':
for eth_port in value[0].split(','):
eth_port_list.append(
const.ETH_PREFIX + str(eth_port).strip())
@ -197,7 +201,7 @@ class UcsmConfig(object):
self.sriov_qos_policy[dev_ip] = value[0].strip()
elif dev_key.lower() == 'ucsm_username':
username = value[0].strip()
else:
elif dev_key.lower() == 'ucsm_password':
password = value[0].strip()
ucsm_info = (username, password)
self.ucsm_dict[dev_ip] = ucsm_info

View File

@ -104,10 +104,19 @@ class CiscoUcsmDriver(object):
# Check if Service Profile to Hostname mapping config has been provided
if cfg.CONF.ml2_cisco_ucsm.ucsm_host_list:
self.ucsm_sp_dict, self.ucsm_host_dict = (
config.parse_ucsm_host_config())
config.parse_ucsm_host_config(
cfg.CONF.ml2_cisco_ucsm.ucsm_ip,
cfg.CONF.ml2_cisco_ucsm.ucsm_host_list))
elif self.ucsm_conf.multi_ucsm_mode:
self.ucsm_sp_dict.update(self.ucsm_conf.ucsm_sp_dict)
self.ucsm_host_dict.update(self.ucsm_conf.ucsm_host_dict)
else:
self._create_ucsm_host_to_service_profile_mapping()
if not self.ucsm_sp_dict:
LOG.error(_LE('UCS Manager network driver failed to get Service '
'Profile information for any of its nodes.'))
@contextmanager
def ucsm_connect_disconnect(self, ucsm_ip):
handle = self.ucs_manager_connect(ucsm_ip)

View File

@ -29,6 +29,7 @@ UCSM_IP_ADDRESS_1 = '1.1.1.1'
UCSM_USERNAME_1 = 'username1'
UCSM_PASSWORD_1 = 'password1'
UCSM_VIRTIO_ETH_PORTS_1 = ['eth0, eth1']
UCSM_HOST_LIST_1 = ['UCS-1:UCS-1-SP, UCS-2:org-root/test/ls-UCS-2-SP']
UCSM_IP_ADDRESS_2 = '2.2.2.2'
UCSM_USERNAME_2 = 'username2'
@ -63,6 +64,7 @@ class ConfigMixin(object):
'ml2_cisco_ucsm_ip: 1.1.1.1': {
'ucsm_username': [UCSM_USERNAME_1],
'ucsm_password': [UCSM_PASSWORD_1],
'ucsm_host_list': UCSM_HOST_LIST_1,
'ucsm_virtio_eth_ports': UCSM_VIRTIO_ETH_PORTS_1,
'vnic_template_list': ['test-physnet:org-root:Test-VNIC'],
'sriov_qos_policy': ['Test']
@ -103,6 +105,11 @@ class ConfigMixin(object):
507, 508, 509, 700]
}
expected_sp_dict = {
('1.1.1.1', 'UCS-1'): ('org-root/ls-UCS-1-SP'),
('1.1.1.1', 'UCS-2'): ('org-root/test/ls-UCS-2-SP'),
}
self.mocked_parser = mock.patch.object(cfg,
'MultiConfigParser').start()
self.mocked_parser.return_value.read.return_value = [ucsm_test_config]
@ -118,3 +125,5 @@ class ConfigMixin(object):
ucsm_config.UcsmConfig.sriov_qos_policy)
self.assertEqual(expected_multivlan_trunk_dict,
ucsm_config.UcsmConfig.multivlan_trunk_dict)
self.assertEqual(expected_sp_dict,
ucsm_config.UcsmConfig.ucsm_sp_dict)

View File

@ -762,7 +762,9 @@ class TestCiscoUcsmMechDriver(testlib_api.SqlTestCase,
expected_ip = '1.1.1.1'
expected_sp1 = "org-root/ls-SP1"
expected_sp2 = "org-root/ls-SP2"
ucsm_sp_dict, ucsm_host_dict = conf.parse_ucsm_host_config()
ucsm_sp_dict, ucsm_host_dict = conf.parse_ucsm_host_config(
cfg.CONF.ml2_cisco_ucsm.ucsm_ip,
cfg.CONF.ml2_cisco_ucsm.ucsm_host_list)
key = (cfg.CONF.ml2_cisco_ucsm.ucsm_ip, 'Host1')
self.assertIn(key, ucsm_sp_dict)
@ -783,11 +785,13 @@ class TestCiscoUcsmMechDriver(testlib_api.SqlTestCase,
"""Verifies malformed ucsm_host_list raises an error."""
cfg.CONF.ml2_cisco_ucsm.ucsm_host_list = ['Host1:', 'Host2:SP2']
self.assertRaisesRegex(cfg.Error, "Host1:",
conf.parse_ucsm_host_config)
conf.parse_ucsm_host_config, UCSM_IP_ADDRESS_1,
cfg.CONF.ml2_cisco_ucsm.ucsm_host_list)
cfg.CONF.ml2_cisco_ucsm.ucsm_host_list = ['Host1:SP1', 'Host2']
self.assertRaisesRegex(cfg.Error, "Host2",
conf.parse_ucsm_host_config)
conf.parse_ucsm_host_config, UCSM_IP_ADDRESS_1,
cfg.CONF.ml2_cisco_ucsm.ucsm_host_list)
def test_parse_virtio_eth_ports(self):
cfg.CONF.ml2_cisco_ucsm.ucsm_virtio_eth_ports = ['test-eth1',
@ -804,7 +808,9 @@ class TestCiscoUcsmMechDriver(testlib_api.SqlTestCase,
cfg.CONF.ml2_cisco_ucsm.ucsm_host_list = ['Host1:SP1',
'Host2:org-root/sub-org1/ls-SP2']
ucsm_sp_dict, ucsm_host_dict = conf.parse_ucsm_host_config()
ucsm_sp_dict, ucsm_host_dict = conf.parse_ucsm_host_config(
cfg.CONF.ml2_cisco_ucsm.ucsm_ip,
cfg.CONF.ml2_cisco_ucsm.ucsm_host_list)
key = ('1.1.1.1', 'Host1')
actual_service_profile1 = ucsm_sp_dict.get(key)