Statistics
| Branch: | Tag: | Revision:

root / lib / cmdlib / tags.py @ 4665b94f

History | View | Annotate | Download (6 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 1c3231aa Thomas Thrainer
from ganeti.cmdlib.common import ExpandNodeUuidAndName, ExpandInstanceName, \
33 1c3231aa Thomas Thrainer
  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 5eacbcae Thomas Thrainer
      self.op.name = ExpandInstanceName(self.cfg, self.op.name)
53 fb3891d0 Thomas Thrainer
      lock_level = locking.LEVEL_INSTANCE
54 fb3891d0 Thomas Thrainer
      lock_name = self.op.name
55 fb3891d0 Thomas Thrainer
    elif self.op.kind == constants.TAG_NODEGROUP:
56 fb3891d0 Thomas Thrainer
      self.group_uuid = self.cfg.LookupNodeGroup(self.op.name)
57 fb3891d0 Thomas Thrainer
      lock_level = locking.LEVEL_NODEGROUP
58 fb3891d0 Thomas Thrainer
      lock_name = self.group_uuid
59 fb3891d0 Thomas Thrainer
    elif self.op.kind == constants.TAG_NETWORK:
60 fb3891d0 Thomas Thrainer
      self.network_uuid = self.cfg.LookupNetwork(self.op.name)
61 fb3891d0 Thomas Thrainer
      lock_level = locking.LEVEL_NETWORK
62 fb3891d0 Thomas Thrainer
      lock_name = self.network_uuid
63 fb3891d0 Thomas Thrainer
    else:
64 fb3891d0 Thomas Thrainer
      lock_level = None
65 fb3891d0 Thomas Thrainer
      lock_name = None
66 fb3891d0 Thomas Thrainer
67 fb3891d0 Thomas Thrainer
    if lock_level and getattr(self.op, "use_locking", True):
68 fb3891d0 Thomas Thrainer
      self.needed_locks[lock_level] = lock_name
69 fb3891d0 Thomas Thrainer
70 fb3891d0 Thomas Thrainer
    # FIXME: Acquire BGL for cluster tag operations (as of this writing it's
71 fb3891d0 Thomas Thrainer
    # not possible to acquire the BGL based on opcode parameters)
72 fb3891d0 Thomas Thrainer
73 fb3891d0 Thomas Thrainer
  def CheckPrereq(self):
74 fb3891d0 Thomas Thrainer
    """Check prerequisites.
75 fb3891d0 Thomas Thrainer

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

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

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

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

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

125 fb3891d0 Thomas Thrainer
    """
126 fb3891d0 Thomas Thrainer
    try:
127 fb3891d0 Thomas Thrainer
      self.re = re.compile(self.op.pattern)
128 fb3891d0 Thomas Thrainer
    except re.error, err:
129 fb3891d0 Thomas Thrainer
      raise errors.OpPrereqError("Invalid search pattern '%s': %s" %
130 fb3891d0 Thomas Thrainer
                                 (self.op.pattern, err), errors.ECODE_INVAL)
131 fb3891d0 Thomas Thrainer
132 fb3891d0 Thomas Thrainer
  def Exec(self, feedback_fn):
133 fb3891d0 Thomas Thrainer
    """Returns the tag list.
134 fb3891d0 Thomas Thrainer

135 fb3891d0 Thomas Thrainer
    """
136 d0d7d7cf Thomas Thrainer
    tgts = [("/cluster", self.cfg.GetClusterInfo())]
137 d0d7d7cf Thomas Thrainer
    ilist = self.cfg.GetAllInstancesInfo().values()
138 fb3891d0 Thomas Thrainer
    tgts.extend([("/instances/%s" % i.name, i) for i in ilist])
139 d0d7d7cf Thomas Thrainer
    nlist = self.cfg.GetAllNodesInfo().values()
140 fb3891d0 Thomas Thrainer
    tgts.extend([("/nodes/%s" % n.name, n) for n in nlist])
141 fb3891d0 Thomas Thrainer
    tgts.extend(("/nodegroup/%s" % n.name, n)
142 d0d7d7cf Thomas Thrainer
                for n in self.cfg.GetAllNodeGroupsInfo().values())
143 fb3891d0 Thomas Thrainer
    results = []
144 fb3891d0 Thomas Thrainer
    for path, target in tgts:
145 fb3891d0 Thomas Thrainer
      for tag in target.GetTags():
146 fb3891d0 Thomas Thrainer
        if self.re.search(tag):
147 fb3891d0 Thomas Thrainer
          results.append((path, tag))
148 fb3891d0 Thomas Thrainer
    return results
149 fb3891d0 Thomas Thrainer
150 fb3891d0 Thomas Thrainer
151 fb3891d0 Thomas Thrainer
class LUTagsSet(TagsLU):
152 fb3891d0 Thomas Thrainer
  """Sets a tag on a given object.
153 fb3891d0 Thomas Thrainer

154 fb3891d0 Thomas Thrainer
  """
155 fb3891d0 Thomas Thrainer
  REQ_BGL = False
156 fb3891d0 Thomas Thrainer
157 fb3891d0 Thomas Thrainer
  def CheckPrereq(self):
158 fb3891d0 Thomas Thrainer
    """Check prerequisites.
159 fb3891d0 Thomas Thrainer

160 fb3891d0 Thomas Thrainer
    This checks the type and length of the tag name and value.
161 fb3891d0 Thomas Thrainer

162 fb3891d0 Thomas Thrainer
    """
163 fb3891d0 Thomas Thrainer
    TagsLU.CheckPrereq(self)
164 fb3891d0 Thomas Thrainer
    for tag in self.op.tags:
165 fb3891d0 Thomas Thrainer
      objects.TaggableObject.ValidateTag(tag)
166 fb3891d0 Thomas Thrainer
167 fb3891d0 Thomas Thrainer
  def Exec(self, feedback_fn):
168 fb3891d0 Thomas Thrainer
    """Sets the tag.
169 fb3891d0 Thomas Thrainer

170 fb3891d0 Thomas Thrainer
    """
171 fb3891d0 Thomas Thrainer
    try:
172 fb3891d0 Thomas Thrainer
      for tag in self.op.tags:
173 fb3891d0 Thomas Thrainer
        self.target.AddTag(tag)
174 fb3891d0 Thomas Thrainer
    except errors.TagError, err:
175 fb3891d0 Thomas Thrainer
      raise errors.OpExecError("Error while setting tag: %s" % str(err))
176 fb3891d0 Thomas Thrainer
    self.cfg.Update(self.target, feedback_fn)
177 fb3891d0 Thomas Thrainer
178 fb3891d0 Thomas Thrainer
179 fb3891d0 Thomas Thrainer
class LUTagsDel(TagsLU):
180 fb3891d0 Thomas Thrainer
  """Delete a list of tags from a given object.
181 fb3891d0 Thomas Thrainer

182 fb3891d0 Thomas Thrainer
  """
183 fb3891d0 Thomas Thrainer
  REQ_BGL = False
184 fb3891d0 Thomas Thrainer
185 fb3891d0 Thomas Thrainer
  def CheckPrereq(self):
186 fb3891d0 Thomas Thrainer
    """Check prerequisites.
187 fb3891d0 Thomas Thrainer

188 fb3891d0 Thomas Thrainer
    This checks that we have the given tag.
189 fb3891d0 Thomas Thrainer

190 fb3891d0 Thomas Thrainer
    """
191 fb3891d0 Thomas Thrainer
    TagsLU.CheckPrereq(self)
192 fb3891d0 Thomas Thrainer
    for tag in self.op.tags:
193 fb3891d0 Thomas Thrainer
      objects.TaggableObject.ValidateTag(tag)
194 fb3891d0 Thomas Thrainer
    del_tags = frozenset(self.op.tags)
195 fb3891d0 Thomas Thrainer
    cur_tags = self.target.GetTags()
196 fb3891d0 Thomas Thrainer
197 fb3891d0 Thomas Thrainer
    diff_tags = del_tags - cur_tags
198 fb3891d0 Thomas Thrainer
    if diff_tags:
199 fb3891d0 Thomas Thrainer
      diff_names = ("'%s'" % i for i in sorted(diff_tags))
200 fb3891d0 Thomas Thrainer
      raise errors.OpPrereqError("Tag(s) %s not found" %
201 fb3891d0 Thomas Thrainer
                                 (utils.CommaJoin(diff_names), ),
202 fb3891d0 Thomas Thrainer
                                 errors.ECODE_NOENT)
203 fb3891d0 Thomas Thrainer
204 fb3891d0 Thomas Thrainer
  def Exec(self, feedback_fn):
205 fb3891d0 Thomas Thrainer
    """Remove the tag from the object.
206 fb3891d0 Thomas Thrainer

207 fb3891d0 Thomas Thrainer
    """
208 fb3891d0 Thomas Thrainer
    for tag in self.op.tags:
209 fb3891d0 Thomas Thrainer
      self.target.RemoveTag(tag)
210 fb3891d0 Thomas Thrainer
    self.cfg.Update(self.target, feedback_fn)