@@ -1103,8 +1103,8 @@ private String validateConfigurationValue(final String name, String value, final
11031103 }
11041104 }
11051105 Class <?> type = null ;
1106- final Config c = Config .getConfig (name );
1107- if (c == null ) {
1106+ final Config configuration = Config .getConfig (name );
1107+ if (configuration == null ) {
11081108 s_logger .warn ("Did not find configuration " + name + " in Config.java. Perhaps moved to ConfigDepot" );
11091109 final ConfigKey <?> configKey = _configDepot .get (name );
11101110 if (configKey == null ) {
@@ -1113,7 +1113,7 @@ private String validateConfigurationValue(final String name, String value, final
11131113 }
11141114 type = configKey .type ();
11151115 } else {
1116- type = c .getType ();
1116+ type = configuration .getType ();
11171117 }
11181118 //no need to validate further if a
11191119 //config can have null value.
@@ -1222,96 +1222,145 @@ private String validateConfigurationValue(final String name, String value, final
12221222 }
12231223 }
12241224
1225- if ( c == null ) {
1225+ if ( configuration == null ) {
12261226 //range validation has to be done per case basis, for now
12271227 //return in case of Configkey parameters
12281228 return null ;
12291229 }
12301230
1231- final String range = c .getRange ();
1231+ final String [] range = configuration .getRange ();
12321232 if (range == null ) {
12331233 return null ;
12341234 }
12351235
12361236 if (type .equals (String .class )) {
1237- if (range .equals ("privateip" )) {
1238- try {
1239- if (!NetUtils .isSiteLocalAddress (value )) {
1240- s_logger .error ("privateip range " + value + " is not a site local address for configuration variable " + name );
1241- return "Please enter a site local IP address." ;
1242- }
1243- } catch (final NullPointerException e ) {
1244- s_logger .error ("Error parsing ip address for " + name );
1245- throw new InvalidParameterValueException ("Error parsing ip address" );
1246- }
1247- } else if (range .equals ("netmask" )) {
1248- if (!NetUtils .isValidIp4Netmask (value )) {
1249- s_logger .error ("netmask " + value + " is not a valid net mask for configuration variable " + name );
1250- return "Please enter a valid netmask." ;
1251- }
1252- } else if (range .equals ("hypervisorList" )) {
1253- final String [] hypervisors = value .split ("," );
1254- if (hypervisors == null ) {
1255- return "Please enter hypervisor list, separated by comma" ;
1256- }
1257- for (final String hypervisor : hypervisors ) {
1258- if (HypervisorType .getType (hypervisor ) == HypervisorType .Any || HypervisorType .getType (hypervisor ) == HypervisorType .None ) {
1259- return "Please enter a valid hypervisor type" ;
1260- }
1261- }
1262- } else if (range .equalsIgnoreCase ("instanceName" )) {
1263- if (!NetUtils .verifyInstanceName (value )) {
1264- return "Instance name can not contain hyphen, space or plus sign" ;
1265- }
1266- } else if (range .equalsIgnoreCase ("domainName" )) {
1267- String domainName = value ;
1268- if (value .startsWith ("*" )) {
1269- domainName = value .substring (2 ); //skip the "*."
1270- }
1271- //max length for FQDN is 253 + 2, code adds xxx-xxx-xxx-xxx to domain name when creating URL
1272- if (domainName .length () >= 238 || !domainName .matches (DOMAIN_NAME_PATTERN )) {
1273- return "Please enter a valid string for domain name, prefixed with '*.' if applicable" ;
1274- }
1275- } else if (range .equals ("routes" )) {
1276- final String [] routes = value .split ("," );
1277- for (final String route : routes ) {
1278- if (route != null ) {
1279- final String routeToVerify = route .trim ();
1280- if (!NetUtils .isValidIp4Cidr (routeToVerify )) {
1281- throw new InvalidParameterValueException ("Invalid value for route: " + route + " in deny list. Valid format is list"
1282- + " of cidrs separated by coma. Example: 10.1.1.0/24,192.168.0.0/24" );
1283- }
1284- }
1285- }
1286- } else {
1287- final String [] options = range .split ("," );
1288- for (final String option : options ) {
1289- if (option .trim ().equalsIgnoreCase (value )) {
1290- return null ;
1291- }
1292- }
1293- s_logger .error ("configuration value for " + name + " is invalid" );
1294- return "Please enter : " + range ;
1237+ return validateIfStringValueIsInRange (name , value , range );
1238+ } else if (type .equals (Integer .class )) {
1239+ return validateIfIntValueIsInRange (name , value , range [0 ]);
1240+ }
1241+ return String .format ("Invalid value for configuration [%s]." , name );
1242+ }
12951243
1244+ /**
1245+ * A valid value should be an integer between min and max (the values from the range).
1246+ */
1247+ protected String validateIfIntValueIsInRange (String name , String value , String range ) {
1248+ final String [] options = range .split ("-" );
1249+ final int min = Integer .parseInt (options [0 ]);
1250+ final int max = Integer .parseInt (options [1 ]);
1251+ final int val = Integer .parseInt (value );
1252+ if (val < min || val > max ) {
1253+ s_logger .error (String .format ("Invalid value for configuration [%s]. Please enter a value in the range [%s]." , name , range ));
1254+ return String .format ("The provided value is not valid for this configuration. Please enter an integer in the range: [%s]" , range );
1255+ }
1256+ return null ;
1257+ }
1258+
1259+ /**
1260+ * This method checks if the value for the configuration is valid for any of the ranges selected.
1261+ */
1262+ protected String validateIfStringValueIsInRange (String name , String value , String ... range ) {
1263+ List <String > message = new ArrayList <String >();
1264+ String errMessage = "" ;
1265+ for (String rangeOption : range ) {
1266+ switch (rangeOption ) {
1267+ case "privateip" :
1268+ errMessage = validateRangePrivateIp (name , value );
1269+ break ;
1270+ case "hypervisorList" :
1271+ errMessage = validateRangeHypervisorList (value );
1272+ break ;
1273+ case "instanceName" :
1274+ errMessage = validateRangeInstanceName (value );
1275+ break ;
1276+ case "domainName" :
1277+ errMessage = validateRangeDomainName (value );
1278+ break ;
1279+ default :
1280+ errMessage = validateRangeOther (name , value , rangeOption );
1281+ }
1282+ if (Strings .isNullOrEmpty (errMessage )) {
1283+ return null ;
12961284 }
1297- } else if (type .equals (Integer .class )) {
1298- final String [] options = range .split ("-" );
1299- if (options .length != 2 ) {
1300- final String msg = "configuration range " + range + " for " + name + " is invalid" ;
1301- s_logger .error (msg );
1302- return msg ;
1285+ message .add (errMessage );
1286+ }
1287+ if (message .size () == 1 ) {
1288+ return String .format ("The provided value is not %s." , message .get (0 ));
1289+ }
1290+ return String .format ("The provided value is neither %s." , String .join (" NOR " , message ));
1291+ }
1292+
1293+ /**
1294+ * Checks if the value is a private IP according to {@link NetUtils#isSiteLocalAddress(String)}.
1295+ */
1296+ protected String validateRangePrivateIp (String name , String value ) {
1297+ try {
1298+ if (NetUtils .isSiteLocalAddress (value )) {
1299+ return null ;
13031300 }
1304- final int min = Integer .parseInt (options [0 ]);
1305- final int max = Integer .parseInt (options [1 ]);
1306- final int val = Integer .parseInt (value );
1307- if (val < min || val > max ) {
1308- s_logger .error ("configuration value for " + name + " is invalid" );
1309- return "Please enter : " + range ;
1301+ s_logger .error (String .format ("Value [%s] is not a valid private IP range for configuration [%s]." , value , name ));
1302+ } catch (final NullPointerException e ) {
1303+ s_logger .error (String .format ("Error while parsing IP address for [%s]." , name ));
1304+ }
1305+ return "a valid site local IP address" ;
1306+ }
1307+
1308+ /**
1309+ * Valid values are XenServer, KVM, VMware, Hyperv, VirtualBox, Parralels, BareMetal, Simulator, Ovm, Ovm3, LXC.
1310+ * Inputting "Any" will return the hypervisor type Any, other inputs will result in the hypervisor type none.
1311+ * Both of these are invalid values and will return an error message.
1312+ */
1313+ protected String validateRangeHypervisorList (String value ) {
1314+ final String [] hypervisors = value .split ("," );
1315+ for (final String hypervisor : hypervisors ) {
1316+ if (HypervisorType .getType (hypervisor ) == HypervisorType .Any || HypervisorType .getType (hypervisor ) == HypervisorType .None ) {
1317+ return "a valid hypervisor type" ;
13101318 }
13111319 }
13121320 return null ;
13131321 }
13141322
1323+ /**
1324+ * Valid values are instance names, the only restriction is that they may not have hyphens, spaces or plus signs.
1325+ */
1326+ protected String validateRangeInstanceName (String value ) {
1327+ if (NetUtils .verifyInstanceName (value )) {
1328+ return null ;
1329+ }
1330+ return "a valid instance name (instance names cannot contain hyphen, space or plus sign)" ;
1331+ }
1332+
1333+ /**
1334+ * Verifies if the value is a valid domain name. If it starts with "*.", these two symbols are ignored and do not count towards the character limit.
1335+ * Max length for FQDN is 253 + 2, code adds xxx-xxx-xxx-xxx to domain name when creating URL.
1336+ */
1337+ protected String validateRangeDomainName (String value ) {
1338+ String domainName = value ;
1339+ if (value .startsWith ("*" )) {
1340+ domainName = value .substring (2 );
1341+ }
1342+ if (domainName .length () >= 238 || !domainName .matches (DOMAIN_NAME_PATTERN )) {
1343+ return "a valid domain name" ;
1344+ }
1345+ return null ;
1346+ }
1347+
1348+ /**
1349+ * In configurations where this type of range is used, a list of possible values is passed as argument in the creation of the configuration,
1350+ * a valid value is any option within this list.
1351+ */
1352+ protected String validateRangeOther (String name , String value , String rangeOption ) {
1353+ final String [] options = rangeOption .split ("," );
1354+ for (final String option : options ) {
1355+ if (option .trim ().equalsIgnoreCase (value )) {
1356+ return null ;
1357+ }
1358+ }
1359+ s_logger .error (String .format ("Invalid value for configuration [%s]." , name ));
1360+ return String .format ("a valid value for this configuration (Options are: [%s])" , rangeOption );
1361+ }
1362+
1363+
13151364 private boolean podHasAllocatedPrivateIPs (final long podId ) {
13161365 final HostPodVO pod = _podDao .findById (podId );
13171366 final int count = _privateIpAddressDao .countIPs (podId , pod .getDataCenterId (), true );
0 commit comments