Eli Mesika has uploaded a new change for review. Change subject: core: add support for custom fencing ......................................................................
core: add support for custom fencing Up to now if a customer wants to add an additional fencing device, he had to tweak the oVirt fencing configuration values while those changes were overridden when engine-setup upgrades oVirt. This patch adds a custom configuration key for each of the relevant fencing configuration keys such that the customer can set those keys using the engin-config utility and the corresponding values are merged with the original after validating that their formats are valid. Change-Id: Ie887b9025d0813c4d101a886614364127aea75a0 Signed-off-by: Eli Mesika <emes...@redhat.com> --- A backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/GetFenceConfigurationValueQuery.java M backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/config/ConfigValues.java M backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/queries/VdcQueryType.java M backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendCapabilitiesResource.java M backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendResource.java A backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/pm/FenceConfigHelper.java M backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/pm/VdsFenceOptions.java M frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/dataprovider/AsyncDataProvider.java M packaging/dbscripts/upgrade/pre_upgrade/0000_config.sql M packaging/etc/engine-config/engine-config.properties 10 files changed, 164 insertions(+), 10 deletions(-) git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/21/28621/1 diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/GetFenceConfigurationValueQuery.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/GetFenceConfigurationValueQuery.java new file mode 100644 index 0000000..914f2ed --- /dev/null +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/GetFenceConfigurationValueQuery.java @@ -0,0 +1,50 @@ +package org.ovirt.engine.core.bll; + + import org.ovirt.engine.core.common.config.Config; + import org.ovirt.engine.core.common.config.ConfigCommon; + import org.ovirt.engine.core.common.config.ConfigValues; + import org.ovirt.engine.core.common.queries.GetConfigurationValueParameters; + import org.ovirt.engine.core.utils.pm.FenceConfigHelper; + +public class GetFenceConfigurationValueQuery<P extends GetConfigurationValueParameters> extends QueriesCommandBase<P> { + public GetFenceConfigurationValueQuery(P parameters) { + super(parameters); + } + + @Override + protected void executeQueryCommand() { + String returnValue = null; + String customReturnValue = null; + if (shouldReturnValue()) { + try { + final GetConfigurationValueParameters params = getParameters(); + final ConfigValues value = ConfigValues.valueOf(params.getConfigValue().toString()); + final ConfigValues customValue = ConfigValues.valueOf(FenceConfigHelper.getCustomKey( params.getConfigValue().toString())); + String version = params.getVersion(); + if (version == null) { + log.warnFormat("calling {0} ({2}) with null version, using default {1} for version", + GetConfigurationValueQuery.class.getSimpleName(), ConfigCommon.defaultConfigurationVersion, value); + version = ConfigCommon.defaultConfigurationVersion; + } + returnValue = Config.getValue(value, version); + customReturnValue = Config.getValue(customValue, ConfigCommon.defaultConfigurationVersion); + } catch (Exception e) { + log.error("Unable to return config parameter: " + getParameters(), e); + } + } + + getQueryReturnValue().setReturnValue(FenceConfigHelper.merge(getParameters().getConfigValue().toString(), returnValue, customReturnValue)); + } + + /** + * Validates if the query should return anything or not, according to the user's permissions: + * <ul> + * <li>If the query is run as an administrator (note that since we've reached the {@link #executeQueryCommand()} method, + * we've already validated that the use is indeed an administrator), the results from the database queries should be returned.</li> + * <li>If the query is run as a user, it may return results <b>ONLY</b> if the configuration value has {@link org.ovirt.engine.core.common.queries.ConfigurationValues.ConfigAuthType#User}.</li> + * </ul> + */ + private boolean shouldReturnValue() { + return !getParameters().isFiltered() || !getParameters().getConfigValue().isAdmin(); + } +} diff --git a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/config/ConfigValues.java b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/config/ConfigValues.java index 45aac02..fbe3804 100644 --- a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/config/ConfigValues.java +++ b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/config/ConfigValues.java @@ -97,8 +97,16 @@ VdsFenceType, @Reloadable @TypeConverterAttribute(String.class) + @DefaultValueAttribute("") + CustomVdsFenceType, + @Reloadable + @TypeConverterAttribute(String.class) @DefaultValueAttribute("alom:secure=secure,port=ipport;apc:secure=secure,port=ipport,slot=port;bladecenter:secure=secure,port=ipport,slot=port;drac5:secure=secure,port=ipport;eps:slot=port;ilo:secure=ssl,port=ipport;ipmilan:;rsa:secure=secure,port=ipport;rsb:;wti:secure=secure,port=ipport,slot=port") VdsFenceOptionMapping, + @Reloadable + @TypeConverterAttribute(String.class) + @DefaultValueAttribute("") + CustomVdsFenceOptionMapping, @Reloadable @TypeConverterAttribute(String.class) @DefaultValueAttribute("secure=bool,port=int,slot=int") @@ -806,9 +814,19 @@ @Reloadable @TypeConverterAttribute(String.class) + @DefaultValueAttribute("") + CustomFenceAgentMapping, + + @Reloadable + @TypeConverterAttribute(String.class) @DefaultValueAttribute("ilo3:lanplus,power_wait=4") FenceAgentDefaultParams, + @Reloadable + @TypeConverterAttribute(String.class) + @DefaultValueAttribute("") + CustomFenceAgentDefaultParams, + @TypeConverterAttribute(String.class) @DefaultValueAttribute("admin") AdminUser, diff --git a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/queries/VdcQueryType.java b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/queries/VdcQueryType.java index fb6bfdc..1d56aab 100644 --- a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/queries/VdcQueryType.java +++ b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/queries/VdcQueryType.java @@ -188,6 +188,7 @@ // Configuration values GetConfigurationValue(VdcQueryAuthType.User), GetConfigurationValues(VdcQueryAuthType.User), + GetFenceConfigurationValue(VdcQueryAuthType.User), GetDefaultTimeZone(VdcQueryAuthType.User), GetAvailableStoragePoolVersions(VdcQueryAuthType.User), GetAvailableClusterVersionsByStoragePool, diff --git a/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendCapabilitiesResource.java b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendCapabilitiesResource.java index fc2c470..bbfa8f2 100644 --- a/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendCapabilitiesResource.java +++ b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendCapabilitiesResource.java @@ -576,9 +576,11 @@ } private List<PowerManagement> getPowerManagers(Version version) { - return FenceOptionsParser.parse(getConfigurationValue(String.class, ConfigurationValues.VdsFenceOptionMapping, version), - getConfigurationValue(String.class, ConfigurationValues.VdsFenceOptionTypes, version), - true); + return FenceOptionsParser.parse(getFenceConfigurationValue(String.class, + ConfigurationValues.VdsFenceOptionMapping, + version), + getConfigurationValue(String.class, ConfigurationValues.VdsFenceOptionTypes, version), + true); } private List<StorageType> getStorageTypes(Version version) { diff --git a/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendResource.java b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendResource.java index 531e270..0d6bd36 100644 --- a/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendResource.java +++ b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendResource.java @@ -314,6 +314,14 @@ config.toString()); } + @SuppressWarnings("serial") + protected <T> T getFenceConfigurationValue(Class<T> clz, ConfigurationValues config, final Version version) { + return getEntity(clz, + VdcQueryType.GetFenceConfigurationValue, + new GetConfigurationValueParameters(config, asString(version)), + config.toString()); + } + protected <T> T getConfigurationValueDefault(Class<T> clz, ConfigurationValues config) { return getEntity(clz, VdcQueryType.GetConfigurationValue, diff --git a/backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/pm/FenceConfigHelper.java b/backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/pm/FenceConfigHelper.java new file mode 100644 index 0000000..0a50a30 --- /dev/null +++ b/backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/pm/FenceConfigHelper.java @@ -0,0 +1,58 @@ +package org.ovirt.engine.core.utils.pm; + +import org.apache.commons.lang.StringUtils; +import org.ovirt.engine.core.utils.log.Log; +import org.ovirt.engine.core.utils.log.LogFactory; + +import java.util.HashMap; + +public class FenceConfigHelper { + private static HashMap<String, String> keyValidatorMap; + private static HashMap<String, String> keySeparatorMap; + private static Log log; + private static boolean initialized=false; + + private static void init() { + log = LogFactory.getLog(FenceConfigHelper.class); + keyValidatorMap = new HashMap<String, String>(); + keyValidatorMap.put("FenceAgentMapping", "((\\w)+[=](\\w)+[,]{0,1})+"); + keyValidatorMap.put("FenceAgentDefaultParams", "([\\w]+([=][\\w]+){0,1}[,]{0,1})+"); + keyValidatorMap.put("VdsFenceOptionMapping", "([\\w]+[:]([\\w]*[=][\\w]*[,]{0,1}[;]{0,1}){0,3}[;]{0,1})+"); + keyValidatorMap.put("VdsFenceType", "((\\w)+[,]{0,1})+"); + keySeparatorMap = new HashMap<String, String>(); + keySeparatorMap.put("FenceAgentMapping", ","); + keySeparatorMap.put("FenceAgentDefaultParams", ";"); + keySeparatorMap.put("VdsFenceOptionMapping", ";"); + keySeparatorMap.put("VdsFenceType", ","); + initialized=true; + } + + public static String getCustomKey(String key) { + return "Custom" + key; + } + + public static String merge(String key, String value, String customValue) { + if (!initialized) { + init(); + } + StringBuilder sb = new StringBuilder(); + sb.append(value); + if (StringUtils.isNotEmpty(value) && StringUtils.isNotEmpty(customValue)) { + if (isValid(key, customValue)) { + sb.append(keySeparatorMap.get(key)); + sb.append(customValue); + } + else { + log.errorFormat("Configuration key {0} has illegal value {1}. Expression should match {2}", key, customValue, keyValidatorMap.get(key)); + } + } + return sb.toString(); + } + + private static boolean isValid(String key, String value) { + if (keyValidatorMap.containsKey(key) && keySeparatorMap.containsKey(key)) { + return value.matches(keyValidatorMap.get(key)); + } + return false; + } +} diff --git a/backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/pm/VdsFenceOptions.java b/backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/pm/VdsFenceOptions.java index 2fdb324..eecbdc3 100644 --- a/backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/pm/VdsFenceOptions.java +++ b/backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/pm/VdsFenceOptions.java @@ -9,6 +9,7 @@ import org.apache.commons.lang.StringUtils; import org.ovirt.engine.core.common.config.Config; +import org.ovirt.engine.core.common.config.ConfigCommon; import org.ovirt.engine.core.common.config.ConfigValues; import org.ovirt.engine.core.compat.IntegerCompat; import org.ovirt.engine.core.utils.log.Log; @@ -75,8 +76,10 @@ * alom:secure=secure,port=ipport;apc:secure=secure,port=ipport,slot=port */ private void CacheFencingAgentsOptionMapping() { - String localfencingOptionMapping = Config.<String> getValue(ConfigValues.VdsFenceOptionMapping, version); - String[] agentsOptionsStr = localfencingOptionMapping.split(Pattern.quote(SEMICOLON), -1); + String localFencingOptionMapping = Config.<String> getValue(ConfigValues.VdsFenceOptionMapping, version); + String customFencingOptionMapping= Config.<String> getValue(ConfigValues.CustomVdsFenceOptionMapping, ConfigCommon.defaultConfigurationVersion); + localFencingOptionMapping = FenceConfigHelper.merge(ConfigValues.VdsFenceOptionMapping.name(), localFencingOptionMapping, customFencingOptionMapping); + String[] agentsOptionsStr = localFencingOptionMapping.split(Pattern.quote(SEMICOLON), -1); for (String agentOptionsStr : agentsOptionsStr) { String[] parts = agentOptionsStr.split(Pattern.quote(COLON), -1); if (parts.length == 2) { @@ -270,7 +273,7 @@ * @return string , the agent real name to be used */ public static String getRealAgent(String agent) { - String agentMapping = Config.<String> getValue(ConfigValues.FenceAgentMapping); + String agentMapping = FenceConfigHelper.merge(ConfigValues.FenceAgentMapping.name(), Config.<String> getValue(ConfigValues.FenceAgentMapping), Config.<String> getValue(ConfigValues.CustomFenceAgentMapping)); String realAgent = agent; // result has the format [<agent>=<real agent>[,]]* String[] settings = agentMapping.split(Pattern.quote(COMMA), -1); @@ -297,7 +300,7 @@ * @return String the options after adding default agent parameters */ public static String getDefaultAgentOptions(String agent, String fenceOptions) { - String agentdefaultParams = Config.<String> getValue(ConfigValues.FenceAgentDefaultParams); + String agentdefaultParams = FenceConfigHelper.merge(ConfigValues.FenceAgentDefaultParams.name(), Config.<String> getValue(ConfigValues.FenceAgentDefaultParams), Config.<String> getValue(ConfigValues.CustomFenceAgentDefaultParams)); StringBuilder realOptions = new StringBuilder(fenceOptions); // result has the format [<agent>:param=value[,]...;]* String[] params = agentdefaultParams.split(Pattern.quote(SEMICOLON), -1); diff --git a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/dataprovider/AsyncDataProvider.java b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/dataprovider/AsyncDataProvider.java index 061ab3e..1b0fded 100644 --- a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/dataprovider/AsyncDataProvider.java +++ b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/dataprovider/AsyncDataProvider.java @@ -1959,9 +1959,9 @@ return list; } }; - GetConfigurationValueParameters tempVar = new GetConfigurationValueParameters(ConfigurationValues.VdsFenceType); - tempVar.setVersion(version != null ? version.toString() : getDefaultConfigurationVersion()); - getConfigFromCache(tempVar, aQuery); + GetConfigurationValueParameters param = new GetConfigurationValueParameters(ConfigurationValues.VdsFenceType); + param.setVersion(version != null ? version.toString() : getDefaultConfigurationVersion()); + Frontend.getInstance().runQuery(VdcQueryType.GetFenceConfigurationValue, param, aQuery); } public static void getPmOptions(AsyncQuery aQuery, String pmType, String version) { diff --git a/packaging/dbscripts/upgrade/pre_upgrade/0000_config.sql b/packaging/dbscripts/upgrade/pre_upgrade/0000_config.sql index 4ca5e3c..b96d91e 100644 --- a/packaging/dbscripts/upgrade/pre_upgrade/0000_config.sql +++ b/packaging/dbscripts/upgrade/pre_upgrade/0000_config.sql @@ -107,7 +107,9 @@ --Handling Use Default Credentials select fn_db_add_config_value('FailedJobCleanupTimeInMinutes','60','general'); select fn_db_add_config_value('FenceAgentDefaultParams','ilo3:lanplus,power_wait=4;ilo4:lanplus,power_wait=4','general'); +select fn_db_add_config_value('CustomFenceAgentDefaultParams','','general'); select fn_db_add_config_value('FenceAgentMapping','drac7=ipmilan,ilo2=ilo,ilo3=ipmilan,ilo4=ipmilan','general'); +select fn_db_add_config_value('CustomFenceAgentMapping','','general'); select fn_db_add_config_value('FenceProxyDefaultPreferences','cluster,dc','general'); select fn_db_add_config_value('FenceQuietTimeBetweenOperationsInSec','180','general'); select fn_db_add_config_value('FenceStartStatusDelayBetweenRetriesInSec','60','general'); @@ -599,6 +601,7 @@ select fn_db_add_config_value('VdsFenceOptionMapping','apc:secure=secure,port=ipport,slot=port;apc_snmp:port=port;bladecenter:secure=secure,port=ipport,slot=port;cisco_ucs:secure=ssl,slot=port;drac5:secure=secure,slot=port;eps:slot=port;ilo:secure=ssl,port=ipport;ipmilan:;ilo2:secure=ssl,port=ipport;ilo3:;ilo4:;rsa:secure=secure,port=ipport;rsb:;wti:secure=secure,port=ipport,slot=port','3.3'); select fn_db_add_config_value('VdsFenceOptionMapping','apc:secure=secure,port=ipport,slot=port;apc_snmp:port=port;bladecenter:secure=secure,port=ipport,slot=port;cisco_ucs:secure=ssl,slot=port;drac5:secure=secure,slot=port;drac7:;eps:slot=port;hpblade:port=port;ilo:secure=ssl,port=ipport;ipmilan:;ilo2:secure=ssl,port=ipport;ilo3:;ilo4:;rsa:secure=secure,port=ipport;rsb:;wti:secure=secure,port=ipport,slot=port','3.4'); select fn_db_add_config_value('VdsFenceOptionMapping','apc:secure=secure,port=ipport,slot=port;apc_snmp:port=port;bladecenter:secure=secure,port=ipport,slot=port;cisco_ucs:secure=ssl,slot=port;drac5:secure=secure,slot=port;drac7:;eps:slot=port;hpblade:port=port;ilo:secure=ssl,port=ipport;ipmilan:;ilo2:secure=ssl,port=ipport;ilo3:;ilo4:;rsa:secure=secure,port=ipport;rsb:;wti:secure=secure,port=ipport,slot=port','3.5'); +select fn_db_add_config_value('CustomVdsFenceOptionMapping','','general'); select fn_db_add_config_value('VdsFenceOptions','','general'); select fn_db_add_config_value('VdsFenceOptionTypes','secure=bool,port=int,slot=int','general'); select fn_db_add_config_value('VdsFenceType','alom,apc,bladecenter,drac5,eps,ilo,ilo3,ipmilan,rsa,rsb,wti,cisco_ucs','3.0'); @@ -607,6 +610,7 @@ select fn_db_add_config_value('VdsFenceType','apc,apc_snmp,bladecenter,cisco_ucs,drac5,eps,ilo,ilo2,ilo3,ilo4,ipmilan,rsa,rsb,wti','3.3'); select fn_db_add_config_value('VdsFenceType','apc,apc_snmp,bladecenter,cisco_ucs,drac5,drac7,eps,hpblade,ilo,ilo2,ilo3,ilo4,ipmilan,rsa,rsb,wti','3.4'); select fn_db_add_config_value('VdsFenceType','apc,apc_snmp,bladecenter,cisco_ucs,drac5,drac7,eps,hpblade,ilo,ilo2,ilo3,ilo4,ipmilan,rsa,rsb,wti','3.5'); +select fn_db_add_config_value('CustomVdsFenceType','','general'); select fn_db_add_config_value('VdsLoadBalancingeIntervalInMinutes','1','general'); select fn_db_add_config_value('VdsLocalDisksCriticallyLowFreeSpace','100','general'); select fn_db_add_config_value('VdsLocalDisksLowFreeSpace','500','general'); diff --git a/packaging/etc/engine-config/engine-config.properties b/packaging/etc/engine-config/engine-config.properties index 444a735..1bd6f05 100644 --- a/packaging/etc/engine-config/engine-config.properties +++ b/packaging/etc/engine-config/engine-config.properties @@ -398,3 +398,13 @@ # Reports link RedirectServletReportsPage.description="Redirection target for Reports link" RedirectServletReportsPage.type=String +# Custome fence agents configurations +CustomFenceAgentMapping.description="Maps a fencing agent to other agent implicitly. Format : ((\\w)+[=](\\w)+[,]{0,1})+" +CustomFenceAgentMapping.type=String +CustomFenceAgentDefaultParams.description="Default parameters per agent. Format ([\\w]+([=][\\w]+){0,1}[,]{0,1})+" +CustomFenceAgentDefaultParams.type=String +CustomVdsFenceOptionMapping.description="secure/port/slot mapping support per agent. Format ([\\w]+[:]([\\w]*[=][\\w]*[,]{0,1}[;]{0,1}){0,3}[;]{0,1})+" +CustomVdsFenceOptionMapping.type=String +CustomVdsFenceType.description="Fence agents types. Format ((\\w)+[,]{0,1})+")" +CustomVdsFenceType.type=String + -- To view, visit http://gerrit.ovirt.org/28621 To unsubscribe, visit http://gerrit.ovirt.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ie887b9025d0813c4d101a886614364127aea75a0 Gerrit-PatchSet: 1 Gerrit-Project: ovirt-engine Gerrit-Branch: master Gerrit-Owner: Eli Mesika <emes...@redhat.com> _______________________________________________ Engine-patches mailing list Engine-patches@ovirt.org http://lists.ovirt.org/mailman/listinfo/engine-patches