Revision f4f36cf3

b/lib/bootstrap.py
600 600
                                   nodegroups=nodegroups,
601 601
                                   nodes=nodes,
602 602
                                   instances={},
603
                                   networks={},
603 604
                                   serial_no=1,
604 605
                                   ctime=now, mtime=now)
605 606
  utils.WriteFile(cfg_file,
b/lib/cmdlib.py
15324 15324
      result = ial.out_text
15325 15325
    return result
15326 15326

  
15327
# Network LUs
15328
class LUNetworkAdd(LogicalUnit):
15329
  def BuildHooksNodes(self):
15330
    pass
15331

  
15332
  def BuildHooksEnv(self):
15333
    pass
15334

  
15335

  
15336
class LUNetworkRemove(LogicalUnit):
15337
  def BuildHooksNodes(self):
15338
    pass
15339

  
15340
  def BuildHooksEnv(self):
15341
    pass
15342

  
15343

  
15344
class LUNetworkSetParams(LogicalUnit):
15345
  def BuildHooksNodes(self):
15346
    pass
15347

  
15348
  def BuildHooksEnv(self):
15349
    pass
15350

  
15351

  
15352
class _NetworkQuery(_QueryBase):
15353
  def ExpandNames(self, lu):
15354
    pass
15355

  
15356
  def DeclareLocks(self, lu, level):
15357
    pass
15358

  
15359
  def _GetQueryData(self, lu):
15360
    pass
15361

  
15362

  
15363
class LUNetworkQuery(NoHooksLU):
15364
  pass
15365

  
15366

  
15367
class LUNetworkConnect(LogicalUnit):
15368
  def BuildHooksNodes(self):
15369
    pass
15370

  
15371
  def BuildHooksEnv(self):
15372
    pass
15373

  
15374

  
15375
class LUNetworkDisconnect(LogicalUnit):
15376
  def BuildHooksNodes(self):
15377
    pass
15378

  
15379
  def BuildHooksEnv(self):
15380
    pass
15381

  
15327 15382

  
15328 15383
#: Query type implementations
15329 15384
_QUERY_IMPL = {
......
15331 15386
  constants.QR_INSTANCE: _InstanceQuery,
15332 15387
  constants.QR_NODE: _NodeQuery,
15333 15388
  constants.QR_GROUP: _GroupQuery,
15389
  constants.QR_NETWORK: _NetworkQuery,
15334 15390
  constants.QR_OS: _OsQuery,
15335 15391
  constants.QR_EXPORT: _ExportQuery,
15336 15392
  }
b/lib/constants.py
369 369
HTYPE_NODE = "NODE"
370 370
HTYPE_GROUP = "GROUP"
371 371
HTYPE_INSTANCE = "INSTANCE"
372
HTYPE_NETWORK = "NETWORK"
372 373

  
373 374
HKR_SKIP = 0
374 375
HKR_FAIL = 1
......
1089 1090

  
1090 1091
NIC_MODE_BRIDGED = "bridged"
1091 1092
NIC_MODE_ROUTED = "routed"
1093
NIC_IP_POOL = "pool"
1092 1094

  
1093 1095
NIC_VALID_MODES = frozenset([NIC_MODE_BRIDGED, NIC_MODE_ROUTED])
1094 1096

  
1097
# An extra description of the network.
1098
# Can be used by hooks/kvm-vif-bridge to apply different rules
1099
NETWORK_TYPE_PRIVATE = "private"
1100
NETWORK_TYPE_PUBLIC = "public"
1101

  
1102
NETWORK_VALID_TYPES = frozenset([NETWORK_TYPE_PRIVATE, NETWORK_TYPE_PUBLIC])
1103

  
1095 1104
NICS_PARAMETER_TYPES = {
1096 1105
  NIC_MODE: VTYPE_STRING,
1097 1106
  NIC_LINK: VTYPE_STRING,
......
1119 1128
INIC_IP = "ip"
1120 1129
INIC_MODE = "mode"
1121 1130
INIC_LINK = "link"
1131
INIC_NETWORK = "network"
1122 1132
INIC_PARAMS_TYPES = {
1123 1133
  INIC_IP: VTYPE_MAYBE_STRING,
1124 1134
  INIC_LINK: VTYPE_STRING,
1125 1135
  INIC_MAC: VTYPE_STRING,
1126 1136
  INIC_MODE: VTYPE_STRING,
1137
  INIC_NETWORK: VTYPE_MAYBE_STRING,
1127 1138
  }
1128 1139
INIC_PARAMS = frozenset(INIC_PARAMS_TYPES.keys())
1129 1140

  
......
1624 1635
QR_OS = "os"
1625 1636
QR_JOB = "job"
1626 1637
QR_EXPORT = "export"
1638
QR_NETWORK = "network"
1627 1639

  
1628 1640
#: List of resources which can be queried using L{opcodes.OpQuery}
1629 1641
QR_VIA_OP = frozenset([
......
1633 1645
  QR_GROUP,
1634 1646
  QR_OS,
1635 1647
  QR_EXPORT,
1648
  QR_NETWORK,
1636 1649
  ])
1637 1650

  
1638 1651
#: List of resources which can be queried using Local UniX Interface
......
1724 1737
SS_MAINTAIN_NODE_HEALTH = "maintain_node_health"
1725 1738
SS_UID_POOL = "uid_pool"
1726 1739
SS_NODEGROUPS = "nodegroups"
1740
SS_NETWORKS = "networks"
1727 1741

  
1728 1742
SS_FILE_PERMS = 0444
1729 1743

  
b/lib/objects.py
50 50

  
51 51

  
52 52
__all__ = ["ConfigObject", "ConfigData", "NIC", "Disk", "Instance",
53
           "OS", "Node", "NodeGroup", "Cluster", "FillDict"]
53
           "OS", "Node", "NodeGroup", "Cluster", "FillDict", "Network"]
54 54

  
55 55
_TIMESTAMPS = ["ctime", "mtime"]
56 56
_UUID = ["uuid"]
......
439 439
    "nodes",
440 440
    "nodegroups",
441 441
    "instances",
442
    "networks",
442 443
    "serial_no",
443 444
    ] + _TIMESTAMPS
444 445

  
......
451 452
    """
452 453
    mydict = super(ConfigData, self).ToDict()
453 454
    mydict["cluster"] = mydict["cluster"].ToDict()
454
    for key in "nodes", "instances", "nodegroups":
455
    for key in "nodes", "instances", "nodegroups", "networks":
455 456
      mydict[key] = self._ContainerToDicts(mydict[key])
456 457

  
457 458
    return mydict
......
466 467
    obj.nodes = cls._ContainerFromDicts(obj.nodes, dict, Node)
467 468
    obj.instances = cls._ContainerFromDicts(obj.instances, dict, Instance)
468 469
    obj.nodegroups = cls._ContainerFromDicts(obj.nodegroups, dict, NodeGroup)
470
    obj.networks = cls._ContainerFromDicts(obj.networks, dict, Network)
469 471
    return obj
470 472

  
471 473
  def HasAnyDiskOfType(self, dev_type):
......
502 504
      # gives a good approximation.
503 505
      if self.HasAnyDiskOfType(constants.LD_DRBD8):
504 506
        self.cluster.drbd_usermode_helper = constants.DEFAULT_DRBD_HELPER
507
    if self.networks is None:
508
      self.networks = {}
505 509

  
506 510

  
507 511
class NIC(ConfigObject):
508 512
  """Config object representing a network card."""
509
  __slots__ = ["mac", "ip", "nicparams"]
513
  __slots__ = ["mac", "ip", "network", "nicparams"]
510 514

  
511 515
  @classmethod
512 516
  def CheckParameterSyntax(cls, nicparams):
......
1389 1393
    "hv_state_static",
1390 1394
    "disk_state_static",
1391 1395
    "alloc_policy",
1396
    "networks",
1392 1397
    ] + _TIMESTAMPS + _UUID
1393 1398

  
1394 1399
  def ToDict(self):
......
1436 1441
    if self.ipolicy is None:
1437 1442
      self.ipolicy = MakeEmptyIPolicy()
1438 1443

  
1444
    if self.networks is None:
1445
      self.networks = {}
1446

  
1439 1447
  def FillND(self, node):
1440 1448
    """Return filled out ndparams for L{objects.Node}
1441 1449

  
......
2020 2028
    return True
2021 2029

  
2022 2030

  
2031
class Network(ConfigObject):
2032
  """Object representing a network definition for ganeti.
2033

  
2034
  """
2035
  __slots__ = [
2036
    "name",
2037
    "serial_no",
2038
    "network_type",
2039
    "mac_prefix",
2040
    "family",
2041
    "network",
2042
    "network6",
2043
    "gateway",
2044
    "gateway6",
2045
    "size",
2046
    "reservations",
2047
    "ext_reservations",
2048
    ] + _TIMESTAMPS + _UUID
2049

  
2050

  
2023 2051
class SerializableConfigParser(ConfigParser.SafeConfigParser):
2024 2052
  """Simple wrapper over ConfigParse that allows serialization.
2025 2053

  
b/lib/opcodes.py
35 35

  
36 36
import logging
37 37
import re
38
import ipaddr
38 39

  
39 40
from ganeti import constants
40 41
from ganeti import errors
......
162 163
_PAllowRuntimeChgs = ("allow_runtime_changes", True, ht.TBool,
163 164
                      "Allow runtime changes (eg. memory ballooning)")
164 165

  
166
#: a required network name
167
_PNetworkName = ("network_name", ht.NoDefault, ht.TNonEmptyString,
168
                 "Set network name")
165 169

  
166 170
#: OP_ID conversion regular expression
167 171
_OPID_RE = re.compile("([a-z])([A-Z])")
......
337 341
_PStorageType = ("storage_type", ht.NoDefault, _CheckStorageType,
338 342
                 "Storage type")
339 343

  
344
_CheckNetworkType = ht.TElemOf(constants.NETWORK_VALID_TYPES)
345

  
346
#: Network type parameter
347
_PNetworkType = ("network_type", None, ht.TOr(ht.TNone, _CheckNetworkType),
348
                 "Network type")
349

  
350
def _CheckCIDRNetNotation(value):
351
  """Ensure a given cidr notation type is valid.
352

  
353
  """
354
  try:
355
    ipaddr.IPv4Network(value)
356
  except ipaddr.AddressValueError:
357
    return False
358
  return True
359

  
360
def _CheckCIDRAddrNotation(value):
361
  """Ensure a given cidr notation type is valid.
362

  
363
  """
364
  try:
365
    ipaddr.IPv4Address(value)
366
  except ipaddr.AddressValueError:
367
    return False
368
  return True
369

  
370
def _CheckCIDR6AddrNotation(value):
371
  """Ensure a given cidr notation type is valid.
372

  
373
  """
374
  try:
375
    ipaddr.IPv6Address(value)
376
  except ipaddr.AddressValueError:
377
    return False
378
  return True
379

  
380
def _CheckCIDR6NetNotation(value):
381
  """Ensure a given cidr notation type is valid.
382

  
383
  """
384
  try:
385
    ipaddr.IPv6Network(value)
386
  except ipaddr.AddressValueError:
387
    return False
388
  return True
340 389

  
341 390
class _AutoOpParamSlots(type):
342 391
  """Meta class for opcode definitions.
......
1195 1244
    ("identify_defaults", False, ht.TBool,
1196 1245
     "Reset instance parameters to default if equal"),
1197 1246
    ("ip_check", True, ht.TBool, _PIpCheckDoc),
1247
    ("conflicts_check", True, ht.TBool, "Check for conflicting IPs"),
1198 1248
    ("mode", ht.NoDefault, ht.TElemOf(constants.INSTANCE_CREATE_MODES),
1199 1249
     "Instance creation mode"),
1200 1250
    ("nics", ht.NoDefault, ht.TListOf(_TestNicDef),
......
1525 1575
    ("wait_for_sync", True, ht.TBool,
1526 1576
     "Whether to wait for the disk to synchronize, when changing template"),
1527 1577
    ("offline", None, ht.TMaybeBool, "Whether to mark instance as offline"),
1578
    ("conflicts_check", True, ht.TBool, "Check for conflicting IPs"),
1528 1579
    ]
1529 1580
  OP_RESULT = _TSetParamsResult
1530 1581

  
......
1881 1932
  WITH_LU = False
1882 1933

  
1883 1934

  
1935
# Network opcodes
1936
# Add a new network in the cluster
1937
class OpNetworkAdd(OpCode):
1938
  """Add an IP network to the cluster."""
1939
  OP_DSC_FIELD = "network_name"
1940
  OP_PARAMS = [
1941
    _PNetworkName,
1942
    _PNetworkType,
1943
    ("network", None, ht.TAnd(ht.TString ,_CheckCIDRNetNotation), None),
1944
    ("gateway", None, ht.TOr(ht.TNone, _CheckCIDRAddrNotation), None),
1945
    ("network6", None, ht.TOr(ht.TNone, _CheckCIDR6NetNotation), None),
1946
    ("gateway6", None, ht.TOr(ht.TNone, _CheckCIDR6AddrNotation), None),
1947
    ("mac_prefix", None, ht.TMaybeString, None),
1948
    ("add_reserved_ips", None,
1949
     ht.TOr(ht.TNone, ht.TListOf(_CheckCIDRAddrNotation)), None),
1950
    ]
1951

  
1952
class OpNetworkRemove(OpCode):
1953
  """Remove an existing network from the cluster.
1954
     Must not be connected to any nodegroup.
1955

  
1956
  """
1957
  OP_DSC_FIELD = "network_name"
1958
  OP_PARAMS = [
1959
    _PNetworkName,
1960
    _PForce,
1961
    ]
1962

  
1963
class OpNetworkSetParams(OpCode):
1964
  """Modify Network's parameters except for IPv4 subnet"""
1965
  OP_DSC_FIELD = "network_name"
1966
  OP_PARAMS = [
1967
    _PNetworkName,
1968
    _PNetworkType,
1969
    ("gateway", None, ht.TOr(ht.TNone, _CheckCIDRAddrNotation), None),
1970
    ("network6", None, ht.TOr(ht.TNone, _CheckCIDR6NetNotation), None),
1971
    ("gateway6", None, ht.TOr(ht.TNone, _CheckCIDR6AddrNotation), None),
1972
    ("mac_prefix", None, ht.TMaybeString, None),
1973
    ("add_reserved_ips", None,
1974
     ht.TOr(ht.TNone, ht.TListOf(_CheckCIDRAddrNotation)), None),
1975
    ("remove_reserved_ips", None,
1976
     ht.TOr(ht.TNone, ht.TListOf(_CheckCIDRAddrNotation)), None),
1977
    ]
1978

  
1979
class OpNetworkConnect(OpCode):
1980
  """Connect a Network to a specific Nodegroup with the defined netparams
1981
     (mode, link). Nics in this Network will inherit those params.
1982
     Produce errors if a NIC (that its not already assigned to a network)
1983
     has an IP that is contained in the Network this will produce error unless
1984
     --no-conflicts-check is passed.
1985

  
1986
  """
1987
  OP_DSC_FIELD = "network_name"
1988
  OP_PARAMS = [
1989
    _PGroupName,
1990
    _PNetworkName,
1991
    ("network_mode", None, ht.TString, None),
1992
    ("network_link", None, ht.TString, None),
1993
    ("conflicts_check", True, ht.TBool, "Check for conflicting IPs"),
1994
    ]
1995

  
1996
class OpNetworkDisconnect(OpCode):
1997
  """Disconnect a Network from a Nodegroup. Produce errors if NICs are
1998
     present in the Network unless --no-conficts-check option is passed.
1999

  
2000
  """
2001
  OP_DSC_FIELD = "network_name"
2002
  OP_PARAMS = [
2003
    _PGroupName,
2004
    _PNetworkName,
2005
    ("conflicts_check", True, ht.TBool, "Check for conflicting IPs"),
2006
    ]
2007

  
2008
class OpNetworkQuery(OpCode):
2009
  """Compute the list of networks."""
2010
  OP_PARAMS = [
2011
    _POutputFields,
2012
    ("names", ht.EmptyList, ht.TListOf(ht.TNonEmptyString),
2013
     "Empty list to query all groups, group names otherwise"),
2014
    ]
2015

  
2016

  
1884 2017
def _GetOpList():
1885 2018
  """Returns list of all defined opcodes.
1886 2019

  

Also available in: Unified diff