Statistics
| Branch: | Tag: | Revision:

root / lib / cmdlib / tags.py @ 7352d33b

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

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

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

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

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

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

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

134 fb3891d0 Thomas Thrainer
    """
135 fb3891d0 Thomas Thrainer
    cfg = self.cfg
136 fb3891d0 Thomas Thrainer
    tgts = [("/cluster", cfg.GetClusterInfo())]
137 fb3891d0 Thomas Thrainer
    ilist = cfg.GetAllInstancesInfo().values()
138 fb3891d0 Thomas Thrainer
    tgts.extend([("/instances/%s" % i.name, i) for i in ilist])
139 fb3891d0 Thomas Thrainer
    nlist = 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 fb3891d0 Thomas Thrainer
                for n in 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)