Statistics
| Branch: | Tag: | Revision:

root / lib / cmdlib / tags.py @ 9808764a

History | View | Annotate | Download (6.4 kB)

1 fb3891d0 Thomas Thrainer
#
2 fb3891d0 Thomas Thrainer
#
3 fb3891d0 Thomas Thrainer
4 fb3891d0 Thomas Thrainer
# Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Google Inc.
5 fb3891d0 Thomas Thrainer
#
6 fb3891d0 Thomas Thrainer
# This program is free software; you can redistribute it and/or modify
7 fb3891d0 Thomas Thrainer
# it under the terms of the GNU General Public License as published by
8 fb3891d0 Thomas Thrainer
# the Free Software Foundation; either version 2 of the License, or
9 fb3891d0 Thomas Thrainer
# (at your option) any later version.
10 fb3891d0 Thomas Thrainer
#
11 fb3891d0 Thomas Thrainer
# This program is distributed in the hope that it will be useful, but
12 fb3891d0 Thomas Thrainer
# WITHOUT ANY WARRANTY; without even the implied warranty of
13 fb3891d0 Thomas Thrainer
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 fb3891d0 Thomas Thrainer
# General Public License for more details.
15 fb3891d0 Thomas Thrainer
#
16 fb3891d0 Thomas Thrainer
# You should have received a copy of the GNU General Public License
17 fb3891d0 Thomas Thrainer
# along with this program; if not, write to the Free Software
18 fb3891d0 Thomas Thrainer
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 fb3891d0 Thomas Thrainer
# 02110-1301, USA.
20 fb3891d0 Thomas Thrainer
21 fb3891d0 Thomas Thrainer
22 fb3891d0 Thomas Thrainer
"""Logical units dealing with tags."""
23 fb3891d0 Thomas Thrainer
24 fb3891d0 Thomas Thrainer
import re
25 fb3891d0 Thomas Thrainer
26 fb3891d0 Thomas Thrainer
from ganeti import constants
27 fb3891d0 Thomas Thrainer
from ganeti import errors
28 fb3891d0 Thomas Thrainer
from ganeti import locking
29 fb3891d0 Thomas Thrainer
from ganeti import objects
30 fb3891d0 Thomas Thrainer
from ganeti import utils
31 fb3891d0 Thomas Thrainer
from ganeti.cmdlib.base import NoHooksLU
32 da4a52a3 Thomas Thrainer
from ganeti.cmdlib.common import ExpandNodeUuidAndName, \
33 da4a52a3 Thomas Thrainer
  ExpandInstanceUuidAndName, ShareAll
34 fb3891d0 Thomas Thrainer
35 fb3891d0 Thomas Thrainer
36 fb3891d0 Thomas Thrainer
class TagsLU(NoHooksLU): # pylint: disable=W0223
37 fb3891d0 Thomas Thrainer
  """Generic tags LU.
38 fb3891d0 Thomas Thrainer

39 fb3891d0 Thomas Thrainer
  This is an abstract class which is the parent of all the other tags LUs.
40 fb3891d0 Thomas Thrainer

41 fb3891d0 Thomas Thrainer
  """
42 fb3891d0 Thomas Thrainer
  def ExpandNames(self):
43 fb3891d0 Thomas Thrainer
    self.group_uuid = None
44 fb3891d0 Thomas Thrainer
    self.needed_locks = {}
45 fb3891d0 Thomas Thrainer
46 fb3891d0 Thomas Thrainer
    if self.op.kind == constants.TAG_NODE:
47 1c3231aa Thomas Thrainer
      (self.node_uuid, _) = \
48 1c3231aa Thomas Thrainer
        ExpandNodeUuidAndName(self.cfg, None, self.op.name)
49 fb3891d0 Thomas Thrainer
      lock_level = locking.LEVEL_NODE
50 1c3231aa Thomas Thrainer
      lock_name = self.node_uuid
51 fb3891d0 Thomas Thrainer
    elif self.op.kind == constants.TAG_INSTANCE:
52 da4a52a3 Thomas Thrainer
      (self.inst_uuid, inst_name) = \
53 da4a52a3 Thomas Thrainer
        ExpandInstanceUuidAndName(self.cfg, None, self.op.name)
54 fb3891d0 Thomas Thrainer
      lock_level = locking.LEVEL_INSTANCE
55 da4a52a3 Thomas Thrainer
      lock_name = inst_name
56 fb3891d0 Thomas Thrainer
    elif self.op.kind == constants.TAG_NODEGROUP:
57 fb3891d0 Thomas Thrainer
      self.group_uuid = self.cfg.LookupNodeGroup(self.op.name)
58 fb3891d0 Thomas Thrainer
      lock_level = locking.LEVEL_NODEGROUP
59 fb3891d0 Thomas Thrainer
      lock_name = self.group_uuid
60 fb3891d0 Thomas Thrainer
    elif self.op.kind == constants.TAG_NETWORK:
61 fb3891d0 Thomas Thrainer
      self.network_uuid = self.cfg.LookupNetwork(self.op.name)
62 fb3891d0 Thomas Thrainer
      lock_level = locking.LEVEL_NETWORK
63 fb3891d0 Thomas Thrainer
      lock_name = self.network_uuid
64 fb3891d0 Thomas Thrainer
    else:
65 fb3891d0 Thomas Thrainer
      lock_level = None
66 fb3891d0 Thomas Thrainer
      lock_name = None
67 fb3891d0 Thomas Thrainer
68 fb3891d0 Thomas Thrainer
    if lock_level and getattr(self.op, "use_locking", True):
69 fb3891d0 Thomas Thrainer
      self.needed_locks[lock_level] = lock_name
70 fb3891d0 Thomas Thrainer
71 fb3891d0 Thomas Thrainer
    # FIXME: Acquire BGL for cluster tag operations (as of this writing it's
72 fb3891d0 Thomas Thrainer
    # not possible to acquire the BGL based on opcode parameters)
73 fb3891d0 Thomas Thrainer
74 fb3891d0 Thomas Thrainer
  def CheckPrereq(self):
75 fb3891d0 Thomas Thrainer
    """Check prerequisites.
76 fb3891d0 Thomas Thrainer

77 fb3891d0 Thomas Thrainer
    """
78 fb3891d0 Thomas Thrainer
    if self.op.kind == constants.TAG_CLUSTER:
79 fb3891d0 Thomas Thrainer
      self.target = self.cfg.GetClusterInfo()
80 fb3891d0 Thomas Thrainer
    elif self.op.kind == constants.TAG_NODE:
81 1c3231aa Thomas Thrainer
      self.target = self.cfg.GetNodeInfo(self.node_uuid)
82 fb3891d0 Thomas Thrainer
    elif self.op.kind == constants.TAG_INSTANCE:
83 da4a52a3 Thomas Thrainer
      self.target = self.cfg.GetInstanceInfo(self.inst_uuid)
84 fb3891d0 Thomas Thrainer
    elif self.op.kind == constants.TAG_NODEGROUP:
85 fb3891d0 Thomas Thrainer
      self.target = self.cfg.GetNodeGroup(self.group_uuid)
86 fb3891d0 Thomas Thrainer
    elif self.op.kind == constants.TAG_NETWORK:
87 fb3891d0 Thomas Thrainer
      self.target = self.cfg.GetNetwork(self.network_uuid)
88 fb3891d0 Thomas Thrainer
    else:
89 fb3891d0 Thomas Thrainer
      raise errors.OpPrereqError("Wrong tag type requested (%s)" %
90 fb3891d0 Thomas Thrainer
                                 str(self.op.kind), errors.ECODE_INVAL)
91 fb3891d0 Thomas Thrainer
92 fb3891d0 Thomas Thrainer
93 fb3891d0 Thomas Thrainer
class LUTagsGet(TagsLU):
94 fb3891d0 Thomas Thrainer
  """Returns the tags of a given object.
95 fb3891d0 Thomas Thrainer

96 fb3891d0 Thomas Thrainer
  """
97 fb3891d0 Thomas Thrainer
  REQ_BGL = False
98 fb3891d0 Thomas Thrainer
99 fb3891d0 Thomas Thrainer
  def ExpandNames(self):
100 fb3891d0 Thomas Thrainer
    TagsLU.ExpandNames(self)
101 fb3891d0 Thomas Thrainer
102 fb3891d0 Thomas Thrainer
    # Share locks as this is only a read operation
103 5eacbcae Thomas Thrainer
    self.share_locks = ShareAll()
104 fb3891d0 Thomas Thrainer
105 fb3891d0 Thomas Thrainer
  def Exec(self, feedback_fn):
106 fb3891d0 Thomas Thrainer
    """Returns the tag list.
107 fb3891d0 Thomas Thrainer

108 fb3891d0 Thomas Thrainer
    """
109 fb3891d0 Thomas Thrainer
    return list(self.target.GetTags())
110 fb3891d0 Thomas Thrainer
111 fb3891d0 Thomas Thrainer
112 fb3891d0 Thomas Thrainer
class LUTagsSearch(NoHooksLU):
113 fb3891d0 Thomas Thrainer
  """Searches the tags for a given pattern.
114 fb3891d0 Thomas Thrainer

115 fb3891d0 Thomas Thrainer
  """
116 fb3891d0 Thomas Thrainer
  REQ_BGL = False
117 fb3891d0 Thomas Thrainer
118 fb3891d0 Thomas Thrainer
  def ExpandNames(self):
119 fb3891d0 Thomas Thrainer
    self.needed_locks = {}
120 fb3891d0 Thomas Thrainer
121 fb3891d0 Thomas Thrainer
  def CheckPrereq(self):
122 fb3891d0 Thomas Thrainer
    """Check prerequisites.
123 fb3891d0 Thomas Thrainer

124 fb3891d0 Thomas Thrainer
    This checks the pattern passed for validity by compiling it.
125 fb3891d0 Thomas Thrainer

126 fb3891d0 Thomas Thrainer
    """
127 fb3891d0 Thomas Thrainer
    try:
128 fb3891d0 Thomas Thrainer
      self.re = re.compile(self.op.pattern)
129 fb3891d0 Thomas Thrainer
    except re.error, err:
130 fb3891d0 Thomas Thrainer
      raise errors.OpPrereqError("Invalid search pattern '%s': %s" %
131 fb3891d0 Thomas Thrainer
                                 (self.op.pattern, err), errors.ECODE_INVAL)
132 fb3891d0 Thomas Thrainer
133 36ccc662 Hrvoje Ribicic
  @staticmethod
134 36ccc662 Hrvoje Ribicic
  def _ExtendTagTargets(targets, object_type_name, object_info_dict):
135 36ccc662 Hrvoje Ribicic
    return targets.extend(("/%s/%s" % (object_type_name, o.name), o)
136 36ccc662 Hrvoje Ribicic
                          for o in object_info_dict.values())
137 36ccc662 Hrvoje Ribicic
138 fb3891d0 Thomas Thrainer
  def Exec(self, feedback_fn):
139 fb3891d0 Thomas Thrainer
    """Returns the tag list.
140 fb3891d0 Thomas Thrainer

141 fb3891d0 Thomas Thrainer
    """
142 d0d7d7cf Thomas Thrainer
    tgts = [("/cluster", self.cfg.GetClusterInfo())]
143 36ccc662 Hrvoje Ribicic
144 3eaa6e1d Klaus Aehlig
    LUTagsSearch._ExtendTagTargets(tgts, "instances",
145 3eaa6e1d Klaus Aehlig
                                   self.cfg.GetAllInstancesInfo())
146 3eaa6e1d Klaus Aehlig
    LUTagsSearch._ExtendTagTargets(tgts, "nodes",
147 3eaa6e1d Klaus Aehlig
                                   self.cfg.GetAllNodesInfo())
148 36ccc662 Hrvoje Ribicic
    LUTagsSearch._ExtendTagTargets(tgts, "nodegroup",
149 3eaa6e1d Klaus Aehlig
                                   self.cfg.GetAllNodeGroupsInfo())
150 3eaa6e1d Klaus Aehlig
    LUTagsSearch._ExtendTagTargets(tgts, "network",
151 3eaa6e1d Klaus Aehlig
                                   self.cfg.GetAllNetworksInfo())
152 36ccc662 Hrvoje Ribicic
153 fb3891d0 Thomas Thrainer
    results = []
154 fb3891d0 Thomas Thrainer
    for path, target in tgts:
155 fb3891d0 Thomas Thrainer
      for tag in target.GetTags():
156 fb3891d0 Thomas Thrainer
        if self.re.search(tag):
157 fb3891d0 Thomas Thrainer
          results.append((path, tag))
158 fb3891d0 Thomas Thrainer
    return results
159 fb3891d0 Thomas Thrainer
160 fb3891d0 Thomas Thrainer
161 fb3891d0 Thomas Thrainer
class LUTagsSet(TagsLU):
162 fb3891d0 Thomas Thrainer
  """Sets a tag on a given object.
163 fb3891d0 Thomas Thrainer

164 fb3891d0 Thomas Thrainer
  """
165 fb3891d0 Thomas Thrainer
  REQ_BGL = False
166 fb3891d0 Thomas Thrainer
167 fb3891d0 Thomas Thrainer
  def CheckPrereq(self):
168 fb3891d0 Thomas Thrainer
    """Check prerequisites.
169 fb3891d0 Thomas Thrainer

170 fb3891d0 Thomas Thrainer
    This checks the type and length of the tag name and value.
171 fb3891d0 Thomas Thrainer

172 fb3891d0 Thomas Thrainer
    """
173 fb3891d0 Thomas Thrainer
    TagsLU.CheckPrereq(self)
174 fb3891d0 Thomas Thrainer
    for tag in self.op.tags:
175 fb3891d0 Thomas Thrainer
      objects.TaggableObject.ValidateTag(tag)
176 fb3891d0 Thomas Thrainer
177 fb3891d0 Thomas Thrainer
  def Exec(self, feedback_fn):
178 fb3891d0 Thomas Thrainer
    """Sets the tag.
179 fb3891d0 Thomas Thrainer

180 fb3891d0 Thomas Thrainer
    """
181 fb3891d0 Thomas Thrainer
    try:
182 fb3891d0 Thomas Thrainer
      for tag in self.op.tags:
183 fb3891d0 Thomas Thrainer
        self.target.AddTag(tag)
184 fb3891d0 Thomas Thrainer
    except errors.TagError, err:
185 fb3891d0 Thomas Thrainer
      raise errors.OpExecError("Error while setting tag: %s" % str(err))
186 fb3891d0 Thomas Thrainer
    self.cfg.Update(self.target, feedback_fn)
187 fb3891d0 Thomas Thrainer
188 fb3891d0 Thomas Thrainer
189 fb3891d0 Thomas Thrainer
class LUTagsDel(TagsLU):
190 fb3891d0 Thomas Thrainer
  """Delete a list of tags from a given object.
191 fb3891d0 Thomas Thrainer

192 fb3891d0 Thomas Thrainer
  """
193 fb3891d0 Thomas Thrainer
  REQ_BGL = False
194 fb3891d0 Thomas Thrainer
195 fb3891d0 Thomas Thrainer
  def CheckPrereq(self):
196 fb3891d0 Thomas Thrainer
    """Check prerequisites.
197 fb3891d0 Thomas Thrainer

198 fb3891d0 Thomas Thrainer
    This checks that we have the given tag.
199 fb3891d0 Thomas Thrainer

200 fb3891d0 Thomas Thrainer
    """
201 fb3891d0 Thomas Thrainer
    TagsLU.CheckPrereq(self)
202 fb3891d0 Thomas Thrainer
    for tag in self.op.tags:
203 fb3891d0 Thomas Thrainer
      objects.TaggableObject.ValidateTag(tag)
204 fb3891d0 Thomas Thrainer
    del_tags = frozenset(self.op.tags)
205 fb3891d0 Thomas Thrainer
    cur_tags = self.target.GetTags()
206 fb3891d0 Thomas Thrainer
207 fb3891d0 Thomas Thrainer
    diff_tags = del_tags - cur_tags
208 fb3891d0 Thomas Thrainer
    if diff_tags:
209 fb3891d0 Thomas Thrainer
      diff_names = ("'%s'" % i for i in sorted(diff_tags))
210 fb3891d0 Thomas Thrainer
      raise errors.OpPrereqError("Tag(s) %s not found" %
211 fb3891d0 Thomas Thrainer
                                 (utils.CommaJoin(diff_names), ),
212 fb3891d0 Thomas Thrainer
                                 errors.ECODE_NOENT)
213 fb3891d0 Thomas Thrainer
214 fb3891d0 Thomas Thrainer
  def Exec(self, feedback_fn):
215 fb3891d0 Thomas Thrainer
    """Remove the tag from the object.
216 fb3891d0 Thomas Thrainer

217 fb3891d0 Thomas Thrainer
    """
218 fb3891d0 Thomas Thrainer
    for tag in self.op.tags:
219 fb3891d0 Thomas Thrainer
      self.target.RemoveTag(tag)
220 fb3891d0 Thomas Thrainer
    self.cfg.Update(self.target, feedback_fn)