Statistics
| Branch: | Tag: | Revision:

root / lib / cmdlib / tags.py @ d0d7d7cf

History | View | Annotate | Download (6 kB)

1
#
2
#
3

    
4
# Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Google Inc.
5
#
6
# This program is free software; you can redistribute it and/or modify
7
# it under the terms of the GNU General Public License as published by
8
# the Free Software Foundation; either version 2 of the License, or
9
# (at your option) any later version.
10
#
11
# This program is distributed in the hope that it will be useful, but
12
# WITHOUT ANY WARRANTY; without even the implied warranty of
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
# General Public License for more details.
15
#
16
# You should have received a copy of the GNU General Public License
17
# along with this program; if not, write to the Free Software
18
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
# 02110-1301, USA.
20

    
21

    
22
"""Logical units dealing with tags."""
23

    
24
import re
25

    
26
from ganeti import constants
27
from ganeti import errors
28
from ganeti import locking
29
from ganeti import objects
30
from ganeti import utils
31
from ganeti.cmdlib.base import NoHooksLU
32
from ganeti.cmdlib.common import ExpandNodeUuidAndName, ExpandInstanceName, \
33
  ShareAll
34

    
35

    
36
class TagsLU(NoHooksLU): # pylint: disable=W0223
37
  """Generic tags LU.
38

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

41
  """
42
  def ExpandNames(self):
43
    self.group_uuid = None
44
    self.needed_locks = {}
45

    
46
    if self.op.kind == constants.TAG_NODE:
47
      (self.node_uuid, _) = \
48
        ExpandNodeUuidAndName(self.cfg, None, self.op.name)
49
      lock_level = locking.LEVEL_NODE
50
      lock_name = self.node_uuid
51
    elif self.op.kind == constants.TAG_INSTANCE:
52
      self.op.name = ExpandInstanceName(self.cfg, self.op.name)
53
      lock_level = locking.LEVEL_INSTANCE
54
      lock_name = self.op.name
55
    elif self.op.kind == constants.TAG_NODEGROUP:
56
      self.group_uuid = self.cfg.LookupNodeGroup(self.op.name)
57
      lock_level = locking.LEVEL_NODEGROUP
58
      lock_name = self.group_uuid
59
    elif self.op.kind == constants.TAG_NETWORK:
60
      self.network_uuid = self.cfg.LookupNetwork(self.op.name)
61
      lock_level = locking.LEVEL_NETWORK
62
      lock_name = self.network_uuid
63
    else:
64
      lock_level = None
65
      lock_name = None
66

    
67
    if lock_level and getattr(self.op, "use_locking", True):
68
      self.needed_locks[lock_level] = lock_name
69

    
70
    # FIXME: Acquire BGL for cluster tag operations (as of this writing it's
71
    # not possible to acquire the BGL based on opcode parameters)
72

    
73
  def CheckPrereq(self):
74
    """Check prerequisites.
75

76
    """
77
    if self.op.kind == constants.TAG_CLUSTER:
78
      self.target = self.cfg.GetClusterInfo()
79
    elif self.op.kind == constants.TAG_NODE:
80
      self.target = self.cfg.GetNodeInfo(self.node_uuid)
81
    elif self.op.kind == constants.TAG_INSTANCE:
82
      self.target = self.cfg.GetInstanceInfo(self.op.name)
83
    elif self.op.kind == constants.TAG_NODEGROUP:
84
      self.target = self.cfg.GetNodeGroup(self.group_uuid)
85
    elif self.op.kind == constants.TAG_NETWORK:
86
      self.target = self.cfg.GetNetwork(self.network_uuid)
87
    else:
88
      raise errors.OpPrereqError("Wrong tag type requested (%s)" %
89
                                 str(self.op.kind), errors.ECODE_INVAL)
90

    
91

    
92
class LUTagsGet(TagsLU):
93
  """Returns the tags of a given object.
94

95
  """
96
  REQ_BGL = False
97

    
98
  def ExpandNames(self):
99
    TagsLU.ExpandNames(self)
100

    
101
    # Share locks as this is only a read operation
102
    self.share_locks = ShareAll()
103

    
104
  def Exec(self, feedback_fn):
105
    """Returns the tag list.
106

107
    """
108
    return list(self.target.GetTags())
109

    
110

    
111
class LUTagsSearch(NoHooksLU):
112
  """Searches the tags for a given pattern.
113

114
  """
115
  REQ_BGL = False
116

    
117
  def ExpandNames(self):
118
    self.needed_locks = {}
119

    
120
  def CheckPrereq(self):
121
    """Check prerequisites.
122

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

125
    """
126
    try:
127
      self.re = re.compile(self.op.pattern)
128
    except re.error, err:
129
      raise errors.OpPrereqError("Invalid search pattern '%s': %s" %
130
                                 (self.op.pattern, err), errors.ECODE_INVAL)
131

    
132
  def Exec(self, feedback_fn):
133
    """Returns the tag list.
134

135
    """
136
    tgts = [("/cluster", self.cfg.GetClusterInfo())]
137
    ilist = self.cfg.GetAllInstancesInfo().values()
138
    tgts.extend([("/instances/%s" % i.name, i) for i in ilist])
139
    nlist = self.cfg.GetAllNodesInfo().values()
140
    tgts.extend([("/nodes/%s" % n.name, n) for n in nlist])
141
    tgts.extend(("/nodegroup/%s" % n.name, n)
142
                for n in self.cfg.GetAllNodeGroupsInfo().values())
143
    results = []
144
    for path, target in tgts:
145
      for tag in target.GetTags():
146
        if self.re.search(tag):
147
          results.append((path, tag))
148
    return results
149

    
150

    
151
class LUTagsSet(TagsLU):
152
  """Sets a tag on a given object.
153

154
  """
155
  REQ_BGL = False
156

    
157
  def CheckPrereq(self):
158
    """Check prerequisites.
159

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

162
    """
163
    TagsLU.CheckPrereq(self)
164
    for tag in self.op.tags:
165
      objects.TaggableObject.ValidateTag(tag)
166

    
167
  def Exec(self, feedback_fn):
168
    """Sets the tag.
169

170
    """
171
    try:
172
      for tag in self.op.tags:
173
        self.target.AddTag(tag)
174
    except errors.TagError, err:
175
      raise errors.OpExecError("Error while setting tag: %s" % str(err))
176
    self.cfg.Update(self.target, feedback_fn)
177

    
178

    
179
class LUTagsDel(TagsLU):
180
  """Delete a list of tags from a given object.
181

182
  """
183
  REQ_BGL = False
184

    
185
  def CheckPrereq(self):
186
    """Check prerequisites.
187

188
    This checks that we have the given tag.
189

190
    """
191
    TagsLU.CheckPrereq(self)
192
    for tag in self.op.tags:
193
      objects.TaggableObject.ValidateTag(tag)
194
    del_tags = frozenset(self.op.tags)
195
    cur_tags = self.target.GetTags()
196

    
197
    diff_tags = del_tags - cur_tags
198
    if diff_tags:
199
      diff_names = ("'%s'" % i for i in sorted(diff_tags))
200
      raise errors.OpPrereqError("Tag(s) %s not found" %
201
                                 (utils.CommaJoin(diff_names), ),
202
                                 errors.ECODE_NOENT)
203

    
204
  def Exec(self, feedback_fn):
205
    """Remove the tag from the object.
206

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