Statistics
| Branch: | Tag: | Revision:

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

History | View | Annotate | Download (6.2 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 ExpandNodeName, ExpandInstanceName, ShareAll
33

    
34

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

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

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

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

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

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

    
71
  def CheckPrereq(self):
72
    """Check prerequisites.
73

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

    
89

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

93
  """
94
  REQ_BGL = False
95

    
96
  def ExpandNames(self):
97
    TagsLU.ExpandNames(self)
98

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

    
102
  def Exec(self, feedback_fn):
103
    """Returns the tag list.
104

105
    """
106
    return list(self.target.GetTags())
107

    
108

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

112
  """
113
  REQ_BGL = False
114

    
115
  def ExpandNames(self):
116
    self.needed_locks = {}
117

    
118
  def CheckPrereq(self):
119
    """Check prerequisites.
120

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

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

    
130
  @staticmethod
131
  def _ExtendTagTargets(targets, object_type_name, object_info_dict):
132
    return targets.extend(("/%s/%s" % (object_type_name, o.name), o)
133
                          for o in object_info_dict.values())
134

    
135
  def Exec(self, feedback_fn):
136
    """Returns the tag list.
137

138
    """
139
    cfg = self.cfg
140
    tgts = [("/cluster", cfg.GetClusterInfo())]
141

    
142
    LUTagsSearch._ExtendTagTargets(tgts, "instances", cfg.GetAllInstancesInfo())
143
    LUTagsSearch._ExtendTagTargets(tgts, "nodes", cfg.GetAllNodesInfo())
144
    LUTagsSearch._ExtendTagTargets(tgts, "nodegroup",
145
                                   cfg.GetAllNodeGroupsInfo())
146
    LUTagsSearch._ExtendTagTargets(tgts, "network", cfg.GetAllNetworksInfo())
147

    
148
    results = []
149
    for path, target in tgts:
150
      for tag in target.GetTags():
151
        if self.re.search(tag):
152
          results.append((path, tag))
153
    return results
154

    
155

    
156
class LUTagsSet(TagsLU):
157
  """Sets a tag on a given object.
158

159
  """
160
  REQ_BGL = False
161

    
162
  def CheckPrereq(self):
163
    """Check prerequisites.
164

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

167
    """
168
    TagsLU.CheckPrereq(self)
169
    for tag in self.op.tags:
170
      objects.TaggableObject.ValidateTag(tag)
171

    
172
  def Exec(self, feedback_fn):
173
    """Sets the tag.
174

175
    """
176
    try:
177
      for tag in self.op.tags:
178
        self.target.AddTag(tag)
179
    except errors.TagError, err:
180
      raise errors.OpExecError("Error while setting tag: %s" % str(err))
181
    self.cfg.Update(self.target, feedback_fn)
182

    
183

    
184
class LUTagsDel(TagsLU):
185
  """Delete a list of tags from a given object.
186

187
  """
188
  REQ_BGL = False
189

    
190
  def CheckPrereq(self):
191
    """Check prerequisites.
192

193
    This checks that we have the given tag.
194

195
    """
196
    TagsLU.CheckPrereq(self)
197
    for tag in self.op.tags:
198
      objects.TaggableObject.ValidateTag(tag)
199
    del_tags = frozenset(self.op.tags)
200
    cur_tags = self.target.GetTags()
201

    
202
    diff_tags = del_tags - cur_tags
203
    if diff_tags:
204
      diff_names = ("'%s'" % i for i in sorted(diff_tags))
205
      raise errors.OpPrereqError("Tag(s) %s not found" %
206
                                 (utils.CommaJoin(diff_names), ),
207
                                 errors.ECODE_NOENT)
208

    
209
  def Exec(self, feedback_fn):
210
    """Remove the tag from the object.
211

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