Merge "Add support for multiple hpe3par backends"

This commit is contained in:
Zuul 2018-09-11 14:21:06 +00:00 committed by Gerrit Code Review
commit 8fae09cf84
7 changed files with 142 additions and 59 deletions

View File

@ -245,7 +245,7 @@ class openstack::cinder::backup
class openstack::cinder::backends::san
inherits ::openstack::cinder::params {
include ::openstack::cinder::emc_vnx
include ::openstack::cinder::hpe3par
include ::openstack::cinder::backends::hpe3par
include ::openstack::cinder::hpelefthand
}
@ -520,23 +520,29 @@ class openstack::cinder::emc_vnx(
}
class openstack::cinder::hpe3par(
$feature_enabled,
$config_params
) inherits ::openstack::cinder::params {
create_resources('cinder_config', hiera_hash('openstack::cinder::hpe3par::config_params', {}))
define openstack::cinder::backend::hpe3par
{
$hiera_params = "openstack::cinder::${name}::config_params"
$feature_enabled = "openstack::cinder::${name}::feature_enabled"
# As HP SANs are addon PS supported options, make sure we have explicit
# logging showing this is being included when the feature is enabled.
create_resources('cinder_config', hiera_hash($hiera_params, {}))
if $feature_enabled {
exec {'Including hpe3par configuration':
exec {"Including $name configuration":
path => [ '/usr/bin', '/usr/sbin', '/bin', '/sbin' ],
command => 'echo Including hpe3par configuration',
command => "echo Including $name configuration",
}
}
}
class openstack::cinder::backends::hpe3par (
$sections = []
) inherits ::openstack::cinder::params {
::openstack::cinder::backend::hpe3par {$sections:}
}
class openstack::cinder::hpelefthand(
$feature_enabled,
$config_params

View File

@ -134,6 +134,21 @@ class ServiceParameterController(rest.RestController):
def __init__(self, parent=None, **kwargs):
self._parent = parent
# Add additional hpe3par backends
for i in range(2, constants.SERVICE_PARAM_MAX_HPE3PAR + 1):
section = "{0}{1}".format(constants.SERVICE_PARAM_SECTION_CINDER_HPE3PAR, i)
service_parameter.SERVICE_PARAMETER_SCHEMA[constants.SERVICE_TYPE_CINDER][section] = {
service_parameter.SERVICE_PARAM_MANDATORY:
service_parameter.CINDER_HPE3PAR_PARAMETER_MANDATORY,
service_parameter.SERVICE_PARAM_PROTECTED:
service_parameter.CINDER_HPE3PAR_PARAMETER_PROTECTED,
service_parameter.SERVICE_PARAM_OPTIONAL:
service_parameter.CINDER_HPE3PAR_PARAMETER_OPTIONAL,
service_parameter.SERVICE_PARAM_VALIDATOR:
service_parameter.CINDER_HPE3PAR_PARAMETER_VALIDATOR,
service_parameter.SERVICE_PARAM_RESOURCE:
service_parameter.CINDER_HPE3PAR_PARAMETER_RESOURCE,
}
def _get_service_parameter_collection(self, marker=None, limit=None,
sort_key=None, sort_dir=None,
@ -952,8 +967,12 @@ class ServiceParameterController(rest.RestController):
self._service_parameter_apply_semantic_check_cinder_emc_vnx()
self._emc_vnx_ip_addresses_reservation()
self._service_parameter_apply_semantic_check_cinder_hpe3par()
self._hpe3par_reserve_ip_addresses()
self._service_parameter_apply_semantic_check_cinder_hpe3par(constants.SERVICE_PARAM_SECTION_CINDER_HPE3PAR)
self._hpe3par_reserve_ip_addresses(constants.SERVICE_PARAM_SECTION_CINDER_HPE3PAR)
for i in range(2, constants.SERVICE_PARAM_MAX_HPE3PAR + 1):
section = "{0}{1}".format(constants.SERVICE_PARAM_SECTION_CINDER_HPE3PAR, i)
self._service_parameter_apply_semantic_check_cinder_hpe3par(section)
self._hpe3par_reserve_ip_addresses(section)
self._service_parameter_apply_semantic_check_cinder_hpelefthand()
self._hpelefthand_reserve_ip_addresses()
@ -986,7 +1005,7 @@ class ServiceParameterController(rest.RestController):
LOG.exception(e)
@staticmethod
def _hpe3par_reserve_ip_addresses():
def _hpe3par_reserve_ip_addresses(section):
"""
We need to keep the address information between service_parameter
@ -997,11 +1016,11 @@ class ServiceParameterController(rest.RestController):
Service Parameter | Address DB Entry Name
---------------------------------------------------------------
hpe3par_api_url | hpe3par-api-ip
hpe3par_api_url | <section>-api-ip
---------------------------------------------------------------
hpe3par_iscsi_ips | hpe3par-iscsi-ip<n>
hpe3par_iscsi_ips | <section>-iscsi-ip<n>
---------------------------------------------------------------
san_ip | hpe3par-san-ip
san_ip | <section>-san-ip
---------------------------------------------------------------
"""
@ -1011,7 +1030,7 @@ class ServiceParameterController(rest.RestController):
# feature is enabled.
#
name = "hpe3par-api-ip"
name = section + "-api-ip"
try:
addr = pecan.request.dbapi.address_get_by_name(name)
LOG.debug("Removing address %s" % name)
@ -1021,7 +1040,7 @@ class ServiceParameterController(rest.RestController):
i = 0
while True:
name = "hpe3par-iscsi-ip" + str(i)
name = section + "-iscsi-ip" + str(i)
try:
addr = pecan.request.dbapi.address_get_by_name(name)
LOG.debug("Removing address %s" % name)
@ -1030,7 +1049,7 @@ class ServiceParameterController(rest.RestController):
except exception.AddressNotFoundByName:
break
name = "hpe3par-san-ip"
name = section + "-san-ip"
try:
addr = pecan.request.dbapi.address_get_by_name(name)
LOG.debug("Removing address %s" % name)
@ -1040,7 +1059,7 @@ class ServiceParameterController(rest.RestController):
enabled = pecan.request.dbapi.service_parameter_get_one(
service=constants.SERVICE_TYPE_CINDER,
section=constants.SERVICE_PARAM_SECTION_CINDER_HPE3PAR,
section=section,
name="enabled")
if enabled.value.lower() == 'false':
@ -1051,7 +1070,7 @@ class ServiceParameterController(rest.RestController):
#
api_url = pecan.request.dbapi.service_parameter_get_one(
service=constants.SERVICE_TYPE_CINDER,
section=constants.SERVICE_PARAM_SECTION_CINDER_HPE3PAR,
section=section,
name="hpe3par_api_url")
url = urlparse.urlparse(api_url.value)
@ -1063,7 +1082,7 @@ class ServiceParameterController(rest.RestController):
#
if pool is not None:
try:
name = "hpe3par-api-ip"
name = section + "-api-ip"
address = {'address': str(ip),
'prefix': pool['prefix'],
'family': pool['family'],
@ -1099,7 +1118,7 @@ class ServiceParameterController(rest.RestController):
#
if pool is not None:
try:
name = "hpe3par-iscsi-ip" + str(i)
name = section + "-iscsi-ip" + str(i)
address = {'address': str(ip),
'prefix': pool['prefix'],
'family': pool['family'],
@ -1122,7 +1141,7 @@ class ServiceParameterController(rest.RestController):
try:
san_ip = pecan.request.dbapi.service_parameter_get_one(
service=constants.SERVICE_TYPE_CINDER,
section=constants.SERVICE_PARAM_SECTION_CINDER_HPE3PAR,
section=section,
name="san_ip")
except exception.NotFound:
return
@ -1135,7 +1154,7 @@ class ServiceParameterController(rest.RestController):
#
if pool is not None:
try:
name = "hpe3par-san-ip"
name = section + "-san-ip"
address = {'address': str(ip),
'prefix': pool['prefix'],
'family': pool['family'],
@ -1219,12 +1238,12 @@ class ServiceParameterController(rest.RestController):
raise wsme.exc.ClientSideError(msg)
@staticmethod
def _service_parameter_apply_semantic_check_cinder_hpe3par():
def _service_parameter_apply_semantic_check_cinder_hpe3par(section):
"""Semantic checks for the Cinder Service Type """
feature_enabled = pecan.request.dbapi.service_parameter_get_one(
service=constants.SERVICE_TYPE_CINDER,
section=constants.SERVICE_PARAM_SECTION_CINDER_HPE3PAR,
name=constants.SERVICE_PARAM_CINDER_HPE3PAR_ENABLED)
section=section,
name=constants.SERVICE_PARAM_CINDER_SAN_CHANGE_STATUS_ENABLED)
if feature_enabled.value.lower() == 'true':
# Client library installed? If not fail.
@ -1237,21 +1256,21 @@ class ServiceParameterController(rest.RestController):
try:
pecan.request.dbapi.service_parameter_get_one(
service=constants.SERVICE_TYPE_CINDER,
section=constants.SERVICE_PARAM_SECTION_CINDER_HPE3PAR,
section=section,
name=name)
except exception.NotFound:
msg = _("Unable to apply service parameters. "
"Missing service parameter '%s' for service '%s' "
"in section '%s'." % (name,
constants.SERVICE_TYPE_CINDER,
constants.SERVICE_PARAM_SECTION_CINDER_HPE3PAR))
section))
raise wsme.exc.ClientSideError(msg)
else:
if not pecan.request.rpcapi.validate_hpe3par_removal(
pecan.request.context):
pecan.request.context, section):
msg = _("Unable to apply service parameters. Can not disable "
"%s while in use. Remove any HPE3PAR volumes."
% constants.SERVICE_PARAM_SECTION_CINDER_HPE3PAR)
% section)
raise wsme.exc.ClientSideError(msg)
@staticmethod
@ -1260,7 +1279,7 @@ class ServiceParameterController(rest.RestController):
feature_enabled = pecan.request.dbapi.service_parameter_get_one(
service=constants.SERVICE_TYPE_CINDER,
section=constants.SERVICE_PARAM_SECTION_CINDER_HPELEFTHAND,
name=constants.SERVICE_PARAM_CINDER_HPELEFTHAND_ENABLED)
name=constants.SERVICE_PARAM_CINDER_SAN_CHANGE_STATUS_ENABLED)
if feature_enabled.value.lower() == 'true':
# Client library installed? If not fail.

View File

@ -815,12 +815,11 @@ SERVICE_PARAM_SECTION_CINDER_EMC_VNX = 'emc_vnx'
SERVICE_PARAM_CINDER_EMC_VNX_ENABLED = 'enabled'
SERVICE_PARAM_SECTION_CINDER_EMC_VNX_STATE = 'emc_vnx.state'
SERVICE_PARAM_MAX_HPE3PAR = 12
SERVICE_PARAM_SECTION_CINDER_HPE3PAR = 'hpe3par'
SERVICE_PARAM_CINDER_HPE3PAR_ENABLED = 'enabled'
SERVICE_PARAM_SECTION_CINDER_HPE3PAR_STATE = 'hpe3par.state'
SERVICE_PARAM_SECTION_CINDER_HPELEFTHAND = 'hpelefthand'
SERVICE_PARAM_CINDER_HPELEFTHAND_ENABLED = 'enabled'
SERVICE_PARAM_SECTION_CINDER_HPELEFTHAND_STATE = 'hpelefthand.state'
SERVICE_PARAM_CINDER_SAN_CHANGE_STATUS = 'status'

View File

@ -1219,7 +1219,7 @@ HPE_DATA_NETWORKS = [
#
CINDER_HPE3PAR_PARAMETER_MANDATORY = [
constants.SERVICE_PARAM_CINDER_HPE3PAR_ENABLED,
constants.SERVICE_PARAM_CINDER_SAN_CHANGE_STATUS_ENABLED,
]
CINDER_HPE3PAR_PARAMETER_PROTECTED = [
@ -1251,7 +1251,7 @@ CINDER_HPE3PAR_PARAMETER_OPTIONAL = (
CINDER_HPE3PAR_PARAMETER_VALIDATOR = {
# Mandatory parameters
constants.SERVICE_PARAM_CINDER_HPE3PAR_ENABLED: _validate_boolean,
constants.SERVICE_PARAM_CINDER_SAN_CHANGE_STATUS_ENABLED: _validate_boolean,
# Required parameters
'hpe3par_api_url': _validate_hpe_api_url,
'hpe3par_username': _validate_not_empty,
@ -1270,7 +1270,7 @@ CINDER_HPE3PAR_PARAMETER_VALIDATOR = {
CINDER_HPE3PAR_PARAMETER_RESOURCE = {
# Mandatory parameters
constants.SERVICE_PARAM_CINDER_HPE3PAR_ENABLED: None,
constants.SERVICE_PARAM_CINDER_SAN_CHANGE_STATUS_ENABLED: None,
# Required parameters
'hpe3par_api_url': None,
'hpe3par_username': None,
@ -1292,7 +1292,7 @@ CINDER_HPE3PAR_PARAMETER_RESOURCE = {
#
CINDER_HPELEFTHAND_PARAMETER_MANDATORY = [
constants.SERVICE_PARAM_CINDER_HPELEFTHAND_ENABLED,
constants.SERVICE_PARAM_CINDER_SAN_CHANGE_STATUS_ENABLED,
]
CINDER_HPELEFTHAND_PARAMETER_PROTECTED = []
@ -1321,7 +1321,7 @@ CINDER_HPELEFTHAND_PARAMETER_OPTIONAL = (
CINDER_HPELEFTHAND_PARAMETER_VALIDATOR = {
# Mandatory parameters
constants.SERVICE_PARAM_CINDER_HPELEFTHAND_ENABLED: _validate_boolean,
constants.SERVICE_PARAM_CINDER_SAN_CHANGE_STATUS_ENABLED: _validate_boolean,
# Required parameters
'hpelefthand_api_url': _validate_hpe_api_url,
'hpelefthand_username': _validate_not_empty,
@ -1335,7 +1335,7 @@ CINDER_HPELEFTHAND_PARAMETER_VALIDATOR = {
CINDER_HPELEFTHAND_PARAMETER_RESOURCE = {
# Mandatory parameters
constants.SERVICE_PARAM_CINDER_HPELEFTHAND_ENABLED: None,
constants.SERVICE_PARAM_CINDER_SAN_CHANGE_STATUS_ENABLED: None,
# Required parameters
'hpelefthand_api_url': None,
'hpelefthand_username': None,

View File

@ -428,12 +428,12 @@ class ConductorManager(service.PeriodicService):
},
{'service': constants.SERVICE_TYPE_CINDER,
'section': constants.SERVICE_PARAM_SECTION_CINDER_HPE3PAR,
'name': constants.SERVICE_PARAM_CINDER_HPE3PAR_ENABLED,
'name': constants.SERVICE_PARAM_CINDER_SAN_CHANGE_STATUS_ENABLED,
'value': False
},
{'service': constants.SERVICE_TYPE_CINDER,
'section': constants.SERVICE_PARAM_SECTION_CINDER_HPELEFTHAND,
'name': constants.SERVICE_PARAM_CINDER_HPELEFTHAND_ENABLED,
'name': constants.SERVICE_PARAM_CINDER_SAN_CHANGE_STATUS_ENABLED,
'value': False
},
{'service': constants.SERVICE_TYPE_CINDER,
@ -510,6 +510,16 @@ class ConductorManager(service.PeriodicService):
'value': constants.SERVICE_PARAM_SWIFT_FS_SIZE_MB_DEFAULT},
]
for i in range(2, constants.SERVICE_PARAM_MAX_HPE3PAR + 1):
section = "{0}{1}".format(constants.SERVICE_PARAM_SECTION_CINDER_HPE3PAR, i)
DEFAULT_PARAMETERS.extend([
{'service': constants.SERVICE_TYPE_CINDER,
'section': section,
'name': constants.SERVICE_PARAM_CINDER_SAN_CHANGE_STATUS_ENABLED,
'value': False
}]
)
def _create_default_service_parameter(self):
""" Populate the default service parameters"""
for p in ConductorManager.DEFAULT_PARAMETERS:
@ -4740,18 +4750,32 @@ class ConductorManager(service.PeriodicService):
of cinder services.
"""
# Only run audit of either one of the backends is enabled
# Only run audit if any one of the backends is enabled
hpe3par_enabled = False
try:
param = self.dbapi.service_parameter_get_one(constants.SERVICE_TYPE_CINDER,
constants.SERVICE_PARAM_SECTION_CINDER_HPE3PAR, 'enabled')
constants.SERVICE_PARAM_SECTION_CINDER_HPE3PAR,
constants.SERVICE_PARAM_CINDER_SAN_CHANGE_STATUS_ENABLED)
hpe3par_enabled = param.value.lower() == 'true'
except exception.NotFound:
hpe3par_enabled = False
pass
if not hpe3par_enabled:
for i in range(2, constants.SERVICE_PARAM_MAX_HPE3PAR + 1):
section = "{0}{1}".format(constants.SERVICE_PARAM_SECTION_CINDER_HPE3PAR, i)
try:
param = self.dbapi.service_parameter_get_one(constants.SERVICE_TYPE_CINDER,
section,
constants.SERVICE_PARAM_CINDER_SAN_CHANGE_STATUS_ENABLED)
hpe3par_enabled = param.value.lower() == 'true'
except exception.NotFound:
pass
if hpe3par_enabled:
break
try:
param = self.dbapi.service_parameter_get_one(constants.SERVICE_TYPE_CINDER,
constants.SERVICE_PARAM_SECTION_CINDER_HPELEFTHAND, 'enabled')
constants.SERVICE_PARAM_SECTION_CINDER_HPELEFTHAND,
constants.SERVICE_PARAM_CINDER_SAN_CHANGE_STATUS_ENABLED)
hpelefthand_enabled = param.value.lower() == 'true'
except exception.NotFound:
hpelefthand_enabled = False
@ -6991,12 +7015,28 @@ class ConductorManager(service.PeriodicService):
status_param = self._hpe_get_state(name)
status = status_param.value
enabled_param = self.dbapi.service_parameter_get_one(
constants.SERVICE_TYPE_CINDER, name,
constants.SERVICE_PARAM_CINDER_SAN_CHANGE_STATUS_ENABLED
)
enabled = (enabled_param.value.lower() == 'true')
enabled = False
try:
enabled_param = self.dbapi.service_parameter_get_one(
constants.SERVICE_TYPE_CINDER, name,
constants.SERVICE_PARAM_CINDER_SAN_CHANGE_STATUS_ENABLED
)
enabled = (enabled_param.value.lower() == 'true')
except exception.NotFound:
pass
if not enabled and name == constants.SERVICE_PARAM_SECTION_CINDER_HPE3PAR:
for i in range(2, constants.SERVICE_PARAM_MAX_HPE3PAR + 1):
section = "{0}{1}".format(name, i)
try:
enabled_param = self.dbapi.service_parameter_get_one(
constants.SERVICE_TYPE_CINDER, section,
constants.SERVICE_PARAM_CINDER_SAN_CHANGE_STATUS_ENABLED
)
enabled = (enabled_param.value.lower() == 'true')
except exception.NotFound:
pass
if enabled:
break
if enabled and status == constants.SERVICE_PARAM_CINDER_SAN_CHANGE_STATUS_DISABLED:
do_update = True
new_state = constants.SERVICE_PARAM_CINDER_SAN_CHANGE_STATUS_ENABLED
@ -9230,7 +9270,7 @@ class ConductorManager(service.PeriodicService):
return not emc_volume_found
def validate_hpe3par_removal(self, context):
def validate_hpe3par_removal(self, context, backend):
"""
Check that it is safe to remove the HPE3PAR SAN
Ensure there are no volumes using the HPE3PAR endpoint
@ -9239,7 +9279,7 @@ class ConductorManager(service.PeriodicService):
for volume in self._openstack.get_cinder_volumes():
end_point = getattr(volume, 'os-vol-host-attr:host', '')
if end_point and '@hpe3par' in end_point:
if end_point and '@' + backend + '#' in end_point:
volume_found = True
break

View File

@ -1368,11 +1368,13 @@ class ConductorAPI(sysinv.openstack.common.rpc.proxy.RpcProxy):
"""
return self.call(context, self.make_msg('validate_emc_removal'))
def validate_hpe3par_removal(self, context):
def validate_hpe3par_removal(self, context, backend):
"""
Check that it is safe to remove the HPE 3PAR storage array
"""
return self.call(context, self.make_msg('validate_hpe3par_removal'))
return self.call(context,
self.make_msg('validate_hpe3par_removal',
backend=backend))
def validate_hpelefthand_removal(self, context):
"""

View File

@ -250,7 +250,7 @@ def sp_hpe3par_post_process(config, section, section_map,
if provided_params.get('enabled', 'false').lower() == 'true':
# Hardcoded params must exist in cinder.conf.
provided_params['volume_backend_name'] = SP_CINDER_HPE3PAR
provided_params['volume_backend_name'] = section
provided_params['volume_driver'] = (
'cinder.volume.drivers.hpe.hpe_3par_iscsi.HPE3PARISCSIDriver')
@ -345,6 +345,18 @@ class CinderPuppet(openstack.OpenstackBasePuppet):
SERVICE_PATH_V3 = 'v3/%(tenant_id)s'
PROXY_SERVICE_PORT = '28776'
def __init__(self, *args, **kwargs):
super(CinderPuppet, self).__init__(*args, **kwargs)
# Update the section mapping for multiple HPE3PAR backends
for i in range(2, constants.SERVICE_PARAM_MAX_HPE3PAR + 1):
section = "{0}{1}".format(SP_CINDER_HPE3PAR, i)
prefix = "{0}{1}".format(SP_CINDER_HPE3PAR_PREFIX, i)
SP_CINDER_SECTION_MAPPING[section] = {
SP_CONF_NAME_KEY: prefix,
SP_PARAM_PROCESS_KEY: sp_common_param_process,
SP_POST_PROCESS_KEY: sp_hpe3par_post_process,
}
def get_static_config(self):
dbuser = self._get_database_username(self.SERVICE_NAME)
@ -760,6 +772,11 @@ class CinderPuppet(openstack.OpenstackBasePuppet):
config, section, sp_section_map,
is_service_enabled, enabled_backends)
# Build the list of possible HPE3PAR backends
possible_hpe3pars = filter(
lambda s: constants.SERVICE_PARAM_SECTION_CINDER_HPE3PAR in s,
SP_CINDER_SECTION_MAPPING.keys())
config.update({'openstack::cinder::backends::hpe3par::sections': possible_hpe3pars})
return config
def is_service_enabled(self):