+ @locking.ssynchronized(_config_lock, shared=1)
+ def GetDefaultIAllocator(self):
+ """Get the default instance allocator for this cluster.
+
+ """
+ return self._config_data.cluster.default_iallocator
+
+ @locking.ssynchronized(_config_lock, shared=1)
+ def GetPrimaryIPFamily(self):
+ """Get cluster primary ip family.
+
+ @return: primary ip family
+
+ """
+ return self._config_data.cluster.primary_ip_family
+
+ @locking.ssynchronized(_config_lock, shared=1)
+ def GetMasterNetworkParameters(self):
+ """Get network parameters of the master node.
+
+ @rtype: L{object.MasterNetworkParameters}
+ @return: network parameters of the master node
+
+ """
+ cluster = self._config_data.cluster
+ result = objects.MasterNetworkParameters(
+ name=cluster.master_node, ip=cluster.master_ip,
+ netmask=cluster.master_netmask, netdev=cluster.master_netdev,
+ ip_family=cluster.primary_ip_family)
+
+ return result
+
+ @locking.ssynchronized(_config_lock)
+ def AddNodeGroup(self, group, ec_id, check_uuid=True):
+ """Add a node group to the configuration.
+
+ This method calls group.UpgradeConfig() to fill any missing attributes
+ according to their default values.
+
+ @type group: L{objects.NodeGroup}
+ @param group: the NodeGroup object to add
+ @type ec_id: string
+ @param ec_id: unique id for the job to use when creating a missing UUID
+ @type check_uuid: bool
+ @param check_uuid: add an UUID to the group if it doesn't have one or, if
+ it does, ensure that it does not exist in the
+ configuration already
+
+ """
+ self._UnlockedAddNodeGroup(group, ec_id, check_uuid)
+ self._WriteConfig()
+
+ def _UnlockedAddNodeGroup(self, group, ec_id, check_uuid):
+ """Add a node group to the configuration.
+
+ """
+ logging.info("Adding node group %s to configuration", group.name)
+
+ # Some code might need to add a node group with a pre-populated UUID
+ # generated with ConfigWriter.GenerateUniqueID(). We allow them to bypass
+ # the "does this UUID" exist already check.
+ if check_uuid:
+ self._EnsureUUID(group, ec_id)
+
+ try:
+ existing_uuid = self._UnlockedLookupNodeGroup(group.name)
+ except errors.OpPrereqError:
+ pass
+ else:
+ raise errors.OpPrereqError("Desired group name '%s' already exists as a"
+ " node group (UUID: %s)" %
+ (group.name, existing_uuid),
+ errors.ECODE_EXISTS)
+
+ group.serial_no = 1
+ group.ctime = group.mtime = time.time()
+ group.UpgradeConfig()
+
+ self._config_data.nodegroups[group.uuid] = group
+ self._config_data.cluster.serial_no += 1
+
+ @locking.ssynchronized(_config_lock)
+ def RemoveNodeGroup(self, group_uuid):
+ """Remove a node group from the configuration.
+
+ @type group_uuid: string
+ @param group_uuid: the UUID of the node group to remove
+
+ """
+ logging.info("Removing node group %s from configuration", group_uuid)
+
+ if group_uuid not in self._config_data.nodegroups:
+ raise errors.ConfigurationError("Unknown node group '%s'" % group_uuid)
+
+ assert len(self._config_data.nodegroups) != 1, \
+ "Group '%s' is the only group, cannot be removed" % group_uuid
+
+ del self._config_data.nodegroups[group_uuid]
+ self._config_data.cluster.serial_no += 1
+ self._WriteConfig()
+
+ def _UnlockedLookupNodeGroup(self, target):
+ """Lookup a node group's UUID.
+
+ @type target: string or None
+ @param target: group name or UUID or None to look for the default
+ @rtype: string
+ @return: nodegroup UUID
+ @raises errors.OpPrereqError: when the target group cannot be found
+
+ """
+ if target is None:
+ if len(self._config_data.nodegroups) != 1:
+ raise errors.OpPrereqError("More than one node group exists. Target"
+ " group must be specified explicitly.")
+ else:
+ return self._config_data.nodegroups.keys()[0]
+ if target in self._config_data.nodegroups:
+ return target
+ for nodegroup in self._config_data.nodegroups.values():
+ if nodegroup.name == target:
+ return nodegroup.uuid
+ raise errors.OpPrereqError("Node group '%s' not found" % target,
+ errors.ECODE_NOENT)
+
+ @locking.ssynchronized(_config_lock, shared=1)
+ def LookupNodeGroup(self, target):
+ """Lookup a node group's UUID.
+
+ This function is just a wrapper over L{_UnlockedLookupNodeGroup}.
+
+ @type target: string or None
+ @param target: group name or UUID or None to look for the default
+ @rtype: string
+ @return: nodegroup UUID
+
+ """
+ return self._UnlockedLookupNodeGroup(target)
+
+ def _UnlockedGetNodeGroup(self, uuid):
+ """Lookup a node group.
+
+ @type uuid: string
+ @param uuid: group UUID
+ @rtype: L{objects.NodeGroup} or None
+ @return: nodegroup object, or None if not found
+
+ """
+ if uuid not in self._config_data.nodegroups:
+ return None
+
+ return self._config_data.nodegroups[uuid]
+
+ @locking.ssynchronized(_config_lock, shared=1)
+ def GetNodeGroup(self, uuid):
+ """Lookup a node group.
+
+ @type uuid: string
+ @param uuid: group UUID
+ @rtype: L{objects.NodeGroup} or None
+ @return: nodegroup object, or None if not found
+
+ """
+ return self._UnlockedGetNodeGroup(uuid)
+
+ @locking.ssynchronized(_config_lock, shared=1)
+ def GetAllNodeGroupsInfo(self):
+ """Get the configuration of all node groups.
+
+ """
+ return dict(self._config_data.nodegroups)
+
+ @locking.ssynchronized(_config_lock, shared=1)
+ def GetNodeGroupList(self):
+ """Get a list of node groups.
+
+ """
+ return self._config_data.nodegroups.keys()
+
+ @locking.ssynchronized(_config_lock, shared=1)
+ def GetNodeGroupMembersByNodes(self, nodes):
+ """Get nodes which are member in the same nodegroups as the given nodes.
+
+ """
+ ngfn = lambda node_name: self._UnlockedGetNodeInfo(node_name).group
+ return frozenset(member_name
+ for node_name in nodes
+ for member_name in
+ self._UnlockedGetNodeGroup(ngfn(node_name)).members)
+
+ @locking.ssynchronized(_config_lock, shared=1)
+ def GetMultiNodeGroupInfo(self, group_uuids):
+ """Get the configuration of multiple node groups.
+
+ @param group_uuids: List of node group UUIDs
+ @rtype: list
+ @return: List of tuples of (group_uuid, group_info)
+
+ """
+ return [(uuid, self._UnlockedGetNodeGroup(uuid)) for uuid in group_uuids]
+