Statistics
| Branch: | Tag: | Revision:

root / lib / cmdlib / tags.py @ 1c3231aa

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

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

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

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

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

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

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

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

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