Revision 918eb80b

b/lib/config.py
426 426
      except errors.ConfigurationError, err:
427 427
        result.append("%s has invalid nicparams: %s" % (owner, err))
428 428

  
429
    def _helper_ipolicy(owner, params):
430
      try:
431
        objects.InstancePolicy.CheckParameterSyntax(params)
432
      except errors.ConfigurationError, err:
433
        result.append("%s has invalid instance policy: %s" % (owner, err))
434

  
435
    def _helper_ispecs(owner, params):
436
      for key, value in params.iteritems():
437
        fullkey = "ipolicy/" + key
438
        _helper(owner, fullkey, value, constants.ISPECS_PARAMETER_TYPES)
439

  
429 440
    # check cluster parameters
430 441
    _helper("cluster", "beparams", cluster.SimpleFillBE({}),
431 442
            constants.BES_PARAMETER_TYPES)
......
434 445
    _helper_nic("cluster", cluster.SimpleFillNIC({}))
435 446
    _helper("cluster", "ndparams", cluster.SimpleFillND({}),
436 447
            constants.NDS_PARAMETER_TYPES)
448
    _helper_ipolicy("cluster", cluster.SimpleFillIPolicy({}))
449
    _helper_ispecs("cluster", cluster.SimpleFillIPolicy({}))
437 450

  
438 451
    # per-instance checks
439 452
    for instance_name in data.instances:
b/lib/constants.py
921 921

  
922 922
BES_PARAMETERS = frozenset(BES_PARAMETER_TYPES.keys())
923 923

  
924
# instance specs
925
MEM_SIZE_SPEC = "memory-size"
926
CPU_COUNT_SPEC = "cpu-count"
927
DISK_COUNT_SPEC = "disk-count"
928
DISK_SIZE_SPEC = "disk-size"
929
NIC_COUNT_SPEC = "nic-count"
930

  
931
ISPECS_PARAMETER_TYPES = {
932
  MEM_SIZE_SPEC: VTYPE_INT,
933
  CPU_COUNT_SPEC: VTYPE_INT,
934
  DISK_COUNT_SPEC: VTYPE_INT,
935
  DISK_SIZE_SPEC: VTYPE_INT,
936
  NIC_COUNT_SPEC: VTYPE_INT,
937
  }
938

  
939
ISPECS_PARAMETERS = frozenset(ISPECS_PARAMETER_TYPES.keys())
940

  
941
MIN_ISPECS = "min"
942
MAX_ISPECS = "max"
943
STD_ISPECS = "std"
944

  
945
IPOLICY_PARAMETERS = frozenset([
946
  MIN_ISPECS,
947
  MAX_ISPECS,
948
  STD_ISPECS
949
  ])
950

  
924 951
# Node parameter names
925 952
ND_OOB_PROGRAM = "oob_program"
926 953

  
......
1783 1810
  NIC_LINK: DEFAULT_BRIDGE,
1784 1811
  }
1785 1812

  
1813
IPOLICY_DEFAULTS = {
1814
  MIN_ISPECS: {
1815
    MEM_SIZE_SPEC: 128,
1816
    CPU_COUNT_SPEC: 1,
1817
    DISK_COUNT_SPEC: 1,
1818
    DISK_SIZE_SPEC: 1024,
1819
    NIC_COUNT_SPEC: 1,
1820
    },
1821
  MAX_ISPECS: {
1822
    MEM_SIZE_SPEC: 128,
1823
    CPU_COUNT_SPEC: 1,
1824
    DISK_COUNT_SPEC: 1,
1825
    DISK_SIZE_SPEC: 1024,
1826
    NIC_COUNT_SPEC: 1,
1827
    },
1828
  STD_ISPECS: {
1829
    MEM_SIZE_SPEC: 128,
1830
    CPU_COUNT_SPEC: 1,
1831
    DISK_COUNT_SPEC: 1,
1832
    DISK_SIZE_SPEC: 1024,
1833
    NIC_COUNT_SPEC: 1,
1834
    }
1835
  }
1836

  
1786 1837
MASTER_POOL_SIZE_DEFAULT = 10
1787 1838

  
1788 1839
CONFD_PROTOCOL_VERSION = 1
b/lib/objects.py
79 79
  return ret_dict
80 80

  
81 81

  
82
def FillDictOfDicts(defaults_dict, custom_dict, skip_keys=None):
83
  """Run FillDict for each key in dictionary.
84

  
85
  """
86
  ret_dict = {}
87
  for key in defaults_dict.keys():
88
    ret_dict[key] = FillDict(defaults_dict[key],
89
                             custom_dict.get(key, {}),
90
                             skip_keys=skip_keys)
91
  return ret_dict
92

  
93

  
82 94
def UpgradeGroupedParams(target, defaults):
83 95
  """Update all groups for the target parameter.
84 96

  
......
136 148
  return result
137 149

  
138 150

  
151
def MakeEmptyIPolicy():
152
  """Create empty IPolicy dictionary.
153

  
154
  """
155
  return dict([
156
    (constants.MIN_ISPECS, dict()),
157
    (constants.MAX_ISPECS, dict()),
158
    (constants.STD_ISPECS, dict()),
159
    ])
160

  
161

  
139 162
class ConfigObject(object):
140 163
  """A generic config object.
141 164

  
......
780 803
    # add here config upgrade for this disk
781 804

  
782 805

  
806
class InstancePolicy(ConfigObject):
807
  """Config object representing instance policy limits dictionary."""
808
  __slots__ = ["min", "max", "std"]
809

  
810
  @classmethod
811
  def CheckParameterSyntax(cls, ipolicy):
812
    """ Check the instance policy for validity.
813

  
814
    """
815
    for param in constants.ISPECS_PARAMETERS:
816
      InstancePolicy.CheckISpecSyntax(ipolicy, param)
817

  
818
  @classmethod
819
  def CheckISpecSyntax(cls, ipolicy, name):
820
    """Check the instance policy for validity on a given key.
821

  
822
    We check if the instance policy makes sense for a given key, that is
823
    if ipolicy[min][name] <= ipolicy[std][name] <= ipolicy[max][name].
824

  
825
    @type ipolicy: dict
826
    @param ipolicy: dictionary with min, max, std specs
827
    @type name: string
828
    @param name: what are the limits for
829
    @raise errors.ConfigureError: when specs for given name are not valid
830

  
831
    """
832
    min_v = ipolicy[constants.MIN_ISPECS].get(name, 0)
833
    std_v = ipolicy[constants.STD_ISPECS].get(name, min_v)
834
    max_v = ipolicy[constants.MAX_ISPECS].get(name, std_v)
835
    err = ("Invalid specification of min/max/std values for %s: %s/%s/%s" %
836
           (name,
837
            ipolicy[constants.MIN_ISPECS].get(name, "-"),
838
            ipolicy[constants.MAX_ISPECS].get(name, "-"),
839
            ipolicy[constants.STD_ISPECS].get(name, "-")))
840
    if min_v > std_v or std_v > max_v:
841
      raise errors.ConfigurationError(err)
842

  
843

  
783 844
class Instance(TaggableObject):
784 845
  """Config object representing an instance."""
785 846
  __slots__ = [
......
1238 1299
    "shared_file_storage_dir",
1239 1300
    "enabled_hypervisors",
1240 1301
    "hvparams",
1302
    "ipolicy",
1241 1303
    "os_hvp",
1242 1304
    "beparams",
1243 1305
    "osparams",
......
1354 1416

  
1355 1417
    self.diskparams = UpgradeDiskParams(self.diskparams)
1356 1418

  
1419
    # instance policy added before 2.6
1420
    if self.ipolicy is None:
1421
      self.ipolicy = MakeEmptyIPolicy()
1422

  
1357 1423
  @property
1358 1424
  def primary_hypervisor(self):
1359 1425
    """The first hypervisor is the primary.
......
1537 1603
    """
1538 1604
    return FillDict(self.ndparams, ndparams)
1539 1605

  
1606
  def SimpleFillIPolicy(self, ipolicy):
1607
    """ Fill instance policy dict with defaults.
1608

  
1609
    @type ipolicy: dict
1610
    @param ipolicy: the dict to fill
1611
    @rtype: dict
1612
    @return: a copy of passed ipolicy with missing keys filled from
1613
      the cluster defaults
1614

  
1615
    """
1616
    return FillDictOfDicts(self.ipolicy, ipolicy)
1617

  
1540 1618

  
1541 1619
class BlockDevStatus(ConfigObject):
1542 1620
  """Config object representing the status of a block device."""

Also available in: Unified diff