Revision b342c9dd

b/lib/objects.py
955 955
    if check_std and constants.ISPECS_STD not in ipolicy:
956 956
      msg = "Missing key in ipolicy: %s" % constants.ISPECS_STD
957 957
      raise errors.ConfigurationError(msg)
958
    minmaxspecs = ipolicy[constants.ISPECS_MINMAX]
959 958
    stdspec = ipolicy.get(constants.ISPECS_STD)
959
    if check_std:
960
      InstancePolicy._CheckIncompleteSpec(stdspec, constants.ISPECS_STD)
961

  
962
    minmaxspecs = ipolicy[constants.ISPECS_MINMAX]
960 963
    missing = constants.ISPECS_MINMAX_KEYS - frozenset(minmaxspecs.keys())
961 964
    if missing:
962 965
      msg = "Missing instance specification: %s" % utils.CommaJoin(missing)
963 966
      raise errors.ConfigurationError(msg)
964 967
    for (key, spec) in minmaxspecs.items():
965 968
      InstancePolicy._CheckIncompleteSpec(spec, key)
966
    if check_std:
967
      InstancePolicy._CheckIncompleteSpec(stdspec, constants.ISPECS_STD)
969

  
970
    spec_std_ok = True
968 971
    for param in constants.ISPECS_PARAMETERS:
969
      InstancePolicy._CheckISpecParamSyntax(minmaxspecs, stdspec, param,
970
                                            check_std)
972
      par_std_ok = InstancePolicy._CheckISpecParamSyntax(minmaxspecs, stdspec,
973
                                                         param, check_std)
974
      spec_std_ok = spec_std_ok and par_std_ok
975
    if not spec_std_ok:
976
      raise errors.ConfigurationError("Invalid std specifications")
971 977

  
972 978
  @classmethod
973 979
  def _CheckISpecParamSyntax(cls, minmaxspecs, stdspec, name, check_std):
......
984 990
    @param name: what are the limits for
985 991
    @type check_std: bool
986 992
    @param check_std: Whether to check std value or just assume compliance
987
    @raise errors.ConfigurationError: when specs for the given name are not
988
        valid
993
    @rtype: bool
994
    @return: C{True} when specs are valid, C{False} when standard spec for the
995
        given name is not valid
996
    @raise errors.ConfigurationError: when min/max specs for the given name
997
        are not valid
989 998

  
990 999
    """
991 1000
    minspec = minmaxspecs[constants.ISPECS_MIN]
992 1001
    maxspec = minmaxspecs[constants.ISPECS_MAX]
993 1002
    min_v = minspec[name]
1003
    max_v = maxspec[name]
994 1004

  
995
    if check_std:
1005
    if min_v > max_v:
1006
      err = ("Invalid specification of min/max values for %s: %s/%s" %
1007
             (name, min_v, max_v))
1008
      raise errors.ConfigurationError(err)
1009
    elif check_std:
996 1010
      std_v = stdspec.get(name, min_v)
997
      std_msg = std_v
1011
      return std_v >= min_v and std_v <= max_v
998 1012
    else:
999
      std_v = min_v
1000
      std_msg = "-"
1001

  
1002
    max_v = maxspec[name]
1003
    if min_v > std_v or std_v > max_v:
1004
      err = ("Invalid specification of min/max/std values for %s: %s/%s/%s" %
1005
             (name, min_v, max_v, std_msg))
1006
      raise errors.ConfigurationError(err)
1013
      return True
1007 1014

  
1008 1015
  @classmethod
1009 1016
  def CheckDiskTemplates(cls, disk_templates):
b/test/py/ganeti.objects_unittest.py
428 428
    self._AssertIPolicyIsFull(constants.IPOLICY_DEFAULTS)
429 429

  
430 430
  def testCheckISpecSyntax(self):
431
    default_stdspec = constants.IPOLICY_DEFAULTS[constants.ISPECS_STD]
431 432
    incomplete_ipolicies = [
432 433
      {
433 434
         constants.ISPECS_MINMAX: {},
434
         constants.ISPECS_STD: NotImplemented,
435
         constants.ISPECS_STD: default_stdspec,
435 436
         },
436 437
      {
437 438
        constants.ISPECS_MINMAX: {
438 439
          constants.ISPECS_MIN: NotImplemented,
439 440
          },
440
        constants.ISPECS_STD: NotImplemented,
441
        constants.ISPECS_STD: default_stdspec,
441 442
        },
442 443
      {
443 444
        constants.ISPECS_MINMAX: {
444 445
          constants.ISPECS_MAX: NotImplemented,
445 446
          },
446
        constants.ISPECS_STD: NotImplemented,
447
        constants.ISPECS_STD: default_stdspec,
447 448
        },
448 449
      {
449 450
        constants.ISPECS_MINMAX: {
......
488 489
      stdspec = {par: st}
489 490
      objects.InstancePolicy._CheckISpecParamSyntax(minmax, stdspec, par, True)
490 491
    bad_values = [
491
      (11, 11,  5),
492
      (40, 11, 11),
493
      (11, 80, 40),
494
      (11,  5, 40),
495
      (11,  5,  5),
496
      (40, 40, 11),
492
      (11, 11,  5, True),
493
      (40, 11, 11, True),
494
      (11, 80, 40, False),
495
      (11,  5, 40, False,),
496
      (11,  5,  5, True),
497
      (40, 40, 11, True),
497 498
      ]
498
    for (mn, st, mx) in bad_values:
499
    for (mn, st, mx, excp) in bad_values:
499 500
      minmax = {
500 501
        constants.ISPECS_MIN: {par: mn},
501 502
        constants.ISPECS_MAX: {par: mx},
502 503
        }
503 504
      stdspec = {par: st}
504
      self.assertRaises(errors.ConfigurationError,
505
                        objects.InstancePolicy._CheckISpecParamSyntax,
506
                        minmax, stdspec, par, True)
505
      if excp:
506
        self.assertRaises(errors.ConfigurationError,
507
                          objects.InstancePolicy._CheckISpecParamSyntax,
508
                          minmax, stdspec, par, True)
509
      else:
510
        ret = objects.InstancePolicy._CheckISpecParamSyntax(minmax, stdspec,
511
                                                            par, True)
512
        self.assertFalse(ret)
507 513

  
508 514
  def testCheckDiskTemplates(self):
509 515
    invalid = "this_is_not_a_good_template"

Also available in: Unified diff