Statistics
| Branch: | Tag: | Revision:

root / lib / query.py @ bc57fa8d

History | View | Annotate | Download (85.7 kB)

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

24 8f8ce6d1 Michael Hanselmann
How it works:
25 8f8ce6d1 Michael Hanselmann

26 8f8ce6d1 Michael Hanselmann
  - Add field definitions
27 8f8ce6d1 Michael Hanselmann
    - See how L{NODE_FIELDS} is built
28 8f8ce6d1 Michael Hanselmann
    - Each field gets:
29 8f8ce6d1 Michael Hanselmann
      - Query field definition (L{objects.QueryFieldDefinition}, use
30 8f8ce6d1 Michael Hanselmann
        L{_MakeField} for creating), containing:
31 8f8ce6d1 Michael Hanselmann
          - Name, must be lowercase and match L{FIELD_NAME_RE}
32 8f8ce6d1 Michael Hanselmann
          - Title for tables, must not contain whitespace and match
33 8f8ce6d1 Michael Hanselmann
            L{TITLE_RE}
34 8f8ce6d1 Michael Hanselmann
          - Value data type, e.g. L{constants.QFT_NUMBER}
35 79b2ca83 Michael Hanselmann
          - Human-readable description, must not end with punctuation or
36 79b2ca83 Michael Hanselmann
            contain newlines
37 8f8ce6d1 Michael Hanselmann
      - Data request type, see e.g. C{NQ_*}
38 111bf531 Michael Hanselmann
      - OR-ed flags, see C{QFF_*}
39 8f8ce6d1 Michael Hanselmann
      - A retrieval function, see L{Query.__init__} for description
40 8f8ce6d1 Michael Hanselmann
    - Pass list of fields through L{_PrepareFieldList} for preparation and
41 8f8ce6d1 Michael Hanselmann
      checks
42 8f8ce6d1 Michael Hanselmann
  - Instantiate L{Query} with prepared field list definition and selected fields
43 8f8ce6d1 Michael Hanselmann
  - Call L{Query.RequestedData} to determine what data to collect/compute
44 8f8ce6d1 Michael Hanselmann
  - Call L{Query.Query} or L{Query.OldStyleQuery} with collected data and use
45 8f8ce6d1 Michael Hanselmann
    result
46 8f8ce6d1 Michael Hanselmann
      - Data container must support iteration using C{__iter__}
47 8f8ce6d1 Michael Hanselmann
      - Items are passed to retrieval functions and can have any format
48 8f8ce6d1 Michael Hanselmann
  - Call L{Query.GetFields} to get list of definitions for selected fields
49 8f8ce6d1 Michael Hanselmann

50 8f8ce6d1 Michael Hanselmann
@attention: Retrieval functions must be idempotent. They can be called multiple
51 fb0be379 Michael Hanselmann
  times, in any order and any number of times.
52 8f8ce6d1 Michael Hanselmann

53 8f8ce6d1 Michael Hanselmann
"""
54 4ca96421 Michael Hanselmann
55 8235fe04 Michael Hanselmann
import logging
56 4ca96421 Michael Hanselmann
import operator
57 4ca96421 Michael Hanselmann
import re
58 4ca96421 Michael Hanselmann
59 4ca96421 Michael Hanselmann
from ganeti import constants
60 4ca96421 Michael Hanselmann
from ganeti import errors
61 4ca96421 Michael Hanselmann
from ganeti import utils
62 4ca96421 Michael Hanselmann
from ganeti import compat
63 4ca96421 Michael Hanselmann
from ganeti import objects
64 4ca96421 Michael Hanselmann
from ganeti import ht
65 dff5f600 Michael Hanselmann
from ganeti import runtime
66 fb0be379 Michael Hanselmann
from ganeti import qlang
67 526f866b Michael Hanselmann
from ganeti import jstore
68 9982754c Jose A. Lopes
from ganeti.hypervisor import hv_base
69 4ca96421 Michael Hanselmann
70 82599b3e Iustin Pop
from ganeti.constants import (QFT_UNKNOWN, QFT_TEXT, QFT_BOOL, QFT_NUMBER,
71 82599b3e Iustin Pop
                              QFT_UNIT, QFT_TIMESTAMP, QFT_OTHER,
72 cfb084ae René Nussbaumer
                              RS_NORMAL, RS_UNKNOWN, RS_NODATA,
73 cfb084ae René Nussbaumer
                              RS_UNAVAIL, RS_OFFLINE)
74 82599b3e Iustin Pop
75 306bed0e Apollon Oikonomopoulos
(NETQ_CONFIG,
76 306bed0e Apollon Oikonomopoulos
 NETQ_GROUP,
77 306bed0e Apollon Oikonomopoulos
 NETQ_STATS,
78 306bed0e Apollon Oikonomopoulos
 NETQ_INST) = range(300, 304)
79 4ca96421 Michael Hanselmann
80 8f8ce6d1 Michael Hanselmann
# Constants for requesting data from the caller/data provider. Each property
81 8f8ce6d1 Michael Hanselmann
# collected/computed separately by the data provider should have its own to
82 8f8ce6d1 Michael Hanselmann
# only collect the requested data and not more.
83 8f8ce6d1 Michael Hanselmann
84 8235fe04 Michael Hanselmann
(NQ_CONFIG,
85 8235fe04 Michael Hanselmann
 NQ_INST,
86 8235fe04 Michael Hanselmann
 NQ_LIVE,
87 52b5d286 René Nussbaumer
 NQ_GROUP,
88 52b5d286 René Nussbaumer
 NQ_OOB) = range(1, 6)
89 8235fe04 Michael Hanselmann
90 1c8addc6 Michael Hanselmann
(IQ_CONFIG,
91 1c8addc6 Michael Hanselmann
 IQ_LIVE,
92 5d28cb6f Michael Hanselmann
 IQ_DISKUSAGE,
93 fab9573b Michael Hanselmann
 IQ_CONSOLE,
94 f98e1175 Dimitris Aragiorgis
 IQ_NODES,
95 f98e1175 Dimitris Aragiorgis
 IQ_NETWORKS) = range(100, 106)
96 1c8addc6 Michael Hanselmann
97 24d16f76 Michael Hanselmann
(LQ_MODE,
98 24d16f76 Michael Hanselmann
 LQ_OWNER,
99 24d16f76 Michael Hanselmann
 LQ_PENDING) = range(10, 13)
100 8235fe04 Michael Hanselmann
101 8e21cfc0 Adeodato Simo
(GQ_CONFIG,
102 8e21cfc0 Adeodato Simo
 GQ_NODE,
103 2c758845 René Nussbaumer
 GQ_INST,
104 2c758845 René Nussbaumer
 GQ_DISKPARAMS) = range(200, 204)
105 8e21cfc0 Adeodato Simo
106 dff5f600 Michael Hanselmann
(CQ_CONFIG,
107 dff5f600 Michael Hanselmann
 CQ_QUEUE_DRAINED,
108 dff5f600 Michael Hanselmann
 CQ_WATCHER_PAUSE) = range(300, 303)
109 dff5f600 Michael Hanselmann
110 0422250e Michael Hanselmann
(JQ_ARCHIVED, ) = range(400, 401)
111 0422250e Michael Hanselmann
112 111bf531 Michael Hanselmann
# Query field flags
113 111bf531 Michael Hanselmann
QFF_HOSTNAME = 0x01
114 111bf531 Michael Hanselmann
QFF_IP_ADDRESS = 0x02
115 526f866b Michael Hanselmann
QFF_JOB_ID = 0x04
116 526f866b Michael Hanselmann
QFF_SPLIT_TIMESTAMP = 0x08
117 526f866b Michael Hanselmann
# Next values: 0x10, 0x20, 0x40, 0x80, 0x100, 0x200
118 526f866b Michael Hanselmann
QFF_ALL = (QFF_HOSTNAME | QFF_IP_ADDRESS | QFF_JOB_ID | QFF_SPLIT_TIMESTAMP)
119 8e21cfc0 Adeodato Simo
120 4ca96421 Michael Hanselmann
FIELD_NAME_RE = re.compile(r"^[a-z0-9/._]+$")
121 4ca96421 Michael Hanselmann
TITLE_RE = re.compile(r"^[^\s]+$")
122 1ae17369 Michael Hanselmann
DOC_RE = re.compile(r"^[A-Z].*[^.,?!]$")
123 4ca96421 Michael Hanselmann
124 4ca96421 Michael Hanselmann
#: Verification function for each field type
125 4ca96421 Michael Hanselmann
_VERIFY_FN = {
126 82599b3e Iustin Pop
  QFT_UNKNOWN: ht.TNone,
127 82599b3e Iustin Pop
  QFT_TEXT: ht.TString,
128 82599b3e Iustin Pop
  QFT_BOOL: ht.TBool,
129 82599b3e Iustin Pop
  QFT_NUMBER: ht.TInt,
130 82599b3e Iustin Pop
  QFT_UNIT: ht.TInt,
131 697f49d5 Michael Hanselmann
  QFT_TIMESTAMP: ht.TNumber,
132 82599b3e Iustin Pop
  QFT_OTHER: lambda _: True,
133 4ca96421 Michael Hanselmann
  }
134 4ca96421 Michael Hanselmann
135 e2d188cc Iustin Pop
# Unique objects for special field statuses
136 e2d188cc Iustin Pop
_FS_UNKNOWN = object()
137 e2d188cc Iustin Pop
_FS_NODATA = object()
138 e2d188cc Iustin Pop
_FS_UNAVAIL = object()
139 e2d188cc Iustin Pop
_FS_OFFLINE = object()
140 e2d188cc Iustin Pop
141 425e5bf0 Michael Hanselmann
#: List of all special status
142 b8028dcf Michael Hanselmann
_FS_ALL = compat.UniqueFrozenset([
143 b8028dcf Michael Hanselmann
  _FS_UNKNOWN,
144 b8028dcf Michael Hanselmann
  _FS_NODATA,
145 b8028dcf Michael Hanselmann
  _FS_UNAVAIL,
146 b8028dcf Michael Hanselmann
  _FS_OFFLINE,
147 b8028dcf Michael Hanselmann
  ])
148 425e5bf0 Michael Hanselmann
149 af58707c Iustin Pop
#: VType to QFT mapping
150 af58707c Iustin Pop
_VTToQFT = {
151 af58707c Iustin Pop
  # TODO: fix validation of empty strings
152 af58707c Iustin Pop
  constants.VTYPE_STRING: QFT_OTHER, # since VTYPE_STRINGs can be empty
153 af58707c Iustin Pop
  constants.VTYPE_MAYBE_STRING: QFT_OTHER,
154 af58707c Iustin Pop
  constants.VTYPE_BOOL: QFT_BOOL,
155 af58707c Iustin Pop
  constants.VTYPE_SIZE: QFT_UNIT,
156 af58707c Iustin Pop
  constants.VTYPE_INT: QFT_NUMBER,
157 af58707c Iustin Pop
  }
158 af58707c Iustin Pop
159 79b2ca83 Michael Hanselmann
_SERIAL_NO_DOC = "%s object serial number, incremented on each modification"
160 79b2ca83 Michael Hanselmann
161 4ca96421 Michael Hanselmann
162 b459a848 Andrea Spadaccini
def _GetUnknownField(ctx, item): # pylint: disable=W0613
163 4ca96421 Michael Hanselmann
  """Gets the contents of an unknown field.
164 4ca96421 Michael Hanselmann

165 4ca96421 Michael Hanselmann
  """
166 e2d188cc Iustin Pop
  return _FS_UNKNOWN
167 4ca96421 Michael Hanselmann
168 4ca96421 Michael Hanselmann
169 4ca96421 Michael Hanselmann
def _GetQueryFields(fielddefs, selected):
170 4ca96421 Michael Hanselmann
  """Calculates the internal list of selected fields.
171 4ca96421 Michael Hanselmann

172 4ca96421 Michael Hanselmann
  Unknown fields are returned as L{constants.QFT_UNKNOWN}.
173 4ca96421 Michael Hanselmann

174 4ca96421 Michael Hanselmann
  @type fielddefs: dict
175 4ca96421 Michael Hanselmann
  @param fielddefs: Field definitions
176 4ca96421 Michael Hanselmann
  @type selected: list of strings
177 4ca96421 Michael Hanselmann
  @param selected: List of selected fields
178 4ca96421 Michael Hanselmann

179 4ca96421 Michael Hanselmann
  """
180 4ca96421 Michael Hanselmann
  result = []
181 4ca96421 Michael Hanselmann
182 4ca96421 Michael Hanselmann
  for name in selected:
183 4ca96421 Michael Hanselmann
    try:
184 4ca96421 Michael Hanselmann
      fdef = fielddefs[name]
185 4ca96421 Michael Hanselmann
    except KeyError:
186 79b2ca83 Michael Hanselmann
      fdef = (_MakeField(name, name, QFT_UNKNOWN, "Unknown field '%s'" % name),
187 111bf531 Michael Hanselmann
              None, 0, _GetUnknownField)
188 4ca96421 Michael Hanselmann
189 111bf531 Michael Hanselmann
    assert len(fdef) == 4
190 4ca96421 Michael Hanselmann
191 4ca96421 Michael Hanselmann
    result.append(fdef)
192 4ca96421 Michael Hanselmann
193 4ca96421 Michael Hanselmann
  return result
194 4ca96421 Michael Hanselmann
195 4ca96421 Michael Hanselmann
196 4ca96421 Michael Hanselmann
def GetAllFields(fielddefs):
197 4ca96421 Michael Hanselmann
  """Extract L{objects.QueryFieldDefinition} from field definitions.
198 4ca96421 Michael Hanselmann

199 4ca96421 Michael Hanselmann
  @rtype: list of L{objects.QueryFieldDefinition}
200 4ca96421 Michael Hanselmann

201 4ca96421 Michael Hanselmann
  """
202 111bf531 Michael Hanselmann
  return [fdef for (fdef, _, _, _) in fielddefs]
203 4ca96421 Michael Hanselmann
204 4ca96421 Michael Hanselmann
205 fb0be379 Michael Hanselmann
class _FilterHints:
206 fb0be379 Michael Hanselmann
  """Class for filter analytics.
207 fb0be379 Michael Hanselmann

208 fb0be379 Michael Hanselmann
  When filters are used, the user of the L{Query} class usually doesn't know
209 fb0be379 Michael Hanselmann
  exactly which items will be necessary for building the result. It therefore
210 fb0be379 Michael Hanselmann
  has to prepare and compute the input data for potentially returning
211 fb0be379 Michael Hanselmann
  everything.
212 fb0be379 Michael Hanselmann

213 fb0be379 Michael Hanselmann
  There are two ways to optimize this. The first, and simpler, is to assign
214 fb0be379 Michael Hanselmann
  each field a group of data, so that the caller can determine which
215 fb0be379 Michael Hanselmann
  computations are necessary depending on the data groups requested. The list
216 fb0be379 Michael Hanselmann
  of referenced groups must also be computed for fields referenced in the
217 fb0be379 Michael Hanselmann
  filter.
218 fb0be379 Michael Hanselmann

219 fb0be379 Michael Hanselmann
  The second is restricting the items based on a primary key. The primary key
220 fb0be379 Michael Hanselmann
  is usually a unique name (e.g. a node name). This class extracts all
221 fb0be379 Michael Hanselmann
  referenced names from a filter. If it encounters any filter condition which
222 fb0be379 Michael Hanselmann
  disallows such a list to be determined (e.g. a non-equality filter), all
223 fb0be379 Michael Hanselmann
  names will be requested.
224 fb0be379 Michael Hanselmann

225 fb0be379 Michael Hanselmann
  The end-effect is that any operation other than L{qlang.OP_OR} and
226 fb0be379 Michael Hanselmann
  L{qlang.OP_EQUAL} will make the query more expensive.
227 fb0be379 Michael Hanselmann

228 fb0be379 Michael Hanselmann
  """
229 fb0be379 Michael Hanselmann
  def __init__(self, namefield):
230 fb0be379 Michael Hanselmann
    """Initializes this class.
231 fb0be379 Michael Hanselmann

232 fb0be379 Michael Hanselmann
    @type namefield: string
233 fb0be379 Michael Hanselmann
    @param namefield: Field caller is interested in
234 fb0be379 Michael Hanselmann

235 fb0be379 Michael Hanselmann
    """
236 fb0be379 Michael Hanselmann
    self._namefield = namefield
237 fb0be379 Michael Hanselmann
238 fb0be379 Michael Hanselmann
    #: Whether all names need to be requested (e.g. if a non-equality operator
239 fb0be379 Michael Hanselmann
    #: has been used)
240 fb0be379 Michael Hanselmann
    self._allnames = False
241 fb0be379 Michael Hanselmann
242 fb0be379 Michael Hanselmann
    #: Which names to request
243 fb0be379 Michael Hanselmann
    self._names = None
244 fb0be379 Michael Hanselmann
245 fb0be379 Michael Hanselmann
    #: Data kinds referenced by the filter (used by L{Query.RequestedData})
246 fb0be379 Michael Hanselmann
    self._datakinds = set()
247 fb0be379 Michael Hanselmann
248 fb0be379 Michael Hanselmann
  def RequestedNames(self):
249 fb0be379 Michael Hanselmann
    """Returns all requested values.
250 fb0be379 Michael Hanselmann

251 fb0be379 Michael Hanselmann
    Returns C{None} if list of values can't be determined (e.g. encountered
252 fb0be379 Michael Hanselmann
    non-equality operators).
253 fb0be379 Michael Hanselmann

254 fb0be379 Michael Hanselmann
    @rtype: list
255 fb0be379 Michael Hanselmann

256 fb0be379 Michael Hanselmann
    """
257 fb0be379 Michael Hanselmann
    if self._allnames or self._names is None:
258 fb0be379 Michael Hanselmann
      return None
259 fb0be379 Michael Hanselmann
260 fb0be379 Michael Hanselmann
    return utils.UniqueSequence(self._names)
261 fb0be379 Michael Hanselmann
262 fb0be379 Michael Hanselmann
  def ReferencedData(self):
263 fb0be379 Michael Hanselmann
    """Returns all kinds of data referenced by the filter.
264 fb0be379 Michael Hanselmann

265 fb0be379 Michael Hanselmann
    """
266 fb0be379 Michael Hanselmann
    return frozenset(self._datakinds)
267 fb0be379 Michael Hanselmann
268 fb0be379 Michael Hanselmann
  def _NeedAllNames(self):
269 fb0be379 Michael Hanselmann
    """Changes internal state to request all names.
270 fb0be379 Michael Hanselmann

271 fb0be379 Michael Hanselmann
    """
272 fb0be379 Michael Hanselmann
    self._allnames = True
273 fb0be379 Michael Hanselmann
    self._names = None
274 fb0be379 Michael Hanselmann
275 fb0be379 Michael Hanselmann
  def NoteLogicOp(self, op):
276 fb0be379 Michael Hanselmann
    """Called when handling a logic operation.
277 fb0be379 Michael Hanselmann

278 fb0be379 Michael Hanselmann
    @type op: string
279 fb0be379 Michael Hanselmann
    @param op: Operator
280 fb0be379 Michael Hanselmann

281 fb0be379 Michael Hanselmann
    """
282 fb0be379 Michael Hanselmann
    if op != qlang.OP_OR:
283 fb0be379 Michael Hanselmann
      self._NeedAllNames()
284 fb0be379 Michael Hanselmann
285 52aa1efa Michael Hanselmann
  def NoteUnaryOp(self, op, datakind): # pylint: disable=W0613
286 fb0be379 Michael Hanselmann
    """Called when handling an unary operation.
287 fb0be379 Michael Hanselmann

288 fb0be379 Michael Hanselmann
    @type op: string
289 fb0be379 Michael Hanselmann
    @param op: Operator
290 fb0be379 Michael Hanselmann

291 fb0be379 Michael Hanselmann
    """
292 52aa1efa Michael Hanselmann
    if datakind is not None:
293 52aa1efa Michael Hanselmann
      self._datakinds.add(datakind)
294 52aa1efa Michael Hanselmann
295 fb0be379 Michael Hanselmann
    self._NeedAllNames()
296 fb0be379 Michael Hanselmann
297 fb0be379 Michael Hanselmann
  def NoteBinaryOp(self, op, datakind, name, value):
298 fb0be379 Michael Hanselmann
    """Called when handling a binary operation.
299 fb0be379 Michael Hanselmann

300 fb0be379 Michael Hanselmann
    @type op: string
301 fb0be379 Michael Hanselmann
    @param op: Operator
302 fb0be379 Michael Hanselmann
    @type name: string
303 fb0be379 Michael Hanselmann
    @param name: Left-hand side of operator (field name)
304 fb0be379 Michael Hanselmann
    @param value: Right-hand side of operator
305 fb0be379 Michael Hanselmann

306 fb0be379 Michael Hanselmann
    """
307 fb0be379 Michael Hanselmann
    if datakind is not None:
308 fb0be379 Michael Hanselmann
      self._datakinds.add(datakind)
309 fb0be379 Michael Hanselmann
310 fb0be379 Michael Hanselmann
    if self._allnames:
311 fb0be379 Michael Hanselmann
      return
312 fb0be379 Michael Hanselmann
313 fb0be379 Michael Hanselmann
    # If any operator other than equality was used, all names need to be
314 fb0be379 Michael Hanselmann
    # retrieved
315 fb0be379 Michael Hanselmann
    if op == qlang.OP_EQUAL and name == self._namefield:
316 fb0be379 Michael Hanselmann
      if self._names is None:
317 fb0be379 Michael Hanselmann
        self._names = []
318 fb0be379 Michael Hanselmann
      self._names.append(value)
319 fb0be379 Michael Hanselmann
    else:
320 fb0be379 Michael Hanselmann
      self._NeedAllNames()
321 fb0be379 Michael Hanselmann
322 fb0be379 Michael Hanselmann
323 fb0be379 Michael Hanselmann
def _WrapLogicOp(op_fn, sentences, ctx, item):
324 fb0be379 Michael Hanselmann
  """Wrapper for logic operator functions.
325 fb0be379 Michael Hanselmann

326 fb0be379 Michael Hanselmann
  """
327 fb0be379 Michael Hanselmann
  return op_fn(fn(ctx, item) for fn in sentences)
328 fb0be379 Michael Hanselmann
329 fb0be379 Michael Hanselmann
330 fb0be379 Michael Hanselmann
def _WrapUnaryOp(op_fn, inner, ctx, item):
331 fb0be379 Michael Hanselmann
  """Wrapper for unary operator functions.
332 fb0be379 Michael Hanselmann

333 fb0be379 Michael Hanselmann
  """
334 fb0be379 Michael Hanselmann
  return op_fn(inner(ctx, item))
335 fb0be379 Michael Hanselmann
336 fb0be379 Michael Hanselmann
337 fb0be379 Michael Hanselmann
def _WrapBinaryOp(op_fn, retrieval_fn, value, ctx, item):
338 fb0be379 Michael Hanselmann
  """Wrapper for binary operator functions.
339 fb0be379 Michael Hanselmann

340 fb0be379 Michael Hanselmann
  """
341 fb0be379 Michael Hanselmann
  return op_fn(retrieval_fn(ctx, item), value)
342 fb0be379 Michael Hanselmann
343 fb0be379 Michael Hanselmann
344 fb0be379 Michael Hanselmann
def _WrapNot(fn, lhs, rhs):
345 fb0be379 Michael Hanselmann
  """Negates the result of a wrapped function.
346 fb0be379 Michael Hanselmann

347 fb0be379 Michael Hanselmann
  """
348 fb0be379 Michael Hanselmann
  return not fn(lhs, rhs)
349 fb0be379 Michael Hanselmann
350 fb0be379 Michael Hanselmann
351 23d0a608 Michael Hanselmann
def _PrepareRegex(pattern):
352 23d0a608 Michael Hanselmann
  """Compiles a regular expression.
353 23d0a608 Michael Hanselmann

354 23d0a608 Michael Hanselmann
  """
355 23d0a608 Michael Hanselmann
  try:
356 23d0a608 Michael Hanselmann
    return re.compile(pattern)
357 23d0a608 Michael Hanselmann
  except re.error, err:
358 23d0a608 Michael Hanselmann
    raise errors.ParameterError("Invalid regex pattern (%s)" % err)
359 23d0a608 Michael Hanselmann
360 23d0a608 Michael Hanselmann
361 526f866b Michael Hanselmann
def _PrepareSplitTimestamp(value):
362 526f866b Michael Hanselmann
  """Prepares a value for comparison by L{_MakeSplitTimestampComparison}.
363 526f866b Michael Hanselmann

364 526f866b Michael Hanselmann
  """
365 526f866b Michael Hanselmann
  if ht.TNumber(value):
366 526f866b Michael Hanselmann
    return value
367 526f866b Michael Hanselmann
  else:
368 526f866b Michael Hanselmann
    return utils.MergeTime(value)
369 526f866b Michael Hanselmann
370 526f866b Michael Hanselmann
371 526f866b Michael Hanselmann
def _MakeSplitTimestampComparison(fn):
372 526f866b Michael Hanselmann
  """Compares split timestamp values after converting to float.
373 526f866b Michael Hanselmann

374 526f866b Michael Hanselmann
  """
375 526f866b Michael Hanselmann
  return lambda lhs, rhs: fn(utils.MergeTime(lhs), rhs)
376 526f866b Michael Hanselmann
377 526f866b Michael Hanselmann
378 526f866b Michael Hanselmann
def _MakeComparisonChecks(fn):
379 526f866b Michael Hanselmann
  """Prepares flag-specific comparisons using a comparison function.
380 526f866b Michael Hanselmann

381 526f866b Michael Hanselmann
  """
382 526f866b Michael Hanselmann
  return [
383 526f866b Michael Hanselmann
    (QFF_SPLIT_TIMESTAMP, _MakeSplitTimestampComparison(fn),
384 526f866b Michael Hanselmann
     _PrepareSplitTimestamp),
385 526f866b Michael Hanselmann
    (QFF_JOB_ID, lambda lhs, rhs: fn(jstore.ParseJobId(lhs), rhs),
386 526f866b Michael Hanselmann
     jstore.ParseJobId),
387 526f866b Michael Hanselmann
    (None, fn, None),
388 526f866b Michael Hanselmann
    ]
389 526f866b Michael Hanselmann
390 526f866b Michael Hanselmann
391 fb0be379 Michael Hanselmann
class _FilterCompilerHelper:
392 fb0be379 Michael Hanselmann
  """Converts a query filter to a callable usable for filtering.
393 fb0be379 Michael Hanselmann

394 fb0be379 Michael Hanselmann
  """
395 b459a848 Andrea Spadaccini
  # String statement has no effect, pylint: disable=W0105
396 fb0be379 Michael Hanselmann
397 fb0be379 Michael Hanselmann
  #: How deep filters can be nested
398 fb0be379 Michael Hanselmann
  _LEVELS_MAX = 10
399 fb0be379 Michael Hanselmann
400 fb0be379 Michael Hanselmann
  # Unique identifiers for operator groups
401 fb0be379 Michael Hanselmann
  (_OPTYPE_LOGIC,
402 fb0be379 Michael Hanselmann
   _OPTYPE_UNARY,
403 fb0be379 Michael Hanselmann
   _OPTYPE_BINARY) = range(1, 4)
404 fb0be379 Michael Hanselmann
405 fb0be379 Michael Hanselmann
  """Functions for equality checks depending on field flags.
406 fb0be379 Michael Hanselmann

407 fb0be379 Michael Hanselmann
  List of tuples containing flags and a callable receiving the left- and
408 fb0be379 Michael Hanselmann
  right-hand side of the operator. The flags are an OR-ed value of C{QFF_*}
409 526f866b Michael Hanselmann
  (e.g. L{QFF_HOSTNAME} or L{QFF_SPLIT_TIMESTAMP}).
410 fb0be379 Michael Hanselmann

411 fb0be379 Michael Hanselmann
  Order matters. The first item with flags will be used. Flags are checked
412 fb0be379 Michael Hanselmann
  using binary AND.
413 fb0be379 Michael Hanselmann

414 fb0be379 Michael Hanselmann
  """
415 fb0be379 Michael Hanselmann
  _EQUALITY_CHECKS = [
416 fb0be379 Michael Hanselmann
    (QFF_HOSTNAME,
417 fb0be379 Michael Hanselmann
     lambda lhs, rhs: utils.MatchNameComponent(rhs, [lhs],
418 23d0a608 Michael Hanselmann
                                               case_sensitive=False),
419 23d0a608 Michael Hanselmann
     None),
420 526f866b Michael Hanselmann
    (QFF_SPLIT_TIMESTAMP, _MakeSplitTimestampComparison(operator.eq),
421 526f866b Michael Hanselmann
     _PrepareSplitTimestamp),
422 23d0a608 Michael Hanselmann
    (None, operator.eq, None),
423 fb0be379 Michael Hanselmann
    ]
424 fb0be379 Michael Hanselmann
425 fb0be379 Michael Hanselmann
  """Known operators
426 fb0be379 Michael Hanselmann

427 fb0be379 Michael Hanselmann
  Operator as key (C{qlang.OP_*}), value a tuple of operator group
428 fb0be379 Michael Hanselmann
  (C{_OPTYPE_*}) and a group-specific value:
429 fb0be379 Michael Hanselmann

430 fb0be379 Michael Hanselmann
    - C{_OPTYPE_LOGIC}: Callable taking any number of arguments; used by
431 fb0be379 Michael Hanselmann
      L{_HandleLogicOp}
432 3b877f08 Michael Hanselmann
    - C{_OPTYPE_UNARY}: Always C{None}; details handled by L{_HandleUnaryOp}
433 fb0be379 Michael Hanselmann
    - C{_OPTYPE_BINARY}: Callable taking exactly two parameters, the left- and
434 fb0be379 Michael Hanselmann
      right-hand side of the operator, used by L{_HandleBinaryOp}
435 fb0be379 Michael Hanselmann

436 fb0be379 Michael Hanselmann
  """
437 fb0be379 Michael Hanselmann
  _OPS = {
438 fb0be379 Michael Hanselmann
    # Logic operators
439 fb0be379 Michael Hanselmann
    qlang.OP_OR: (_OPTYPE_LOGIC, compat.any),
440 fb0be379 Michael Hanselmann
    qlang.OP_AND: (_OPTYPE_LOGIC, compat.all),
441 fb0be379 Michael Hanselmann
442 fb0be379 Michael Hanselmann
    # Unary operators
443 3b877f08 Michael Hanselmann
    qlang.OP_NOT: (_OPTYPE_UNARY, None),
444 3b877f08 Michael Hanselmann
    qlang.OP_TRUE: (_OPTYPE_UNARY, None),
445 fb0be379 Michael Hanselmann
446 fb0be379 Michael Hanselmann
    # Binary operators
447 fb0be379 Michael Hanselmann
    qlang.OP_EQUAL: (_OPTYPE_BINARY, _EQUALITY_CHECKS),
448 fb0be379 Michael Hanselmann
    qlang.OP_NOT_EQUAL:
449 23d0a608 Michael Hanselmann
      (_OPTYPE_BINARY, [(flags, compat.partial(_WrapNot, fn), valprepfn)
450 23d0a608 Michael Hanselmann
                        for (flags, fn, valprepfn) in _EQUALITY_CHECKS]),
451 526f866b Michael Hanselmann
    qlang.OP_LT: (_OPTYPE_BINARY, _MakeComparisonChecks(operator.lt)),
452 526f866b Michael Hanselmann
    qlang.OP_LE: (_OPTYPE_BINARY, _MakeComparisonChecks(operator.le)),
453 526f866b Michael Hanselmann
    qlang.OP_GT: (_OPTYPE_BINARY, _MakeComparisonChecks(operator.gt)),
454 526f866b Michael Hanselmann
    qlang.OP_GE: (_OPTYPE_BINARY, _MakeComparisonChecks(operator.ge)),
455 23d0a608 Michael Hanselmann
    qlang.OP_REGEXP: (_OPTYPE_BINARY, [
456 23d0a608 Michael Hanselmann
      (None, lambda lhs, rhs: rhs.search(lhs), _PrepareRegex),
457 23d0a608 Michael Hanselmann
      ]),
458 fb0be379 Michael Hanselmann
    qlang.OP_CONTAINS: (_OPTYPE_BINARY, [
459 23d0a608 Michael Hanselmann
      (None, operator.contains, None),
460 fb0be379 Michael Hanselmann
      ]),
461 fb0be379 Michael Hanselmann
    }
462 fb0be379 Michael Hanselmann
463 fb0be379 Michael Hanselmann
  def __init__(self, fields):
464 fb0be379 Michael Hanselmann
    """Initializes this class.
465 fb0be379 Michael Hanselmann

466 fb0be379 Michael Hanselmann
    @param fields: Field definitions (return value of L{_PrepareFieldList})
467 fb0be379 Michael Hanselmann

468 fb0be379 Michael Hanselmann
    """
469 fb0be379 Michael Hanselmann
    self._fields = fields
470 fb0be379 Michael Hanselmann
    self._hints = None
471 fb0be379 Michael Hanselmann
    self._op_handler = None
472 fb0be379 Michael Hanselmann
473 2e5c33db Iustin Pop
  def __call__(self, hints, qfilter):
474 fb0be379 Michael Hanselmann
    """Converts a query filter into a callable function.
475 fb0be379 Michael Hanselmann

476 fb0be379 Michael Hanselmann
    @type hints: L{_FilterHints} or None
477 fb0be379 Michael Hanselmann
    @param hints: Callbacks doing analysis on filter
478 2e5c33db Iustin Pop
    @type qfilter: list
479 2e5c33db Iustin Pop
    @param qfilter: Filter structure
480 fb0be379 Michael Hanselmann
    @rtype: callable
481 fb0be379 Michael Hanselmann
    @return: Function receiving context and item as parameters, returning
482 fb0be379 Michael Hanselmann
             boolean as to whether item matches filter
483 fb0be379 Michael Hanselmann

484 fb0be379 Michael Hanselmann
    """
485 fb0be379 Michael Hanselmann
    self._op_handler = {
486 fb0be379 Michael Hanselmann
      self._OPTYPE_LOGIC:
487 fb0be379 Michael Hanselmann
        (self._HandleLogicOp, getattr(hints, "NoteLogicOp", None)),
488 fb0be379 Michael Hanselmann
      self._OPTYPE_UNARY:
489 fb0be379 Michael Hanselmann
        (self._HandleUnaryOp, getattr(hints, "NoteUnaryOp", None)),
490 fb0be379 Michael Hanselmann
      self._OPTYPE_BINARY:
491 fb0be379 Michael Hanselmann
        (self._HandleBinaryOp, getattr(hints, "NoteBinaryOp", None)),
492 fb0be379 Michael Hanselmann
      }
493 fb0be379 Michael Hanselmann
494 fb0be379 Michael Hanselmann
    try:
495 2e5c33db Iustin Pop
      filter_fn = self._Compile(qfilter, 0)
496 fb0be379 Michael Hanselmann
    finally:
497 fb0be379 Michael Hanselmann
      self._op_handler = None
498 fb0be379 Michael Hanselmann
499 fb0be379 Michael Hanselmann
    return filter_fn
500 fb0be379 Michael Hanselmann
501 2e5c33db Iustin Pop
  def _Compile(self, qfilter, level):
502 fb0be379 Michael Hanselmann
    """Inner function for converting filters.
503 fb0be379 Michael Hanselmann

504 fb0be379 Michael Hanselmann
    Calls the correct handler functions for the top-level operator. This
505 fb0be379 Michael Hanselmann
    function is called recursively (e.g. for logic operators).
506 fb0be379 Michael Hanselmann

507 fb0be379 Michael Hanselmann
    """
508 2e5c33db Iustin Pop
    if not (isinstance(qfilter, (list, tuple)) and qfilter):
509 fb0be379 Michael Hanselmann
      raise errors.ParameterError("Invalid filter on level %s" % level)
510 fb0be379 Michael Hanselmann
511 fb0be379 Michael Hanselmann
    # Limit recursion
512 fb0be379 Michael Hanselmann
    if level >= self._LEVELS_MAX:
513 fb0be379 Michael Hanselmann
      raise errors.ParameterError("Only up to %s levels are allowed (filter"
514 fb0be379 Michael Hanselmann
                                  " nested too deep)" % self._LEVELS_MAX)
515 fb0be379 Michael Hanselmann
516 fb0be379 Michael Hanselmann
    # Create copy to be modified
517 2e5c33db Iustin Pop
    operands = qfilter[:]
518 fb0be379 Michael Hanselmann
    op = operands.pop(0)
519 fb0be379 Michael Hanselmann
520 fb0be379 Michael Hanselmann
    try:
521 fb0be379 Michael Hanselmann
      (kind, op_data) = self._OPS[op]
522 fb0be379 Michael Hanselmann
    except KeyError:
523 fb0be379 Michael Hanselmann
      raise errors.ParameterError("Unknown operator '%s'" % op)
524 fb0be379 Michael Hanselmann
525 fb0be379 Michael Hanselmann
    (handler, hints_cb) = self._op_handler[kind]
526 fb0be379 Michael Hanselmann
527 fb0be379 Michael Hanselmann
    return handler(hints_cb, level, op, op_data, operands)
528 fb0be379 Michael Hanselmann
529 3b877f08 Michael Hanselmann
  def _LookupField(self, name):
530 3b877f08 Michael Hanselmann
    """Returns a field definition by name.
531 3b877f08 Michael Hanselmann

532 3b877f08 Michael Hanselmann
    """
533 3b877f08 Michael Hanselmann
    try:
534 3b877f08 Michael Hanselmann
      return self._fields[name]
535 3b877f08 Michael Hanselmann
    except KeyError:
536 3b877f08 Michael Hanselmann
      raise errors.ParameterError("Unknown field '%s'" % name)
537 3b877f08 Michael Hanselmann
538 fb0be379 Michael Hanselmann
  def _HandleLogicOp(self, hints_fn, level, op, op_fn, operands):
539 fb0be379 Michael Hanselmann
    """Handles logic operators.
540 fb0be379 Michael Hanselmann

541 fb0be379 Michael Hanselmann
    @type hints_fn: callable
542 fb0be379 Michael Hanselmann
    @param hints_fn: Callback doing some analysis on the filter
543 fb0be379 Michael Hanselmann
    @type level: integer
544 fb0be379 Michael Hanselmann
    @param level: Current depth
545 fb0be379 Michael Hanselmann
    @type op: string
546 fb0be379 Michael Hanselmann
    @param op: Operator
547 fb0be379 Michael Hanselmann
    @type op_fn: callable
548 fb0be379 Michael Hanselmann
    @param op_fn: Function implementing operator
549 fb0be379 Michael Hanselmann
    @type operands: list
550 fb0be379 Michael Hanselmann
    @param operands: List of operands
551 fb0be379 Michael Hanselmann

552 fb0be379 Michael Hanselmann
    """
553 fb0be379 Michael Hanselmann
    if hints_fn:
554 fb0be379 Michael Hanselmann
      hints_fn(op)
555 fb0be379 Michael Hanselmann
556 fb0be379 Michael Hanselmann
    return compat.partial(_WrapLogicOp, op_fn,
557 fb0be379 Michael Hanselmann
                          [self._Compile(op, level + 1) for op in operands])
558 fb0be379 Michael Hanselmann
559 fb0be379 Michael Hanselmann
  def _HandleUnaryOp(self, hints_fn, level, op, op_fn, operands):
560 fb0be379 Michael Hanselmann
    """Handles unary operators.
561 fb0be379 Michael Hanselmann

562 fb0be379 Michael Hanselmann
    @type hints_fn: callable
563 fb0be379 Michael Hanselmann
    @param hints_fn: Callback doing some analysis on the filter
564 fb0be379 Michael Hanselmann
    @type level: integer
565 fb0be379 Michael Hanselmann
    @param level: Current depth
566 fb0be379 Michael Hanselmann
    @type op: string
567 fb0be379 Michael Hanselmann
    @param op: Operator
568 fb0be379 Michael Hanselmann
    @type op_fn: callable
569 fb0be379 Michael Hanselmann
    @param op_fn: Function implementing operator
570 fb0be379 Michael Hanselmann
    @type operands: list
571 fb0be379 Michael Hanselmann
    @param operands: List of operands
572 fb0be379 Michael Hanselmann

573 fb0be379 Michael Hanselmann
    """
574 3b877f08 Michael Hanselmann
    assert op_fn is None
575 3b877f08 Michael Hanselmann
576 fb0be379 Michael Hanselmann
    if len(operands) != 1:
577 fb0be379 Michael Hanselmann
      raise errors.ParameterError("Unary operator '%s' expects exactly one"
578 fb0be379 Michael Hanselmann
                                  " operand" % op)
579 fb0be379 Michael Hanselmann
580 3b877f08 Michael Hanselmann
    if op == qlang.OP_TRUE:
581 52aa1efa Michael Hanselmann
      (_, datakind, _, retrieval_fn) = self._LookupField(operands[0])
582 52aa1efa Michael Hanselmann
583 52aa1efa Michael Hanselmann
      if hints_fn:
584 52aa1efa Michael Hanselmann
        hints_fn(op, datakind)
585 3b877f08 Michael Hanselmann
586 3b877f08 Michael Hanselmann
      op_fn = operator.truth
587 3b877f08 Michael Hanselmann
      arg = retrieval_fn
588 3b877f08 Michael Hanselmann
    elif op == qlang.OP_NOT:
589 52aa1efa Michael Hanselmann
      if hints_fn:
590 52aa1efa Michael Hanselmann
        hints_fn(op, None)
591 52aa1efa Michael Hanselmann
592 3b877f08 Michael Hanselmann
      op_fn = operator.not_
593 3b877f08 Michael Hanselmann
      arg = self._Compile(operands[0], level + 1)
594 3b877f08 Michael Hanselmann
    else:
595 3b877f08 Michael Hanselmann
      raise errors.ProgrammerError("Can't handle operator '%s'" % op)
596 3b877f08 Michael Hanselmann
597 3b877f08 Michael Hanselmann
    return compat.partial(_WrapUnaryOp, op_fn, arg)
598 fb0be379 Michael Hanselmann
599 fb0be379 Michael Hanselmann
  def _HandleBinaryOp(self, hints_fn, level, op, op_data, operands):
600 fb0be379 Michael Hanselmann
    """Handles binary operators.
601 fb0be379 Michael Hanselmann

602 fb0be379 Michael Hanselmann
    @type hints_fn: callable
603 fb0be379 Michael Hanselmann
    @param hints_fn: Callback doing some analysis on the filter
604 fb0be379 Michael Hanselmann
    @type level: integer
605 fb0be379 Michael Hanselmann
    @param level: Current depth
606 fb0be379 Michael Hanselmann
    @type op: string
607 fb0be379 Michael Hanselmann
    @param op: Operator
608 fb0be379 Michael Hanselmann
    @param op_data: Functions implementing operators
609 fb0be379 Michael Hanselmann
    @type operands: list
610 fb0be379 Michael Hanselmann
    @param operands: List of operands
611 fb0be379 Michael Hanselmann

612 fb0be379 Michael Hanselmann
    """
613 b459a848 Andrea Spadaccini
    # Unused arguments, pylint: disable=W0613
614 fb0be379 Michael Hanselmann
    try:
615 fb0be379 Michael Hanselmann
      (name, value) = operands
616 fb0be379 Michael Hanselmann
    except (ValueError, TypeError):
617 fb0be379 Michael Hanselmann
      raise errors.ParameterError("Invalid binary operator, expected exactly"
618 fb0be379 Michael Hanselmann
                                  " two operands")
619 fb0be379 Michael Hanselmann
620 3b877f08 Michael Hanselmann
    (fdef, datakind, field_flags, retrieval_fn) = self._LookupField(name)
621 fb0be379 Michael Hanselmann
622 fb0be379 Michael Hanselmann
    assert fdef.kind != QFT_UNKNOWN
623 fb0be379 Michael Hanselmann
624 fb0be379 Michael Hanselmann
    # TODO: Type conversions?
625 fb0be379 Michael Hanselmann
626 fb0be379 Michael Hanselmann
    verify_fn = _VERIFY_FN[fdef.kind]
627 fb0be379 Michael Hanselmann
    if not verify_fn(value):
628 fb0be379 Michael Hanselmann
      raise errors.ParameterError("Unable to compare field '%s' (type '%s')"
629 fb0be379 Michael Hanselmann
                                  " with '%s', expected %s" %
630 fb0be379 Michael Hanselmann
                                  (name, fdef.kind, value.__class__.__name__,
631 fb0be379 Michael Hanselmann
                                   verify_fn))
632 fb0be379 Michael Hanselmann
633 fb0be379 Michael Hanselmann
    if hints_fn:
634 fb0be379 Michael Hanselmann
      hints_fn(op, datakind, name, value)
635 fb0be379 Michael Hanselmann
636 23d0a608 Michael Hanselmann
    for (fn_flags, fn, valprepfn) in op_data:
637 fb0be379 Michael Hanselmann
      if fn_flags is None or fn_flags & field_flags:
638 23d0a608 Michael Hanselmann
        # Prepare value if necessary (e.g. compile regular expression)
639 23d0a608 Michael Hanselmann
        if valprepfn:
640 23d0a608 Michael Hanselmann
          value = valprepfn(value)
641 23d0a608 Michael Hanselmann
642 fb0be379 Michael Hanselmann
        return compat.partial(_WrapBinaryOp, fn, retrieval_fn, value)
643 fb0be379 Michael Hanselmann
644 fb0be379 Michael Hanselmann
    raise errors.ProgrammerError("Unable to find operator implementation"
645 fb0be379 Michael Hanselmann
                                 " (op '%s', flags %s)" % (op, field_flags))
646 fb0be379 Michael Hanselmann
647 fb0be379 Michael Hanselmann
648 2e5c33db Iustin Pop
def _CompileFilter(fields, hints, qfilter):
649 fb0be379 Michael Hanselmann
  """Converts a query filter into a callable function.
650 fb0be379 Michael Hanselmann

651 fb0be379 Michael Hanselmann
  See L{_FilterCompilerHelper} for details.
652 fb0be379 Michael Hanselmann

653 fb0be379 Michael Hanselmann
  @rtype: callable
654 fb0be379 Michael Hanselmann

655 fb0be379 Michael Hanselmann
  """
656 2e5c33db Iustin Pop
  return _FilterCompilerHelper(fields)(hints, qfilter)
657 fb0be379 Michael Hanselmann
658 fb0be379 Michael Hanselmann
659 4ca96421 Michael Hanselmann
class Query:
660 2e5c33db Iustin Pop
  def __init__(self, fieldlist, selected, qfilter=None, namefield=None):
661 4ca96421 Michael Hanselmann
    """Initializes this class.
662 4ca96421 Michael Hanselmann

663 4ca96421 Michael Hanselmann
    The field definition is a dictionary with the field's name as a key and a
664 4ca96421 Michael Hanselmann
    tuple containing, in order, the field definition object
665 4ca96421 Michael Hanselmann
    (L{objects.QueryFieldDefinition}, the data kind to help calling code
666 4ca96421 Michael Hanselmann
    collect data and a retrieval function. The retrieval function is called
667 4ca96421 Michael Hanselmann
    with two parameters, in order, the data container and the item in container
668 4ca96421 Michael Hanselmann
    (see L{Query.Query}).
669 4ca96421 Michael Hanselmann

670 4ca96421 Michael Hanselmann
    Users of this class can call L{RequestedData} before preparing the data
671 4ca96421 Michael Hanselmann
    container to determine what data is needed.
672 4ca96421 Michael Hanselmann

673 4ca96421 Michael Hanselmann
    @type fieldlist: dictionary
674 4ca96421 Michael Hanselmann
    @param fieldlist: Field definitions
675 4ca96421 Michael Hanselmann
    @type selected: list of strings
676 4ca96421 Michael Hanselmann
    @param selected: List of selected fields
677 4ca96421 Michael Hanselmann

678 4ca96421 Michael Hanselmann
    """
679 fb0be379 Michael Hanselmann
    assert namefield is None or namefield in fieldlist
680 fb0be379 Michael Hanselmann
681 4ca96421 Michael Hanselmann
    self._fields = _GetQueryFields(fieldlist, selected)
682 4ca96421 Michael Hanselmann
683 fb0be379 Michael Hanselmann
    self._filter_fn = None
684 fb0be379 Michael Hanselmann
    self._requested_names = None
685 fb0be379 Michael Hanselmann
    self._filter_datakinds = frozenset()
686 fb0be379 Michael Hanselmann
687 2e5c33db Iustin Pop
    if qfilter is not None:
688 fb0be379 Michael Hanselmann
      # Collect requested names if wanted
689 fb0be379 Michael Hanselmann
      if namefield:
690 fb0be379 Michael Hanselmann
        hints = _FilterHints(namefield)
691 fb0be379 Michael Hanselmann
      else:
692 fb0be379 Michael Hanselmann
        hints = None
693 fb0be379 Michael Hanselmann
694 fb0be379 Michael Hanselmann
      # Build filter function
695 2e5c33db Iustin Pop
      self._filter_fn = _CompileFilter(fieldlist, hints, qfilter)
696 fb0be379 Michael Hanselmann
      if hints:
697 fb0be379 Michael Hanselmann
        self._requested_names = hints.RequestedNames()
698 fb0be379 Michael Hanselmann
        self._filter_datakinds = hints.ReferencedData()
699 fb0be379 Michael Hanselmann
700 fb0be379 Michael Hanselmann
    if namefield is None:
701 fb0be379 Michael Hanselmann
      self._name_fn = None
702 fb0be379 Michael Hanselmann
    else:
703 fb0be379 Michael Hanselmann
      (_, _, _, self._name_fn) = fieldlist[namefield]
704 fb0be379 Michael Hanselmann
705 fb0be379 Michael Hanselmann
  def RequestedNames(self):
706 fb0be379 Michael Hanselmann
    """Returns all names referenced in the filter.
707 fb0be379 Michael Hanselmann

708 fb0be379 Michael Hanselmann
    If there is no filter or operators are preventing determining the exact
709 fb0be379 Michael Hanselmann
    names, C{None} is returned.
710 fb0be379 Michael Hanselmann

711 fb0be379 Michael Hanselmann
    """
712 fb0be379 Michael Hanselmann
    return self._requested_names
713 fb0be379 Michael Hanselmann
714 4ca96421 Michael Hanselmann
  def RequestedData(self):
715 4ca96421 Michael Hanselmann
    """Gets requested kinds of data.
716 4ca96421 Michael Hanselmann

717 4ca96421 Michael Hanselmann
    @rtype: frozenset
718 4ca96421 Michael Hanselmann

719 4ca96421 Michael Hanselmann
    """
720 fb0be379 Michael Hanselmann
    return (self._filter_datakinds |
721 fb0be379 Michael Hanselmann
            frozenset(datakind for (_, datakind, _, _) in self._fields
722 fb0be379 Michael Hanselmann
                      if datakind is not None))
723 4ca96421 Michael Hanselmann
724 4ca96421 Michael Hanselmann
  def GetFields(self):
725 4ca96421 Michael Hanselmann
    """Returns the list of fields for this query.
726 4ca96421 Michael Hanselmann

727 4ca96421 Michael Hanselmann
    Includes unknown fields.
728 4ca96421 Michael Hanselmann

729 4ca96421 Michael Hanselmann
    @rtype: List of L{objects.QueryFieldDefinition}
730 4ca96421 Michael Hanselmann

731 4ca96421 Michael Hanselmann
    """
732 4ca96421 Michael Hanselmann
    return GetAllFields(self._fields)
733 4ca96421 Michael Hanselmann
734 fbc263a9 Michael Hanselmann
  def Query(self, ctx, sort_by_name=True):
735 4ca96421 Michael Hanselmann
    """Execute a query.
736 4ca96421 Michael Hanselmann

737 4ca96421 Michael Hanselmann
    @param ctx: Data container passed to field retrieval functions, must
738 4ca96421 Michael Hanselmann
      support iteration using C{__iter__}
739 fbc263a9 Michael Hanselmann
    @type sort_by_name: boolean
740 fbc263a9 Michael Hanselmann
    @param sort_by_name: Whether to sort by name or keep the input data's
741 fbc263a9 Michael Hanselmann
      ordering
742 4ca96421 Michael Hanselmann

743 4ca96421 Michael Hanselmann
    """
744 fbc263a9 Michael Hanselmann
    sort = (self._name_fn and sort_by_name)
745 fbc263a9 Michael Hanselmann
746 fb0be379 Michael Hanselmann
    result = []
747 fb0be379 Michael Hanselmann
748 fb0be379 Michael Hanselmann
    for idx, item in enumerate(ctx):
749 fb0be379 Michael Hanselmann
      if not (self._filter_fn is None or self._filter_fn(ctx, item)):
750 fb0be379 Michael Hanselmann
        continue
751 4ca96421 Michael Hanselmann
752 fb0be379 Michael Hanselmann
      row = [_ProcessResult(fn(ctx, item)) for (_, _, _, fn) in self._fields]
753 fb0be379 Michael Hanselmann
754 fb0be379 Michael Hanselmann
      # Verify result
755 fb0be379 Michael Hanselmann
      if __debug__:
756 d1c3c3b3 Iustin Pop
        _VerifyResultRow(self._fields, row)
757 4ca96421 Michael Hanselmann
758 fbc263a9 Michael Hanselmann
      if sort:
759 fb0be379 Michael Hanselmann
        (status, name) = _ProcessResult(self._name_fn(ctx, item))
760 fb0be379 Michael Hanselmann
        assert status == constants.RS_NORMAL
761 fb0be379 Michael Hanselmann
        # TODO: Are there cases where we wouldn't want to use NiceSort?
762 76b62028 Iustin Pop
        # Answer: if the name field is non-string...
763 fbc263a9 Michael Hanselmann
        result.append((utils.NiceSortKey(name), idx, row))
764 fb0be379 Michael Hanselmann
      else:
765 fbc263a9 Michael Hanselmann
        result.append(row)
766 fb0be379 Michael Hanselmann
767 fbc263a9 Michael Hanselmann
    if not sort:
768 fbc263a9 Michael Hanselmann
      return result
769 fb0be379 Michael Hanselmann
770 fb0be379 Michael Hanselmann
    # TODO: Would "heapq" be more efficient than sorting?
771 fb0be379 Michael Hanselmann
772 fb0be379 Michael Hanselmann
    # Sorting in-place instead of using "sorted()"
773 fb0be379 Michael Hanselmann
    result.sort()
774 fb0be379 Michael Hanselmann
775 fb0be379 Michael Hanselmann
    assert not result or (len(result[0]) == 3 and len(result[-1]) == 3)
776 fb0be379 Michael Hanselmann
777 fb0be379 Michael Hanselmann
    return map(operator.itemgetter(2), result)
778 4ca96421 Michael Hanselmann
779 fbc263a9 Michael Hanselmann
  def OldStyleQuery(self, ctx, sort_by_name=True):
780 4ca96421 Michael Hanselmann
    """Query with "old" query result format.
781 4ca96421 Michael Hanselmann

782 4ca96421 Michael Hanselmann
    See L{Query.Query} for arguments.
783 4ca96421 Michael Hanselmann

784 4ca96421 Michael Hanselmann
    """
785 111bf531 Michael Hanselmann
    unknown = set(fdef.name for (fdef, _, _, _) in self._fields
786 111bf531 Michael Hanselmann
                  if fdef.kind == QFT_UNKNOWN)
787 4ca96421 Michael Hanselmann
    if unknown:
788 4ca96421 Michael Hanselmann
      raise errors.OpPrereqError("Unknown output fields selected: %s" %
789 4ca96421 Michael Hanselmann
                                 (utils.CommaJoin(unknown), ),
790 4ca96421 Michael Hanselmann
                                 errors.ECODE_INVAL)
791 4ca96421 Michael Hanselmann
792 4ca96421 Michael Hanselmann
    return [[value for (_, value) in row]
793 fbc263a9 Michael Hanselmann
            for row in self.Query(ctx, sort_by_name=sort_by_name)]
794 4ca96421 Michael Hanselmann
795 4ca96421 Michael Hanselmann
796 e2d188cc Iustin Pop
def _ProcessResult(value):
797 e2d188cc Iustin Pop
  """Converts result values into externally-visible ones.
798 e2d188cc Iustin Pop

799 e2d188cc Iustin Pop
  """
800 e2d188cc Iustin Pop
  if value is _FS_UNKNOWN:
801 cfb084ae René Nussbaumer
    return (RS_UNKNOWN, None)
802 e2d188cc Iustin Pop
  elif value is _FS_NODATA:
803 cfb084ae René Nussbaumer
    return (RS_NODATA, None)
804 e2d188cc Iustin Pop
  elif value is _FS_UNAVAIL:
805 cfb084ae René Nussbaumer
    return (RS_UNAVAIL, None)
806 e2d188cc Iustin Pop
  elif value is _FS_OFFLINE:
807 cfb084ae René Nussbaumer
    return (RS_OFFLINE, None)
808 e2d188cc Iustin Pop
  else:
809 cfb084ae René Nussbaumer
    return (RS_NORMAL, value)
810 e2d188cc Iustin Pop
811 e2d188cc Iustin Pop
812 4ca96421 Michael Hanselmann
def _VerifyResultRow(fields, row):
813 4ca96421 Michael Hanselmann
  """Verifies the contents of a query result row.
814 4ca96421 Michael Hanselmann

815 4ca96421 Michael Hanselmann
  @type fields: list
816 4ca96421 Michael Hanselmann
  @param fields: Field definitions for result
817 4ca96421 Michael Hanselmann
  @type row: list of tuples
818 4ca96421 Michael Hanselmann
  @param row: Row data
819 4ca96421 Michael Hanselmann

820 4ca96421 Michael Hanselmann
  """
821 d1c3c3b3 Iustin Pop
  assert len(row) == len(fields)
822 d1c3c3b3 Iustin Pop
  errs = []
823 111bf531 Michael Hanselmann
  for ((status, value), (fdef, _, _, _)) in zip(row, fields):
824 cfb084ae René Nussbaumer
    if status == RS_NORMAL:
825 d1c3c3b3 Iustin Pop
      if not _VERIFY_FN[fdef.kind](value):
826 d1c3c3b3 Iustin Pop
        errs.append("normal field %s fails validation (value is %s)" %
827 d1c3c3b3 Iustin Pop
                    (fdef.name, value))
828 d1c3c3b3 Iustin Pop
    elif value is not None:
829 d1c3c3b3 Iustin Pop
      errs.append("abnormal field %s has a non-None value" % fdef.name)
830 d1c3c3b3 Iustin Pop
  assert not errs, ("Failed validation: %s in row %s" %
831 34598551 Agata Murawska
                    (utils.CommaJoin(errs), row))
832 4ca96421 Michael Hanselmann
833 4ca96421 Michael Hanselmann
834 320e34df Michael Hanselmann
def _FieldDictKey((fdef, _, flags, fn)):
835 320e34df Michael Hanselmann
  """Generates key for field dictionary.
836 320e34df Michael Hanselmann

837 320e34df Michael Hanselmann
  """
838 320e34df Michael Hanselmann
  assert fdef.name and fdef.title, "Name and title are required"
839 320e34df Michael Hanselmann
  assert FIELD_NAME_RE.match(fdef.name)
840 320e34df Michael Hanselmann
  assert TITLE_RE.match(fdef.title)
841 320e34df Michael Hanselmann
  assert (DOC_RE.match(fdef.doc) and len(fdef.doc.splitlines()) == 1 and
842 320e34df Michael Hanselmann
          fdef.doc.strip() == fdef.doc), \
843 320e34df Michael Hanselmann
         "Invalid description for field '%s'" % fdef.name
844 320e34df Michael Hanselmann
  assert callable(fn)
845 320e34df Michael Hanselmann
  assert (flags & ~QFF_ALL) == 0, "Unknown flags for field '%s'" % fdef.name
846 320e34df Michael Hanselmann
847 320e34df Michael Hanselmann
  return fdef.name
848 320e34df Michael Hanselmann
849 320e34df Michael Hanselmann
850 d63bd540 Iustin Pop
def _PrepareFieldList(fields, aliases):
851 4ca96421 Michael Hanselmann
  """Prepares field list for use by L{Query}.
852 4ca96421 Michael Hanselmann

853 4ca96421 Michael Hanselmann
  Converts the list to a dictionary and does some verification.
854 4ca96421 Michael Hanselmann

855 d63bd540 Iustin Pop
  @type fields: list of tuples; (L{objects.QueryFieldDefinition}, data
856 d63bd540 Iustin Pop
      kind, retrieval function)
857 d63bd540 Iustin Pop
  @param fields: List of fields, see L{Query.__init__} for a better
858 d63bd540 Iustin Pop
      description
859 d63bd540 Iustin Pop
  @type aliases: list of tuples; (alias, target)
860 d63bd540 Iustin Pop
  @param aliases: list of tuples containing aliases; for each
861 d63bd540 Iustin Pop
      alias/target pair, a duplicate will be created in the field list
862 4ca96421 Michael Hanselmann
  @rtype: dict
863 4ca96421 Michael Hanselmann
  @return: Field dictionary for L{Query}
864 4ca96421 Michael Hanselmann

865 4ca96421 Michael Hanselmann
  """
866 89ce4acc Michael Hanselmann
  if __debug__:
867 89ce4acc Michael Hanselmann
    duplicates = utils.FindDuplicates(fdef.title.lower()
868 111bf531 Michael Hanselmann
                                      for (fdef, _, _, _) in fields)
869 89ce4acc Michael Hanselmann
    assert not duplicates, "Duplicate title(s) found: %r" % duplicates
870 4ca96421 Michael Hanselmann
871 320e34df Michael Hanselmann
  result = utils.SequenceToDict(fields, key=_FieldDictKey)
872 4ca96421 Michael Hanselmann
873 d63bd540 Iustin Pop
  for alias, target in aliases:
874 d63bd540 Iustin Pop
    assert alias not in result, "Alias %s overrides an existing field" % alias
875 d63bd540 Iustin Pop
    assert target in result, "Missing target %s for alias %s" % (target, alias)
876 111bf531 Michael Hanselmann
    (fdef, k, flags, fn) = result[target]
877 d63bd540 Iustin Pop
    fdef = fdef.Copy()
878 d63bd540 Iustin Pop
    fdef.name = alias
879 111bf531 Michael Hanselmann
    result[alias] = (fdef, k, flags, fn)
880 d63bd540 Iustin Pop
881 d63bd540 Iustin Pop
  assert len(result) == len(fields) + len(aliases)
882 4ca96421 Michael Hanselmann
  assert compat.all(name == fdef.name
883 111bf531 Michael Hanselmann
                    for (name, (fdef, _, _, _)) in result.items())
884 4ca96421 Michael Hanselmann
885 4ca96421 Michael Hanselmann
  return result
886 4ca96421 Michael Hanselmann
887 4ca96421 Michael Hanselmann
888 fbc263a9 Michael Hanselmann
def GetQueryResponse(query, ctx, sort_by_name=True):
889 b60fcb6f Michael Hanselmann
  """Prepares the response for a query.
890 b60fcb6f Michael Hanselmann

891 b60fcb6f Michael Hanselmann
  @type query: L{Query}
892 b60fcb6f Michael Hanselmann
  @param ctx: Data container, see L{Query.Query}
893 fbc263a9 Michael Hanselmann
  @type sort_by_name: boolean
894 fbc263a9 Michael Hanselmann
  @param sort_by_name: Whether to sort by name or keep the input data's
895 fbc263a9 Michael Hanselmann
    ordering
896 b60fcb6f Michael Hanselmann

897 b60fcb6f Michael Hanselmann
  """
898 fbc263a9 Michael Hanselmann
  return objects.QueryResponse(data=query.Query(ctx, sort_by_name=sort_by_name),
899 b60fcb6f Michael Hanselmann
                               fields=query.GetFields()).ToDict()
900 b60fcb6f Michael Hanselmann
901 b60fcb6f Michael Hanselmann
902 aa29e95f Michael Hanselmann
def QueryFields(fielddefs, selected):
903 aa29e95f Michael Hanselmann
  """Returns list of available fields.
904 aa29e95f Michael Hanselmann

905 aa29e95f Michael Hanselmann
  @type fielddefs: dict
906 aa29e95f Michael Hanselmann
  @param fielddefs: Field definitions
907 aa29e95f Michael Hanselmann
  @type selected: list of strings
908 aa29e95f Michael Hanselmann
  @param selected: List of selected fields
909 aa29e95f Michael Hanselmann
  @return: List of L{objects.QueryFieldDefinition}
910 aa29e95f Michael Hanselmann

911 aa29e95f Michael Hanselmann
  """
912 aa29e95f Michael Hanselmann
  if selected is None:
913 aa29e95f Michael Hanselmann
    # Client requests all fields, sort by name
914 aa29e95f Michael Hanselmann
    fdefs = utils.NiceSort(GetAllFields(fielddefs.values()),
915 aa29e95f Michael Hanselmann
                           key=operator.attrgetter("name"))
916 aa29e95f Michael Hanselmann
  else:
917 aa29e95f Michael Hanselmann
    # Keep order as requested by client
918 aa29e95f Michael Hanselmann
    fdefs = Query(fielddefs, selected).GetFields()
919 aa29e95f Michael Hanselmann
920 aa29e95f Michael Hanselmann
  return objects.QueryFieldsResponse(fields=fdefs).ToDict()
921 aa29e95f Michael Hanselmann
922 aa29e95f Michael Hanselmann
923 79b2ca83 Michael Hanselmann
def _MakeField(name, title, kind, doc):
924 4ca96421 Michael Hanselmann
  """Wrapper for creating L{objects.QueryFieldDefinition} instances.
925 4ca96421 Michael Hanselmann

926 4ca96421 Michael Hanselmann
  @param name: Field name as a regular expression
927 4ca96421 Michael Hanselmann
  @param title: Human-readable title
928 4ca96421 Michael Hanselmann
  @param kind: Field type
929 1ae17369 Michael Hanselmann
  @param doc: Human-readable description
930 4ca96421 Michael Hanselmann

931 4ca96421 Michael Hanselmann
  """
932 1ae17369 Michael Hanselmann
  return objects.QueryFieldDefinition(name=name, title=title, kind=kind,
933 1ae17369 Michael Hanselmann
                                      doc=doc)
934 8235fe04 Michael Hanselmann
935 8235fe04 Michael Hanselmann
936 dff5f600 Michael Hanselmann
def _StaticValueInner(value, ctx, _): # pylint: disable=W0613
937 dff5f600 Michael Hanselmann
  """Returns a static value.
938 dff5f600 Michael Hanselmann

939 dff5f600 Michael Hanselmann
  """
940 dff5f600 Michael Hanselmann
  return value
941 dff5f600 Michael Hanselmann
942 dff5f600 Michael Hanselmann
943 dff5f600 Michael Hanselmann
def _StaticValue(value):
944 dff5f600 Michael Hanselmann
  """Prepares a function to return a static value.
945 dff5f600 Michael Hanselmann

946 dff5f600 Michael Hanselmann
  """
947 dff5f600 Michael Hanselmann
  return compat.partial(_StaticValueInner, value)
948 dff5f600 Michael Hanselmann
949 dff5f600 Michael Hanselmann
950 8235fe04 Michael Hanselmann
def _GetNodeRole(node, master_name):
951 8235fe04 Michael Hanselmann
  """Determine node role.
952 8235fe04 Michael Hanselmann

953 8235fe04 Michael Hanselmann
  @type node: L{objects.Node}
954 8235fe04 Michael Hanselmann
  @param node: Node object
955 8235fe04 Michael Hanselmann
  @type master_name: string
956 8235fe04 Michael Hanselmann
  @param master_name: Master node name
957 8235fe04 Michael Hanselmann

958 8235fe04 Michael Hanselmann
  """
959 8235fe04 Michael Hanselmann
  if node.name == master_name:
960 1e28e3b8 Michael Hanselmann
    return constants.NR_MASTER
961 8235fe04 Michael Hanselmann
  elif node.master_candidate:
962 1e28e3b8 Michael Hanselmann
    return constants.NR_MCANDIDATE
963 8235fe04 Michael Hanselmann
  elif node.drained:
964 1e28e3b8 Michael Hanselmann
    return constants.NR_DRAINED
965 8235fe04 Michael Hanselmann
  elif node.offline:
966 1e28e3b8 Michael Hanselmann
    return constants.NR_OFFLINE
967 8235fe04 Michael Hanselmann
  else:
968 1e28e3b8 Michael Hanselmann
    return constants.NR_REGULAR
969 8235fe04 Michael Hanselmann
970 8235fe04 Michael Hanselmann
971 8235fe04 Michael Hanselmann
def _GetItemAttr(attr):
972 8235fe04 Michael Hanselmann
  """Returns a field function to return an attribute of the item.
973 8235fe04 Michael Hanselmann

974 8235fe04 Michael Hanselmann
  @param attr: Attribute name
975 8235fe04 Michael Hanselmann

976 8235fe04 Michael Hanselmann
  """
977 8235fe04 Michael Hanselmann
  getter = operator.attrgetter(attr)
978 e2d188cc Iustin Pop
  return lambda _, item: getter(item)
979 8235fe04 Michael Hanselmann
980 8235fe04 Michael Hanselmann
981 40b118d3 Iustin Pop
def _GetItemMaybeAttr(attr):
982 40b118d3 Iustin Pop
  """Returns a field function to return a not-None attribute of the item.
983 40b118d3 Iustin Pop

984 40b118d3 Iustin Pop
  If the value is None, then C{_FS_UNAVAIL} will be returned instead.
985 40b118d3 Iustin Pop

986 40b118d3 Iustin Pop
  @param attr: Attribute name
987 40b118d3 Iustin Pop

988 40b118d3 Iustin Pop
  """
989 40b118d3 Iustin Pop
  def _helper(_, obj):
990 40b118d3 Iustin Pop
    val = getattr(obj, attr)
991 40b118d3 Iustin Pop
    if val is None:
992 40b118d3 Iustin Pop
      return _FS_UNAVAIL
993 40b118d3 Iustin Pop
    else:
994 40b118d3 Iustin Pop
      return val
995 40b118d3 Iustin Pop
  return _helper
996 40b118d3 Iustin Pop
997 40b118d3 Iustin Pop
998 8930b0f0 Iustin Pop
def _GetNDParam(name):
999 8930b0f0 Iustin Pop
  """Return a field function to return an ND parameter out of the context.
1000 8930b0f0 Iustin Pop

1001 8930b0f0 Iustin Pop
  """
1002 8930b0f0 Iustin Pop
  def _helper(ctx, _):
1003 8930b0f0 Iustin Pop
    if ctx.ndparams is None:
1004 8930b0f0 Iustin Pop
      return _FS_UNAVAIL
1005 8930b0f0 Iustin Pop
    else:
1006 8930b0f0 Iustin Pop
      return ctx.ndparams.get(name, None)
1007 8930b0f0 Iustin Pop
  return _helper
1008 8930b0f0 Iustin Pop
1009 8930b0f0 Iustin Pop
1010 8930b0f0 Iustin Pop
def _BuildNDFields(is_group):
1011 8930b0f0 Iustin Pop
  """Builds all the ndparam fields.
1012 8930b0f0 Iustin Pop

1013 8930b0f0 Iustin Pop
  @param is_group: whether this is called at group or node level
1014 8930b0f0 Iustin Pop

1015 8930b0f0 Iustin Pop
  """
1016 8930b0f0 Iustin Pop
  if is_group:
1017 8930b0f0 Iustin Pop
    field_kind = GQ_CONFIG
1018 8930b0f0 Iustin Pop
  else:
1019 8930b0f0 Iustin Pop
    field_kind = NQ_GROUP
1020 a6c7e2a2 Iustin Pop
  return [(_MakeField("ndp/%s" % name,
1021 a6c7e2a2 Iustin Pop
                      constants.NDS_PARAMETER_TITLES.get(name,
1022 a6c7e2a2 Iustin Pop
                                                         "ndp/%s" % name),
1023 8930b0f0 Iustin Pop
                      _VTToQFT[kind], "The \"%s\" node parameter" % name),
1024 8930b0f0 Iustin Pop
           field_kind, 0, _GetNDParam(name))
1025 8930b0f0 Iustin Pop
          for name, kind in constants.NDS_PARAMETER_TYPES.items()]
1026 8930b0f0 Iustin Pop
1027 8930b0f0 Iustin Pop
1028 425e5bf0 Michael Hanselmann
def _ConvWrapInner(convert, fn, ctx, item):
1029 425e5bf0 Michael Hanselmann
  """Wrapper for converting values.
1030 425e5bf0 Michael Hanselmann

1031 425e5bf0 Michael Hanselmann
  @param convert: Conversion function receiving value as single parameter
1032 425e5bf0 Michael Hanselmann
  @param fn: Retrieval function
1033 425e5bf0 Michael Hanselmann

1034 425e5bf0 Michael Hanselmann
  """
1035 425e5bf0 Michael Hanselmann
  value = fn(ctx, item)
1036 425e5bf0 Michael Hanselmann
1037 425e5bf0 Michael Hanselmann
  # Is the value an abnormal status?
1038 425e5bf0 Michael Hanselmann
  if compat.any(value is fs for fs in _FS_ALL):
1039 425e5bf0 Michael Hanselmann
    # Return right away
1040 425e5bf0 Michael Hanselmann
    return value
1041 425e5bf0 Michael Hanselmann
1042 425e5bf0 Michael Hanselmann
  # TODO: Should conversion function also receive context, item or both?
1043 425e5bf0 Michael Hanselmann
  return convert(value)
1044 425e5bf0 Michael Hanselmann
1045 425e5bf0 Michael Hanselmann
1046 425e5bf0 Michael Hanselmann
def _ConvWrap(convert, fn):
1047 425e5bf0 Michael Hanselmann
  """Convenience wrapper for L{_ConvWrapInner}.
1048 425e5bf0 Michael Hanselmann

1049 425e5bf0 Michael Hanselmann
  @param convert: Conversion function receiving value as single parameter
1050 425e5bf0 Michael Hanselmann
  @param fn: Retrieval function
1051 425e5bf0 Michael Hanselmann

1052 425e5bf0 Michael Hanselmann
  """
1053 425e5bf0 Michael Hanselmann
  return compat.partial(_ConvWrapInner, convert, fn)
1054 425e5bf0 Michael Hanselmann
1055 425e5bf0 Michael Hanselmann
1056 145bea54 Michael Hanselmann
def _GetItemTimestamp(getter):
1057 145bea54 Michael Hanselmann
  """Returns function for getting timestamp of item.
1058 145bea54 Michael Hanselmann

1059 145bea54 Michael Hanselmann
  @type getter: callable
1060 145bea54 Michael Hanselmann
  @param getter: Function to retrieve timestamp attribute
1061 145bea54 Michael Hanselmann

1062 145bea54 Michael Hanselmann
  """
1063 145bea54 Michael Hanselmann
  def fn(_, item):
1064 145bea54 Michael Hanselmann
    """Returns a timestamp of item.
1065 145bea54 Michael Hanselmann

1066 145bea54 Michael Hanselmann
    """
1067 145bea54 Michael Hanselmann
    timestamp = getter(item)
1068 145bea54 Michael Hanselmann
    if timestamp is None:
1069 145bea54 Michael Hanselmann
      # Old configs might not have all timestamps
1070 e2d188cc Iustin Pop
      return _FS_UNAVAIL
1071 145bea54 Michael Hanselmann
    else:
1072 e2d188cc Iustin Pop
      return timestamp
1073 145bea54 Michael Hanselmann
1074 145bea54 Michael Hanselmann
  return fn
1075 145bea54 Michael Hanselmann
1076 145bea54 Michael Hanselmann
1077 145bea54 Michael Hanselmann
def _GetItemTimestampFields(datatype):
1078 145bea54 Michael Hanselmann
  """Returns common timestamp fields.
1079 145bea54 Michael Hanselmann

1080 145bea54 Michael Hanselmann
  @param datatype: Field data type for use by L{Query.RequestedData}
1081 145bea54 Michael Hanselmann

1082 145bea54 Michael Hanselmann
  """
1083 145bea54 Michael Hanselmann
  return [
1084 79b2ca83 Michael Hanselmann
    (_MakeField("ctime", "CTime", QFT_TIMESTAMP, "Creation timestamp"),
1085 111bf531 Michael Hanselmann
     datatype, 0, _GetItemTimestamp(operator.attrgetter("ctime"))),
1086 79b2ca83 Michael Hanselmann
    (_MakeField("mtime", "MTime", QFT_TIMESTAMP, "Modification timestamp"),
1087 111bf531 Michael Hanselmann
     datatype, 0, _GetItemTimestamp(operator.attrgetter("mtime"))),
1088 145bea54 Michael Hanselmann
    ]
1089 145bea54 Michael Hanselmann
1090 145bea54 Michael Hanselmann
1091 8235fe04 Michael Hanselmann
class NodeQueryData:
1092 8235fe04 Michael Hanselmann
  """Data container for node data queries.
1093 8235fe04 Michael Hanselmann

1094 8235fe04 Michael Hanselmann
  """
1095 1c3231aa Thomas Thrainer
  def __init__(self, nodes, live_data, master_uuid, node_to_primary,
1096 da4a52a3 Thomas Thrainer
               node_to_secondary, inst_uuid_to_inst_name, groups, oob_support,
1097 da4a52a3 Thomas Thrainer
               cluster):
1098 8235fe04 Michael Hanselmann
    """Initializes this class.
1099 8235fe04 Michael Hanselmann

1100 8235fe04 Michael Hanselmann
    """
1101 8235fe04 Michael Hanselmann
    self.nodes = nodes
1102 8235fe04 Michael Hanselmann
    self.live_data = live_data
1103 1c3231aa Thomas Thrainer
    self.master_uuid = master_uuid
1104 8235fe04 Michael Hanselmann
    self.node_to_primary = node_to_primary
1105 8235fe04 Michael Hanselmann
    self.node_to_secondary = node_to_secondary
1106 da4a52a3 Thomas Thrainer
    self.inst_uuid_to_inst_name = inst_uuid_to_inst_name
1107 8235fe04 Michael Hanselmann
    self.groups = groups
1108 52b5d286 René Nussbaumer
    self.oob_support = oob_support
1109 8572f1fe René Nussbaumer
    self.cluster = cluster
1110 8235fe04 Michael Hanselmann
1111 8235fe04 Michael Hanselmann
    # Used for individual rows
1112 8235fe04 Michael Hanselmann
    self.curlive_data = None
1113 8930b0f0 Iustin Pop
    self.ndparams = None
1114 8235fe04 Michael Hanselmann
1115 8235fe04 Michael Hanselmann
  def __iter__(self):
1116 8235fe04 Michael Hanselmann
    """Iterate over all nodes.
1117 8235fe04 Michael Hanselmann

1118 8235fe04 Michael Hanselmann
    This function has side-effects and only one instance of the resulting
1119 8235fe04 Michael Hanselmann
    generator should be used at a time.
1120 8235fe04 Michael Hanselmann

1121 8235fe04 Michael Hanselmann
    """
1122 8235fe04 Michael Hanselmann
    for node in self.nodes:
1123 8930b0f0 Iustin Pop
      group = self.groups.get(node.group, None)
1124 8930b0f0 Iustin Pop
      if group is None:
1125 8930b0f0 Iustin Pop
        self.ndparams = None
1126 8930b0f0 Iustin Pop
      else:
1127 8930b0f0 Iustin Pop
        self.ndparams = self.cluster.FillND(node, group)
1128 8235fe04 Michael Hanselmann
      if self.live_data:
1129 1c3231aa Thomas Thrainer
        self.curlive_data = self.live_data.get(node.uuid, None)
1130 8235fe04 Michael Hanselmann
      else:
1131 8235fe04 Michael Hanselmann
        self.curlive_data = None
1132 8235fe04 Michael Hanselmann
      yield node
1133 8235fe04 Michael Hanselmann
1134 8235fe04 Michael Hanselmann
1135 8235fe04 Michael Hanselmann
#: Fields that are direct attributes of an L{objects.Node} object
1136 8235fe04 Michael Hanselmann
_NODE_SIMPLE_FIELDS = {
1137 111bf531 Michael Hanselmann
  "drained": ("Drained", QFT_BOOL, 0, "Whether node is drained"),
1138 111bf531 Michael Hanselmann
  "master_candidate": ("MasterC", QFT_BOOL, 0,
1139 79b2ca83 Michael Hanselmann
                       "Whether node is a master candidate"),
1140 111bf531 Michael Hanselmann
  "master_capable": ("MasterCapable", QFT_BOOL, 0,
1141 79b2ca83 Michael Hanselmann
                     "Whether node can become a master candidate"),
1142 111bf531 Michael Hanselmann
  "name": ("Node", QFT_TEXT, QFF_HOSTNAME, "Node name"),
1143 111bf531 Michael Hanselmann
  "offline": ("Offline", QFT_BOOL, 0, "Whether node is marked offline"),
1144 111bf531 Michael Hanselmann
  "serial_no": ("SerialNo", QFT_NUMBER, 0, _SERIAL_NO_DOC % "Node"),
1145 111bf531 Michael Hanselmann
  "uuid": ("UUID", QFT_TEXT, 0, "Node UUID"),
1146 111bf531 Michael Hanselmann
  "vm_capable": ("VMCapable", QFT_BOOL, 0, "Whether node can host instances"),
1147 8235fe04 Michael Hanselmann
  }
1148 8235fe04 Michael Hanselmann
1149 8235fe04 Michael Hanselmann
1150 8235fe04 Michael Hanselmann
#: Fields requiring talking to the node
1151 effab4ca Iustin Pop
# Note that none of these are available for non-vm_capable nodes
1152 8235fe04 Michael Hanselmann
_NODE_LIVE_FIELDS = {
1153 79b2ca83 Michael Hanselmann
  "bootid": ("BootID", QFT_TEXT, "bootid",
1154 79b2ca83 Michael Hanselmann
             "Random UUID renewed for each system reboot, can be used"
1155 79b2ca83 Michael Hanselmann
             " for detecting reboots by tracking changes"),
1156 79b2ca83 Michael Hanselmann
  "cnodes": ("CNodes", QFT_NUMBER, "cpu_nodes",
1157 79b2ca83 Michael Hanselmann
             "Number of NUMA domains on node (if exported by hypervisor)"),
1158 f43c898d Bernardo Dal Seno
  "cnos": ("CNOs", QFT_NUMBER, "cpu_dom0",
1159 f43c898d Bernardo Dal Seno
            "Number of logical processors used by the node OS (dom0 for Xen)"),
1160 79b2ca83 Michael Hanselmann
  "csockets": ("CSockets", QFT_NUMBER, "cpu_sockets",
1161 79b2ca83 Michael Hanselmann
               "Number of physical CPU sockets (if exported by hypervisor)"),
1162 79b2ca83 Michael Hanselmann
  "ctotal": ("CTotal", QFT_NUMBER, "cpu_total", "Number of logical processors"),
1163 32389d91 Helga Velroyen
  "dfree": ("DFree", QFT_UNIT, "storage_free",
1164 32389d91 Helga Velroyen
            "Available storage space in storage unit"),
1165 32389d91 Helga Velroyen
  "dtotal": ("DTotal", QFT_UNIT, "storage_size",
1166 32389d91 Helga Velroyen
             "Total storage space in storage unit used for instance disk"
1167 79b2ca83 Michael Hanselmann
             " allocation"),
1168 06fb92cf Bernardo Dal Seno
  "spfree": ("SpFree", QFT_NUMBER, "spindles_free",
1169 06fb92cf Bernardo Dal Seno
             "Available spindles in volume group (exclusive storage only)"),
1170 06fb92cf Bernardo Dal Seno
  "sptotal": ("SpTotal", QFT_NUMBER, "spindles_total",
1171 06fb92cf Bernardo Dal Seno
              "Total spindles in volume group (exclusive storage only)"),
1172 79b2ca83 Michael Hanselmann
  "mfree": ("MFree", QFT_UNIT, "memory_free",
1173 79b2ca83 Michael Hanselmann
            "Memory available for instance allocations"),
1174 79b2ca83 Michael Hanselmann
  "mnode": ("MNode", QFT_UNIT, "memory_dom0",
1175 79b2ca83 Michael Hanselmann
            "Amount of memory used by node (dom0 for Xen)"),
1176 79b2ca83 Michael Hanselmann
  "mtotal": ("MTotal", QFT_UNIT, "memory_total",
1177 79b2ca83 Michael Hanselmann
             "Total amount of memory of physical machine"),
1178 8235fe04 Michael Hanselmann
  }
1179 8235fe04 Michael Hanselmann
1180 8235fe04 Michael Hanselmann
1181 8572f1fe René Nussbaumer
def _GetGroup(cb):
1182 8572f1fe René Nussbaumer
  """Build function for calling another function with an node group.
1183 8572f1fe René Nussbaumer

1184 8572f1fe René Nussbaumer
  @param cb: The callback to be called with the nodegroup
1185 8572f1fe René Nussbaumer

1186 8572f1fe René Nussbaumer
  """
1187 8572f1fe René Nussbaumer
  def fn(ctx, node):
1188 8572f1fe René Nussbaumer
    """Get group data for a node.
1189 8572f1fe René Nussbaumer

1190 8572f1fe René Nussbaumer
    @type ctx: L{NodeQueryData}
1191 8572f1fe René Nussbaumer
    @type inst: L{objects.Node}
1192 8572f1fe René Nussbaumer
    @param inst: Node object
1193 8572f1fe René Nussbaumer

1194 8572f1fe René Nussbaumer
    """
1195 8572f1fe René Nussbaumer
    ng = ctx.groups.get(node.group, None)
1196 8572f1fe René Nussbaumer
    if ng is None:
1197 8572f1fe René Nussbaumer
      # Nodes always have a group, or the configuration is corrupt
1198 e2d188cc Iustin Pop
      return _FS_UNAVAIL
1199 8572f1fe René Nussbaumer
1200 8572f1fe René Nussbaumer
    return cb(ctx, node, ng)
1201 8572f1fe René Nussbaumer
1202 8572f1fe René Nussbaumer
  return fn
1203 8572f1fe René Nussbaumer
1204 8572f1fe René Nussbaumer
1205 b459a848 Andrea Spadaccini
def _GetNodeGroup(ctx, node, ng): # pylint: disable=W0613
1206 8235fe04 Michael Hanselmann
  """Returns the name of a node's group.
1207 8235fe04 Michael Hanselmann

1208 8235fe04 Michael Hanselmann
  @type ctx: L{NodeQueryData}
1209 8235fe04 Michael Hanselmann
  @type node: L{objects.Node}
1210 8235fe04 Michael Hanselmann
  @param node: Node object
1211 8572f1fe René Nussbaumer
  @type ng: L{objects.NodeGroup}
1212 8572f1fe René Nussbaumer
  @param ng: The node group this node belongs to
1213 8235fe04 Michael Hanselmann

1214 8235fe04 Michael Hanselmann
  """
1215 e2d188cc Iustin Pop
  return ng.name
1216 8235fe04 Michael Hanselmann
1217 8235fe04 Michael Hanselmann
1218 52b5d286 René Nussbaumer
def _GetNodePower(ctx, node):
1219 52b5d286 René Nussbaumer
  """Returns the node powered state
1220 52b5d286 René Nussbaumer

1221 52b5d286 René Nussbaumer
  @type ctx: L{NodeQueryData}
1222 52b5d286 René Nussbaumer
  @type node: L{objects.Node}
1223 52b5d286 René Nussbaumer
  @param node: Node object
1224 52b5d286 René Nussbaumer

1225 52b5d286 René Nussbaumer
  """
1226 1c3231aa Thomas Thrainer
  if ctx.oob_support[node.uuid]:
1227 e2d188cc Iustin Pop
    return node.powered
1228 52b5d286 René Nussbaumer
1229 e2d188cc Iustin Pop
  return _FS_UNAVAIL
1230 52b5d286 René Nussbaumer
1231 52b5d286 René Nussbaumer
1232 8572f1fe René Nussbaumer
def _GetNdParams(ctx, node, ng):
1233 8572f1fe René Nussbaumer
  """Returns the ndparams for this node.
1234 8572f1fe René Nussbaumer

1235 8572f1fe René Nussbaumer
  @type ctx: L{NodeQueryData}
1236 8572f1fe René Nussbaumer
  @type node: L{objects.Node}
1237 8572f1fe René Nussbaumer
  @param node: Node object
1238 8572f1fe René Nussbaumer
  @type ng: L{objects.NodeGroup}
1239 8572f1fe René Nussbaumer
  @param ng: The node group this node belongs to
1240 8572f1fe René Nussbaumer

1241 8572f1fe René Nussbaumer
  """
1242 e2d188cc Iustin Pop
  return ctx.cluster.SimpleFillND(ng.FillND(node))
1243 8572f1fe René Nussbaumer
1244 8572f1fe René Nussbaumer
1245 a6070ef7 Michael Hanselmann
def _GetLiveNodeField(field, kind, ctx, node):
1246 8235fe04 Michael Hanselmann
  """Gets the value of a "live" field from L{NodeQueryData}.
1247 8235fe04 Michael Hanselmann

1248 8235fe04 Michael Hanselmann
  @param field: Live field name
1249 8235fe04 Michael Hanselmann
  @param kind: Data kind, one of L{constants.QFT_ALL}
1250 8235fe04 Michael Hanselmann
  @type ctx: L{NodeQueryData}
1251 a6070ef7 Michael Hanselmann
  @type node: L{objects.Node}
1252 a6070ef7 Michael Hanselmann
  @param node: Node object
1253 8235fe04 Michael Hanselmann

1254 8235fe04 Michael Hanselmann
  """
1255 a6070ef7 Michael Hanselmann
  if node.offline:
1256 e2d188cc Iustin Pop
    return _FS_OFFLINE
1257 a6070ef7 Michael Hanselmann
1258 effab4ca Iustin Pop
  if not node.vm_capable:
1259 effab4ca Iustin Pop
    return _FS_UNAVAIL
1260 effab4ca Iustin Pop
1261 8235fe04 Michael Hanselmann
  if not ctx.curlive_data:
1262 e2d188cc Iustin Pop
    return _FS_NODATA
1263 8235fe04 Michael Hanselmann
1264 b4600d4f Michael Hanselmann
  return _GetStatsField(field, kind, ctx.curlive_data)
1265 b4600d4f Michael Hanselmann
1266 b4600d4f Michael Hanselmann
1267 b4600d4f Michael Hanselmann
def _GetStatsField(field, kind, data):
1268 b4600d4f Michael Hanselmann
  """Gets a value from live statistics.
1269 b4600d4f Michael Hanselmann

1270 b4600d4f Michael Hanselmann
  If the value is not found, L{_FS_UNAVAIL} is returned. If the field kind is
1271 b4600d4f Michael Hanselmann
  numeric a conversion to integer is attempted. If that fails, L{_FS_UNAVAIL}
1272 b4600d4f Michael Hanselmann
  is returned.
1273 b4600d4f Michael Hanselmann

1274 b4600d4f Michael Hanselmann
  @param field: Live field name
1275 b4600d4f Michael Hanselmann
  @param kind: Data kind, one of L{constants.QFT_ALL}
1276 b4600d4f Michael Hanselmann
  @type data: dict
1277 b4600d4f Michael Hanselmann
  @param data: Statistics
1278 b4600d4f Michael Hanselmann

1279 b4600d4f Michael Hanselmann
  """
1280 8235fe04 Michael Hanselmann
  try:
1281 b4600d4f Michael Hanselmann
    value = data[field]
1282 8235fe04 Michael Hanselmann
  except KeyError:
1283 e2d188cc Iustin Pop
    return _FS_UNAVAIL
1284 8235fe04 Michael Hanselmann
1285 82599b3e Iustin Pop
  if kind == QFT_TEXT:
1286 e2d188cc Iustin Pop
    return value
1287 8235fe04 Michael Hanselmann
1288 82599b3e Iustin Pop
  assert kind in (QFT_NUMBER, QFT_UNIT)
1289 8235fe04 Michael Hanselmann
1290 8235fe04 Michael Hanselmann
  # Try to convert into number
1291 8235fe04 Michael Hanselmann
  try:
1292 e2d188cc Iustin Pop
    return int(value)
1293 8235fe04 Michael Hanselmann
  except (ValueError, TypeError):
1294 8235fe04 Michael Hanselmann
    logging.exception("Failed to convert node field '%s' (value %r) to int",
1295 b4600d4f Michael Hanselmann
                      field, value)
1296 e2d188cc Iustin Pop
    return _FS_UNAVAIL
1297 8235fe04 Michael Hanselmann
1298 8235fe04 Michael Hanselmann
1299 54ac87c0 Michael Hanselmann
def _GetNodeHvState(_, node):
1300 54ac87c0 Michael Hanselmann
  """Converts node's hypervisor state for query result.
1301 54ac87c0 Michael Hanselmann

1302 54ac87c0 Michael Hanselmann
  """
1303 54ac87c0 Michael Hanselmann
  hv_state = node.hv_state
1304 54ac87c0 Michael Hanselmann
1305 54ac87c0 Michael Hanselmann
  if hv_state is None:
1306 54ac87c0 Michael Hanselmann
    return _FS_UNAVAIL
1307 54ac87c0 Michael Hanselmann
1308 54ac87c0 Michael Hanselmann
  return dict((name, value.ToDict()) for (name, value) in hv_state.items())
1309 54ac87c0 Michael Hanselmann
1310 54ac87c0 Michael Hanselmann
1311 54ac87c0 Michael Hanselmann
def _GetNodeDiskState(_, node):
1312 54ac87c0 Michael Hanselmann
  """Converts node's disk state for query result.
1313 54ac87c0 Michael Hanselmann

1314 54ac87c0 Michael Hanselmann
  """
1315 54ac87c0 Michael Hanselmann
  disk_state = node.disk_state
1316 54ac87c0 Michael Hanselmann
1317 54ac87c0 Michael Hanselmann
  if disk_state is None:
1318 54ac87c0 Michael Hanselmann
    return _FS_UNAVAIL
1319 54ac87c0 Michael Hanselmann
1320 54ac87c0 Michael Hanselmann
  return dict((disk_kind, dict((name, value.ToDict())
1321 54ac87c0 Michael Hanselmann
                               for (name, value) in kind_state.items()))
1322 54ac87c0 Michael Hanselmann
              for (disk_kind, kind_state) in disk_state.items())
1323 54ac87c0 Michael Hanselmann
1324 54ac87c0 Michael Hanselmann
1325 8235fe04 Michael Hanselmann
def _BuildNodeFields():
1326 8235fe04 Michael Hanselmann
  """Builds list of fields for node queries.
1327 8235fe04 Michael Hanselmann

1328 8235fe04 Michael Hanselmann
  """
1329 8235fe04 Michael Hanselmann
  fields = [
1330 79b2ca83 Michael Hanselmann
    (_MakeField("pip", "PrimaryIP", QFT_TEXT, "Primary IP address"),
1331 111bf531 Michael Hanselmann
     NQ_CONFIG, 0, _GetItemAttr("primary_ip")),
1332 79b2ca83 Michael Hanselmann
    (_MakeField("sip", "SecondaryIP", QFT_TEXT, "Secondary IP address"),
1333 111bf531 Michael Hanselmann
     NQ_CONFIG, 0, _GetItemAttr("secondary_ip")),
1334 111bf531 Michael Hanselmann
    (_MakeField("tags", "Tags", QFT_OTHER, "Tags"), NQ_CONFIG, 0,
1335 e2d188cc Iustin Pop
     lambda ctx, node: list(node.GetTags())),
1336 79b2ca83 Michael Hanselmann
    (_MakeField("master", "IsMaster", QFT_BOOL, "Whether node is master"),
1337 1c3231aa Thomas Thrainer
     NQ_CONFIG, 0, lambda ctx, node: node.uuid == ctx.master_uuid),
1338 111bf531 Michael Hanselmann
    (_MakeField("group", "Group", QFT_TEXT, "Node group"), NQ_GROUP, 0,
1339 8572f1fe René Nussbaumer
     _GetGroup(_GetNodeGroup)),
1340 79b2ca83 Michael Hanselmann
    (_MakeField("group.uuid", "GroupUUID", QFT_TEXT, "UUID of node group"),
1341 111bf531 Michael Hanselmann
     NQ_CONFIG, 0, _GetItemAttr("group")),
1342 79b2ca83 Michael Hanselmann
    (_MakeField("powered", "Powered", QFT_BOOL,
1343 79b2ca83 Michael Hanselmann
                "Whether node is thought to be powered on"),
1344 111bf531 Michael Hanselmann
     NQ_OOB, 0, _GetNodePower),
1345 79b2ca83 Michael Hanselmann
    (_MakeField("ndparams", "NodeParameters", QFT_OTHER,
1346 79b2ca83 Michael Hanselmann
                "Merged node parameters"),
1347 111bf531 Michael Hanselmann
     NQ_GROUP, 0, _GetGroup(_GetNdParams)),
1348 79b2ca83 Michael Hanselmann
    (_MakeField("custom_ndparams", "CustomNodeParameters", QFT_OTHER,
1349 79b2ca83 Michael Hanselmann
                "Custom node parameters"),
1350 111bf531 Michael Hanselmann
      NQ_GROUP, 0, _GetItemAttr("ndparams")),
1351 54ac87c0 Michael Hanselmann
    (_MakeField("hv_state", "HypervisorState", QFT_OTHER, "Hypervisor state"),
1352 54ac87c0 Michael Hanselmann
     NQ_CONFIG, 0, _GetNodeHvState),
1353 54ac87c0 Michael Hanselmann
    (_MakeField("disk_state", "DiskState", QFT_OTHER, "Disk state"),
1354 54ac87c0 Michael Hanselmann
     NQ_CONFIG, 0, _GetNodeDiskState),
1355 8235fe04 Michael Hanselmann
    ]
1356 8235fe04 Michael Hanselmann
1357 8930b0f0 Iustin Pop
  fields.extend(_BuildNDFields(False))
1358 8930b0f0 Iustin Pop
1359 79b2ca83 Michael Hanselmann
  # Node role
1360 79b2ca83 Michael Hanselmann
  role_values = (constants.NR_MASTER, constants.NR_MCANDIDATE,
1361 79b2ca83 Michael Hanselmann
                 constants.NR_REGULAR, constants.NR_DRAINED,
1362 79b2ca83 Michael Hanselmann
                 constants.NR_OFFLINE)
1363 79b2ca83 Michael Hanselmann
  role_doc = ("Node role; \"%s\" for master, \"%s\" for master candidate,"
1364 a9310b2f Iustin Pop
              " \"%s\" for regular, \"%s\" for drained, \"%s\" for offline" %
1365 79b2ca83 Michael Hanselmann
              role_values)
1366 111bf531 Michael Hanselmann
  fields.append((_MakeField("role", "Role", QFT_TEXT, role_doc), NQ_CONFIG, 0,
1367 1c3231aa Thomas Thrainer
                 lambda ctx, node: _GetNodeRole(node, ctx.master_uuid)))
1368 79b2ca83 Michael Hanselmann
  assert set(role_values) == constants.NR_ALL
1369 79b2ca83 Michael Hanselmann
1370 8235fe04 Michael Hanselmann
  def _GetLength(getter):
1371 1c3231aa Thomas Thrainer
    return lambda ctx, node: len(getter(ctx)[node.uuid])
1372 8235fe04 Michael Hanselmann
1373 8235fe04 Michael Hanselmann
  def _GetList(getter):
1374 da4a52a3 Thomas Thrainer
    return lambda ctx, node: utils.NiceSort(
1375 da4a52a3 Thomas Thrainer
                               [ctx.inst_uuid_to_inst_name[uuid]
1376 da4a52a3 Thomas Thrainer
                                for uuid in getter(ctx)[node.uuid]])
1377 8235fe04 Michael Hanselmann
1378 8235fe04 Michael Hanselmann
  # Add fields operating on instance lists
1379 79b2ca83 Michael Hanselmann
  for prefix, titleprefix, docword, getter in \
1380 79b2ca83 Michael Hanselmann
      [("p", "Pri", "primary", operator.attrgetter("node_to_primary")),
1381 79b2ca83 Michael Hanselmann
       ("s", "Sec", "secondary", operator.attrgetter("node_to_secondary"))]:
1382 111bf531 Michael Hanselmann
    # TODO: Allow filterting by hostname in list
1383 8235fe04 Michael Hanselmann
    fields.extend([
1384 79b2ca83 Michael Hanselmann
      (_MakeField("%sinst_cnt" % prefix, "%sinst" % prefix.upper(), QFT_NUMBER,
1385 79b2ca83 Michael Hanselmann
                  "Number of instances with this node as %s" % docword),
1386 111bf531 Michael Hanselmann
       NQ_INST, 0, _GetLength(getter)),
1387 8235fe04 Michael Hanselmann
      (_MakeField("%sinst_list" % prefix, "%sInstances" % titleprefix,
1388 79b2ca83 Michael Hanselmann
                  QFT_OTHER,
1389 79b2ca83 Michael Hanselmann
                  "List of instances with this node as %s" % docword),
1390 111bf531 Michael Hanselmann
       NQ_INST, 0, _GetList(getter)),
1391 8235fe04 Michael Hanselmann
      ])
1392 8235fe04 Michael Hanselmann
1393 8235fe04 Michael Hanselmann
  # Add simple fields
1394 111bf531 Michael Hanselmann
  fields.extend([
1395 111bf531 Michael Hanselmann
    (_MakeField(name, title, kind, doc), NQ_CONFIG, flags, _GetItemAttr(name))
1396 3c286190 Dimitris Aragiorgis
    for (name, (title, kind, flags, doc)) in _NODE_SIMPLE_FIELDS.items()])
1397 8235fe04 Michael Hanselmann
1398 8235fe04 Michael Hanselmann
  # Add fields requiring live data
1399 8235fe04 Michael Hanselmann
  fields.extend([
1400 111bf531 Michael Hanselmann
    (_MakeField(name, title, kind, doc), NQ_LIVE, 0,
1401 8235fe04 Michael Hanselmann
     compat.partial(_GetLiveNodeField, nfield, kind))
1402 3c286190 Dimitris Aragiorgis
    for (name, (title, kind, nfield, doc)) in _NODE_LIVE_FIELDS.items()])
1403 8235fe04 Michael Hanselmann
1404 145bea54 Michael Hanselmann
  # Add timestamps
1405 145bea54 Michael Hanselmann
  fields.extend(_GetItemTimestampFields(NQ_CONFIG))
1406 145bea54 Michael Hanselmann
1407 d63bd540 Iustin Pop
  return _PrepareFieldList(fields, [])
1408 8235fe04 Michael Hanselmann
1409 8235fe04 Michael Hanselmann
1410 1c8addc6 Michael Hanselmann
class InstanceQueryData:
1411 1c8addc6 Michael Hanselmann
  """Data container for instance data queries.
1412 1c8addc6 Michael Hanselmann

1413 1c8addc6 Michael Hanselmann
  """
1414 1c3231aa Thomas Thrainer
  def __init__(self, instances, cluster, disk_usage, offline_node_uuids,
1415 1c3231aa Thomas Thrainer
               bad_node_uuids, live_data, wrongnode_inst, console, nodes,
1416 1c3231aa Thomas Thrainer
               groups, networks):
1417 1c8addc6 Michael Hanselmann
    """Initializes this class.
1418 1c8addc6 Michael Hanselmann

1419 1c8addc6 Michael Hanselmann
    @param instances: List of instance objects
1420 1c8addc6 Michael Hanselmann
    @param cluster: Cluster object
1421 da4a52a3 Thomas Thrainer
    @type disk_usage: dict; instance UUID as key
1422 1c8addc6 Michael Hanselmann
    @param disk_usage: Per-instance disk usage
1423 1c3231aa Thomas Thrainer
    @type offline_node_uuids: list of strings
1424 1c3231aa Thomas Thrainer
    @param offline_node_uuids: List of offline nodes
1425 1c3231aa Thomas Thrainer
    @type bad_node_uuids: list of strings
1426 1c3231aa Thomas Thrainer
    @param bad_node_uuids: List of faulty nodes
1427 da4a52a3 Thomas Thrainer
    @type live_data: dict; instance UUID as key
1428 1c8addc6 Michael Hanselmann
    @param live_data: Per-instance live data
1429 e431074f René Nussbaumer
    @type wrongnode_inst: set
1430 e431074f René Nussbaumer
    @param wrongnode_inst: Set of instances running on wrong node(s)
1431 da4a52a3 Thomas Thrainer
    @type console: dict; instance UUID as key
1432 5d28cb6f Michael Hanselmann
    @param console: Per-instance console information
1433 1c3231aa Thomas Thrainer
    @type nodes: dict; node UUID as key
1434 fab9573b Michael Hanselmann
    @param nodes: Node objects
1435 f98e1175 Dimitris Aragiorgis
    @type networks: dict; net_uuid as key
1436 f98e1175 Dimitris Aragiorgis
    @param networks: Network objects
1437 1c8addc6 Michael Hanselmann

1438 1c8addc6 Michael Hanselmann
    """
1439 1c3231aa Thomas Thrainer
    assert len(set(bad_node_uuids) & set(offline_node_uuids)) == \
1440 1c3231aa Thomas Thrainer
           len(offline_node_uuids), \
1441 1c8addc6 Michael Hanselmann
           "Offline nodes not included in bad nodes"
1442 1c3231aa Thomas Thrainer
    assert not (set(live_data.keys()) & set(bad_node_uuids)), \
1443 1c8addc6 Michael Hanselmann
           "Found live data for bad or offline nodes"
1444 1c8addc6 Michael Hanselmann
1445 1c8addc6 Michael Hanselmann
    self.instances = instances
1446 1c8addc6 Michael Hanselmann
    self.cluster = cluster
1447 1c8addc6 Michael Hanselmann
    self.disk_usage = disk_usage
1448 1c3231aa Thomas Thrainer
    self.offline_nodes = offline_node_uuids
1449 1c3231aa Thomas Thrainer
    self.bad_nodes = bad_node_uuids
1450 1c8addc6 Michael Hanselmann
    self.live_data = live_data
1451 e431074f René Nussbaumer
    self.wrongnode_inst = wrongnode_inst
1452 5d28cb6f Michael Hanselmann
    self.console = console
1453 fab9573b Michael Hanselmann
    self.nodes = nodes
1454 fab9573b Michael Hanselmann
    self.groups = groups
1455 f98e1175 Dimitris Aragiorgis
    self.networks = networks
1456 1c8addc6 Michael Hanselmann
1457 1c8addc6 Michael Hanselmann
    # Used for individual rows
1458 1c8addc6 Michael Hanselmann
    self.inst_hvparams = None
1459 1c8addc6 Michael Hanselmann
    self.inst_beparams = None
1460 7c670076 Michael Hanselmann
    self.inst_osparams = None
1461 1c8addc6 Michael Hanselmann
    self.inst_nicparams = None
1462 1c8addc6 Michael Hanselmann
1463 1c8addc6 Michael Hanselmann
  def __iter__(self):
1464 1c8addc6 Michael Hanselmann
    """Iterate over all instances.
1465 1c8addc6 Michael Hanselmann

1466 1c8addc6 Michael Hanselmann
    This function has side-effects and only one instance of the resulting
1467 1c8addc6 Michael Hanselmann
    generator should be used at a time.
1468 1c8addc6 Michael Hanselmann

1469 1c8addc6 Michael Hanselmann
    """
1470 1c8addc6 Michael Hanselmann
    for inst in self.instances:
1471 1c8addc6 Michael Hanselmann
      self.inst_hvparams = self.cluster.FillHV(inst, skip_globals=True)
1472 1c8addc6 Michael Hanselmann
      self.inst_beparams = self.cluster.FillBE(inst)
1473 7c670076 Michael Hanselmann
      self.inst_osparams = self.cluster.SimpleFillOS(inst.os, inst.osparams)
1474 1c8addc6 Michael Hanselmann
      self.inst_nicparams = [self.cluster.SimpleFillNIC(nic.nicparams)
1475 1c8addc6 Michael Hanselmann
                             for nic in inst.nics]
1476 1c8addc6 Michael Hanselmann
1477 1c8addc6 Michael Hanselmann
      yield inst
1478 1c8addc6 Michael Hanselmann
1479 1c8addc6 Michael Hanselmann
1480 1c8addc6 Michael Hanselmann
def _GetInstOperState(ctx, inst):
1481 1c8addc6 Michael Hanselmann
  """Get instance's operational status.
1482 1c8addc6 Michael Hanselmann

1483 1c8addc6 Michael Hanselmann
  @type ctx: L{InstanceQueryData}
1484 1c8addc6 Michael Hanselmann
  @type inst: L{objects.Instance}
1485 1c8addc6 Michael Hanselmann
  @param inst: Instance object
1486 1c8addc6 Michael Hanselmann

1487 1c8addc6 Michael Hanselmann
  """
1488 cfb084ae René Nussbaumer
  # Can't use RS_OFFLINE here as it would describe the instance to
1489 e2d188cc Iustin Pop
  # be offline when we actually don't know due to missing data
1490 1c8addc6 Michael Hanselmann
  if inst.primary_node in ctx.bad_nodes:
1491 e2d188cc Iustin Pop
    return _FS_NODATA
1492 1c8addc6 Michael Hanselmann
  else:
1493 da4a52a3 Thomas Thrainer
    return bool(ctx.live_data.get(inst.uuid))
1494 1c8addc6 Michael Hanselmann
1495 1c8addc6 Michael Hanselmann
1496 1c8addc6 Michael Hanselmann
def _GetInstLiveData(name):
1497 1c8addc6 Michael Hanselmann
  """Build function for retrieving live data.
1498 1c8addc6 Michael Hanselmann

1499 1c8addc6 Michael Hanselmann
  @type name: string
1500 1c8addc6 Michael Hanselmann
  @param name: Live data field name
1501 1c8addc6 Michael Hanselmann

1502 1c8addc6 Michael Hanselmann
  """
1503 1c8addc6 Michael Hanselmann
  def fn(ctx, inst):
1504 1c8addc6 Michael Hanselmann
    """Get live data for an instance.
1505 1c8addc6 Michael Hanselmann

1506 1c8addc6 Michael Hanselmann
    @type ctx: L{InstanceQueryData}
1507 1c8addc6 Michael Hanselmann
    @type inst: L{objects.Instance}
1508 1c8addc6 Michael Hanselmann
    @param inst: Instance object
1509 1c8addc6 Michael Hanselmann

1510 1c8addc6 Michael Hanselmann
    """
1511 1c8addc6 Michael Hanselmann
    if (inst.primary_node in ctx.bad_nodes or
1512 1c8addc6 Michael Hanselmann
        inst.primary_node in ctx.offline_nodes):
1513 cfb084ae René Nussbaumer
      # Can't use RS_OFFLINE here as it would describe the instance to be
1514 a6070ef7 Michael Hanselmann
      # offline when we actually don't know due to missing data
1515 e2d188cc Iustin Pop
      return _FS_NODATA
1516 1c8addc6 Michael Hanselmann
1517 da4a52a3 Thomas Thrainer
    if inst.uuid in ctx.live_data:
1518 da4a52a3 Thomas Thrainer
      data = ctx.live_data[inst.uuid]
1519 1c8addc6 Michael Hanselmann
      if name in data:
1520 e2d188cc Iustin Pop
        return data[name]
1521 1c8addc6 Michael Hanselmann
1522 e2d188cc Iustin Pop
    return _FS_UNAVAIL
1523 1c8addc6 Michael Hanselmann
1524 1c8addc6 Michael Hanselmann
  return fn
1525 1c8addc6 Michael Hanselmann
1526 1c8addc6 Michael Hanselmann
1527 1c8addc6 Michael Hanselmann
def _GetInstStatus(ctx, inst):
1528 1c8addc6 Michael Hanselmann
  """Get instance status.
1529 1c8addc6 Michael Hanselmann

1530 1c8addc6 Michael Hanselmann
  @type ctx: L{InstanceQueryData}
1531 1c8addc6 Michael Hanselmann
  @type inst: L{objects.Instance}
1532 1c8addc6 Michael Hanselmann
  @param inst: Instance object
1533 1c8addc6 Michael Hanselmann

1534 1c8addc6 Michael Hanselmann
  """
1535 1c8addc6 Michael Hanselmann
  if inst.primary_node in ctx.offline_nodes:
1536 61a980a9 Michael Hanselmann
    return constants.INSTST_NODEOFFLINE
1537 1c8addc6 Michael Hanselmann
1538 1c8addc6 Michael Hanselmann
  if inst.primary_node in ctx.bad_nodes:
1539 61a980a9 Michael Hanselmann
    return constants.INSTST_NODEDOWN
1540 1c8addc6 Michael Hanselmann
1541 9982754c Jose A. Lopes
  instance_live_data = ctx.live_data.get(inst.uuid)
1542 9982754c Jose A. Lopes
1543 9982754c Jose A. Lopes
  if bool(instance_live_data):
1544 9982754c Jose A. Lopes
    instance_state = instance_live_data["state"]
1545 9982754c Jose A. Lopes
1546 da4a52a3 Thomas Thrainer
    if inst.uuid in ctx.wrongnode_inst:
1547 61a980a9 Michael Hanselmann
      return constants.INSTST_WRONGNODE
1548 1c8addc6 Michael Hanselmann
    else:
1549 9982754c Jose A. Lopes
      if hv_base.HvInstanceState.IsShutdown(instance_state):
1550 9982754c Jose A. Lopes
        if inst.admin_state == constants.ADMINST_UP:
1551 9982754c Jose A. Lopes
          return constants.INSTST_USERDOWN
1552 9982754c Jose A. Lopes
        else:
1553 9982754c Jose A. Lopes
          return constants.INSTST_ADMINDOWN
1554 9982754c Jose A. Lopes
      else:
1555 9982754c Jose A. Lopes
        if inst.admin_state == constants.ADMINST_UP:
1556 9982754c Jose A. Lopes
          return constants.INSTST_RUNNING
1557 9982754c Jose A. Lopes
        else:
1558 9982754c Jose A. Lopes
          return constants.INSTST_ERRORUP
1559 1c8addc6 Michael Hanselmann
1560 2e04d454 Agata Murawska
  if inst.admin_state == constants.ADMINST_UP:
1561 61a980a9 Michael Hanselmann
    return constants.INSTST_ERRORDOWN
1562 2e04d454 Agata Murawska
  elif inst.admin_state == constants.ADMINST_DOWN:
1563 2e04d454 Agata Murawska
    return constants.INSTST_ADMINDOWN
1564 1c8addc6 Michael Hanselmann
1565 2e04d454 Agata Murawska
  return constants.INSTST_ADMINOFFLINE
1566 1c8addc6 Michael Hanselmann
1567 1c8addc6 Michael Hanselmann
1568 3fe22abd Christos Stavrakakis
def _GetInstDisk(index, cb):
1569 3fe22abd Christos Stavrakakis
  """Build function for calling another function with an instance Disk.
1570 1c8addc6 Michael Hanselmann

1571 1c8addc6 Michael Hanselmann
  @type index: int
1572 1c8addc6 Michael Hanselmann
  @param index: Disk index
1573 3fe22abd Christos Stavrakakis
  @type cb: callable
1574 3fe22abd Christos Stavrakakis
  @param cb: Callback
1575 1c8addc6 Michael Hanselmann

1576 1c8addc6 Michael Hanselmann
  """
1577 3fe22abd Christos Stavrakakis
  def fn(ctx, inst):
1578 3fe22abd Christos Stavrakakis
    """Call helper function with instance Disk.
1579 1c8addc6 Michael Hanselmann

1580 3fe22abd Christos Stavrakakis
    @type ctx: L{InstanceQueryData}
1581 1c8addc6 Michael Hanselmann
    @type inst: L{objects.Instance}
1582 1c8addc6 Michael Hanselmann
    @param inst: Instance object
1583 1c8addc6 Michael Hanselmann

1584 1c8addc6 Michael Hanselmann
    """
1585 1c8addc6 Michael Hanselmann
    try:
1586 3fe22abd Christos Stavrakakis
      nic = inst.disks[index]
1587 1c8addc6 Michael Hanselmann
    except IndexError:
1588 e2d188cc Iustin Pop
      return _FS_UNAVAIL
1589 1c8addc6 Michael Hanselmann
1590 3fe22abd Christos Stavrakakis
    return cb(ctx, index, nic)
1591 3fe22abd Christos Stavrakakis
1592 1c8addc6 Michael Hanselmann
  return fn
1593 1c8addc6 Michael Hanselmann
1594 1c8addc6 Michael Hanselmann
1595 3fe22abd Christos Stavrakakis
def _GetInstDiskSize(ctx, _, disk): # pylint: disable=W0613
1596 3fe22abd Christos Stavrakakis
  """Get a Disk's size.
1597 3fe22abd Christos Stavrakakis

1598 3fe22abd Christos Stavrakakis
  @type ctx: L{InstanceQueryData}
1599 3fe22abd Christos Stavrakakis
  @type disk: L{objects.Disk}
1600 3fe22abd Christos Stavrakakis
  @param disk: The Disk object
1601 3fe22abd Christos Stavrakakis

1602 3fe22abd Christos Stavrakakis
  """
1603 3fe22abd Christos Stavrakakis
  if disk.size is None:
1604 3fe22abd Christos Stavrakakis
    return _FS_UNAVAIL
1605 3fe22abd Christos Stavrakakis
  else:
1606 3fe22abd Christos Stavrakakis
    return disk.size
1607 3fe22abd Christos Stavrakakis
1608 3fe22abd Christos Stavrakakis
1609 0e514de1 Bernardo Dal Seno
def _GetInstDiskSpindles(ctx, _, disk): # pylint: disable=W0613
1610 0e514de1 Bernardo Dal Seno
  """Get a Disk's spindles.
1611 0e514de1 Bernardo Dal Seno

1612 0e514de1 Bernardo Dal Seno
  @type disk: L{objects.Disk}
1613 0e514de1 Bernardo Dal Seno
  @param disk: The Disk object
1614 0e514de1 Bernardo Dal Seno

1615 0e514de1 Bernardo Dal Seno
  """
1616 0e514de1 Bernardo Dal Seno
  if disk.spindles is None:
1617 0e514de1 Bernardo Dal Seno
    return _FS_UNAVAIL
1618 0e514de1 Bernardo Dal Seno
  else:
1619 0e514de1 Bernardo Dal Seno
    return disk.spindles
1620 0e514de1 Bernardo Dal Seno
1621 0e514de1 Bernardo Dal Seno
1622 3fe22abd Christos Stavrakakis
def _GetInstDeviceName(ctx, _, device): # pylint: disable=W0613
1623 3fe22abd Christos Stavrakakis
  """Get a Device's Name.
1624 3fe22abd Christos Stavrakakis

1625 3fe22abd Christos Stavrakakis
  @type ctx: L{InstanceQueryData}
1626 3fe22abd Christos Stavrakakis
  @type device: L{objects.NIC} or L{objects.Disk}
1627 3fe22abd Christos Stavrakakis
  @param device: The NIC or Disk object
1628 3fe22abd Christos Stavrakakis

1629 3fe22abd Christos Stavrakakis
  """
1630 3fe22abd Christos Stavrakakis
  if device.name is None:
1631 3fe22abd Christos Stavrakakis
    return _FS_UNAVAIL
1632 3fe22abd Christos Stavrakakis
  else:
1633 3fe22abd Christos Stavrakakis
    return device.name
1634 3fe22abd Christos Stavrakakis
1635 3fe22abd Christos Stavrakakis
1636 3fe22abd Christos Stavrakakis
def _GetInstDeviceUUID(ctx, _, device): # pylint: disable=W0613
1637 3fe22abd Christos Stavrakakis
  """Get a Device's UUID.
1638 3fe22abd Christos Stavrakakis

1639 3fe22abd Christos Stavrakakis
  @type ctx: L{InstanceQueryData}
1640 3fe22abd Christos Stavrakakis
  @type device: L{objects.NIC} or L{objects.Disk}
1641 3fe22abd Christos Stavrakakis
  @param device: The NIC or Disk object
1642 3fe22abd Christos Stavrakakis

1643 3fe22abd Christos Stavrakakis
  """
1644 3fe22abd Christos Stavrakakis
  if device.uuid is None:
1645 3fe22abd Christos Stavrakakis
    return _FS_UNAVAIL
1646 3fe22abd Christos Stavrakakis
  else:
1647 3fe22abd Christos Stavrakakis
    return device.uuid
1648 3fe22abd Christos Stavrakakis
1649 3fe22abd Christos Stavrakakis
1650 1c8addc6 Michael Hanselmann
def _GetInstNic(index, cb):
1651 1c8addc6 Michael Hanselmann
  """Build function for calling another function with an instance NIC.
1652 1c8addc6 Michael Hanselmann

1653 1c8addc6 Michael Hanselmann
  @type index: int
1654 1c8addc6 Michael Hanselmann
  @param index: NIC index
1655 1c8addc6 Michael Hanselmann
  @type cb: callable
1656 1c8addc6 Michael Hanselmann
  @param cb: Callback
1657 1c8addc6 Michael Hanselmann

1658 1c8addc6 Michael Hanselmann
  """
1659 1c8addc6 Michael Hanselmann
  def fn(ctx, inst):
1660 1c8addc6 Michael Hanselmann
    """Call helper function with instance NIC.
1661 1c8addc6 Michael Hanselmann

1662 1c8addc6 Michael Hanselmann
    @type ctx: L{InstanceQueryData}
1663 1c8addc6 Michael Hanselmann
    @type inst: L{objects.Instance}
1664 1c8addc6 Michael Hanselmann
    @param inst: Instance object
1665 1c8addc6 Michael Hanselmann

1666 1c8addc6 Michael Hanselmann
    """
1667 1c8addc6 Michael Hanselmann
    try:
1668 1c8addc6 Michael Hanselmann
      nic = inst.nics[index]
1669 1c8addc6 Michael Hanselmann
    except IndexError:
1670 e2d188cc Iustin Pop
      return _FS_UNAVAIL
1671 1c8addc6 Michael Hanselmann
1672 1c8addc6 Michael Hanselmann
    return cb(ctx, index, nic)
1673 1c8addc6 Michael Hanselmann
1674 1c8addc6 Michael Hanselmann
  return fn
1675 1c8addc6 Michael Hanselmann
1676 1c8addc6 Michael Hanselmann
1677 f98e1175 Dimitris Aragiorgis
def _GetInstNicNetworkName(ctx, _, nic): # pylint: disable=W0613
1678 f98e1175 Dimitris Aragiorgis
  """Get a NIC's Network.
1679 f98e1175 Dimitris Aragiorgis

1680 f98e1175 Dimitris Aragiorgis
  @type ctx: L{InstanceQueryData}
1681 f98e1175 Dimitris Aragiorgis
  @type nic: L{objects.NIC}
1682 f98e1175 Dimitris Aragiorgis
  @param nic: NIC object
1683 f98e1175 Dimitris Aragiorgis

1684 f98e1175 Dimitris Aragiorgis
  """
1685 f98e1175 Dimitris Aragiorgis
  if nic.network is None:
1686 f98e1175 Dimitris Aragiorgis
    return _FS_UNAVAIL
1687 f98e1175 Dimitris Aragiorgis
  else:
1688 f98e1175 Dimitris Aragiorgis
    return ctx.networks[nic.network].name
1689 f98e1175 Dimitris Aragiorgis
1690 f98e1175 Dimitris Aragiorgis
1691 d4117a72 Apollon Oikonomopoulos
def _GetInstNicNetwork(ctx, _, nic): # pylint: disable=W0613
1692 d4117a72 Apollon Oikonomopoulos
  """Get a NIC's Network.
1693 d4117a72 Apollon Oikonomopoulos

1694 d4117a72 Apollon Oikonomopoulos
  @type ctx: L{InstanceQueryData}
1695 d4117a72 Apollon Oikonomopoulos
  @type nic: L{objects.NIC}
1696 d4117a72 Apollon Oikonomopoulos
  @param nic: NIC object
1697 d4117a72 Apollon Oikonomopoulos

1698 d4117a72 Apollon Oikonomopoulos
  """
1699 d4117a72 Apollon Oikonomopoulos
  if nic.network is None:
1700 d4117a72 Apollon Oikonomopoulos
    return _FS_UNAVAIL
1701 d4117a72 Apollon Oikonomopoulos
  else:
1702 d4117a72 Apollon Oikonomopoulos
    return nic.network
1703 d4117a72 Apollon Oikonomopoulos
1704 d4117a72 Apollon Oikonomopoulos
1705 b459a848 Andrea Spadaccini
def _GetInstNicIp(ctx, _, nic): # pylint: disable=W0613
1706 1c8addc6 Michael Hanselmann
  """Get a NIC's IP address.
1707 1c8addc6 Michael Hanselmann

1708 1c8addc6 Michael Hanselmann
  @type ctx: L{InstanceQueryData}
1709 1c8addc6 Michael Hanselmann
  @type nic: L{objects.NIC}
1710 1c8addc6 Michael Hanselmann
  @param nic: NIC object
1711 1c8addc6 Michael Hanselmann

1712 1c8addc6 Michael Hanselmann
  """
1713 1c8addc6 Michael Hanselmann
  if nic.ip is None:
1714 e2d188cc Iustin Pop
    return _FS_UNAVAIL
1715 1c8addc6 Michael Hanselmann
  else:
1716 e2d188cc Iustin Pop
    return nic.ip
1717 1c8addc6 Michael Hanselmann
1718 1c8addc6 Michael Hanselmann
1719 1c8addc6 Michael Hanselmann
def _GetInstNicBridge(ctx, index, _):
1720 1c8addc6 Michael Hanselmann
  """Get a NIC's bridge.
1721 1c8addc6 Michael Hanselmann

1722 1c8addc6 Michael Hanselmann
  @type ctx: L{InstanceQueryData}
1723 1c8addc6 Michael Hanselmann
  @type index: int
1724 1c8addc6 Michael Hanselmann
  @param index: NIC index
1725 1c8addc6 Michael Hanselmann

1726 1c8addc6 Michael Hanselmann
  """
1727 1c8addc6 Michael Hanselmann
  assert len(ctx.inst_nicparams) >= index
1728 1c8addc6 Michael Hanselmann
1729 1c8addc6 Michael Hanselmann
  nicparams = ctx.inst_nicparams[index]
1730 1c8addc6 Michael Hanselmann
1731 1c8addc6 Michael Hanselmann
  if nicparams[constants.NIC_MODE] == constants.NIC_MODE_BRIDGED:
1732 e2d188cc Iustin Pop
    return nicparams[constants.NIC_LINK]
1733 1c8addc6 Michael Hanselmann
  else:
1734 e2d188cc Iustin Pop
    return _FS_UNAVAIL
1735 1c8addc6 Michael Hanselmann
1736 1c8addc6 Michael Hanselmann
1737 9a03cffb Thomas Thrainer
def _GetInstNicVLan(ctx, index, _):
1738 9a03cffb Thomas Thrainer
  """Get a NIC's VLAN.
1739 9a03cffb Thomas Thrainer

1740 9a03cffb Thomas Thrainer
  @type ctx: L{InstanceQueryData}
1741 9a03cffb Thomas Thrainer
  @type index: int
1742 9a03cffb Thomas Thrainer
  @param index: NIC index
1743 9a03cffb Thomas Thrainer

1744 9a03cffb Thomas Thrainer
  """
1745 9a03cffb Thomas Thrainer
  assert len(ctx.inst_nicparams) >= index
1746 9a03cffb Thomas Thrainer
1747 9a03cffb Thomas Thrainer
  nicparams = ctx.inst_nicparams[index]
1748 9a03cffb Thomas Thrainer
1749 9a03cffb Thomas Thrainer
  if nicparams[constants.NIC_MODE] == constants.NIC_MODE_OVS:
1750 9a03cffb Thomas Thrainer
    return nicparams[constants.NIC_VLAN]
1751 9a03cffb Thomas Thrainer
  else:
1752 9a03cffb Thomas Thrainer
    return _FS_UNAVAIL
1753 9a03cffb Thomas Thrainer
1754 9a03cffb Thomas Thrainer
1755 f98e1175 Dimitris Aragiorgis
def _GetInstAllNicNetworkNames(ctx, inst):
1756 f98e1175 Dimitris Aragiorgis
  """Get all network names for an instance.
1757 f98e1175 Dimitris Aragiorgis

1758 f98e1175 Dimitris Aragiorgis
  @type ctx: L{InstanceQueryData}
1759 f98e1175 Dimitris Aragiorgis
  @type inst: L{objects.Instance}
1760 f98e1175 Dimitris Aragiorgis
  @param inst: Instance object
1761 f98e1175 Dimitris Aragiorgis

1762 f98e1175 Dimitris Aragiorgis
  """
1763 f98e1175 Dimitris Aragiorgis
  result = []
1764 f98e1175 Dimitris Aragiorgis
1765 f98e1175 Dimitris Aragiorgis
  for nic in inst.nics:
1766 f98e1175 Dimitris Aragiorgis
    name = None
1767 f98e1175 Dimitris Aragiorgis
    if nic.network:
1768 f98e1175 Dimitris Aragiorgis
      name = ctx.networks[nic.network].name
1769 f98e1175 Dimitris Aragiorgis
    result.append(name)
1770 f98e1175 Dimitris Aragiorgis
1771 f98e1175 Dimitris Aragiorgis
  assert len(result) == len(inst.nics)
1772 f98e1175 Dimitris Aragiorgis
1773 f98e1175 Dimitris Aragiorgis
  return result
1774 f98e1175 Dimitris Aragiorgis
1775 f98e1175 Dimitris Aragiorgis
1776 1c8addc6 Michael Hanselmann
def _GetInstAllNicBridges(ctx, inst):
1777 1c8addc6 Michael Hanselmann
  """Get all network bridges for an instance.
1778 1c8addc6 Michael Hanselmann

1779 1c8addc6 Michael Hanselmann
  @type ctx: L{InstanceQueryData}
1780 1c8addc6 Michael Hanselmann
  @type inst: L{objects.Instance}
1781 1c8addc6 Michael Hanselmann
  @param inst: Instance object
1782 1c8addc6 Michael Hanselmann

1783 1c8addc6 Michael Hanselmann
  """
1784 1c8addc6 Michael Hanselmann
  assert len(ctx.inst_nicparams) == len(inst.nics)
1785 1c8addc6 Michael Hanselmann
1786 1c8addc6 Michael Hanselmann
  result = []
1787 1c8addc6 Michael Hanselmann
1788 1c8addc6 Michael Hanselmann
  for nicp in ctx.inst_nicparams:
1789 1c8addc6 Michael Hanselmann
    if nicp[constants.NIC_MODE] == constants.NIC_MODE_BRIDGED:
1790 1c8addc6 Michael Hanselmann
      result.append(nicp[constants.NIC_LINK])
1791 1c8addc6 Michael Hanselmann
    else:
1792 1c8addc6 Michael Hanselmann
      result.append(None)
1793 1c8addc6 Michael Hanselmann
1794 1c8addc6 Michael Hanselmann
  assert len(result) == len(inst.nics)
1795 1c8addc6 Michael Hanselmann
1796 e2d188cc Iustin Pop
  return result
1797 1c8addc6 Michael Hanselmann
1798 1c8addc6 Michael Hanselmann
1799 1c8addc6 Michael Hanselmann
def _GetInstNicParam(name):
1800 1c8addc6 Michael Hanselmann
  """Build function for retrieving a NIC parameter.
1801 1c8addc6 Michael Hanselmann

1802 1c8addc6 Michael Hanselmann
  @type name: string
1803 1c8addc6 Michael Hanselmann
  @param name: Parameter name
1804 1c8addc6 Michael Hanselmann

1805 1c8addc6 Michael Hanselmann
  """
1806 1c8addc6 Michael Hanselmann
  def fn(ctx, index, _):
1807 1c8addc6 Michael Hanselmann
    """Get a NIC's bridge.
1808 1c8addc6 Michael Hanselmann

1809 1c8addc6 Michael Hanselmann
    @type ctx: L{InstanceQueryData}
1810 1c8addc6 Michael Hanselmann
    @type inst: L{objects.Instance}
1811 1c8addc6 Michael Hanselmann
    @param inst: Instance object
1812 1c8addc6 Michael Hanselmann
    @type nic: L{objects.NIC}
1813 1c8addc6 Michael Hanselmann
    @param nic: NIC object
1814 1c8addc6 Michael Hanselmann

1815 1c8addc6 Michael Hanselmann
    """
1816 1c8addc6 Michael Hanselmann
    assert len(ctx.inst_nicparams) >= index
1817 e2d188cc Iustin Pop
    return ctx.inst_nicparams[index][name]
1818 1c8addc6 Michael Hanselmann
1819 1c8addc6 Michael Hanselmann
  return fn
1820 1c8addc6 Michael Hanselmann
1821 1c8addc6 Michael Hanselmann
1822 1c8addc6 Michael Hanselmann
def _GetInstanceNetworkFields():
1823 1c8addc6 Michael Hanselmann
  """Get instance fields involving network interfaces.
1824 1c8addc6 Michael Hanselmann

1825 4cc4d1fa Michael Hanselmann
  @return: Tuple containing list of field definitions used as input for
1826 4cc4d1fa Michael Hanselmann
    L{_PrepareFieldList} and a list of aliases
1827 1c8addc6 Michael Hanselmann

1828 1c8addc6 Michael Hanselmann
  """
1829 e2d188cc Iustin Pop
  nic_mac_fn = lambda ctx, _, nic: nic.mac
1830 1c8addc6 Michael Hanselmann
  nic_mode_fn = _GetInstNicParam(constants.NIC_MODE)
1831 1c8addc6 Michael Hanselmann
  nic_link_fn = _GetInstNicParam(constants.NIC_LINK)
1832 1c8addc6 Michael Hanselmann
1833 1c8addc6 Michael Hanselmann
  fields = [
1834 1c8addc6 Michael Hanselmann
    # All NICs
1835 79b2ca83 Michael Hanselmann
    (_MakeField("nic.count", "NICs", QFT_NUMBER,
1836 79b2ca83 Michael Hanselmann
                "Number of network interfaces"),
1837 111bf531 Michael Hanselmann
     IQ_CONFIG, 0, lambda ctx, inst: len(inst.nics)),
1838 79b2ca83 Michael Hanselmann
    (_MakeField("nic.macs", "NIC_MACs", QFT_OTHER,
1839 79b2ca83 Michael Hanselmann
                "List containing each network interface's MAC address"),
1840 111bf531 Michael Hanselmann
     IQ_CONFIG, 0, lambda ctx, inst: [nic.mac for nic in inst.nics]),
1841 79b2ca83 Michael Hanselmann
    (_MakeField("nic.ips", "NIC_IPs", QFT_OTHER,
1842 79b2ca83 Michael Hanselmann
                "List containing each network interface's IP address"),
1843 111bf531 Michael Hanselmann
     IQ_CONFIG, 0, lambda ctx, inst: [nic.ip for nic in inst.nics]),
1844 3fe22abd Christos Stavrakakis
    (_MakeField("nic.names", "NIC_Names", QFT_OTHER,
1845 3fe22abd Christos Stavrakakis
                "List containing each network interface's name"),
1846 3fe22abd Christos Stavrakakis
     IQ_CONFIG, 0, lambda ctx, inst: [nic.name for nic in inst.nics]),
1847 3fe22abd Christos Stavrakakis
    (_MakeField("nic.uuids", "NIC_UUIDs", QFT_OTHER,
1848 3fe22abd Christos Stavrakakis
                "List containing each network interface's UUID"),
1849 3fe22abd Christos Stavrakakis
     IQ_CONFIG, 0, lambda ctx, inst: [nic.uuid for nic in inst.nics]),
1850 79b2ca83 Michael Hanselmann
    (_MakeField("nic.modes", "NIC_modes", QFT_OTHER,
1851 111bf531 Michael Hanselmann
                "List containing each network interface's mode"), IQ_CONFIG, 0,
1852 e2d188cc Iustin Pop
     lambda ctx, inst: [nicp[constants.NIC_MODE]
1853 e2d188cc Iustin Pop
                        for nicp in ctx.inst_nicparams]),
1854 79b2ca83 Michael Hanselmann
    (_MakeField("nic.links", "NIC_links", QFT_OTHER,
1855 111bf531 Michael Hanselmann
                "List containing each network interface's link"), IQ_CONFIG, 0,
1856 e2d188cc Iustin Pop
     lambda ctx, inst: [nicp[constants.NIC_LINK]
1857 e2d188cc Iustin Pop
                        for nicp in ctx.inst_nicparams]),
1858 79b2ca83 Michael Hanselmann
    (_MakeField("nic.bridges", "NIC_bridges", QFT_OTHER,
1859 111bf531 Michael Hanselmann
                "List containing each network interface's bridge"),
1860 111bf531 Michael Hanselmann
     IQ_CONFIG, 0, _GetInstAllNicBridges),
1861 d4117a72 Apollon Oikonomopoulos
    (_MakeField("nic.networks", "NIC_networks", QFT_OTHER,
1862 d4117a72 Apollon Oikonomopoulos
                "List containing each interface's network"), IQ_CONFIG, 0,
1863 d4117a72 Apollon Oikonomopoulos
     lambda ctx, inst: [nic.network for nic in inst.nics]),
1864 f98e1175 Dimitris Aragiorgis
    (_MakeField("nic.networks.names", "NIC_networks_names", QFT_OTHER,
1865 f98e1175 Dimitris Aragiorgis
                "List containing each interface's network"),
1866 f98e1175 Dimitris Aragiorgis
     IQ_NETWORKS, 0, _GetInstAllNicNetworkNames)
1867 1c8addc6 Michael Hanselmann
    ]
1868 1c8addc6 Michael Hanselmann
1869 1c8addc6 Michael Hanselmann
  # NICs by number
1870 1c8addc6 Michael Hanselmann
  for i in range(constants.MAX_NICS):
1871 79b2ca83 Michael Hanselmann
    numtext = utils.FormatOrdinal(i + 1)
1872 1c8addc6 Michael Hanselmann
    fields.extend([
1873 79b2ca83 Michael Hanselmann
      (_MakeField("nic.ip/%s" % i, "NicIP/%s" % i, QFT_TEXT,
1874 79b2ca83 Michael Hanselmann
                  "IP address of %s network interface" % numtext),
1875 111bf531 Michael Hanselmann
       IQ_CONFIG, 0, _GetInstNic(i, _GetInstNicIp)),
1876 79b2ca83 Michael Hanselmann
      (_MakeField("nic.mac/%s" % i, "NicMAC/%s" % i, QFT_TEXT,
1877 79b2ca83 Michael Hanselmann
                  "MAC address of %s network interface" % numtext),
1878 111bf531 Michael Hanselmann
       IQ_CONFIG, 0, _GetInstNic(i, nic_mac_fn)),
1879 3fe22abd Christos Stavrakakis
      (_MakeField("nic.name/%s" % i, "NicName/%s" % i, QFT_TEXT,
1880 3fe22abd Christos Stavrakakis
                  "Name address of %s network interface" % numtext),
1881 3fe22abd Christos Stavrakakis
       IQ_CONFIG, 0, _GetInstNic(i, _GetInstDeviceName)),
1882 3fe22abd Christos Stavrakakis
      (_MakeField("nic.uuid/%s" % i, "NicUUID/%s" % i, QFT_TEXT,
1883 3fe22abd Christos Stavrakakis
                  "UUID address of %s network interface" % numtext),
1884 3fe22abd Christos Stavrakakis
       IQ_CONFIG, 0, _GetInstNic(i, _GetInstDeviceUUID)),
1885 79b2ca83 Michael Hanselmann
      (_MakeField("nic.mode/%s" % i, "NicMode/%s" % i, QFT_TEXT,
1886 79b2ca83 Michael Hanselmann
                  "Mode of %s network interface" % numtext),
1887 111bf531 Michael Hanselmann
       IQ_CONFIG, 0, _GetInstNic(i, nic_mode_fn)),
1888 79b2ca83 Michael Hanselmann
      (_MakeField("nic.link/%s" % i, "NicLink/%s" % i, QFT_TEXT,
1889 79b2ca83 Michael Hanselmann
                  "Link of %s network interface" % numtext),
1890 111bf531 Michael Hanselmann
       IQ_CONFIG, 0, _GetInstNic(i, nic_link_fn)),
1891 79b2ca83 Michael Hanselmann
      (_MakeField("nic.bridge/%s" % i, "NicBridge/%s" % i, QFT_TEXT,
1892 79b2ca83 Michael Hanselmann
                  "Bridge of %s network interface" % numtext),
1893 111bf531 Michael Hanselmann
       IQ_CONFIG, 0, _GetInstNic(i, _GetInstNicBridge)),
1894 9a03cffb Thomas Thrainer
      (_MakeField("nic.vlan/%s" % i, "NicVLAN/%s" % i, QFT_TEXT,
1895 9a03cffb Thomas Thrainer
                  "VLAN of %s network interface" % numtext),
1896 9a03cffb Thomas Thrainer
       IQ_CONFIG, 0, _GetInstNic(i, _GetInstNicVLan)),
1897 d4117a72 Apollon Oikonomopoulos
      (_MakeField("nic.network/%s" % i, "NicNetwork/%s" % i, QFT_TEXT,
1898 d4117a72 Apollon Oikonomopoulos
                  "Network of %s network interface" % numtext),
1899 d4117a72 Apollon Oikonomopoulos
       IQ_CONFIG, 0, _GetInstNic(i, _GetInstNicNetwork)),
1900 f98e1175 Dimitris Aragiorgis
      (_MakeField("nic.network.name/%s" % i, "NicNetworkName/%s" % i, QFT_TEXT,
1901 f98e1175 Dimitris Aragiorgis
                  "Network name of %s network interface" % numtext),
1902 f98e1175 Dimitris Aragiorgis
       IQ_NETWORKS, 0, _GetInstNic(i, _GetInstNicNetworkName)),
1903 1c8addc6 Michael Hanselmann
      ])
1904 1c8addc6 Michael Hanselmann
1905 4cc4d1fa Michael Hanselmann
  aliases = [
1906 4cc4d1fa Michael Hanselmann
    # Legacy fields for first NIC
1907 4cc4d1fa Michael Hanselmann
    ("ip", "nic.ip/0"),
1908 4cc4d1fa Michael Hanselmann
    ("mac", "nic.mac/0"),
1909 4cc4d1fa Michael Hanselmann
    ("bridge", "nic.bridge/0"),
1910 4cc4d1fa Michael Hanselmann
    ("nic_mode", "nic.mode/0"),
1911 4cc4d1fa Michael Hanselmann
    ("nic_link", "nic.link/0"),
1912 d4117a72 Apollon Oikonomopoulos
    ("nic_network", "nic.network/0"),
1913 4cc4d1fa Michael Hanselmann
    ]
1914 4cc4d1fa Michael Hanselmann
1915 4cc4d1fa Michael Hanselmann
  return (fields, aliases)
1916 1c8addc6 Michael Hanselmann
1917 1c8addc6 Michael Hanselmann
1918 1c8addc6 Michael Hanselmann
def _GetInstDiskUsage(ctx, inst):
1919 1c8addc6 Michael Hanselmann
  """Get disk usage for an instance.
1920 1c8addc6 Michael Hanselmann

1921 1c8addc6 Michael Hanselmann
  @type ctx: L{InstanceQueryData}
1922 1c8addc6 Michael Hanselmann
  @type inst: L{objects.Instance}
1923 1c8addc6 Michael Hanselmann
  @param inst: Instance object
1924 1c8addc6 Michael Hanselmann

1925 1c8addc6 Michael Hanselmann
  """
1926 da4a52a3 Thomas Thrainer
  usage = ctx.disk_usage[inst.uuid]
1927 1c8addc6 Michael Hanselmann
1928 1c8addc6 Michael Hanselmann
  if usage is None:
1929 1c8addc6 Michael Hanselmann
    usage = 0
1930 1c8addc6 Michael Hanselmann
1931 e2d188cc Iustin Pop
  return usage
1932 1c8addc6 Michael Hanselmann
1933 1c8addc6 Michael Hanselmann
1934 5d28cb6f Michael Hanselmann
def _GetInstanceConsole(ctx, inst):
1935 5d28cb6f Michael Hanselmann
  """Get console information for instance.
1936 5d28cb6f Michael Hanselmann

1937 5d28cb6f Michael Hanselmann
  @type ctx: L{InstanceQueryData}
1938 5d28cb6f Michael Hanselmann
  @type inst: L{objects.Instance}
1939 5d28cb6f Michael Hanselmann
  @param inst: Instance object
1940 5d28cb6f Michael Hanselmann

1941 5d28cb6f Michael Hanselmann
  """
1942 da4a52a3 Thomas Thrainer
  consinfo = ctx.console[inst.uuid]
1943 5d28cb6f Michael Hanselmann
1944 5d28cb6f Michael Hanselmann
  if consinfo is None:
1945 5d28cb6f Michael Hanselmann
    return _FS_UNAVAIL
1946 5d28cb6f Michael Hanselmann
1947 5d28cb6f Michael Hanselmann
  return consinfo
1948 5d28cb6f Michael Hanselmann
1949 5d28cb6f Michael Hanselmann
1950 1c8addc6 Michael Hanselmann
def _GetInstanceDiskFields():
1951 1c8addc6 Michael Hanselmann
  """Get instance fields involving disks.
1952 1c8addc6 Michael Hanselmann

1953 1c8addc6 Michael Hanselmann
  @return: List of field definitions used as input for L{_PrepareFieldList}
1954 1c8addc6 Michael Hanselmann

1955 1c8addc6 Michael Hanselmann
  """
1956 1c8addc6 Michael Hanselmann
  fields = [
1957 79b2ca83 Michael Hanselmann
    (_MakeField("disk_usage", "DiskUsage", QFT_UNIT,
1958 79b2ca83 Michael Hanselmann
                "Total disk space used by instance on each of its nodes;"
1959 79b2ca83 Michael Hanselmann
                " this is not the disk size visible to the instance, but"
1960 79b2ca83 Michael Hanselmann
                " the usage on the node"),
1961 111bf531 Michael Hanselmann
     IQ_DISKUSAGE, 0, _GetInstDiskUsage),
1962 79b2ca83 Michael Hanselmann
    (_MakeField("disk.count", "Disks", QFT_NUMBER, "Number of disks"),
1963 111bf531 Michael Hanselmann
     IQ_CONFIG, 0, lambda ctx, inst: len(inst.disks)),
1964 79b2ca83 Michael Hanselmann
    (_MakeField("disk.sizes", "Disk_sizes", QFT_OTHER, "List of disk sizes"),
1965 111bf531 Michael Hanselmann
     IQ_CONFIG, 0, lambda ctx, inst: [disk.size for disk in inst.disks]),
1966 0e514de1 Bernardo Dal Seno
    (_MakeField("disk.spindles", "Disk_spindles", QFT_OTHER,
1967 0e514de1 Bernardo Dal Seno
                "List of disk spindles"),
1968 0e514de1 Bernardo Dal Seno
     IQ_CONFIG, 0, lambda ctx, inst: [disk.spindles for disk in inst.disks]),
1969 3fe22abd Christos Stavrakakis
    (_MakeField("disk.names", "Disk_names", QFT_OTHER, "List of disk names"),
1970 3fe22abd Christos Stavrakakis
     IQ_CONFIG, 0, lambda ctx, inst: [disk.name for disk in inst.disks]),
1971 3fe22abd Christos Stavrakakis
    (_MakeField("disk.uuids", "Disk_UUIDs", QFT_OTHER, "List of disk UUIDs"),
1972 3fe22abd Christos Stavrakakis
     IQ_CONFIG, 0, lambda ctx, inst: [disk.uuid for disk in inst.disks]),
1973 1c8addc6 Michael Hanselmann
    ]
1974 1c8addc6 Michael Hanselmann
1975 1c8addc6 Michael Hanselmann
  # Disks by number
1976 3fe22abd Christos Stavrakakis
  for i in range(constants.MAX_DISKS):
1977 3fe22abd Christos Stavrakakis
    numtext = utils.FormatOrdinal(i + 1)
1978 3fe22abd Christos Stavrakakis
    fields.extend([
1979 3fe22abd Christos Stavrakakis
        (_MakeField("disk.size/%s" % i, "Disk/%s" % i, QFT_UNIT,
1980 3fe22abd Christos Stavrakakis
                    "Disk size of %s disk" % numtext),
1981 e0e44476 Michele Tartara
         IQ_CONFIG, 0, _GetInstDisk(i, _GetInstDiskSize)),
1982 0e514de1 Bernardo Dal Seno
        (_MakeField("disk.spindles/%s" % i, "DiskSpindles/%s" % i, QFT_NUMBER,
1983 0e514de1 Bernardo Dal Seno
                    "Spindles of %s disk" % numtext),
1984 0e514de1 Bernardo Dal Seno
         IQ_CONFIG, 0, _GetInstDisk(i, _GetInstDiskSpindles)),
1985 3fe22abd Christos Stavrakakis
        (_MakeField("disk.name/%s" % i, "DiskName/%s" % i, QFT_TEXT,
1986 3fe22abd Christos Stavrakakis
                    "Name of %s disk" % numtext),
1987 e0e44476 Michele Tartara
         IQ_CONFIG, 0, _GetInstDisk(i, _GetInstDeviceName)),
1988 3fe22abd Christos Stavrakakis
        (_MakeField("disk.uuid/%s" % i, "DiskUUID/%s" % i, QFT_TEXT,
1989 3fe22abd Christos Stavrakakis
                    "UUID of %s disk" % numtext),
1990 e0e44476 Michele Tartara
         IQ_CONFIG, 0, _GetInstDisk(i, _GetInstDeviceUUID))])
1991 1c8addc6 Michael Hanselmann
1992 1c8addc6 Michael Hanselmann
  return fields
1993 1c8addc6 Michael Hanselmann
1994 1c8addc6 Michael Hanselmann
1995 1c8addc6 Michael Hanselmann
def _GetInstanceParameterFields():
1996 1c8addc6 Michael Hanselmann
  """Get instance fields involving parameters.
1997 1c8addc6 Michael Hanselmann

1998 1c8addc6 Michael Hanselmann
  @return: List of field definitions used as input for L{_PrepareFieldList}
1999 1c8addc6 Michael Hanselmann

2000 1c8addc6 Michael Hanselmann
  """
2001 1c8addc6 Michael Hanselmann
  fields = [
2002 1c8addc6 Michael Hanselmann
    # Filled parameters
2003 79b2ca83 Michael Hanselmann
    (_MakeField("hvparams", "HypervisorParameters", QFT_OTHER,
2004 7c670076 Michael Hanselmann
                "Hypervisor parameters (merged)"),
2005 111bf531 Michael Hanselmann
     IQ_CONFIG, 0, lambda ctx, _: ctx.inst_hvparams),
2006 79b2ca83 Michael Hanselmann
    (_MakeField("beparams", "BackendParameters", QFT_OTHER,
2007 7c670076 Michael Hanselmann
                "Backend parameters (merged)"),
2008 111bf531 Michael Hanselmann
     IQ_CONFIG, 0, lambda ctx, _: ctx.inst_beparams),
2009 7c670076 Michael Hanselmann
    (_MakeField("osparams", "OpSysParameters", QFT_OTHER,
2010 7c670076 Michael Hanselmann
                "Operating system parameters (merged)"),
2011 7c670076 Michael Hanselmann
     IQ_CONFIG, 0, lambda ctx, _: ctx.inst_osparams),
2012 1c8addc6 Michael Hanselmann
2013 1c8addc6 Michael Hanselmann
    # Unfilled parameters
2014 79b2ca83 Michael Hanselmann
    (_MakeField("custom_hvparams", "CustomHypervisorParameters", QFT_OTHER,
2015 79b2ca83 Michael Hanselmann
                "Custom hypervisor parameters"),
2016 111bf531 Michael Hanselmann
     IQ_CONFIG, 0, _GetItemAttr("hvparams")),
2017 79b2ca83 Michael Hanselmann
    (_MakeField("custom_beparams", "CustomBackendParameters", QFT_OTHER,
2018 79b2ca83 Michael Hanselmann
                "Custom backend parameters",),
2019 111bf531 Michael Hanselmann
     IQ_CONFIG, 0, _GetItemAttr("beparams")),
2020 7c670076 Michael Hanselmann
    (_MakeField("custom_osparams", "CustomOpSysParameters", QFT_OTHER,
2021 7c670076 Michael Hanselmann
                "Custom operating system parameters",),
2022 7c670076 Michael Hanselmann
     IQ_CONFIG, 0, _GetItemAttr("osparams")),
2023 79b2ca83 Michael Hanselmann
    (_MakeField("custom_nicparams", "CustomNicParameters", QFT_OTHER,
2024 79b2ca83 Michael Hanselmann
                "Custom network interface parameters"),
2025 111bf531 Michael Hanselmann
     IQ_CONFIG, 0, lambda ctx, inst: [nic.nicparams for nic in inst.nics]),
2026 1c8addc6 Michael Hanselmann
    ]
2027 1c8addc6 Michael Hanselmann
2028 1c8addc6 Michael Hanselmann
  # HV params
2029 1c8addc6 Michael Hanselmann
  def _GetInstHvParam(name):
2030 ff4cd4d2 Iustin Pop
    return lambda ctx, _: ctx.inst_hvparams.get(name, _FS_UNAVAIL)
2031 1c8addc6 Michael Hanselmann
2032 1c8addc6 Michael Hanselmann
  fields.extend([
2033 a6c7e2a2 Iustin Pop
    (_MakeField("hv/%s" % name,
2034 a6c7e2a2 Iustin Pop
                constants.HVS_PARAMETER_TITLES.get(name, "hv/%s" % name),
2035 79b2ca83 Michael Hanselmann
                _VTToQFT[kind], "The \"%s\" hypervisor parameter" % name),
2036 111bf531 Michael Hanselmann
     IQ_CONFIG, 0, _GetInstHvParam(name))
2037 af58707c Iustin Pop
    for name, kind in constants.HVS_PARAMETER_TYPES.items()
2038 3c286190 Dimitris Aragiorgis
    if name not in constants.HVC_GLOBALS])
2039 1c8addc6 Michael Hanselmann
2040 1c8addc6 Michael Hanselmann
  # BE params
2041 1c8addc6 Michael Hanselmann
  def _GetInstBeParam(name):
2042 e2d188cc Iustin Pop
    return lambda ctx, _: ctx.inst_beparams.get(name, None)
2043 1c8addc6 Michael Hanselmann
2044 1c8addc6 Michael Hanselmann
  fields.extend([
2045 a6c7e2a2 Iustin Pop
    (_MakeField("be/%s" % name,
2046 a6c7e2a2 Iustin Pop
                constants.BES_PARAMETER_TITLES.get(name, "be/%s" % name),
2047 79b2ca83 Michael Hanselmann
                _VTToQFT[kind], "The \"%s\" backend parameter" % name),
2048 111bf531 Michael Hanselmann
     IQ_CONFIG, 0, _GetInstBeParam(name))
2049 3c286190 Dimitris Aragiorgis
    for name, kind in constants.BES_PARAMETER_TYPES.items()])
2050 1c8addc6 Michael Hanselmann
2051 1c8addc6 Michael Hanselmann
  return fields
2052 1c8addc6 Michael Hanselmann
2053 1c8addc6 Michael Hanselmann
2054 1c8addc6 Michael Hanselmann
_INST_SIMPLE_FIELDS = {
2055 111bf531 Michael Hanselmann
  "disk_template": ("Disk_template", QFT_TEXT, 0, "Instance disk template"),
2056 111bf531 Michael Hanselmann
  "hypervisor": ("Hypervisor", QFT_TEXT, 0, "Hypervisor name"),
2057 111bf531 Michael Hanselmann
  "name": ("Instance", QFT_TEXT, QFF_HOSTNAME, "Instance name"),
2058 1c8addc6 Michael Hanselmann
  # Depending on the hypervisor, the port can be None
2059 111bf531 Michael Hanselmann
  "network_port": ("Network_port", QFT_OTHER, 0,
2060 79b2ca83 Michael Hanselmann
                   "Instance network port if available (e.g. for VNC console)"),
2061 111bf531 Michael Hanselmann
  "os": ("OS", QFT_TEXT, 0, "Operating system"),
2062 111bf531 Michael Hanselmann
  "serial_no": ("SerialNo", QFT_NUMBER, 0, _SERIAL_NO_DOC % "Instance"),
2063 111bf531 Michael Hanselmann
  "uuid": ("UUID", QFT_TEXT, 0, "Instance UUID"),
2064 1c8addc6 Michael Hanselmann
  }
2065 1c8addc6 Michael Hanselmann
2066 1c8addc6 Michael Hanselmann
2067 1c3231aa Thomas Thrainer
def _GetNodeName(ctx, default, node_uuid):
2068 1c3231aa Thomas Thrainer
  """Gets node name of a node.
2069 1c3231aa Thomas Thrainer

2070 1c3231aa Thomas Thrainer
  @type ctx: L{InstanceQueryData}
2071 1c3231aa Thomas Thrainer
  @param default: Default value
2072 1c3231aa Thomas Thrainer
  @type node_uuid: string
2073 1c3231aa Thomas Thrainer
  @param node_uuid: Node UUID
2074 1c3231aa Thomas Thrainer

2075 1c3231aa Thomas Thrainer
  """
2076 1c3231aa Thomas Thrainer
  try:
2077 1c3231aa Thomas Thrainer
    node = ctx.nodes[node_uuid]
2078 1c3231aa Thomas Thrainer
  except KeyError:
2079 1c3231aa Thomas Thrainer
    return default
2080 1c3231aa Thomas Thrainer
  else:
2081 1c3231aa Thomas Thrainer
    return node.name
2082 1c3231aa Thomas Thrainer
2083 1c3231aa Thomas Thrainer
2084 1c3231aa Thomas Thrainer
def _GetInstNodeGroup(ctx, default, node_uuid):
2085 fab9573b Michael Hanselmann
  """Gets group UUID of an instance node.
2086 fab9573b Michael Hanselmann

2087 fab9573b Michael Hanselmann
  @type ctx: L{InstanceQueryData}
2088 fab9573b Michael Hanselmann
  @param default: Default value
2089 1c3231aa Thomas Thrainer
  @type node_uuid: string
2090 1c3231aa Thomas Thrainer
  @param node_uuid: Node UUID
2091 fab9573b Michael Hanselmann

2092 fab9573b Michael Hanselmann
  """
2093 fab9573b Michael Hanselmann
  try:
2094 1c3231aa Thomas Thrainer
    node = ctx.nodes[node_uuid]
2095 fab9573b Michael Hanselmann
  except KeyError:
2096 fab9573b Michael Hanselmann
    return default
2097 fab9573b Michael Hanselmann
  else:
2098 fab9573b Michael Hanselmann
    return node.group
2099 fab9573b Michael Hanselmann
2100 fab9573b Michael Hanselmann
2101 1c3231aa Thomas Thrainer
def _GetInstNodeGroupName(ctx, default, node_uuid):
2102 fab9573b Michael Hanselmann
  """Gets group name of an instance node.
2103 fab9573b Michael Hanselmann

2104 fab9573b Michael Hanselmann
  @type ctx: L{InstanceQueryData}
2105 fab9573b Michael Hanselmann
  @param default: Default value
2106 1c3231aa Thomas Thrainer
  @type node_uuid: string
2107 1c3231aa Thomas Thrainer
  @param node_uuid: Node UUID
2108 fab9573b Michael Hanselmann

2109 fab9573b Michael Hanselmann
  """
2110 fab9573b Michael Hanselmann
  try:
2111 1c3231aa Thomas Thrainer
    node = ctx.nodes[node_uuid]
2112 fab9573b Michael Hanselmann
  except KeyError:
2113 fab9573b Michael Hanselmann
    return default
2114 fab9573b Michael Hanselmann
2115 fab9573b Michael Hanselmann
  try:
2116 fab9573b Michael Hanselmann
    group = ctx.groups[node.group]
2117 fab9573b Michael Hanselmann
  except KeyError:
2118 fab9573b Michael Hanselmann
    return default
2119 fab9573b Michael Hanselmann
2120 fab9573b Michael Hanselmann
  return group.name
2121 fab9573b Michael Hanselmann
2122 fab9573b Michael Hanselmann
2123 1c8addc6 Michael Hanselmann
def _BuildInstanceFields():
2124 1c8addc6 Michael Hanselmann
  """Builds list of fields for instance queries.
2125 1c8addc6 Michael Hanselmann

2126 1c8addc6 Michael Hanselmann
  """
2127 1c8addc6 Michael Hanselmann
  fields = [
2128 111bf531 Michael Hanselmann
    (_MakeField("pnode", "Primary_node", QFT_TEXT, "Primary node"),
2129 1c3231aa Thomas Thrainer
     IQ_NODES, QFF_HOSTNAME,
2130 1c3231aa Thomas Thrainer
     lambda ctx, inst: _GetNodeName(ctx, None, inst.primary_node)),
2131 fab9573b Michael Hanselmann
    (_MakeField("pnode.group", "PrimaryNodeGroup", QFT_TEXT,
2132 fab9573b Michael Hanselmann
                "Primary node's group"),
2133 fab9573b Michael Hanselmann
     IQ_NODES, 0,
2134 fab9573b Michael Hanselmann
     lambda ctx, inst: _GetInstNodeGroupName(ctx, _FS_UNAVAIL,
2135 fab9573b Michael Hanselmann
                                             inst.primary_node)),
2136 fab9573b Michael Hanselmann
    (_MakeField("pnode.group.uuid", "PrimaryNodeGroupUUID", QFT_TEXT,
2137 fab9573b Michael Hanselmann
                "Primary node's group UUID"),
2138 fab9573b Michael Hanselmann
     IQ_NODES, 0,
2139 fab9573b Michael Hanselmann
     lambda ctx, inst: _GetInstNodeGroup(ctx, _FS_UNAVAIL, inst.primary_node)),
2140 111bf531 Michael Hanselmann
    # TODO: Allow filtering by secondary node as hostname
2141 79b2ca83 Michael Hanselmann
    (_MakeField("snodes", "Secondary_Nodes", QFT_OTHER,
2142 79b2ca83 Michael Hanselmann
                "Secondary nodes; usually this will just be one node"),
2143 1c3231aa Thomas Thrainer
     IQ_NODES, 0,
2144 1c3231aa Thomas Thrainer
     lambda ctx, inst: map(compat.partial(_GetNodeName, ctx, None),
2145 1c3231aa Thomas Thrainer
                           inst.secondary_nodes)),
2146 fab9573b Michael Hanselmann
    (_MakeField("snodes.group", "SecondaryNodesGroups", QFT_OTHER,
2147 fab9573b Michael Hanselmann
                "Node groups of secondary nodes"),
2148 fab9573b Michael Hanselmann
     IQ_NODES, 0,
2149 fab9573b Michael Hanselmann
     lambda ctx, inst: map(compat.partial(_GetInstNodeGroupName, ctx, None),
2150 fab9573b Michael Hanselmann
                           inst.secondary_nodes)),
2151 fab9573b Michael Hanselmann
    (_MakeField("snodes.group.uuid", "SecondaryNodesGroupsUUID", QFT_OTHER,
2152 fab9573b Michael Hanselmann
                "Node group UUIDs of secondary nodes"),
2153 fab9573b Michael Hanselmann
     IQ_NODES, 0,
2154 fab9573b Michael Hanselmann
     lambda ctx, inst: map(compat.partial(_GetInstNodeGroup, ctx, None),
2155 fab9573b Michael Hanselmann
                           inst.secondary_nodes)),
2156 2e04d454 Agata Murawska
    (_MakeField("admin_state", "InstanceState", QFT_TEXT,
2157 2e04d454 Agata Murawska
                "Desired state of instance"),
2158 9ca8a7c5 Agata Murawska
     IQ_CONFIG, 0, _GetItemAttr("admin_state")),
2159 754cc530 Agata Murawska
    (_MakeField("admin_up", "Autostart", QFT_BOOL,
2160 754cc530 Agata Murawska
                "Desired state of instance"),
2161 754cc530 Agata Murawska
     IQ_CONFIG, 0, lambda ctx, inst: inst.admin_state == constants.ADMINST_UP),
2162 ca83454f Thomas Thrainer
    (_MakeField("disks_active", "DisksActive", QFT_BOOL,
2163 ca83454f Thomas Thrainer
                "Desired state of instance disks"),
2164 ca83454f Thomas Thrainer
     IQ_CONFIG, 0, _GetItemAttr("disks_active")),
2165 111bf531 Michael Hanselmann
    (_MakeField("tags", "Tags", QFT_OTHER, "Tags"), IQ_CONFIG, 0,
2166 e2d188cc Iustin Pop
     lambda ctx, inst: list(inst.GetTags())),
2167 79b2ca83 Michael Hanselmann
    (_MakeField("console", "Console", QFT_OTHER,
2168 111bf531 Michael Hanselmann
                "Instance console information"), IQ_CONSOLE, 0,
2169 5d28cb6f Michael Hanselmann
     _GetInstanceConsole),
2170 1c8addc6 Michael Hanselmann
    ]
2171 1c8addc6 Michael Hanselmann
2172 1c8addc6 Michael Hanselmann
  # Add simple fields
2173 111bf531 Michael Hanselmann
  fields.extend([
2174 111bf531 Michael Hanselmann
    (_MakeField(name, title, kind, doc), IQ_CONFIG, flags, _GetItemAttr(name))
2175 3c286190 Dimitris Aragiorgis
    for (name, (title, kind, flags, doc)) in _INST_SIMPLE_FIELDS.items()])
2176 1c8addc6 Michael Hanselmann
2177 1c8addc6 Michael Hanselmann
  # Fields requiring talking to the node
2178 1c8addc6 Michael Hanselmann
  fields.extend([
2179 79b2ca83 Michael Hanselmann
    (_MakeField("oper_state", "Running", QFT_BOOL, "Actual state of instance"),
2180 111bf531 Michael Hanselmann
     IQ_LIVE, 0, _GetInstOperState),
2181 79b2ca83 Michael Hanselmann
    (_MakeField("oper_ram", "Memory", QFT_UNIT,
2182 79b2ca83 Michael Hanselmann
                "Actual memory usage as seen by hypervisor"),
2183 111bf531 Michael Hanselmann
     IQ_LIVE, 0, _GetInstLiveData("memory")),
2184 79b2ca83 Michael Hanselmann
    (_MakeField("oper_vcpus", "VCPUs", QFT_NUMBER,
2185 79b2ca83 Michael Hanselmann
                "Actual number of VCPUs as seen by hypervisor"),
2186 111bf531 Michael Hanselmann
     IQ_LIVE, 0, _GetInstLiveData("vcpus")),
2187 1c8addc6 Michael Hanselmann
    ])
2188 1c8addc6 Michael Hanselmann
2189 79b2ca83 Michael Hanselmann
  # Status field
2190 79b2ca83 Michael Hanselmann
  status_values = (constants.INSTST_RUNNING, constants.INSTST_ADMINDOWN,
2191 79b2ca83 Michael Hanselmann
                   constants.INSTST_WRONGNODE, constants.INSTST_ERRORUP,
2192 79b2ca83 Michael Hanselmann
                   constants.INSTST_ERRORDOWN, constants.INSTST_NODEDOWN,
2193 9982754c Jose A. Lopes
                   constants.INSTST_NODEOFFLINE, constants.INSTST_ADMINOFFLINE,
2194 9982754c Jose A. Lopes
                   constants.INSTST_USERDOWN)
2195 79b2ca83 Michael Hanselmann
  status_doc = ("Instance status; \"%s\" if instance is set to be running"
2196 79b2ca83 Michael Hanselmann
                " and actually is, \"%s\" if instance is stopped and"
2197 79b2ca83 Michael Hanselmann
                " is not running, \"%s\" if instance running, but not on its"
2198 79b2ca83 Michael Hanselmann
                " designated primary node, \"%s\" if instance should be"
2199 79b2ca83 Michael Hanselmann
                " stopped, but is actually running, \"%s\" if instance should"
2200 79b2ca83 Michael Hanselmann
                " run, but doesn't, \"%s\" if instance's primary node is down,"
2201 2e04d454 Agata Murawska
                " \"%s\" if instance's primary node is marked offline,"
2202 9982754c Jose A. Lopes
                " \"%s\" if instance is offline and does not use dynamic,"
2203 9982754c Jose A. Lopes
                " \"%s\" if the user shutdown the instance"
2204 2e04d454 Agata Murawska
                " resources" % status_values)
2205 79b2ca83 Michael Hanselmann
  fields.append((_MakeField("status", "Status", QFT_TEXT, status_doc),
2206 111bf531 Michael Hanselmann
                 IQ_LIVE, 0, _GetInstStatus))
2207 9982754c Jose A. Lopes
2208 79b2ca83 Michael Hanselmann
  assert set(status_values) == constants.INSTST_ALL, \
2209 79b2ca83 Michael Hanselmann
         "Status documentation mismatch"
2210 79b2ca83 Michael Hanselmann
2211 4cc4d1fa Michael Hanselmann
  (network_fields, network_aliases) = _GetInstanceNetworkFields()
2212 4cc4d1fa Michael Hanselmann
2213 4cc4d1fa Michael Hanselmann
  fields.extend(network_fields)
2214 1c8addc6 Michael Hanselmann
  fields.extend(_GetInstanceParameterFields())
2215 1c8addc6 Michael Hanselmann
  fields.extend(_GetInstanceDiskFields())
2216 145bea54 Michael Hanselmann
  fields.extend(_GetItemTimestampFields(IQ_CONFIG))
2217 1c8addc6 Michael Hanselmann
2218 e7e8037b Iustin Pop
  aliases = [
2219 e7e8037b Iustin Pop
    ("vcpus", "be/vcpus"),
2220 31d1791a Guido Trotter
    ("be/memory", "be/maxmem"),
2221 e7e8037b Iustin Pop
    ("sda_size", "disk.size/0"),
2222 e7e8037b Iustin Pop
    ("sdb_size", "disk.size/1"),
2223 4cc4d1fa Michael Hanselmann
    ] + network_aliases
2224 e7e8037b Iustin Pop
2225 e7e8037b Iustin Pop
  return _PrepareFieldList(fields, aliases)
2226 1c8addc6 Michael Hanselmann
2227 1c8addc6 Michael Hanselmann
2228 24d16f76 Michael Hanselmann
class LockQueryData:
2229 24d16f76 Michael Hanselmann
  """Data container for lock data queries.
2230 24d16f76 Michael Hanselmann

2231 24d16f76 Michael Hanselmann
  """
2232 24d16f76 Michael Hanselmann
  def __init__(self, lockdata):
2233 24d16f76 Michael Hanselmann
    """Initializes this class.
2234 24d16f76 Michael Hanselmann

2235 24d16f76 Michael Hanselmann
    """
2236 24d16f76 Michael Hanselmann
    self.lockdata = lockdata
2237 24d16f76 Michael Hanselmann
2238 24d16f76 Michael Hanselmann
  def __iter__(self):
2239 24d16f76 Michael Hanselmann
    """Iterate over all locks.
2240 24d16f76 Michael Hanselmann

2241 24d16f76 Michael Hanselmann
    """
2242 24d16f76 Michael Hanselmann
    return iter(self.lockdata)
2243 24d16f76 Michael Hanselmann
2244 24d16f76 Michael Hanselmann
2245 24d16f76 Michael Hanselmann
def _GetLockOwners(_, data):
2246 24d16f76 Michael Hanselmann
  """Returns a sorted list of a lock's current owners.
2247 24d16f76 Michael Hanselmann

2248 24d16f76 Michael Hanselmann
  """
2249 24d16f76 Michael Hanselmann
  (_, _, owners, _) = data
2250 24d16f76 Michael Hanselmann
2251 24d16f76 Michael Hanselmann
  if owners:
2252 24d16f76 Michael Hanselmann
    owners = utils.NiceSort(owners)
2253 24d16f76 Michael Hanselmann
2254 e2d188cc Iustin Pop
  return owners
2255 24d16f76 Michael Hanselmann
2256 24d16f76 Michael Hanselmann
2257 24d16f76 Michael Hanselmann
def _GetLockPending(_, data):
2258 24d16f76 Michael Hanselmann
  """Returns a sorted list of a lock's pending acquires.
2259 24d16f76 Michael Hanselmann

2260 24d16f76 Michael Hanselmann
  """
2261 24d16f76 Michael Hanselmann
  (_, _, _, pending) = data
2262 24d16f76 Michael Hanselmann
2263 24d16f76 Michael Hanselmann
  if pending:
2264 24d16f76 Michael Hanselmann
    pending = [(mode, utils.NiceSort(names))
2265 24d16f76 Michael Hanselmann
               for (mode, names) in pending]
2266 24d16f76 Michael Hanselmann
2267 e2d188cc Iustin Pop
  return pending
2268 24d16f76 Michael Hanselmann
2269 24d16f76 Michael Hanselmann
2270 24d16f76 Michael Hanselmann
def _BuildLockFields():
2271 24d16f76 Michael Hanselmann
  """Builds list of fields for lock queries.
2272 24d16f76 Michael Hanselmann

2273 24d16f76 Michael Hanselmann
  """
2274 24d16f76 Michael Hanselmann
  return _PrepareFieldList([
2275 111bf531 Michael Hanselmann
    # TODO: Lock names are not always hostnames. Should QFF_HOSTNAME be used?
2276 111bf531 Michael Hanselmann
    (_MakeField("name", "Name", QFT_TEXT, "Lock name"), None, 0,
2277 e2d188cc Iustin Pop
     lambda ctx, (name, mode, owners, pending): name),
2278 79b2ca83 Michael Hanselmann
    (_MakeField("mode", "Mode", QFT_OTHER,
2279 79b2ca83 Michael Hanselmann
                "Mode in which the lock is currently acquired"
2280 79b2ca83 Michael Hanselmann
                " (exclusive or shared)"),
2281 111bf531 Michael Hanselmann
     LQ_MODE, 0, lambda ctx, (name, mode, owners, pending): mode),
2282 79b2ca83 Michael Hanselmann
    (_MakeField("owner", "Owner", QFT_OTHER, "Current lock owner(s)"),
2283 111bf531 Michael Hanselmann
     LQ_OWNER, 0, _GetLockOwners),
2284 79b2ca83 Michael Hanselmann
    (_MakeField("pending", "Pending", QFT_OTHER,
2285 79b2ca83 Michael Hanselmann
                "Threads waiting for the lock"),
2286 111bf531 Michael Hanselmann
     LQ_PENDING, 0, _GetLockPending),
2287 d63bd540 Iustin Pop
    ], [])
2288 24d16f76 Michael Hanselmann
2289 24d16f76 Michael Hanselmann
2290 8e21cfc0 Adeodato Simo
class GroupQueryData:
2291 8e21cfc0 Adeodato Simo
  """Data container for node group data queries.
2292 8e21cfc0 Adeodato Simo

2293 8e21cfc0 Adeodato Simo
  """
2294 2c758845 René Nussbaumer
  def __init__(self, cluster, groups, group_to_nodes, group_to_instances,
2295 2c758845 René Nussbaumer
               want_diskparams):
2296 8e21cfc0 Adeodato Simo
    """Initializes this class.
2297 8e21cfc0 Adeodato Simo

2298 edd49f9b Agata Murawska
    @param cluster: Cluster object
2299 8e21cfc0 Adeodato Simo
    @param groups: List of node group objects
2300 8e21cfc0 Adeodato Simo
    @type group_to_nodes: dict; group UUID as key
2301 8e21cfc0 Adeodato Simo
    @param group_to_nodes: Per-group list of nodes
2302 8e21cfc0 Adeodato Simo
    @type group_to_instances: dict; group UUID as key
2303 8e21cfc0 Adeodato Simo
    @param group_to_instances: Per-group list of (primary) instances
2304 2c758845 René Nussbaumer
    @type want_diskparams: bool
2305 2c758845 René Nussbaumer
    @param want_diskparams: Whether diskparamters should be calculated
2306 8e21cfc0 Adeodato Simo

2307 8e21cfc0 Adeodato Simo
    """
2308 8e21cfc0 Adeodato Simo
    self.groups = groups
2309 8e21cfc0 Adeodato Simo
    self.group_to_nodes = group_to_nodes
2310 8e21cfc0 Adeodato Simo
    self.group_to_instances = group_to_instances
2311 edd49f9b Agata Murawska
    self.cluster = cluster
2312 2c758845 René Nussbaumer
    self.want_diskparams = want_diskparams
2313 edd49f9b Agata Murawska
2314 edd49f9b Agata Murawska
    # Used for individual rows
2315 edd49f9b Agata Murawska
    self.group_ipolicy = None
2316 8930b0f0 Iustin Pop
    self.ndparams = None
2317 2c758845 René Nussbaumer
    self.group_dp = None
2318 8e21cfc0 Adeodato Simo
2319 8e21cfc0 Adeodato Simo
  def __iter__(self):
2320 8e21cfc0 Adeodato Simo
    """Iterate over all node groups.
2321 8e21cfc0 Adeodato Simo

2322 edd49f9b Agata Murawska
    This function has side-effects and only one instance of the resulting
2323 edd49f9b Agata Murawska
    generator should be used at a time.
2324 edd49f9b Agata Murawska

2325 8e21cfc0 Adeodato Simo
    """
2326 edd49f9b Agata Murawska
    for group in self.groups:
2327 edd49f9b Agata Murawska
      self.group_ipolicy = self.cluster.SimpleFillIPolicy(group.ipolicy)
2328 8930b0f0 Iustin Pop
      self.ndparams = self.cluster.SimpleFillND(group.ndparams)
2329 2c758845 René Nussbaumer
      if self.want_diskparams:
2330 2c758845 René Nussbaumer
        self.group_dp = self.cluster.SimpleFillDP(group.diskparams)
2331 2c758845 René Nussbaumer
      else:
2332 2c758845 René Nussbaumer
        self.group_dp = None
2333 edd49f9b Agata Murawska
      yield group
2334 8e21cfc0 Adeodato Simo
2335 8e21cfc0 Adeodato Simo
2336 8e21cfc0 Adeodato Simo
_GROUP_SIMPLE_FIELDS = {
2337 79b2ca83 Michael Hanselmann
  "alloc_policy": ("AllocPolicy", QFT_TEXT, "Allocation policy for group"),
2338 79b2ca83 Michael Hanselmann
  "name": ("Group", QFT_TEXT, "Group name"),
2339 79b2ca83 Michael Hanselmann
  "serial_no": ("SerialNo", QFT_NUMBER, _SERIAL_NO_DOC % "Group"),
2340 79b2ca83 Michael Hanselmann
  "uuid": ("UUID", QFT_TEXT, "Group UUID"),
2341 8e21cfc0 Adeodato Simo
  }
2342 8e21cfc0 Adeodato Simo
2343 8e21cfc0 Adeodato Simo
2344 8e21cfc0 Adeodato Simo
def _BuildGroupFields():
2345 8e21cfc0 Adeodato Simo
  """Builds list of fields for node group queries.
2346 8e21cfc0 Adeodato Simo

2347 8e21cfc0 Adeodato Simo
  """
2348 8e21cfc0 Adeodato Simo
  # Add simple fields
2349 111bf531 Michael Hanselmann
  fields = [(_MakeField(name, title, kind, doc), GQ_CONFIG, 0,
2350 111bf531 Michael Hanselmann
             _GetItemAttr(name))
2351 79b2ca83 Michael Hanselmann
            for (name, (title, kind, doc)) in _GROUP_SIMPLE_FIELDS.items()]
2352 8e21cfc0 Adeodato Simo
2353 8e21cfc0 Adeodato Simo
  def _GetLength(getter):
2354 e2d188cc Iustin Pop
    return lambda ctx, group: len(getter(ctx)[group.uuid])
2355 8e21cfc0 Adeodato Simo
2356 8e21cfc0 Adeodato Simo
  def _GetSortedList(getter):
2357 e2d188cc Iustin Pop
    return lambda ctx, group: utils.NiceSort(getter(ctx)[group.uuid])
2358 8e21cfc0 Adeodato Simo
2359 8e21cfc0 Adeodato Simo
  group_to_nodes = operator.attrgetter("group_to_nodes")
2360 8e21cfc0 Adeodato Simo
  group_to_instances = operator.attrgetter("group_to_instances")
2361 8e21cfc0 Adeodato Simo
2362 8e21cfc0 Adeodato Simo
  # Add fields for nodes
2363 8e21cfc0 Adeodato Simo
  fields.extend([
2364 79b2ca83 Michael Hanselmann
    (_MakeField("node_cnt", "Nodes", QFT_NUMBER, "Number of nodes"),
2365 111bf531 Michael Hanselmann
     GQ_NODE, 0, _GetLength(group_to_nodes)),
2366 79b2ca83 Michael Hanselmann
    (_MakeField("node_list", "NodeList", QFT_OTHER, "List of nodes"),
2367 111bf531 Michael Hanselmann
     GQ_NODE, 0, _GetSortedList(group_to_nodes)),
2368 8e21cfc0 Adeodato Simo
    ])
2369 8e21cfc0 Adeodato Simo
2370 8e21cfc0 Adeodato Simo
  # Add fields for instances
2371 8e21cfc0 Adeodato Simo
  fields.extend([
2372 79b2ca83 Michael Hanselmann
    (_MakeField("pinst_cnt", "Instances", QFT_NUMBER,
2373 79b2ca83 Michael Hanselmann
                "Number of primary instances"),
2374 111bf531 Michael Hanselmann
     GQ_INST, 0, _GetLength(group_to_instances)),
2375 79b2ca83 Michael Hanselmann
    (_MakeField("pinst_list", "InstanceList", QFT_OTHER,
2376 79b2ca83 Michael Hanselmann
                "List of primary instances"),
2377 111bf531 Michael Hanselmann
     GQ_INST, 0, _GetSortedList(group_to_instances)),
2378 8e21cfc0 Adeodato Simo
    ])
2379 8e21cfc0 Adeodato Simo
2380 1ffd2673 Michael Hanselmann
  # Other fields
2381 1ffd2673 Michael Hanselmann
  fields.extend([
2382 1ffd2673 Michael Hanselmann
    (_MakeField("tags", "Tags", QFT_OTHER, "Tags"), GQ_CONFIG, 0,
2383 1ffd2673 Michael Hanselmann
     lambda ctx, group: list(group.GetTags())),
2384 edd49f9b Agata Murawska
    (_MakeField("ipolicy", "InstancePolicy", QFT_OTHER,
2385 edd49f9b Agata Murawska
                "Instance policy limitations (merged)"),
2386 edd49f9b Agata Murawska
     GQ_CONFIG, 0, lambda ctx, _: ctx.group_ipolicy),
2387 edd49f9b Agata Murawska
    (_MakeField("custom_ipolicy", "CustomInstancePolicy", QFT_OTHER,
2388 edd49f9b Agata Murawska
                "Custom instance policy limitations"),
2389 edd49f9b Agata Murawska
     GQ_CONFIG, 0, _GetItemAttr("ipolicy")),
2390 8930b0f0 Iustin Pop
    (_MakeField("custom_ndparams", "CustomNDParams", QFT_OTHER,
2391 8930b0f0 Iustin Pop
                "Custom node parameters"),
2392 8930b0f0 Iustin Pop
     GQ_CONFIG, 0, _GetItemAttr("ndparams")),
2393 8930b0f0 Iustin Pop
    (_MakeField("ndparams", "NDParams", QFT_OTHER,
2394 8930b0f0 Iustin Pop
                "Node parameters"),
2395 8930b0f0 Iustin Pop
     GQ_CONFIG, 0, lambda ctx, _: ctx.ndparams),
2396 2c758845 René Nussbaumer
    (_MakeField("diskparams", "DiskParameters", QFT_OTHER,
2397 2c758845 René Nussbaumer
                "Disk parameters (merged)"),
2398 2c758845 René Nussbaumer
     GQ_DISKPARAMS, 0, lambda ctx, _: ctx.group_dp),
2399 2c758845 René Nussbaumer
    (_MakeField("custom_diskparams", "CustomDiskParameters", QFT_OTHER,
2400 2c758845 René Nussbaumer
                "Custom disk parameters"),
2401 2c758845 René Nussbaumer
     GQ_CONFIG, 0, _GetItemAttr("diskparams")),
2402 1ffd2673 Michael Hanselmann
    ])
2403 1ffd2673 Michael Hanselmann
2404 8930b0f0 Iustin Pop
  # ND parameters
2405 8930b0f0 Iustin Pop
  fields.extend(_BuildNDFields(True))
2406 8930b0f0 Iustin Pop
2407 8e21cfc0 Adeodato Simo
  fields.extend(_GetItemTimestampFields(GQ_CONFIG))
2408 8e21cfc0 Adeodato Simo
2409 d63bd540 Iustin Pop
  return _PrepareFieldList(fields, [])
2410 8e21cfc0 Adeodato Simo
2411 8e21cfc0 Adeodato Simo
2412 be3a4b14 Michael Hanselmann
class OsInfo(objects.ConfigObject):
2413 be3a4b14 Michael Hanselmann
  __slots__ = [
2414 be3a4b14 Michael Hanselmann
    "name",
2415 be3a4b14 Michael Hanselmann
    "valid",
2416 be3a4b14 Michael Hanselmann
    "hidden",
2417 be3a4b14 Michael Hanselmann
    "blacklisted",
2418 be3a4b14 Michael Hanselmann
    "variants",
2419 be3a4b14 Michael Hanselmann
    "api_versions",
2420 be3a4b14 Michael Hanselmann
    "parameters",
2421 be3a4b14 Michael Hanselmann
    "node_status",
2422 be3a4b14 Michael Hanselmann
    ]
2423 be3a4b14 Michael Hanselmann
2424 be3a4b14 Michael Hanselmann
2425 be3a4b14 Michael Hanselmann
def _BuildOsFields():
2426 be3a4b14 Michael Hanselmann
  """Builds list of fields for operating system queries.
2427 be3a4b14 Michael Hanselmann

2428 be3a4b14 Michael Hanselmann
  """
2429 be3a4b14 Michael Hanselmann
  fields = [
2430 be3a4b14 Michael Hanselmann
    (_MakeField("name", "Name", QFT_TEXT, "Operating system name"),
2431 be3a4b14 Michael Hanselmann
     None, 0, _GetItemAttr("name")),
2432 be3a4b14 Michael Hanselmann
    (_MakeField("valid", "Valid", QFT_BOOL,
2433 be3a4b14 Michael Hanselmann
                "Whether operating system definition is valid"),
2434 be3a4b14 Michael Hanselmann
     None, 0, _GetItemAttr("valid")),
2435 be3a4b14 Michael Hanselmann
    (_MakeField("hidden", "Hidden", QFT_BOOL,
2436 be3a4b14 Michael Hanselmann
                "Whether operating system is hidden"),
2437 be3a4b14 Michael Hanselmann
     None, 0, _GetItemAttr("hidden")),
2438 be3a4b14 Michael Hanselmann
    (_MakeField("blacklisted", "Blacklisted", QFT_BOOL,
2439 be3a4b14 Michael Hanselmann
                "Whether operating system is blacklisted"),
2440 be3a4b14 Michael Hanselmann
     None, 0, _GetItemAttr("blacklisted")),
2441 be3a4b14 Michael Hanselmann
    (_MakeField("variants", "Variants", QFT_OTHER,
2442 be3a4b14 Michael Hanselmann
                "Operating system variants"),
2443 be3a4b14 Michael Hanselmann
     None, 0, _ConvWrap(utils.NiceSort, _GetItemAttr("variants"))),
2444 be3a4b14 Michael Hanselmann
    (_MakeField("api_versions", "ApiVersions", QFT_OTHER,
2445 be3a4b14 Michael Hanselmann
                "Operating system API versions"),
2446 be3a4b14 Michael Hanselmann
     None, 0, _ConvWrap(sorted, _GetItemAttr("api_versions"))),
2447 be3a4b14 Michael Hanselmann
    (_MakeField("parameters", "Parameters", QFT_OTHER,
2448 be3a4b14 Michael Hanselmann
                "Operating system parameters"),
2449 eb62069e Iustin Pop
     None, 0, _ConvWrap(compat.partial(utils.NiceSort, key=compat.fst),
2450 6ae1fade Iustin Pop
                        _GetItemAttr("parameters"))),
2451 be3a4b14 Michael Hanselmann
    (_MakeField("node_status", "NodeStatus", QFT_OTHER,
2452 be3a4b14 Michael Hanselmann
                "Status from node"),
2453 be3a4b14 Michael Hanselmann
     None, 0, _GetItemAttr("node_status")),
2454 be3a4b14 Michael Hanselmann
    ]
2455 be3a4b14 Michael Hanselmann
2456 be3a4b14 Michael Hanselmann
  return _PrepareFieldList(fields, [])
2457 be3a4b14 Michael Hanselmann
2458 be3a4b14 Michael Hanselmann
2459 b954f097 Constantinos Venetsanopoulos
class ExtStorageInfo(objects.ConfigObject):
2460 b954f097 Constantinos Venetsanopoulos
  __slots__ = [
2461 b954f097 Constantinos Venetsanopoulos
    "name",
2462 b954f097 Constantinos Venetsanopoulos
    "node_status",
2463 b954f097 Constantinos Venetsanopoulos
    "nodegroup_status",
2464 b954f097 Constantinos Venetsanopoulos
    "parameters",
2465 b954f097 Constantinos Venetsanopoulos
    ]
2466 b954f097 Constantinos Venetsanopoulos
2467 b954f097 Constantinos Venetsanopoulos
2468 b954f097 Constantinos Venetsanopoulos
def _BuildExtStorageFields():
2469 b954f097 Constantinos Venetsanopoulos
  """Builds list of fields for extstorage provider queries.
2470 b954f097 Constantinos Venetsanopoulos

2471 b954f097 Constantinos Venetsanopoulos
  """
2472 b954f097 Constantinos Venetsanopoulos
  fields = [
2473 b954f097 Constantinos Venetsanopoulos
    (_MakeField("name", "Name", QFT_TEXT, "ExtStorage provider name"),
2474 b954f097 Constantinos Venetsanopoulos
     None, 0, _GetItemAttr("name")),
2475 b954f097 Constantinos Venetsanopoulos
    (_MakeField("node_status", "NodeStatus", QFT_OTHER,
2476 b954f097 Constantinos Venetsanopoulos
                "Status from node"),
2477 b954f097 Constantinos Venetsanopoulos
     None, 0, _GetItemAttr("node_status")),
2478 b954f097 Constantinos Venetsanopoulos
    (_MakeField("nodegroup_status", "NodegroupStatus", QFT_OTHER,
2479 b954f097 Constantinos Venetsanopoulos
                "Overall Nodegroup status"),
2480 b954f097 Constantinos Venetsanopoulos
     None, 0, _GetItemAttr("nodegroup_status")),
2481 b954f097 Constantinos Venetsanopoulos
    (_MakeField("parameters", "Parameters", QFT_OTHER,
2482 b954f097 Constantinos Venetsanopoulos
                "ExtStorage provider parameters"),
2483 b954f097 Constantinos Venetsanopoulos
     None, 0, _GetItemAttr("parameters")),
2484 b954f097 Constantinos Venetsanopoulos
    ]
2485 b954f097 Constantinos Venetsanopoulos
2486 b954f097 Constantinos Venetsanopoulos
  return _PrepareFieldList(fields, [])
2487 b954f097 Constantinos Venetsanopoulos
2488 b954f097 Constantinos Venetsanopoulos
2489 9665bb3a Michael Hanselmann
def _JobUnavailInner(fn, ctx, (job_id, job)): # pylint: disable=W0613
2490 9665bb3a Michael Hanselmann
  """Return L{_FS_UNAVAIL} if job is None.
2491 9665bb3a Michael Hanselmann

2492 9665bb3a Michael Hanselmann
  When listing specifc jobs (e.g. "gnt-job list 1 2 3"), a job may not be
2493 9665bb3a Michael Hanselmann
  found, in which case this function converts it to L{_FS_UNAVAIL}.
2494 9665bb3a Michael Hanselmann

2495 9665bb3a Michael Hanselmann
  """
2496 9665bb3a Michael Hanselmann
  if job is None:
2497 9665bb3a Michael Hanselmann
    return _FS_UNAVAIL
2498 9665bb3a Michael Hanselmann
  else:
2499 9665bb3a Michael Hanselmann
    return fn(job)
2500 9665bb3a Michael Hanselmann
2501 9665bb3a Michael Hanselmann
2502 9665bb3a Michael Hanselmann
def _JobUnavail(inner):
2503 9665bb3a Michael Hanselmann
  """Wrapper for L{_JobUnavailInner}.
2504 9665bb3a Michael Hanselmann

2505 9665bb3a Michael Hanselmann
  """
2506 9665bb3a Michael Hanselmann
  return compat.partial(_JobUnavailInner, inner)
2507 9665bb3a Michael Hanselmann
2508 9665bb3a Michael Hanselmann
2509 9665bb3a Michael Hanselmann
def _PerJobOpInner(fn, job):
2510 9665bb3a Michael Hanselmann
  """Executes a function per opcode in a job.
2511 9665bb3a Michael Hanselmann

2512 9665bb3a Michael Hanselmann
  """
2513 9665bb3a Michael Hanselmann
  return map(fn, job.ops)
2514 9665bb3a Michael Hanselmann
2515 9665bb3a Michael Hanselmann
2516 9665bb3a Michael Hanselmann
def _PerJobOp(fn):
2517 9665bb3a Michael Hanselmann
  """Wrapper for L{_PerJobOpInner}.
2518 9665bb3a Michael Hanselmann

2519 9665bb3a Michael Hanselmann
  """
2520 9665bb3a Michael Hanselmann
  return _JobUnavail(compat.partial(_PerJobOpInner, fn))
2521 9665bb3a Michael Hanselmann
2522 9665bb3a Michael Hanselmann
2523 9665bb3a Michael Hanselmann
def _JobTimestampInner(fn, job):
2524 9665bb3a Michael Hanselmann
  """Converts unavailable timestamp to L{_FS_UNAVAIL}.
2525 9665bb3a Michael Hanselmann

2526 9665bb3a Michael Hanselmann
  """
2527 9665bb3a Michael Hanselmann
  timestamp = fn(job)
2528 9665bb3a Michael Hanselmann
2529 9665bb3a Michael Hanselmann
  if timestamp is None:
2530 9665bb3a Michael Hanselmann
    return _FS_UNAVAIL
2531 9665bb3a Michael Hanselmann
  else:
2532 9665bb3a Michael Hanselmann
    return timestamp
2533 9665bb3a Michael Hanselmann
2534 9665bb3a Michael Hanselmann
2535 9665bb3a Michael Hanselmann
def _JobTimestamp(fn):
2536 9665bb3a Michael Hanselmann
  """Wrapper for L{_JobTimestampInner}.
2537 9665bb3a Michael Hanselmann

2538 9665bb3a Michael Hanselmann
  """
2539 9665bb3a Michael Hanselmann
  return _JobUnavail(compat.partial(_JobTimestampInner, fn))
2540 9665bb3a Michael Hanselmann
2541 9665bb3a Michael Hanselmann
2542 9665bb3a Michael Hanselmann
def _BuildJobFields():
2543 9665bb3a Michael Hanselmann
  """Builds list of fields for job queries.
2544 9665bb3a Michael Hanselmann

2545 9665bb3a Michael Hanselmann
  """
2546 9665bb3a Michael Hanselmann
  fields = [
2547 76b62028 Iustin Pop
    (_MakeField("id", "ID", QFT_NUMBER, "Job ID"),
2548 526f866b Michael Hanselmann
     None, QFF_JOB_ID, lambda _, (job_id, job): job_id),
2549 9665bb3a Michael Hanselmann
    (_MakeField("status", "Status", QFT_TEXT, "Job status"),
2550 9665bb3a Michael Hanselmann
     None, 0, _JobUnavail(lambda job: job.CalcStatus())),
2551 9665bb3a Michael Hanselmann
    (_MakeField("priority", "Priority", QFT_NUMBER,
2552 9665bb3a Michael Hanselmann
                ("Current job priority (%s to %s)" %
2553 9665bb3a Michael Hanselmann
                 (constants.OP_PRIO_LOWEST, constants.OP_PRIO_HIGHEST))),
2554 9665bb3a Michael Hanselmann
     None, 0, _JobUnavail(lambda job: job.CalcPriority())),
2555 0422250e Michael Hanselmann
    (_MakeField("archived", "Archived", QFT_BOOL, "Whether job is archived"),
2556 0422250e Michael Hanselmann
     JQ_ARCHIVED, 0, lambda _, (job_id, job): job.archived),
2557 9665bb3a Michael Hanselmann
    (_MakeField("ops", "OpCodes", QFT_OTHER, "List of all opcodes"),
2558 9665bb3a Michael Hanselmann
     None, 0, _PerJobOp(lambda op: op.input.__getstate__())),
2559 9665bb3a Michael Hanselmann
    (_MakeField("opresult", "OpCode_result", QFT_OTHER,
2560 9665bb3a Michael Hanselmann
                "List of opcodes results"),
2561 9665bb3a Michael Hanselmann
     None, 0, _PerJobOp(operator.attrgetter("result"))),
2562 9665bb3a Michael Hanselmann
    (_MakeField("opstatus", "OpCode_status", QFT_OTHER,
2563 9665bb3a Michael Hanselmann
                "List of opcodes status"),
2564 9665bb3a Michael Hanselmann
     None, 0, _PerJobOp(operator.attrgetter("status"))),
2565 9665bb3a Michael Hanselmann
    (_MakeField("oplog", "OpCode_log", QFT_OTHER,
2566 9665bb3a Michael Hanselmann
                "List of opcode output logs"),
2567 9665bb3a Michael Hanselmann
     None, 0, _PerJobOp(operator.attrgetter("log"))),
2568 9665bb3a Michael Hanselmann
    (_MakeField("opstart", "OpCode_start", QFT_OTHER,
2569 9665bb3a Michael Hanselmann
                "List of opcode start timestamps (before acquiring locks)"),
2570 9665bb3a Michael Hanselmann
     None, 0, _PerJobOp(operator.attrgetter("start_timestamp"))),
2571 9665bb3a Michael Hanselmann
    (_MakeField("opexec", "OpCode_exec", QFT_OTHER,
2572 9665bb3a Michael Hanselmann
                "List of opcode execution start timestamps (after acquiring"
2573 9665bb3a Michael Hanselmann
                " locks)"),
2574 9665bb3a Michael Hanselmann
     None, 0, _PerJobOp(operator.attrgetter("exec_timestamp"))),
2575 9665bb3a Michael Hanselmann
    (_MakeField("opend", "OpCode_end", QFT_OTHER,
2576 9665bb3a Michael Hanselmann
                "List of opcode execution end timestamps"),
2577 9665bb3a Michael Hanselmann
     None, 0, _PerJobOp(operator.attrgetter("end_timestamp"))),
2578 9665bb3a Michael Hanselmann
    (_MakeField("oppriority", "OpCode_prio", QFT_OTHER,
2579 9665bb3a Michael Hanselmann
                "List of opcode priorities"),
2580 9665bb3a Michael Hanselmann
     None, 0, _PerJobOp(operator.attrgetter("priority"))),
2581 9665bb3a Michael Hanselmann
    (_MakeField("summary", "Summary", QFT_OTHER,
2582 9665bb3a Michael Hanselmann
                "List of per-opcode summaries"),
2583 9665bb3a Michael Hanselmann
     None, 0, _PerJobOp(lambda op: op.input.Summary())),
2584 9665bb3a Michael Hanselmann
    ]
2585 9665bb3a Michael Hanselmann
2586 526f866b Michael Hanselmann
  # Timestamp fields
2587 526f866b Michael Hanselmann
  for (name, attr, title, desc) in [
2588 526f866b Michael Hanselmann
    ("received_ts", "received_timestamp", "Received",
2589 526f866b Michael Hanselmann
     "Timestamp of when job was received"),
2590 526f866b Michael Hanselmann
    ("start_ts", "start_timestamp", "Start", "Timestamp of job start"),
2591 526f866b Michael Hanselmann
    ("end_ts", "end_timestamp", "End", "Timestamp of job end"),
2592 526f866b Michael Hanselmann
    ]:
2593 526f866b Michael Hanselmann
    getter = operator.attrgetter(attr)
2594 526f866b Michael Hanselmann
    fields.extend([
2595 526f866b Michael Hanselmann
      (_MakeField(name, title, QFT_OTHER,
2596 526f866b Michael Hanselmann
                  "%s (tuple containing seconds and microseconds)" % desc),
2597 526f866b Michael Hanselmann
       None, QFF_SPLIT_TIMESTAMP, _JobTimestamp(getter)),
2598 526f866b Michael Hanselmann
      ])
2599 526f866b Michael Hanselmann
2600 9665bb3a Michael Hanselmann
  return _PrepareFieldList(fields, [])
2601 9665bb3a Michael Hanselmann
2602 9665bb3a Michael Hanselmann
2603 0fdf247d Michael Hanselmann
def _GetExportName(_, (node_name, expname)): # pylint: disable=W0613
2604 0fdf247d Michael Hanselmann
  """Returns an export name if available.
2605 0fdf247d Michael Hanselmann

2606 0fdf247d Michael Hanselmann
  """
2607 0fdf247d Michael Hanselmann
  if expname is None:
2608 0b1c7a55 Iustin Pop
    return _FS_NODATA
2609 0fdf247d Michael Hanselmann
  else:
2610 0fdf247d Michael Hanselmann
    return expname
2611 0fdf247d Michael Hanselmann
2612 0fdf247d Michael Hanselmann
2613 0fdf247d Michael Hanselmann
def _BuildExportFields():
2614 0fdf247d Michael Hanselmann
  """Builds list of fields for exports.
2615 0fdf247d Michael Hanselmann

2616 0fdf247d Michael Hanselmann
  """
2617 0fdf247d Michael Hanselmann
  fields = [
2618 0fdf247d Michael Hanselmann
    (_MakeField("node", "Node", QFT_TEXT, "Node name"),
2619 0fdf247d Michael Hanselmann
     None, QFF_HOSTNAME, lambda _, (node_name, expname): node_name),
2620 0fdf247d Michael Hanselmann
    (_MakeField("export", "Export", QFT_TEXT, "Export name"),
2621 0fdf247d Michael Hanselmann
     None, 0, _GetExportName),
2622 0fdf247d Michael Hanselmann
    ]
2623 0fdf247d Michael Hanselmann
2624 0fdf247d Michael Hanselmann
  return _PrepareFieldList(fields, [])
2625 0fdf247d Michael Hanselmann
2626 0fdf247d Michael Hanselmann
2627 dff5f600 Michael Hanselmann
_CLUSTER_VERSION_FIELDS = {
2628 dff5f600 Michael Hanselmann
  "software_version": ("SoftwareVersion", QFT_TEXT, constants.RELEASE_VERSION,
2629 dff5f600 Michael Hanselmann
                       "Software version"),
2630 dff5f600 Michael Hanselmann
  "protocol_version": ("ProtocolVersion", QFT_NUMBER,
2631 dff5f600 Michael Hanselmann
                       constants.PROTOCOL_VERSION,
2632 dff5f600 Michael Hanselmann
                       "RPC protocol version"),
2633 dff5f600 Michael Hanselmann
  "config_version": ("ConfigVersion", QFT_NUMBER, constants.CONFIG_VERSION,
2634 dff5f600 Michael Hanselmann
                     "Configuration format version"),
2635 dff5f600 Michael Hanselmann
  "os_api_version": ("OsApiVersion", QFT_NUMBER, max(constants.OS_API_VERSIONS),
2636 dff5f600 Michael Hanselmann
                     "API version for OS template scripts"),
2637 dff5f600 Michael Hanselmann
  "export_version": ("ExportVersion", QFT_NUMBER, constants.EXPORT_VERSION,
2638 dff5f600 Michael Hanselmann
                     "Import/export file format version"),
2639 026f444f Thomas Thrainer
  "vcs_version": ("VCSVersion", QFT_TEXT, constants.VCS_VERSION,
2640 026f444f Thomas Thrainer
                     "VCS version"),
2641 dff5f600 Michael Hanselmann
  }
2642 dff5f600 Michael Hanselmann
2643 dff5f600 Michael Hanselmann
2644 dff5f600 Michael Hanselmann
_CLUSTER_SIMPLE_FIELDS = {
2645 dff5f600 Michael Hanselmann
  "cluster_name": ("Name", QFT_TEXT, QFF_HOSTNAME, "Cluster name"),
2646 dff5f600 Michael Hanselmann
  "volume_group_name": ("VgName", QFT_TEXT, 0, "LVM volume group name"),
2647 dff5f600 Michael Hanselmann
  }
2648 dff5f600 Michael Hanselmann
2649 dff5f600 Michael Hanselmann
2650 dff5f600 Michael Hanselmann
class ClusterQueryData:
2651 1c3231aa Thomas Thrainer
  def __init__(self, cluster, nodes, drain_flag, watcher_pause):
2652 dff5f600 Michael Hanselmann
    """Initializes this class.
2653 dff5f600 Michael Hanselmann

2654 dff5f600 Michael Hanselmann
    @type cluster: L{objects.Cluster}
2655 dff5f600 Michael Hanselmann
    @param cluster: Instance of cluster object
2656 1c3231aa Thomas Thrainer
    @type nodes: dict; node UUID as key
2657 1c3231aa Thomas Thrainer
    @param nodes: Node objects
2658 dff5f600 Michael Hanselmann
    @type drain_flag: bool
2659 dff5f600 Michael Hanselmann
    @param drain_flag: Whether job queue is drained
2660 dff5f600 Michael Hanselmann
    @type watcher_pause: number
2661 dff5f600 Michael Hanselmann
    @param watcher_pause: Until when watcher is paused (Unix timestamp)
2662 dff5f600 Michael Hanselmann

2663 dff5f600 Michael Hanselmann
    """
2664 dff5f600 Michael Hanselmann
    self._cluster = cluster
2665 1c3231aa Thomas Thrainer
    self.nodes = nodes
2666 dff5f600 Michael Hanselmann
    self.drain_flag = drain_flag
2667 dff5f600 Michael Hanselmann
    self.watcher_pause = watcher_pause
2668 dff5f600 Michael Hanselmann
2669 dff5f600 Michael Hanselmann
  def __iter__(self):
2670 dff5f600 Michael Hanselmann
    return iter([self._cluster])
2671 dff5f600 Michael Hanselmann
2672 dff5f600 Michael Hanselmann
2673 dff5f600 Michael Hanselmann
def _ClusterWatcherPause(ctx, _):
2674 dff5f600 Michael Hanselmann
  """Returns until when watcher is paused (if available).
2675 dff5f600 Michael Hanselmann

2676 dff5f600 Michael Hanselmann
  """
2677 dff5f600 Michael Hanselmann
  if ctx.watcher_pause is None:
2678 dff5f600 Michael Hanselmann
    return _FS_UNAVAIL
2679 dff5f600 Michael Hanselmann
  else:
2680 dff5f600 Michael Hanselmann
    return ctx.watcher_pause
2681 dff5f600 Michael Hanselmann
2682 dff5f600 Michael Hanselmann
2683 dff5f600 Michael Hanselmann
def _BuildClusterFields():
2684 dff5f600 Michael Hanselmann
  """Builds list of fields for cluster information.
2685 dff5f600 Michael Hanselmann

2686 dff5f600 Michael Hanselmann
  """
2687 dff5f600 Michael Hanselmann
  fields = [
2688 dff5f600 Michael Hanselmann
    (_MakeField("tags", "Tags", QFT_OTHER, "Tags"), CQ_CONFIG, 0,
2689 dff5f600 Michael Hanselmann
     lambda ctx, cluster: list(cluster.GetTags())),
2690 dff5f600 Michael Hanselmann
    (_MakeField("architecture", "ArchInfo", QFT_OTHER,
2691 dff5f600 Michael Hanselmann
                "Architecture information"), None, 0,
2692 dff5f600 Michael Hanselmann
     lambda ctx, _: runtime.GetArchInfo()),
2693 dff5f600 Michael Hanselmann
    (_MakeField("drain_flag", "QueueDrained", QFT_BOOL,
2694 dff5f600 Michael Hanselmann
                "Flag whether job queue is drained"), CQ_QUEUE_DRAINED, 0,
2695 dff5f600 Michael Hanselmann
     lambda ctx, _: ctx.drain_flag),
2696 dff5f600 Michael Hanselmann
    (_MakeField("watcher_pause", "WatcherPause", QFT_TIMESTAMP,
2697 dff5f600 Michael Hanselmann
                "Until when watcher is paused"), CQ_WATCHER_PAUSE, 0,
2698 dff5f600 Michael Hanselmann
     _ClusterWatcherPause),
2699 1c3231aa Thomas Thrainer
    (_MakeField("master_node", "Master", QFT_TEXT, "Master node name"),
2700 1c3231aa Thomas Thrainer
     CQ_CONFIG, QFF_HOSTNAME,
2701 1c3231aa Thomas Thrainer
     lambda ctx, cluster: _GetNodeName(ctx, None, cluster.master_node)),
2702 dff5f600 Michael Hanselmann
    ]
2703 dff5f600 Michael Hanselmann
2704 dff5f600 Michael Hanselmann
  # Simple fields
2705 dff5f600 Michael Hanselmann
  fields.extend([
2706 dff5f600 Michael Hanselmann
    (_MakeField(name, title, kind, doc), CQ_CONFIG, flags, _GetItemAttr(name))
2707 dff5f600 Michael Hanselmann
    for (name, (title, kind, flags, doc)) in _CLUSTER_SIMPLE_FIELDS.items()
2708 3c286190 Dimitris Aragiorgis
    ],)
2709 dff5f600 Michael Hanselmann
2710 dff5f600 Michael Hanselmann
  # Version fields
2711 dff5f600 Michael Hanselmann
  fields.extend([
2712 dff5f600 Michael Hanselmann
    (_MakeField(name, title, kind, doc), None, 0, _StaticValue(value))
2713 3c286190 Dimitris Aragiorgis
    for (name, (title, kind, value, doc)) in _CLUSTER_VERSION_FIELDS.items()])
2714 dff5f600 Michael Hanselmann
2715 dff5f600 Michael Hanselmann
  # Add timestamps
2716 dff5f600 Michael Hanselmann
  fields.extend(_GetItemTimestampFields(CQ_CONFIG))
2717 dff5f600 Michael Hanselmann
2718 dff5f600 Michael Hanselmann
  return _PrepareFieldList(fields, [
2719 3c286190 Dimitris Aragiorgis
    ("name", "cluster_name")])
2720 dff5f600 Michael Hanselmann
2721 dff5f600 Michael Hanselmann
2722 306bed0e Apollon Oikonomopoulos
class NetworkQueryData:
2723 306bed0e Apollon Oikonomopoulos
  """Data container for network data queries.
2724 306bed0e Apollon Oikonomopoulos

2725 306bed0e Apollon Oikonomopoulos
  """
2726 306bed0e Apollon Oikonomopoulos
  def __init__(self, networks, network_to_groups,
2727 306bed0e Apollon Oikonomopoulos
               network_to_instances, stats):
2728 306bed0e Apollon Oikonomopoulos
    """Initializes this class.
2729 306bed0e Apollon Oikonomopoulos

2730 306bed0e Apollon Oikonomopoulos
    @param networks: List of network objects
2731 306bed0e Apollon Oikonomopoulos
    @type network_to_groups: dict; network UUID as key
2732 306bed0e Apollon Oikonomopoulos
    @param network_to_groups: Per-network list of groups
2733 306bed0e Apollon Oikonomopoulos
    @type network_to_instances: dict; network UUID as key
2734 306bed0e Apollon Oikonomopoulos
    @param network_to_instances: Per-network list of instances
2735 306bed0e Apollon Oikonomopoulos
    @type stats: dict; network UUID as key
2736 306bed0e Apollon Oikonomopoulos
    @param stats: Per-network usage statistics
2737 306bed0e Apollon Oikonomopoulos

2738 306bed0e Apollon Oikonomopoulos
    """
2739 306bed0e Apollon Oikonomopoulos
    self.networks = networks
2740 306bed0e Apollon Oikonomopoulos
    self.network_to_groups = network_to_groups
2741 306bed0e Apollon Oikonomopoulos
    self.network_to_instances = network_to_instances
2742 306bed0e Apollon Oikonomopoulos
    self.stats = stats
2743 306bed0e Apollon Oikonomopoulos
2744 306bed0e Apollon Oikonomopoulos
  def __iter__(self):
2745 306bed0e Apollon Oikonomopoulos
    """Iterate over all networks.
2746 306bed0e Apollon Oikonomopoulos

2747 306bed0e Apollon Oikonomopoulos
    """
2748 306bed0e Apollon Oikonomopoulos
    for net in self.networks:
2749 306bed0e Apollon Oikonomopoulos
      if self.stats:
2750 306bed0e Apollon Oikonomopoulos
        self.curstats = self.stats.get(net.uuid, None)
2751 306bed0e Apollon Oikonomopoulos
      else:
2752 306bed0e Apollon Oikonomopoulos
        self.curstats = None
2753 306bed0e Apollon Oikonomopoulos
      yield net
2754 306bed0e Apollon Oikonomopoulos
2755 306bed0e Apollon Oikonomopoulos
2756 306bed0e Apollon Oikonomopoulos
_NETWORK_SIMPLE_FIELDS = {
2757 0b3f2215 Michael Hanselmann
  "name": ("Network", QFT_TEXT, 0, "Name"),
2758 0b3f2215 Michael Hanselmann
  "network": ("Subnet", QFT_TEXT, 0, "IPv4 subnet"),
2759 0b3f2215 Michael Hanselmann
  "gateway": ("Gateway", QFT_OTHER, 0, "IPv4 gateway"),
2760 0b3f2215 Michael Hanselmann
  "network6": ("IPv6Subnet", QFT_OTHER, 0, "IPv6 subnet"),
2761 0b3f2215 Michael Hanselmann
  "gateway6": ("IPv6Gateway", QFT_OTHER, 0, "IPv6 gateway"),
2762 0b3f2215 Michael Hanselmann
  "mac_prefix": ("MacPrefix", QFT_OTHER, 0, "MAC address prefix"),
2763 9675661c Dimitris Aragiorgis
  "serial_no": ("SerialNo", QFT_NUMBER, 0, _SERIAL_NO_DOC % "Network"),
2764 9675661c Dimitris Aragiorgis
  "uuid": ("UUID", QFT_TEXT, 0, "Network UUID"),
2765 306bed0e Apollon Oikonomopoulos
  }
2766 306bed0e Apollon Oikonomopoulos
2767 306bed0e Apollon Oikonomopoulos
2768 306bed0e Apollon Oikonomopoulos
_NETWORK_STATS_FIELDS = {
2769 0b3f2215 Michael Hanselmann
  "free_count": ("FreeCount", QFT_NUMBER, 0, "Number of available addresses"),
2770 0b3f2215 Michael Hanselmann
  "reserved_count":
2771 0b3f2215 Michael Hanselmann
    ("ReservedCount", QFT_NUMBER, 0, "Number of reserved addresses"),
2772 0b3f2215 Michael Hanselmann
  "map": ("Map", QFT_TEXT, 0, "Actual mapping"),
2773 0b3f2215 Michael Hanselmann
  "external_reservations":
2774 0b3f2215 Michael Hanselmann
    ("ExternalReservations", QFT_TEXT, 0, "External reservations"),
2775 306bed0e Apollon Oikonomopoulos
  }
2776 306bed0e Apollon Oikonomopoulos
2777 3c286190 Dimitris Aragiorgis
2778 83a14695 Helga Velroyen
def _GetNetworkStatsField(field, kind, ctx, _):
2779 306bed0e Apollon Oikonomopoulos
  """Gets the value of a "stats" field from L{NetworkQueryData}.
2780 306bed0e Apollon Oikonomopoulos

2781 306bed0e Apollon Oikonomopoulos
  @param field: Field name
2782 306bed0e Apollon Oikonomopoulos
  @param kind: Data kind, one of L{constants.QFT_ALL}
2783 306bed0e Apollon Oikonomopoulos
  @type ctx: L{NetworkQueryData}
2784 306bed0e Apollon Oikonomopoulos

2785 306bed0e Apollon Oikonomopoulos
  """
2786 b4600d4f Michael Hanselmann
  return _GetStatsField(field, kind, ctx.curstats)
2787 306bed0e Apollon Oikonomopoulos
2788 306bed0e Apollon Oikonomopoulos
2789 306bed0e Apollon Oikonomopoulos
def _BuildNetworkFields():
2790 306bed0e Apollon Oikonomopoulos
  """Builds list of fields for network queries.
2791 306bed0e Apollon Oikonomopoulos

2792 306bed0e Apollon Oikonomopoulos
  """
2793 306bed0e Apollon Oikonomopoulos
  fields = [
2794 8140e24f Dimitris Aragiorgis
    (_MakeField("tags", "Tags", QFT_OTHER, "Tags"), IQ_CONFIG, 0,
2795 8140e24f Dimitris Aragiorgis
     lambda ctx, inst: list(inst.GetTags())),
2796 8140e24f Dimitris Aragiorgis
    ]
2797 8140e24f Dimitris Aragiorgis
2798 8140e24f Dimitris Aragiorgis
  # Add simple fields
2799 8140e24f Dimitris Aragiorgis
  fields.extend([
2800 306bed0e Apollon Oikonomopoulos
    (_MakeField(name, title, kind, doc),
2801 40b118d3 Iustin Pop
     NETQ_CONFIG, 0, _GetItemMaybeAttr(name))
2802 3c286190 Dimitris Aragiorgis
     for (name, (title, kind, _, doc)) in _NETWORK_SIMPLE_FIELDS.items()])
2803 306bed0e Apollon Oikonomopoulos
2804 306bed0e Apollon Oikonomopoulos
  def _GetLength(getter):
2805 306bed0e Apollon Oikonomopoulos
    return lambda ctx, network: len(getter(ctx)[network.uuid])
2806 306bed0e Apollon Oikonomopoulos
2807 306bed0e Apollon Oikonomopoulos
  def _GetSortedList(getter):
2808 306bed0e Apollon Oikonomopoulos
    return lambda ctx, network: utils.NiceSort(getter(ctx)[network.uuid])
2809 306bed0e Apollon Oikonomopoulos
2810 306bed0e Apollon Oikonomopoulos
  network_to_groups = operator.attrgetter("network_to_groups")
2811 306bed0e Apollon Oikonomopoulos
  network_to_instances = operator.attrgetter("network_to_instances")
2812 306bed0e Apollon Oikonomopoulos
2813 306bed0e Apollon Oikonomopoulos
  # Add fields for node groups
2814 306bed0e Apollon Oikonomopoulos
  fields.extend([
2815 306bed0e Apollon Oikonomopoulos
    (_MakeField("group_cnt", "NodeGroups", QFT_NUMBER, "Number of nodegroups"),
2816 306bed0e Apollon Oikonomopoulos
     NETQ_GROUP, 0, _GetLength(network_to_groups)),
2817 503574ec Michael Hanselmann
    (_MakeField("group_list", "GroupList", QFT_OTHER,
2818 503574ec Michael Hanselmann
     "List of nodegroups (group name, NIC mode, NIC link)"),
2819 503574ec Michael Hanselmann
     NETQ_GROUP, 0, lambda ctx, network: network_to_groups(ctx)[network.uuid]),
2820 306bed0e Apollon Oikonomopoulos
    ])
2821 306bed0e Apollon Oikonomopoulos
2822 306bed0e Apollon Oikonomopoulos
  # Add fields for instances
2823 306bed0e Apollon Oikonomopoulos
  fields.extend([
2824 306bed0e Apollon Oikonomopoulos
    (_MakeField("inst_cnt", "Instances", QFT_NUMBER, "Number of instances"),
2825 306bed0e Apollon Oikonomopoulos
     NETQ_INST, 0, _GetLength(network_to_instances)),
2826 306bed0e Apollon Oikonomopoulos
    (_MakeField("inst_list", "InstanceList", QFT_OTHER, "List of instances"),
2827 306bed0e Apollon Oikonomopoulos
     NETQ_INST, 0, _GetSortedList(network_to_instances)),
2828 306bed0e Apollon Oikonomopoulos
    ])
2829 306bed0e Apollon Oikonomopoulos
2830 306bed0e Apollon Oikonomopoulos
  # Add fields for usage statistics
2831 306bed0e Apollon Oikonomopoulos
  fields.extend([
2832 306bed0e Apollon Oikonomopoulos
    (_MakeField(name, title, kind, doc), NETQ_STATS, 0,
2833 e0e44476 Michele Tartara
     compat.partial(_GetNetworkStatsField, name, kind))
2834 3c286190 Dimitris Aragiorgis
    for (name, (title, kind, _, doc)) in _NETWORK_STATS_FIELDS.items()])
2835 306bed0e Apollon Oikonomopoulos
2836 22ff02a7 Christos Stavrakakis
  # Add timestamps
2837 22ff02a7 Christos Stavrakakis
  fields.extend(_GetItemTimestampFields(IQ_NETWORKS))
2838 22ff02a7 Christos Stavrakakis
2839 306bed0e Apollon Oikonomopoulos
  return _PrepareFieldList(fields, [])
2840 306bed0e Apollon Oikonomopoulos
2841 dff5f600 Michael Hanselmann
#: Fields for cluster information
2842 dff5f600 Michael Hanselmann
CLUSTER_FIELDS = _BuildClusterFields()
2843 dff5f600 Michael Hanselmann
2844 8235fe04 Michael Hanselmann
#: Fields available for node queries
2845 8235fe04 Michael Hanselmann
NODE_FIELDS = _BuildNodeFields()
2846 1c8addc6 Michael Hanselmann
2847 1c8addc6 Michael Hanselmann
#: Fields available for instance queries
2848 1c8addc6 Michael Hanselmann
INSTANCE_FIELDS = _BuildInstanceFields()
2849 24d16f76 Michael Hanselmann
2850 24d16f76 Michael Hanselmann
#: Fields available for lock queries
2851 24d16f76 Michael Hanselmann
LOCK_FIELDS = _BuildLockFields()
2852 e571ee44 Adeodato Simo
2853 8e21cfc0 Adeodato Simo
#: Fields available for node group queries
2854 8e21cfc0 Adeodato Simo
GROUP_FIELDS = _BuildGroupFields()
2855 8e21cfc0 Adeodato Simo
2856 be3a4b14 Michael Hanselmann
#: Fields available for operating system queries
2857 be3a4b14 Michael Hanselmann
OS_FIELDS = _BuildOsFields()
2858 be3a4b14 Michael Hanselmann
2859 b954f097 Constantinos Venetsanopoulos
#: Fields available for extstorage provider queries
2860 b954f097 Constantinos Venetsanopoulos
EXTSTORAGE_FIELDS = _BuildExtStorageFields()
2861 b954f097 Constantinos Venetsanopoulos
2862 9665bb3a Michael Hanselmann
#: Fields available for job queries
2863 9665bb3a Michael Hanselmann
JOB_FIELDS = _BuildJobFields()
2864 9665bb3a Michael Hanselmann
2865 0fdf247d Michael Hanselmann
#: Fields available for exports
2866 0fdf247d Michael Hanselmann
EXPORT_FIELDS = _BuildExportFields()
2867 0fdf247d Michael Hanselmann
2868 306bed0e Apollon Oikonomopoulos
#: Fields available for network queries
2869 306bed0e Apollon Oikonomopoulos
NETWORK_FIELDS = _BuildNetworkFields()
2870 306bed0e Apollon Oikonomopoulos
2871 95eb4188 Michael Hanselmann
#: All available resources
2872 95eb4188 Michael Hanselmann
ALL_FIELDS = {
2873 dff5f600 Michael Hanselmann
  constants.QR_CLUSTER: CLUSTER_FIELDS,
2874 95eb4188 Michael Hanselmann
  constants.QR_INSTANCE: INSTANCE_FIELDS,
2875 95eb4188 Michael Hanselmann
  constants.QR_NODE: NODE_FIELDS,
2876 95eb4188 Michael Hanselmann
  constants.QR_LOCK: LOCK_FIELDS,
2877 95eb4188 Michael Hanselmann
  constants.QR_GROUP: GROUP_FIELDS,
2878 be3a4b14 Michael Hanselmann
  constants.QR_OS: OS_FIELDS,
2879 b954f097 Constantinos Venetsanopoulos
  constants.QR_EXTSTORAGE: EXTSTORAGE_FIELDS,
2880 9665bb3a Michael Hanselmann
  constants.QR_JOB: JOB_FIELDS,
2881 0fdf247d Michael Hanselmann
  constants.QR_EXPORT: EXPORT_FIELDS,
2882 306bed0e Apollon Oikonomopoulos
  constants.QR_NETWORK: NETWORK_FIELDS,
2883 95eb4188 Michael Hanselmann
  }
2884 95eb4188 Michael Hanselmann
2885 e571ee44 Adeodato Simo
#: All available field lists
2886 95eb4188 Michael Hanselmann
ALL_FIELD_LISTS = ALL_FIELDS.values()