Statistics
| Branch: | Tag: | Revision:

root / lib / cmdlib / tags.py @ 06c2fb4a

History | View | Annotate | Download (6.2 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 5eacbcae Thomas Thrainer
from ganeti.cmdlib.common import ExpandNodeName, ExpandInstanceName, ShareAll
33 fb3891d0 Thomas Thrainer
34 fb3891d0 Thomas Thrainer
35 fb3891d0 Thomas Thrainer
class TagsLU(NoHooksLU): # pylint: disable=W0223
36 fb3891d0 Thomas Thrainer
  """Generic tags LU.
37 fb3891d0 Thomas Thrainer

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

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

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

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

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

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

121 fb3891d0 Thomas Thrainer
    This checks the pattern passed for validity by compiling it.
122 fb3891d0 Thomas Thrainer

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

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

159 fb3891d0 Thomas Thrainer
  """
160 fb3891d0 Thomas Thrainer
  REQ_BGL = False
161 fb3891d0 Thomas Thrainer
162 fb3891d0 Thomas Thrainer
  def CheckPrereq(self):
163 fb3891d0 Thomas Thrainer
    """Check prerequisites.
164 fb3891d0 Thomas Thrainer

165 fb3891d0 Thomas Thrainer
    This checks the type and length of the tag name and value.
166 fb3891d0 Thomas Thrainer

167 fb3891d0 Thomas Thrainer
    """
168 fb3891d0 Thomas Thrainer
    TagsLU.CheckPrereq(self)
169 fb3891d0 Thomas Thrainer
    for tag in self.op.tags:
170 fb3891d0 Thomas Thrainer
      objects.TaggableObject.ValidateTag(tag)
171 fb3891d0 Thomas Thrainer
172 fb3891d0 Thomas Thrainer
  def Exec(self, feedback_fn):
173 fb3891d0 Thomas Thrainer
    """Sets the tag.
174 fb3891d0 Thomas Thrainer

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

187 fb3891d0 Thomas Thrainer
  """
188 fb3891d0 Thomas Thrainer
  REQ_BGL = False
189 fb3891d0 Thomas Thrainer
190 fb3891d0 Thomas Thrainer
  def CheckPrereq(self):
191 fb3891d0 Thomas Thrainer
    """Check prerequisites.
192 fb3891d0 Thomas Thrainer

193 fb3891d0 Thomas Thrainer
    This checks that we have the given tag.
194 fb3891d0 Thomas Thrainer

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

212 fb3891d0 Thomas Thrainer
    """
213 fb3891d0 Thomas Thrainer
    for tag in self.op.tags:
214 fb3891d0 Thomas Thrainer
      self.target.RemoveTag(tag)
215 fb3891d0 Thomas Thrainer
    self.cfg.Update(self.target, feedback_fn)