diff --git a/lib/cmdlib.py b/lib/cmdlib.py index 18395a4762ba8c06dc6063d16d96390b8fb79b3e..57586f79ab33eb8f5111c539619339ac90e72ef7 100644 --- a/lib/cmdlib.py +++ b/lib/cmdlib.py @@ -11170,8 +11170,8 @@ class TagsLU(NoHooksLU): # pylint: disable-msg=W0223 This is an abstract class which is the parent of all the other tags LUs. """ - def ExpandNames(self): + self.group_uuid = None self.needed_locks = {} if self.op.kind == constants.TAG_NODE: self.op.name = _ExpandNodeName(self.cfg, self.op.name) @@ -11179,6 +11179,8 @@ class TagsLU(NoHooksLU): # pylint: disable-msg=W0223 elif self.op.kind == constants.TAG_INSTANCE: self.op.name = _ExpandInstanceName(self.cfg, self.op.name) self.needed_locks[locking.LEVEL_INSTANCE] = self.op.name + elif self.op.kind == constants.TAG_NODEGROUP: + self.group_uuid = self.cfg.LookupNodeGroup(self.op.name) # FIXME: Acquire BGL for cluster tag operations (as of this writing it's # not possible to acquire the BGL based on opcode parameters) @@ -11193,6 +11195,8 @@ class TagsLU(NoHooksLU): # pylint: disable-msg=W0223 self.target = self.cfg.GetNodeInfo(self.op.name) elif self.op.kind == constants.TAG_INSTANCE: self.target = self.cfg.GetInstanceInfo(self.op.name) + elif self.op.kind == constants.TAG_NODEGROUP: + self.target = self.cfg.GetNodeGroup(self.group_uuid) else: raise errors.OpPrereqError("Wrong tag type requested (%s)" % str(self.op.kind), errors.ECODE_INVAL) @@ -11248,6 +11252,8 @@ class LUTagsSearch(NoHooksLU): tgts.extend([("/instances/%s" % i.name, i) for i in ilist]) nlist = cfg.GetAllNodesInfo().values() tgts.extend([("/nodes/%s" % n.name, n) for n in nlist]) + tgts.extend(("/nodegroup/%s" % n.name, n) + for n in cfg.GetAllNodeGroupsInfo().values()) results = [] for path, target in tgts: for tag in target.GetTags(): diff --git a/lib/constants.py b/lib/constants.py index 55e81bdd9535a5c137934feba93e5bfe6e6e5854..2a4140093545974d5121e0ccdbdc7885f13e9a6f 100644 --- a/lib/constants.py +++ b/lib/constants.py @@ -503,10 +503,12 @@ EXIT_UNKNOWN_FIELD = 14 # tags TAG_CLUSTER = "cluster" +TAG_NODEGROUP = "nodegroup" TAG_NODE = "node" TAG_INSTANCE = "instance" VALID_TAG_TYPES = frozenset([ TAG_CLUSTER, + TAG_NODEGROUP, TAG_NODE, TAG_INSTANCE, ]) diff --git a/lib/objects.py b/lib/objects.py index 119edde8a5e68d7dabb44637317d97952d9fc97e..7be9e7179828d70bfe14b25722784db0a2b12be4 100644 --- a/lib/objects.py +++ b/lib/objects.py @@ -978,7 +978,7 @@ class Node(TaggableObject): self.powered = True -class NodeGroup(ConfigObject): +class NodeGroup(TaggableObject): """Config object representing a node group.""" __slots__ = [ "name", diff --git a/lib/query.py b/lib/query.py index f050cca9051d34ca1773972af5cd9c60c79be530..51448bab035848bef3aa5e65a49d738861cf2702 100644 --- a/lib/query.py +++ b/lib/query.py @@ -1907,6 +1907,12 @@ def _BuildGroupFields(): GQ_INST, 0, _GetSortedList(group_to_instances)), ]) + # Other fields + fields.extend([ + (_MakeField("tags", "Tags", QFT_OTHER, "Tags"), GQ_CONFIG, 0, + lambda ctx, group: list(group.GetTags())), + ]) + fields.extend(_GetItemTimestampFields(GQ_CONFIG)) return _PrepareFieldList(fields, [])