result = ial.out_text
return result
+# Network LUs
+class LUNetworkAdd(LogicalUnit):
+ def BuildHooksNodes(self):
+ pass
+
+ def BuildHooksEnv(self):
+ pass
+
+
+class LUNetworkRemove(LogicalUnit):
+ def BuildHooksNodes(self):
+ pass
+
+ def BuildHooksEnv(self):
+ pass
+
+
+class LUNetworkSetParams(LogicalUnit):
+ def BuildHooksNodes(self):
+ pass
+
+ def BuildHooksEnv(self):
+ pass
+
+
+class _NetworkQuery(_QueryBase):
+ def ExpandNames(self, lu):
+ pass
+
+ def DeclareLocks(self, lu, level):
+ pass
+
+ def _GetQueryData(self, lu):
+ pass
+
+
+class LUNetworkQuery(NoHooksLU):
+ pass
+
+
+class LUNetworkConnect(LogicalUnit):
+ def BuildHooksNodes(self):
+ pass
+
+ def BuildHooksEnv(self):
+ pass
+
+
+class LUNetworkDisconnect(LogicalUnit):
+ def BuildHooksNodes(self):
+ pass
+
+ def BuildHooksEnv(self):
+ pass
+
#: Query type implementations
_QUERY_IMPL = {
constants.QR_INSTANCE: _InstanceQuery,
constants.QR_NODE: _NodeQuery,
constants.QR_GROUP: _GroupQuery,
+ constants.QR_NETWORK: _NetworkQuery,
constants.QR_OS: _OsQuery,
constants.QR_EXPORT: _ExportQuery,
}
__all__ = ["ConfigObject", "ConfigData", "NIC", "Disk", "Instance",
- "OS", "Node", "NodeGroup", "Cluster", "FillDict"]
+ "OS", "Node", "NodeGroup", "Cluster", "FillDict", "Network"]
_TIMESTAMPS = ["ctime", "mtime"]
_UUID = ["uuid"]
"nodes",
"nodegroups",
"instances",
+ "networks",
"serial_no",
] + _TIMESTAMPS
"""
mydict = super(ConfigData, self).ToDict()
mydict["cluster"] = mydict["cluster"].ToDict()
- for key in "nodes", "instances", "nodegroups":
+ for key in "nodes", "instances", "nodegroups", "networks":
mydict[key] = self._ContainerToDicts(mydict[key])
return mydict
obj.nodes = cls._ContainerFromDicts(obj.nodes, dict, Node)
obj.instances = cls._ContainerFromDicts(obj.instances, dict, Instance)
obj.nodegroups = cls._ContainerFromDicts(obj.nodegroups, dict, NodeGroup)
+ obj.networks = cls._ContainerFromDicts(obj.networks, dict, Network)
return obj
def HasAnyDiskOfType(self, dev_type):
# gives a good approximation.
if self.HasAnyDiskOfType(constants.LD_DRBD8):
self.cluster.drbd_usermode_helper = constants.DEFAULT_DRBD_HELPER
+ if self.networks is None:
+ self.networks = {}
class NIC(ConfigObject):
"""Config object representing a network card."""
- __slots__ = ["mac", "ip", "nicparams"]
+ __slots__ = ["mac", "ip", "network", "nicparams"]
@classmethod
def CheckParameterSyntax(cls, nicparams):
"hv_state_static",
"disk_state_static",
"alloc_policy",
+ "networks",
] + _TIMESTAMPS + _UUID
def ToDict(self):
if self.ipolicy is None:
self.ipolicy = MakeEmptyIPolicy()
+ if self.networks is None:
+ self.networks = {}
+
def FillND(self, node):
"""Return filled out ndparams for L{objects.Node}
return True
+class Network(ConfigObject):
+ """Object representing a network definition for ganeti.
+
+ """
+ __slots__ = [
+ "name",
+ "serial_no",
+ "network_type",
+ "mac_prefix",
+ "family",
+ "network",
+ "network6",
+ "gateway",
+ "gateway6",
+ "size",
+ "reservations",
+ "ext_reservations",
+ ] + _TIMESTAMPS + _UUID
+
+
class SerializableConfigParser(ConfigParser.SafeConfigParser):
"""Simple wrapper over ConfigParse that allows serialization.
import logging
import re
+import ipaddr
from ganeti import constants
from ganeti import errors
_PAllowRuntimeChgs = ("allow_runtime_changes", True, ht.TBool,
"Allow runtime changes (eg. memory ballooning)")
+#: a required network name
+_PNetworkName = ("network_name", ht.NoDefault, ht.TNonEmptyString,
+ "Set network name")
#: OP_ID conversion regular expression
_OPID_RE = re.compile("([a-z])([A-Z])")
_PStorageType = ("storage_type", ht.NoDefault, _CheckStorageType,
"Storage type")
+_CheckNetworkType = ht.TElemOf(constants.NETWORK_VALID_TYPES)
+
+#: Network type parameter
+_PNetworkType = ("network_type", None, ht.TOr(ht.TNone, _CheckNetworkType),
+ "Network type")
+
+def _CheckCIDRNetNotation(value):
+ """Ensure a given cidr notation type is valid.
+
+ """
+ try:
+ ipaddr.IPv4Network(value)
+ except ipaddr.AddressValueError:
+ return False
+ return True
+
+def _CheckCIDRAddrNotation(value):
+ """Ensure a given cidr notation type is valid.
+
+ """
+ try:
+ ipaddr.IPv4Address(value)
+ except ipaddr.AddressValueError:
+ return False
+ return True
+
+def _CheckCIDR6AddrNotation(value):
+ """Ensure a given cidr notation type is valid.
+
+ """
+ try:
+ ipaddr.IPv6Address(value)
+ except ipaddr.AddressValueError:
+ return False
+ return True
+
+def _CheckCIDR6NetNotation(value):
+ """Ensure a given cidr notation type is valid.
+
+ """
+ try:
+ ipaddr.IPv6Network(value)
+ except ipaddr.AddressValueError:
+ return False
+ return True
class _AutoOpParamSlots(type):
"""Meta class for opcode definitions.
("identify_defaults", False, ht.TBool,
"Reset instance parameters to default if equal"),
("ip_check", True, ht.TBool, _PIpCheckDoc),
+ ("conflicts_check", True, ht.TBool, "Check for conflicting IPs"),
("mode", ht.NoDefault, ht.TElemOf(constants.INSTANCE_CREATE_MODES),
"Instance creation mode"),
("nics", ht.NoDefault, ht.TListOf(_TestNicDef),
("wait_for_sync", True, ht.TBool,
"Whether to wait for the disk to synchronize, when changing template"),
("offline", None, ht.TMaybeBool, "Whether to mark instance as offline"),
+ ("conflicts_check", True, ht.TBool, "Check for conflicting IPs"),
]
OP_RESULT = _TSetParamsResult
WITH_LU = False
+# Network opcodes
+# Add a new network in the cluster
+class OpNetworkAdd(OpCode):
+ """Add an IP network to the cluster."""
+ OP_DSC_FIELD = "network_name"
+ OP_PARAMS = [
+ _PNetworkName,
+ _PNetworkType,
+ ("network", None, ht.TAnd(ht.TString ,_CheckCIDRNetNotation), None),
+ ("gateway", None, ht.TOr(ht.TNone, _CheckCIDRAddrNotation), None),
+ ("network6", None, ht.TOr(ht.TNone, _CheckCIDR6NetNotation), None),
+ ("gateway6", None, ht.TOr(ht.TNone, _CheckCIDR6AddrNotation), None),
+ ("mac_prefix", None, ht.TMaybeString, None),
+ ("add_reserved_ips", None,
+ ht.TOr(ht.TNone, ht.TListOf(_CheckCIDRAddrNotation)), None),
+ ]
+
+class OpNetworkRemove(OpCode):
+ """Remove an existing network from the cluster.
+ Must not be connected to any nodegroup.
+
+ """
+ OP_DSC_FIELD = "network_name"
+ OP_PARAMS = [
+ _PNetworkName,
+ _PForce,
+ ]
+
+class OpNetworkSetParams(OpCode):
+ """Modify Network's parameters except for IPv4 subnet"""
+ OP_DSC_FIELD = "network_name"
+ OP_PARAMS = [
+ _PNetworkName,
+ _PNetworkType,
+ ("gateway", None, ht.TOr(ht.TNone, _CheckCIDRAddrNotation), None),
+ ("network6", None, ht.TOr(ht.TNone, _CheckCIDR6NetNotation), None),
+ ("gateway6", None, ht.TOr(ht.TNone, _CheckCIDR6AddrNotation), None),
+ ("mac_prefix", None, ht.TMaybeString, None),
+ ("add_reserved_ips", None,
+ ht.TOr(ht.TNone, ht.TListOf(_CheckCIDRAddrNotation)), None),
+ ("remove_reserved_ips", None,
+ ht.TOr(ht.TNone, ht.TListOf(_CheckCIDRAddrNotation)), None),
+ ]
+
+class OpNetworkConnect(OpCode):
+ """Connect a Network to a specific Nodegroup with the defined netparams
+ (mode, link). Nics in this Network will inherit those params.
+ Produce errors if a NIC (that its not already assigned to a network)
+ has an IP that is contained in the Network this will produce error unless
+ --no-conflicts-check is passed.
+
+ """
+ OP_DSC_FIELD = "network_name"
+ OP_PARAMS = [
+ _PGroupName,
+ _PNetworkName,
+ ("network_mode", None, ht.TString, None),
+ ("network_link", None, ht.TString, None),
+ ("conflicts_check", True, ht.TBool, "Check for conflicting IPs"),
+ ]
+
+class OpNetworkDisconnect(OpCode):
+ """Disconnect a Network from a Nodegroup. Produce errors if NICs are
+ present in the Network unless --no-conficts-check option is passed.
+
+ """
+ OP_DSC_FIELD = "network_name"
+ OP_PARAMS = [
+ _PGroupName,
+ _PNetworkName,
+ ("conflicts_check", True, ht.TBool, "Check for conflicting IPs"),
+ ]
+
+class OpNetworkQuery(OpCode):
+ """Compute the list of networks."""
+ OP_PARAMS = [
+ _POutputFields,
+ ("names", ht.EmptyList, ht.TListOf(ht.TNonEmptyString),
+ "Empty list to query all groups, group names otherwise"),
+ ]
+
+
def _GetOpList():
"""Returns list of all defined opcodes.