Statistics
| Branch: | Tag: | Revision:

root / lib / ht.py @ 93f1e606

History | View | Annotate | Download (17.5 kB)

1 62e0e880 Iustin Pop
#
2 62e0e880 Iustin Pop
#
3 62e0e880 Iustin Pop
4 2c9fa1ff Iustin Pop
# Copyright (C) 2010, 2011, 2012 Google Inc.
5 62e0e880 Iustin Pop
#
6 62e0e880 Iustin Pop
# This program is free software; you can redistribute it and/or modify
7 62e0e880 Iustin Pop
# it under the terms of the GNU General Public License as published by
8 62e0e880 Iustin Pop
# the Free Software Foundation; either version 2 of the License, or
9 62e0e880 Iustin Pop
# (at your option) any later version.
10 62e0e880 Iustin Pop
#
11 62e0e880 Iustin Pop
# This program is distributed in the hope that it will be useful, but
12 62e0e880 Iustin Pop
# WITHOUT ANY WARRANTY; without even the implied warranty of
13 62e0e880 Iustin Pop
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 62e0e880 Iustin Pop
# General Public License for more details.
15 62e0e880 Iustin Pop
#
16 62e0e880 Iustin Pop
# You should have received a copy of the GNU General Public License
17 62e0e880 Iustin Pop
# along with this program; if not, write to the Free Software
18 62e0e880 Iustin Pop
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 62e0e880 Iustin Pop
# 02110-1301, USA.
20 62e0e880 Iustin Pop
21 62e0e880 Iustin Pop
22 62e0e880 Iustin Pop
"""Module implementing the parameter types code."""
23 62e0e880 Iustin Pop
24 8c9ee749 Michael Hanselmann
import re
25 b247c6fc Michael Hanselmann
import operator
26 72cd5493 Jose A. Lopes
import ipaddr
27 8c9ee749 Michael Hanselmann
28 62e0e880 Iustin Pop
from ganeti import compat
29 8c9ee749 Michael Hanselmann
from ganeti import utils
30 8620f50e Michael Hanselmann
from ganeti import constants
31 72cd5493 Jose A. Lopes
from ganeti import objects
32 4884f187 Santi Raffa
from ganeti.serializer import Private
33 8c9ee749 Michael Hanselmann
34 8c9ee749 Michael Hanselmann
_PAREN_RE = re.compile("^[a-zA-Z0-9_-]+$")
35 8c9ee749 Michael Hanselmann
36 8c9ee749 Michael Hanselmann
37 8c9ee749 Michael Hanselmann
def Parens(text):
38 8c9ee749 Michael Hanselmann
  """Enclose text in parens if necessary.
39 8c9ee749 Michael Hanselmann

40 8c9ee749 Michael Hanselmann
  @param text: Text
41 8c9ee749 Michael Hanselmann

42 8c9ee749 Michael Hanselmann
  """
43 8c9ee749 Michael Hanselmann
  text = str(text)
44 8c9ee749 Michael Hanselmann
45 8c9ee749 Michael Hanselmann
  if _PAREN_RE.match(text):
46 8c9ee749 Michael Hanselmann
    return text
47 8c9ee749 Michael Hanselmann
  else:
48 8c9ee749 Michael Hanselmann
    return "(%s)" % text
49 8c9ee749 Michael Hanselmann
50 8c9ee749 Michael Hanselmann
51 9eec6d67 Michael Hanselmann
class _WrapperBase(object):
52 7fc548e9 Michael Hanselmann
  __slots__ = [
53 7fc548e9 Michael Hanselmann
    "_fn",
54 7fc548e9 Michael Hanselmann
    "_text",
55 7fc548e9 Michael Hanselmann
    ]
56 7fc548e9 Michael Hanselmann
57 7fc548e9 Michael Hanselmann
  def __init__(self, text, fn):
58 7fc548e9 Michael Hanselmann
    """Initializes this class.
59 7fc548e9 Michael Hanselmann

60 7fc548e9 Michael Hanselmann
    @param text: Description
61 7fc548e9 Michael Hanselmann
    @param fn: Wrapped function
62 7fc548e9 Michael Hanselmann

63 7fc548e9 Michael Hanselmann
    """
64 9eec6d67 Michael Hanselmann
    assert text.strip()
65 9eec6d67 Michael Hanselmann
66 7fc548e9 Michael Hanselmann
    self._text = text
67 7fc548e9 Michael Hanselmann
    self._fn = fn
68 7fc548e9 Michael Hanselmann
69 7fc548e9 Michael Hanselmann
  def __call__(self, *args):
70 7fc548e9 Michael Hanselmann
    return self._fn(*args)
71 7fc548e9 Michael Hanselmann
72 9eec6d67 Michael Hanselmann
73 9eec6d67 Michael Hanselmann
class _DescWrapper(_WrapperBase):
74 9eec6d67 Michael Hanselmann
  """Wrapper class for description text.
75 9eec6d67 Michael Hanselmann

76 9eec6d67 Michael Hanselmann
  """
77 7fc548e9 Michael Hanselmann
  def __str__(self):
78 7fc548e9 Michael Hanselmann
    return self._text
79 7fc548e9 Michael Hanselmann
80 4884f187 Santi Raffa
  def __repr__(self):
81 4884f187 Santi Raffa
    return "<%s %r>" % (self._text, self._fn)
82 4884f187 Santi Raffa
83 7fc548e9 Michael Hanselmann
84 9eec6d67 Michael Hanselmann
class _CommentWrapper(_WrapperBase):
85 9eec6d67 Michael Hanselmann
  """Wrapper class for comment.
86 9eec6d67 Michael Hanselmann

87 9eec6d67 Michael Hanselmann
  """
88 9eec6d67 Michael Hanselmann
  def __str__(self):
89 9eec6d67 Michael Hanselmann
    return "%s [%s]" % (self._fn, self._text)
90 9eec6d67 Michael Hanselmann
91 9eec6d67 Michael Hanselmann
92 8c9ee749 Michael Hanselmann
def WithDesc(text):
93 8c9ee749 Michael Hanselmann
  """Builds wrapper class with description text.
94 8c9ee749 Michael Hanselmann

95 8c9ee749 Michael Hanselmann
  @type text: string
96 8c9ee749 Michael Hanselmann
  @param text: Description text
97 8c9ee749 Michael Hanselmann
  @return: Callable class
98 8c9ee749 Michael Hanselmann

99 8c9ee749 Michael Hanselmann
  """
100 8c9ee749 Michael Hanselmann
  assert text[0] == text[0].upper()
101 8c9ee749 Michael Hanselmann
102 7fc548e9 Michael Hanselmann
  return compat.partial(_DescWrapper, text)
103 8c9ee749 Michael Hanselmann
104 8c9ee749 Michael Hanselmann
105 9eec6d67 Michael Hanselmann
def Comment(text):
106 9eec6d67 Michael Hanselmann
  """Builds wrapper for adding comment to description text.
107 9eec6d67 Michael Hanselmann

108 9eec6d67 Michael Hanselmann
  @type text: string
109 9eec6d67 Michael Hanselmann
  @param text: Comment text
110 9eec6d67 Michael Hanselmann
  @return: Callable class
111 9eec6d67 Michael Hanselmann

112 9eec6d67 Michael Hanselmann
  """
113 9eec6d67 Michael Hanselmann
  assert not frozenset(text).intersection("[]")
114 9eec6d67 Michael Hanselmann
115 9eec6d67 Michael Hanselmann
  return compat.partial(_CommentWrapper, text)
116 9eec6d67 Michael Hanselmann
117 9eec6d67 Michael Hanselmann
118 8c9ee749 Michael Hanselmann
def CombinationDesc(op, args, fn):
119 8c9ee749 Michael Hanselmann
  """Build description for combinating operator.
120 8c9ee749 Michael Hanselmann

121 8c9ee749 Michael Hanselmann
  @type op: string
122 8c9ee749 Michael Hanselmann
  @param op: Operator as text (e.g. "and")
123 8c9ee749 Michael Hanselmann
  @type args: list
124 8c9ee749 Michael Hanselmann
  @param args: Operator arguments
125 8c9ee749 Michael Hanselmann
  @type fn: callable
126 8c9ee749 Michael Hanselmann
  @param fn: Wrapped function
127 8c9ee749 Michael Hanselmann

128 8c9ee749 Michael Hanselmann
  """
129 a138ead7 Michael Hanselmann
  # Some type descriptions are rather long. If "None" is listed at the
130 a138ead7 Michael Hanselmann
  # end or somewhere in between it is easily missed. Therefore it should
131 a138ead7 Michael Hanselmann
  # be at the beginning, e.g. "None or (long description)".
132 a138ead7 Michael Hanselmann
  if __debug__ and TNone in args and args.index(TNone) > 0:
133 a138ead7 Michael Hanselmann
    raise Exception("TNone must be listed first")
134 a138ead7 Michael Hanselmann
135 8c9ee749 Michael Hanselmann
  if len(args) == 1:
136 8c9ee749 Michael Hanselmann
    descr = str(args[0])
137 8c9ee749 Michael Hanselmann
  else:
138 8c9ee749 Michael Hanselmann
    descr = (" %s " % op).join(Parens(i) for i in args)
139 8c9ee749 Michael Hanselmann
140 8c9ee749 Michael Hanselmann
  return WithDesc(descr)(fn)
141 8c9ee749 Michael Hanselmann
142 62e0e880 Iustin Pop
143 62e0e880 Iustin Pop
# Modifiable default values; need to define these here before the
144 62e0e880 Iustin Pop
# actual LUs
145 62e0e880 Iustin Pop
146 8c9ee749 Michael Hanselmann
@WithDesc(str([]))
147 62e0e880 Iustin Pop
def EmptyList():
148 62e0e880 Iustin Pop
  """Returns an empty list.
149 62e0e880 Iustin Pop

150 62e0e880 Iustin Pop
  """
151 62e0e880 Iustin Pop
  return []
152 62e0e880 Iustin Pop
153 62e0e880 Iustin Pop
154 8c9ee749 Michael Hanselmann
@WithDesc(str({}))
155 62e0e880 Iustin Pop
def EmptyDict():
156 62e0e880 Iustin Pop
  """Returns an empty dict.
157 62e0e880 Iustin Pop

158 62e0e880 Iustin Pop
  """
159 62e0e880 Iustin Pop
  return {}
160 62e0e880 Iustin Pop
161 62e0e880 Iustin Pop
162 62e0e880 Iustin Pop
#: The without-default default value
163 62e0e880 Iustin Pop
NoDefault = object()
164 62e0e880 Iustin Pop
165 62e0e880 Iustin Pop
166 62e0e880 Iustin Pop
# Some basic types
167 8620f50e Michael Hanselmann
@WithDesc("Anything")
168 8620f50e Michael Hanselmann
def TAny(_):
169 8620f50e Michael Hanselmann
  """Accepts any value.
170 8620f50e Michael Hanselmann

171 8620f50e Michael Hanselmann
  """
172 8620f50e Michael Hanselmann
  return True
173 8620f50e Michael Hanselmann
174 8620f50e Michael Hanselmann
175 8c9ee749 Michael Hanselmann
@WithDesc("NotNone")
176 62e0e880 Iustin Pop
def TNotNone(val):
177 62e0e880 Iustin Pop
  """Checks if the given value is not None.
178 62e0e880 Iustin Pop

179 62e0e880 Iustin Pop
  """
180 62e0e880 Iustin Pop
  return val is not None
181 62e0e880 Iustin Pop
182 62e0e880 Iustin Pop
183 8c9ee749 Michael Hanselmann
@WithDesc("None")
184 62e0e880 Iustin Pop
def TNone(val):
185 62e0e880 Iustin Pop
  """Checks if the given value is None.
186 62e0e880 Iustin Pop

187 62e0e880 Iustin Pop
  """
188 62e0e880 Iustin Pop
  return val is None
189 62e0e880 Iustin Pop
190 62e0e880 Iustin Pop
191 e055a2ab Dimitris Aragiorgis
@WithDesc("ValueNone")
192 e055a2ab Dimitris Aragiorgis
def TValueNone(val):
193 e055a2ab Dimitris Aragiorgis
  """Checks if the given value is L{constants.VALUE_NONE}.
194 e055a2ab Dimitris Aragiorgis

195 e055a2ab Dimitris Aragiorgis
  """
196 e055a2ab Dimitris Aragiorgis
  return val == constants.VALUE_NONE
197 e055a2ab Dimitris Aragiorgis
198 e055a2ab Dimitris Aragiorgis
199 8c9ee749 Michael Hanselmann
@WithDesc("Boolean")
200 62e0e880 Iustin Pop
def TBool(val):
201 62e0e880 Iustin Pop
  """Checks if the given value is a boolean.
202 62e0e880 Iustin Pop

203 62e0e880 Iustin Pop
  """
204 62e0e880 Iustin Pop
  return isinstance(val, bool)
205 62e0e880 Iustin Pop
206 62e0e880 Iustin Pop
207 8c9ee749 Michael Hanselmann
@WithDesc("Integer")
208 62e0e880 Iustin Pop
def TInt(val):
209 62e0e880 Iustin Pop
  """Checks if the given value is an integer.
210 62e0e880 Iustin Pop

211 62e0e880 Iustin Pop
  """
212 8568de9e Michael Hanselmann
  # For backwards compatibility with older Python versions, boolean values are
213 8568de9e Michael Hanselmann
  # also integers and should be excluded in this test.
214 8568de9e Michael Hanselmann
  #
215 8568de9e Michael Hanselmann
  # >>> (isinstance(False, int), isinstance(True, int))
216 8568de9e Michael Hanselmann
  # (True, True)
217 b99b607f Michael Hanselmann
  return isinstance(val, (int, long)) and not isinstance(val, bool)
218 62e0e880 Iustin Pop
219 62e0e880 Iustin Pop
220 8c9ee749 Michael Hanselmann
@WithDesc("Float")
221 62e0e880 Iustin Pop
def TFloat(val):
222 62e0e880 Iustin Pop
  """Checks if the given value is a float.
223 62e0e880 Iustin Pop

224 62e0e880 Iustin Pop
  """
225 62e0e880 Iustin Pop
  return isinstance(val, float)
226 62e0e880 Iustin Pop
227 62e0e880 Iustin Pop
228 8c9ee749 Michael Hanselmann
@WithDesc("String")
229 62e0e880 Iustin Pop
def TString(val):
230 62e0e880 Iustin Pop
  """Checks if the given value is a string.
231 62e0e880 Iustin Pop

232 62e0e880 Iustin Pop
  """
233 62e0e880 Iustin Pop
  return isinstance(val, basestring)
234 62e0e880 Iustin Pop
235 62e0e880 Iustin Pop
236 8c9ee749 Michael Hanselmann
@WithDesc("EvalToTrue")
237 62e0e880 Iustin Pop
def TTrue(val):
238 62e0e880 Iustin Pop
  """Checks if a given value evaluates to a boolean True value.
239 62e0e880 Iustin Pop

240 62e0e880 Iustin Pop
  """
241 62e0e880 Iustin Pop
  return bool(val)
242 62e0e880 Iustin Pop
243 62e0e880 Iustin Pop
244 62e0e880 Iustin Pop
def TElemOf(target_list):
245 62e0e880 Iustin Pop
  """Builds a function that checks if a given value is a member of a list.
246 62e0e880 Iustin Pop

247 62e0e880 Iustin Pop
  """
248 8c9ee749 Michael Hanselmann
  def fn(val):
249 8c9ee749 Michael Hanselmann
    return val in target_list
250 8c9ee749 Michael Hanselmann
251 8c9ee749 Michael Hanselmann
  return WithDesc("OneOf %s" % (utils.CommaJoin(target_list), ))(fn)
252 62e0e880 Iustin Pop
253 62e0e880 Iustin Pop
254 62e0e880 Iustin Pop
# Container types
255 8c9ee749 Michael Hanselmann
@WithDesc("List")
256 62e0e880 Iustin Pop
def TList(val):
257 62e0e880 Iustin Pop
  """Checks if the given value is a list.
258 62e0e880 Iustin Pop

259 62e0e880 Iustin Pop
  """
260 62e0e880 Iustin Pop
  return isinstance(val, list)
261 62e0e880 Iustin Pop
262 62e0e880 Iustin Pop
263 dd076c21 Iustin Pop
@WithDesc("Tuple")
264 dd076c21 Iustin Pop
def TTuple(val):
265 dd076c21 Iustin Pop
  """Checks if the given value is a tuple.
266 dd076c21 Iustin Pop

267 dd076c21 Iustin Pop
  """
268 dd076c21 Iustin Pop
  return isinstance(val, tuple)
269 dd076c21 Iustin Pop
270 dd076c21 Iustin Pop
271 8c9ee749 Michael Hanselmann
@WithDesc("Dictionary")
272 62e0e880 Iustin Pop
def TDict(val):
273 62e0e880 Iustin Pop
  """Checks if the given value is a dictionary.
274 62e0e880 Iustin Pop

275 4884f187 Santi Raffa
  Note that L{PrivateDict}s subclass dict and pass this check.
276 4884f187 Santi Raffa

277 62e0e880 Iustin Pop
  """
278 62e0e880 Iustin Pop
  return isinstance(val, dict)
279 62e0e880 Iustin Pop
280 62e0e880 Iustin Pop
281 62e0e880 Iustin Pop
def TIsLength(size):
282 62e0e880 Iustin Pop
  """Check is the given container is of the given size.
283 62e0e880 Iustin Pop

284 62e0e880 Iustin Pop
  """
285 8c9ee749 Michael Hanselmann
  def fn(container):
286 8c9ee749 Michael Hanselmann
    return len(container) == size
287 8c9ee749 Michael Hanselmann
288 8c9ee749 Michael Hanselmann
  return WithDesc("Length %s" % (size, ))(fn)
289 62e0e880 Iustin Pop
290 62e0e880 Iustin Pop
291 62e0e880 Iustin Pop
# Combinator types
292 62e0e880 Iustin Pop
def TAnd(*args):
293 62e0e880 Iustin Pop
  """Combine multiple functions using an AND operation.
294 62e0e880 Iustin Pop

295 62e0e880 Iustin Pop
  """
296 62e0e880 Iustin Pop
  def fn(val):
297 62e0e880 Iustin Pop
    return compat.all(t(val) for t in args)
298 8c9ee749 Michael Hanselmann
299 8c9ee749 Michael Hanselmann
  return CombinationDesc("and", args, fn)
300 62e0e880 Iustin Pop
301 62e0e880 Iustin Pop
302 62e0e880 Iustin Pop
def TOr(*args):
303 b3ab9a8a Christos Stavrakakis
  """Combine multiple functions using an OR operation.
304 62e0e880 Iustin Pop

305 62e0e880 Iustin Pop
  """
306 62e0e880 Iustin Pop
  def fn(val):
307 62e0e880 Iustin Pop
    return compat.any(t(val) for t in args)
308 8c9ee749 Michael Hanselmann
309 8c9ee749 Michael Hanselmann
  return CombinationDesc("or", args, fn)
310 62e0e880 Iustin Pop
311 62e0e880 Iustin Pop
312 62e0e880 Iustin Pop
def TMap(fn, test):
313 62e0e880 Iustin Pop
  """Checks that a modified version of the argument passes the given test.
314 62e0e880 Iustin Pop

315 62e0e880 Iustin Pop
  """
316 8c9ee749 Michael Hanselmann
  return WithDesc("Result of %s must be %s" %
317 8c9ee749 Michael Hanselmann
                  (Parens(fn), Parens(test)))(lambda val: test(fn(val)))
318 62e0e880 Iustin Pop
319 62e0e880 Iustin Pop
320 8620f50e Michael Hanselmann
def TRegex(pobj):
321 8620f50e Michael Hanselmann
  """Checks whether a string matches a specific regular expression.
322 8620f50e Michael Hanselmann

323 8620f50e Michael Hanselmann
  @param pobj: Compiled regular expression as returned by C{re.compile}
324 8620f50e Michael Hanselmann

325 8620f50e Michael Hanselmann
  """
326 8620f50e Michael Hanselmann
  desc = WithDesc("String matching regex \"%s\"" %
327 8620f50e Michael Hanselmann
                  pobj.pattern.encode("string_escape"))
328 8620f50e Michael Hanselmann
329 8620f50e Michael Hanselmann
  return desc(TAnd(TString, pobj.match))
330 8620f50e Michael Hanselmann
331 8620f50e Michael Hanselmann
332 fd9f58fd Iustin Pop
def TMaybe(test):
333 fd9f58fd Iustin Pop
  """Wrap a test in a TOr(TNone, test).
334 fd9f58fd Iustin Pop

335 fd9f58fd Iustin Pop
  This makes it easier to define TMaybe* types.
336 fd9f58fd Iustin Pop

337 fd9f58fd Iustin Pop
  """
338 fd9f58fd Iustin Pop
  return TOr(TNone, test)
339 fd9f58fd Iustin Pop
340 fd9f58fd Iustin Pop
341 e055a2ab Dimitris Aragiorgis
def TMaybeValueNone(test):
342 e055a2ab Dimitris Aragiorgis
  """Used for unsetting values.
343 e055a2ab Dimitris Aragiorgis

344 e055a2ab Dimitris Aragiorgis
  """
345 e055a2ab Dimitris Aragiorgis
  return TMaybe(TOr(TValueNone, test))
346 e055a2ab Dimitris Aragiorgis
347 e055a2ab Dimitris Aragiorgis
348 62e0e880 Iustin Pop
# Type aliases
349 62e0e880 Iustin Pop
350 62e0e880 Iustin Pop
#: a non-empty string
351 8c9ee749 Michael Hanselmann
TNonEmptyString = WithDesc("NonEmptyString")(TAnd(TString, TTrue))
352 62e0e880 Iustin Pop
353 62e0e880 Iustin Pop
#: a maybe non-empty string
354 fd9f58fd Iustin Pop
TMaybeString = TMaybe(TNonEmptyString)
355 62e0e880 Iustin Pop
356 62e0e880 Iustin Pop
#: a maybe boolean (bool or none)
357 fd9f58fd Iustin Pop
TMaybeBool = TMaybe(TBool)
358 62e0e880 Iustin Pop
359 5f074973 Michael Hanselmann
#: Maybe a dictionary (dict or None)
360 fd9f58fd Iustin Pop
TMaybeDict = TMaybe(TDict)
361 62e0e880 Iustin Pop
362 ab98e236 Michele Tartara
#: Maybe a list (list or None)
363 ab98e236 Michele Tartara
TMaybeList = TMaybe(TList)
364 ab98e236 Michele Tartara
365 72cd5493 Jose A. Lopes
366 72cd5493 Jose A. Lopes
#: a non-negative number (value > 0)
367 72cd5493 Jose A. Lopes
# val_type should be TInt, TDouble (== TFloat), or TNumber
368 72cd5493 Jose A. Lopes
def TNonNegative(val_type):
369 72cd5493 Jose A. Lopes
  return WithDesc("EqualOrGreaterThanZero")(TAnd(val_type, lambda v: v >= 0))
370 72cd5493 Jose A. Lopes
371 72cd5493 Jose A. Lopes
372 72cd5493 Jose A. Lopes
#: a positive number (value >= 0)
373 72cd5493 Jose A. Lopes
# val_type should be TInt, TDouble (== TFloat), or TNumber
374 72cd5493 Jose A. Lopes
def TPositive(val_type):
375 72cd5493 Jose A. Lopes
  return WithDesc("GreaterThanZero")(TAnd(val_type, lambda v: v > 0))
376 72cd5493 Jose A. Lopes
377 72cd5493 Jose A. Lopes
378 2c9fa1ff Iustin Pop
#: a non-negative integer (value >= 0)
379 72cd5493 Jose A. Lopes
TNonNegativeInt = TNonNegative(TInt)
380 2c9fa1ff Iustin Pop
381 2c9fa1ff Iustin Pop
#: a positive integer (value > 0)
382 72cd5493 Jose A. Lopes
TPositiveInt = TPositive(TInt)
383 62e0e880 Iustin Pop
384 2c0af7da Guido Trotter
#: a maybe positive integer (positive integer or None)
385 fd9f58fd Iustin Pop
TMaybePositiveInt = TMaybe(TPositiveInt)
386 2c0af7da Guido Trotter
387 2c9fa1ff Iustin Pop
#: a negative integer (value < 0)
388 2c9fa1ff Iustin Pop
TNegativeInt = \
389 b247c6fc Michael Hanselmann
  TAnd(TInt, WithDesc("LessThanZero")(compat.partial(operator.gt, 0)))
390 b247c6fc Michael Hanselmann
391 beff3779 Renรฉ Nussbaumer
#: a positive float
392 2c9fa1ff Iustin Pop
TNonNegativeFloat = \
393 2c9fa1ff Iustin Pop
  TAnd(TFloat, WithDesc("EqualOrGreaterThanZero")(lambda v: v >= 0.0))
394 beff3779 Renรฉ Nussbaumer
395 8620f50e Michael Hanselmann
#: Job ID
396 2c9fa1ff Iustin Pop
TJobId = WithDesc("JobId")(TOr(TNonNegativeInt,
397 bdfd7802 Michael Hanselmann
                               TRegex(re.compile("^%s$" %
398 bdfd7802 Michael Hanselmann
                                                 constants.JOB_ID_TEMPLATE))))
399 8620f50e Michael Hanselmann
400 72cd5493 Jose A. Lopes
#: Double (== Float)
401 72cd5493 Jose A. Lopes
TDouble = TFloat
402 72cd5493 Jose A. Lopes
403 697f49d5 Michael Hanselmann
#: Number
404 697f49d5 Michael Hanselmann
TNumber = TOr(TInt, TFloat)
405 697f49d5 Michael Hanselmann
406 b247c6fc Michael Hanselmann
#: Relative job ID
407 2c9fa1ff Iustin Pop
TRelativeJobId = WithDesc("RelativeJobId")(TNegativeInt)
408 b247c6fc Michael Hanselmann
409 62e0e880 Iustin Pop
410 16091a6e Michael Hanselmann
def TInstanceOf(cls):
411 16091a6e Michael Hanselmann
  """Checks if a given value is an instance of C{cls}.
412 16091a6e Michael Hanselmann

413 16091a6e Michael Hanselmann
  @type cls: class
414 16091a6e Michael Hanselmann
  @param cls: Class object
415 b1e47e2d Renรฉ Nussbaumer

416 b1e47e2d Renรฉ Nussbaumer
  """
417 16091a6e Michael Hanselmann
  name = "%s.%s" % (cls.__module__, cls.__name__)
418 16091a6e Michael Hanselmann
419 16091a6e Michael Hanselmann
  desc = WithDesc("Instance of %s" % (Parens(name), ))
420 16091a6e Michael Hanselmann
421 16091a6e Michael Hanselmann
  return desc(lambda val: isinstance(val, cls))
422 b1e47e2d Renรฉ Nussbaumer
423 b1e47e2d Renรฉ Nussbaumer
424 4884f187 Santi Raffa
def TPrivate(val_type):
425 4884f187 Santi Raffa
  """Checks if a given value is an instance of Private.
426 4884f187 Santi Raffa

427 4884f187 Santi Raffa
  """
428 4884f187 Santi Raffa
  def fn(val):
429 4884f187 Santi Raffa
    return isinstance(val, Private) and val_type(val.Get())
430 4884f187 Santi Raffa
431 4884f187 Santi Raffa
  desc = WithDesc("Private %s" % Parens(val_type))
432 4884f187 Santi Raffa
433 4884f187 Santi Raffa
  return desc(fn)
434 4884f187 Santi Raffa
435 4884f187 Santi Raffa
436 62e0e880 Iustin Pop
def TListOf(my_type):
437 62e0e880 Iustin Pop
  """Checks if a given value is a list with all elements of the same type.
438 62e0e880 Iustin Pop

439 62e0e880 Iustin Pop
  """
440 8c9ee749 Michael Hanselmann
  desc = WithDesc("List of %s" % (Parens(my_type), ))
441 8c9ee749 Michael Hanselmann
  return desc(TAnd(TList, lambda lst: compat.all(my_type(v) for v in lst)))
442 62e0e880 Iustin Pop
443 62e0e880 Iustin Pop
444 fd9f58fd Iustin Pop
TMaybeListOf = lambda item_type: TMaybe(TListOf(item_type))
445 ff8067cf Michael Hanselmann
446 ff8067cf Michael Hanselmann
447 72cd5493 Jose A. Lopes
def TTupleOf(*val_types):
448 72cd5493 Jose A. Lopes
  """Checks if a given value is a list with the proper size and its
449 72cd5493 Jose A. Lopes
     elements match the given types.
450 72cd5493 Jose A. Lopes

451 72cd5493 Jose A. Lopes
  """
452 72cd5493 Jose A. Lopes
  desc = WithDesc("Tuple of %s" % (Parens(val_types), ))
453 72cd5493 Jose A. Lopes
  return desc(TAnd(TIsLength(len(val_types)), TItems(val_types)))
454 72cd5493 Jose A. Lopes
455 72cd5493 Jose A. Lopes
456 72cd5493 Jose A. Lopes
def TSetOf(val_type):
457 72cd5493 Jose A. Lopes
  """Checks if a given value is a list with all elements of the same
458 72cd5493 Jose A. Lopes
     type and eliminates duplicated elements.
459 72cd5493 Jose A. Lopes

460 72cd5493 Jose A. Lopes
  """
461 72cd5493 Jose A. Lopes
  desc = WithDesc("Set of %s" % (Parens(val_type), ))
462 72cd5493 Jose A. Lopes
  return desc(lambda st: TListOf(val_type)(list(set(st))))
463 72cd5493 Jose A. Lopes
464 72cd5493 Jose A. Lopes
465 62e0e880 Iustin Pop
def TDictOf(key_type, val_type):
466 62e0e880 Iustin Pop
  """Checks a dict type for the type of its key/values.
467 62e0e880 Iustin Pop

468 62e0e880 Iustin Pop
  """
469 8c9ee749 Michael Hanselmann
  desc = WithDesc("Dictionary with keys of %s and values of %s" %
470 8c9ee749 Michael Hanselmann
                  (Parens(key_type), Parens(val_type)))
471 8c9ee749 Michael Hanselmann
472 8c9ee749 Michael Hanselmann
  def fn(container):
473 8c9ee749 Michael Hanselmann
    return (compat.all(key_type(v) for v in container.keys()) and
474 8c9ee749 Michael Hanselmann
            compat.all(val_type(v) for v in container.values()))
475 8c9ee749 Michael Hanselmann
476 8c9ee749 Michael Hanselmann
  return desc(TAnd(TDict, fn))
477 a464ce71 Michael Hanselmann
478 a464ce71 Michael Hanselmann
479 a464ce71 Michael Hanselmann
def _TStrictDictCheck(require_all, exclusive, items, val):
480 a464ce71 Michael Hanselmann
  """Helper function for L{TStrictDict}.
481 a464ce71 Michael Hanselmann

482 a464ce71 Michael Hanselmann
  """
483 a464ce71 Michael Hanselmann
  notfound_fn = lambda _: not exclusive
484 a464ce71 Michael Hanselmann
485 a464ce71 Michael Hanselmann
  if require_all and not frozenset(val.keys()).issuperset(items.keys()):
486 a464ce71 Michael Hanselmann
    # Requires items not found in value
487 a464ce71 Michael Hanselmann
    return False
488 a464ce71 Michael Hanselmann
489 a464ce71 Michael Hanselmann
  return compat.all(items.get(key, notfound_fn)(value)
490 a464ce71 Michael Hanselmann
                    for (key, value) in val.items())
491 a464ce71 Michael Hanselmann
492 a464ce71 Michael Hanselmann
493 a464ce71 Michael Hanselmann
def TStrictDict(require_all, exclusive, items):
494 a464ce71 Michael Hanselmann
  """Strict dictionary check with specific keys.
495 a464ce71 Michael Hanselmann

496 a464ce71 Michael Hanselmann
  @type require_all: boolean
497 a464ce71 Michael Hanselmann
  @param require_all: Whether all keys in L{items} are required
498 a464ce71 Michael Hanselmann
  @type exclusive: boolean
499 a464ce71 Michael Hanselmann
  @param exclusive: Whether only keys listed in L{items} should be accepted
500 a464ce71 Michael Hanselmann
  @type items: dictionary
501 a464ce71 Michael Hanselmann
  @param items: Mapping from key (string) to verification function
502 a464ce71 Michael Hanselmann

503 a464ce71 Michael Hanselmann
  """
504 a464ce71 Michael Hanselmann
  descparts = ["Dictionary containing"]
505 a464ce71 Michael Hanselmann
506 a464ce71 Michael Hanselmann
  if exclusive:
507 a464ce71 Michael Hanselmann
    descparts.append(" none but the")
508 a464ce71 Michael Hanselmann
509 a464ce71 Michael Hanselmann
  if require_all:
510 a464ce71 Michael Hanselmann
    descparts.append(" required")
511 a464ce71 Michael Hanselmann
512 a464ce71 Michael Hanselmann
  if len(items) == 1:
513 a464ce71 Michael Hanselmann
    descparts.append(" key ")
514 a464ce71 Michael Hanselmann
  else:
515 a464ce71 Michael Hanselmann
    descparts.append(" keys ")
516 a464ce71 Michael Hanselmann
517 a464ce71 Michael Hanselmann
  descparts.append(utils.CommaJoin("\"%s\" (value %s)" % (key, value)
518 a464ce71 Michael Hanselmann
                                   for (key, value) in items.items()))
519 a464ce71 Michael Hanselmann
520 a464ce71 Michael Hanselmann
  desc = WithDesc("".join(descparts))
521 a464ce71 Michael Hanselmann
522 a464ce71 Michael Hanselmann
  return desc(TAnd(TDict,
523 a464ce71 Michael Hanselmann
                   compat.partial(_TStrictDictCheck, require_all, exclusive,
524 a464ce71 Michael Hanselmann
                                  items)))
525 8620f50e Michael Hanselmann
526 8620f50e Michael Hanselmann
527 8620f50e Michael Hanselmann
def TItems(items):
528 8620f50e Michael Hanselmann
  """Checks individual items of a container.
529 8620f50e Michael Hanselmann

530 8620f50e Michael Hanselmann
  If the verified value and the list of expected items differ in length, this
531 8620f50e Michael Hanselmann
  check considers only as many items as are contained in the shorter list. Use
532 8620f50e Michael Hanselmann
  L{TIsLength} to enforce a certain length.
533 8620f50e Michael Hanselmann

534 8620f50e Michael Hanselmann
  @type items: list
535 8620f50e Michael Hanselmann
  @param items: List of checks
536 8620f50e Michael Hanselmann

537 8620f50e Michael Hanselmann
  """
538 8620f50e Michael Hanselmann
  assert items, "Need items"
539 8620f50e Michael Hanselmann
540 8620f50e Michael Hanselmann
  text = ["Item", "item"]
541 8620f50e Michael Hanselmann
  desc = WithDesc(utils.CommaJoin("%s %s is %s" %
542 8620f50e Michael Hanselmann
                                  (text[int(idx > 0)], idx, Parens(check))
543 8620f50e Michael Hanselmann
                                  for (idx, check) in enumerate(items)))
544 8620f50e Michael Hanselmann
545 8620f50e Michael Hanselmann
  return desc(lambda value: compat.all(check(i)
546 8620f50e Michael Hanselmann
                                       for (check, i) in zip(items, value)))
547 72cd5493 Jose A. Lopes
548 72cd5493 Jose A. Lopes
549 72cd5493 Jose A. Lopes
TAllocPolicy = TElemOf(constants.VALID_ALLOC_POLICIES)
550 72cd5493 Jose A. Lopes
TCVErrorCode = TElemOf(constants.CV_ALL_ECODES_STRINGS)
551 72cd5493 Jose A. Lopes
TQueryResultCode = TElemOf(constants.RS_ALL)
552 72cd5493 Jose A. Lopes
TExportTarget = TOr(TNonEmptyString, TList)
553 72cd5493 Jose A. Lopes
TExportMode = TElemOf(constants.EXPORT_MODES)
554 72cd5493 Jose A. Lopes
TDiskIndex = TAnd(TNonNegativeInt, lambda val: val < constants.MAX_DISKS)
555 72cd5493 Jose A. Lopes
TReplaceDisksMode = TElemOf(constants.REPLACE_MODES)
556 72cd5493 Jose A. Lopes
TDiskTemplate = TElemOf(constants.DISK_TEMPLATES)
557 d067f40b Jose A. Lopes
TEvacMode = TElemOf(constants.NODE_EVAC_MODES)
558 72cd5493 Jose A. Lopes
TIAllocatorTestDir = TElemOf(constants.VALID_IALLOCATOR_DIRECTIONS)
559 72cd5493 Jose A. Lopes
TIAllocatorMode = TElemOf(constants.VALID_IALLOCATOR_MODES)
560 f198cf91 Thomas Thrainer
TImportExportCompression = TElemOf(constants.IEC_ALL)
561 72cd5493 Jose A. Lopes
562 72cd5493 Jose A. Lopes
563 72cd5493 Jose A. Lopes
def TSetParamsMods(fn):
564 72cd5493 Jose A. Lopes
  """Generates a check for modification lists.
565 72cd5493 Jose A. Lopes

566 72cd5493 Jose A. Lopes
  """
567 72cd5493 Jose A. Lopes
  # Old format
568 72cd5493 Jose A. Lopes
  # TODO: Remove in version 2.11 including support in LUInstanceSetParams
569 72cd5493 Jose A. Lopes
  old_mod_item_fn = \
570 72cd5493 Jose A. Lopes
    TAnd(TIsLength(2),
571 72cd5493 Jose A. Lopes
         TItems([TOr(TElemOf(constants.DDMS_VALUES), TNonNegativeInt), fn]))
572 72cd5493 Jose A. Lopes
573 72cd5493 Jose A. Lopes
  # New format, supporting adding/removing disks/NICs at arbitrary indices
574 72cd5493 Jose A. Lopes
  mod_item_fn = \
575 72cd5493 Jose A. Lopes
      TAnd(TIsLength(3), TItems([
576 72cd5493 Jose A. Lopes
        TElemOf(constants.DDMS_VALUES_WITH_MODIFY),
577 72cd5493 Jose A. Lopes
        Comment("Device index, can be negative, e.g. -1 for last disk")
578 72cd5493 Jose A. Lopes
                 (TOr(TInt, TString)),
579 72cd5493 Jose A. Lopes
        fn,
580 72cd5493 Jose A. Lopes
        ]))
581 72cd5493 Jose A. Lopes
582 72cd5493 Jose A. Lopes
  return TOr(Comment("Recommended")(TListOf(mod_item_fn)),
583 72cd5493 Jose A. Lopes
             Comment("Deprecated")(TListOf(old_mod_item_fn)))
584 72cd5493 Jose A. Lopes
585 72cd5493 Jose A. Lopes
586 72cd5493 Jose A. Lopes
TINicParams = \
587 72cd5493 Jose A. Lopes
    Comment("NIC parameters")(TDictOf(TElemOf(constants.INIC_PARAMS),
588 9e67e425 Jose A. Lopes
                                      TMaybe(TString)))
589 72cd5493 Jose A. Lopes
590 72cd5493 Jose A. Lopes
TIDiskParams = \
591 b26a275a Klaus Aehlig
    Comment("Disk parameters")(TDictOf(TNonEmptyString,
592 72cd5493 Jose A. Lopes
                                       TOr(TNonEmptyString, TInt)))
593 72cd5493 Jose A. Lopes
594 72cd5493 Jose A. Lopes
THypervisor = TElemOf(constants.HYPER_TYPES)
595 72cd5493 Jose A. Lopes
TMigrationMode = TElemOf(constants.HT_MIGRATION_MODES)
596 72cd5493 Jose A. Lopes
TNICMode = TElemOf(constants.NIC_VALID_MODES)
597 72cd5493 Jose A. Lopes
TInstCreateMode = TElemOf(constants.INSTANCE_CREATE_MODES)
598 72cd5493 Jose A. Lopes
TRebootType = TElemOf(constants.REBOOT_TYPES)
599 72cd5493 Jose A. Lopes
TFileDriver = TElemOf(constants.FILE_DRIVER)
600 72cd5493 Jose A. Lopes
TOobCommand = TElemOf(constants.OOB_COMMANDS)
601 a9532fb0 Helga Velroyen
# FIXME: adjust this after all queries are in haskell
602 a9532fb0 Helga Velroyen
TQueryTypeOp = TElemOf(set(constants.QR_VIA_OP)
603 a9532fb0 Helga Velroyen
                       .union(set(constants.QR_VIA_LUXI)))
604 72cd5493 Jose A. Lopes
605 72cd5493 Jose A. Lopes
TDiskParams = \
606 72cd5493 Jose A. Lopes
    Comment("Disk parameters")(TDictOf(TNonEmptyString,
607 72cd5493 Jose A. Lopes
                                       TOr(TNonEmptyString, TInt)))
608 72cd5493 Jose A. Lopes
609 72cd5493 Jose A. Lopes
TDiskChanges = \
610 72cd5493 Jose A. Lopes
    TAnd(TIsLength(2),
611 72cd5493 Jose A. Lopes
         TItems([Comment("Disk index")(TNonNegativeInt),
612 72cd5493 Jose A. Lopes
                 Comment("Parameters")(TDiskParams)]))
613 72cd5493 Jose A. Lopes
614 72cd5493 Jose A. Lopes
TRecreateDisksInfo = TOr(TListOf(TNonNegativeInt), TListOf(TDiskChanges))
615 72cd5493 Jose A. Lopes
616 72cd5493 Jose A. Lopes
617 72cd5493 Jose A. Lopes
def TStorageType(val):
618 72cd5493 Jose A. Lopes
  """Builds a function that checks if a given value is a valid storage
619 72cd5493 Jose A. Lopes
  type.
620 72cd5493 Jose A. Lopes

621 72cd5493 Jose A. Lopes
  """
622 72cd5493 Jose A. Lopes
  return (val in constants.STORAGE_TYPES)
623 72cd5493 Jose A. Lopes
624 72cd5493 Jose A. Lopes
625 72cd5493 Jose A. Lopes
TTagKind = TElemOf(constants.VALID_TAG_TYPES)
626 72cd5493 Jose A. Lopes
TDdmSimple = TElemOf(constants.DDMS_VALUES)
627 72cd5493 Jose A. Lopes
TVerifyOptionalChecks = TElemOf(constants.VERIFY_OPTIONAL_CHECKS)
628 72cd5493 Jose A. Lopes
629 72cd5493 Jose A. Lopes
630 72cd5493 Jose A. Lopes
@WithDesc("IPv4 network")
631 72cd5493 Jose A. Lopes
def _CheckCIDRNetNotation(value):
632 72cd5493 Jose A. Lopes
  """Ensure a given CIDR notation type is valid.
633 72cd5493 Jose A. Lopes

634 72cd5493 Jose A. Lopes
  """
635 72cd5493 Jose A. Lopes
  try:
636 72cd5493 Jose A. Lopes
    ipaddr.IPv4Network(value)
637 72cd5493 Jose A. Lopes
  except ipaddr.AddressValueError:
638 72cd5493 Jose A. Lopes
    return False
639 72cd5493 Jose A. Lopes
  return True
640 72cd5493 Jose A. Lopes
641 72cd5493 Jose A. Lopes
642 72cd5493 Jose A. Lopes
@WithDesc("IPv4 address")
643 72cd5493 Jose A. Lopes
def _CheckCIDRAddrNotation(value):
644 72cd5493 Jose A. Lopes
  """Ensure a given CIDR notation type is valid.
645 72cd5493 Jose A. Lopes

646 72cd5493 Jose A. Lopes
  """
647 72cd5493 Jose A. Lopes
  try:
648 72cd5493 Jose A. Lopes
    ipaddr.IPv4Address(value)
649 72cd5493 Jose A. Lopes
  except ipaddr.AddressValueError:
650 72cd5493 Jose A. Lopes
    return False
651 72cd5493 Jose A. Lopes
  return True
652 72cd5493 Jose A. Lopes
653 72cd5493 Jose A. Lopes
654 72cd5493 Jose A. Lopes
@WithDesc("IPv6 address")
655 72cd5493 Jose A. Lopes
def _CheckCIDR6AddrNotation(value):
656 72cd5493 Jose A. Lopes
  """Ensure a given CIDR notation type is valid.
657 72cd5493 Jose A. Lopes

658 72cd5493 Jose A. Lopes
  """
659 72cd5493 Jose A. Lopes
  try:
660 72cd5493 Jose A. Lopes
    ipaddr.IPv6Address(value)
661 72cd5493 Jose A. Lopes
  except ipaddr.AddressValueError:
662 72cd5493 Jose A. Lopes
    return False
663 72cd5493 Jose A. Lopes
  return True
664 72cd5493 Jose A. Lopes
665 72cd5493 Jose A. Lopes
666 72cd5493 Jose A. Lopes
@WithDesc("IPv6 network")
667 72cd5493 Jose A. Lopes
def _CheckCIDR6NetNotation(value):
668 72cd5493 Jose A. Lopes
  """Ensure a given CIDR notation type is valid.
669 72cd5493 Jose A. Lopes

670 72cd5493 Jose A. Lopes
  """
671 72cd5493 Jose A. Lopes
  try:
672 72cd5493 Jose A. Lopes
    ipaddr.IPv6Network(value)
673 72cd5493 Jose A. Lopes
  except ipaddr.AddressValueError:
674 72cd5493 Jose A. Lopes
    return False
675 72cd5493 Jose A. Lopes
  return True
676 72cd5493 Jose A. Lopes
677 72cd5493 Jose A. Lopes
678 72cd5493 Jose A. Lopes
TIPv4Address = TAnd(TString, _CheckCIDRAddrNotation)
679 72cd5493 Jose A. Lopes
TIPv6Address = TAnd(TString, _CheckCIDR6AddrNotation)
680 72cd5493 Jose A. Lopes
TIPv4Network = TAnd(TString, _CheckCIDRNetNotation)
681 72cd5493 Jose A. Lopes
TIPv6Network = TAnd(TString, _CheckCIDR6NetNotation)
682 72cd5493 Jose A. Lopes
683 72cd5493 Jose A. Lopes
684 72cd5493 Jose A. Lopes
def TObject(val_type):
685 72cd5493 Jose A. Lopes
  return TDictOf(TAny, val_type)
686 72cd5493 Jose A. Lopes
687 72cd5493 Jose A. Lopes
688 72cd5493 Jose A. Lopes
def TObjectCheck(obj, fields_types):
689 72cd5493 Jose A. Lopes
  """Helper to generate type checks for objects.
690 72cd5493 Jose A. Lopes

691 72cd5493 Jose A. Lopes
  @param obj: The object to generate type checks
692 72cd5493 Jose A. Lopes
  @param fields_types: The fields and their types as a dict
693 72cd5493 Jose A. Lopes
  @return: A ht type check function
694 72cd5493 Jose A. Lopes

695 72cd5493 Jose A. Lopes
  """
696 72cd5493 Jose A. Lopes
  assert set(obj.GetAllSlots()) == set(fields_types.keys()), \
697 72cd5493 Jose A. Lopes
    "%s != %s" % (set(obj.GetAllSlots()), set(fields_types.keys()))
698 72cd5493 Jose A. Lopes
  return TStrictDict(True, True, fields_types)
699 72cd5493 Jose A. Lopes
700 72cd5493 Jose A. Lopes
701 72cd5493 Jose A. Lopes
TQueryFieldDef = \
702 72cd5493 Jose A. Lopes
    TObjectCheck(objects.QueryFieldDefinition, {
703 72cd5493 Jose A. Lopes
        "name": TNonEmptyString,
704 72cd5493 Jose A. Lopes
        "title": TNonEmptyString,
705 72cd5493 Jose A. Lopes
        "kind": TElemOf(constants.QFT_ALL),
706 72cd5493 Jose A. Lopes
        "doc": TNonEmptyString
707 72cd5493 Jose A. Lopes
    })
708 72cd5493 Jose A. Lopes
709 72cd5493 Jose A. Lopes
TQueryRow = \
710 72cd5493 Jose A. Lopes
    TListOf(TAnd(TIsLength(2),
711 72cd5493 Jose A. Lopes
                 TItems([TElemOf(constants.RS_ALL), TAny])))
712 72cd5493 Jose A. Lopes
713 72cd5493 Jose A. Lopes
TQueryResult = TListOf(TQueryRow)
714 72cd5493 Jose A. Lopes
715 72cd5493 Jose A. Lopes
TQueryResponse = \
716 72cd5493 Jose A. Lopes
    TObjectCheck(objects.QueryResponse, {
717 72cd5493 Jose A. Lopes
        "fields": TListOf(TQueryFieldDef),
718 72cd5493 Jose A. Lopes
        "data": TQueryResult
719 72cd5493 Jose A. Lopes
    })
720 72cd5493 Jose A. Lopes
721 72cd5493 Jose A. Lopes
TQueryFieldsResponse = \
722 72cd5493 Jose A. Lopes
    TObjectCheck(objects.QueryFieldsResponse, {
723 72cd5493 Jose A. Lopes
        "fields": TListOf(TQueryFieldDef)
724 72cd5493 Jose A. Lopes
    })
725 72cd5493 Jose A. Lopes
726 72cd5493 Jose A. Lopes
TJobIdListItem = \
727 72cd5493 Jose A. Lopes
    TAnd(TIsLength(2),
728 72cd5493 Jose A. Lopes
         TItems([Comment("success")(TBool),
729 72cd5493 Jose A. Lopes
                 Comment("Job ID if successful, error message"
730 72cd5493 Jose A. Lopes
                         " otherwise")(TOr(TString, TJobId))]))
731 72cd5493 Jose A. Lopes
732 72cd5493 Jose A. Lopes
TJobIdList = TListOf(TJobIdListItem)
733 72cd5493 Jose A. Lopes
734 72cd5493 Jose A. Lopes
TJobIdListOnly = TStrictDict(True, True, {
735 72cd5493 Jose A. Lopes
  constants.JOB_IDS_KEY: Comment("List of submitted jobs")(TJobIdList)
736 72cd5493 Jose A. Lopes
  })
737 72cd5493 Jose A. Lopes
738 72cd5493 Jose A. Lopes
TInstanceMultiAllocResponse = \
739 72cd5493 Jose A. Lopes
    TStrictDict(True, True, {
740 72cd5493 Jose A. Lopes
      constants.JOB_IDS_KEY: Comment("List of submitted jobs")(TJobIdList),
741 884dc063 Jose A. Lopes
      constants.ALLOCATABLE_KEY: TListOf(TNonEmptyString),
742 884dc063 Jose A. Lopes
      constants.FAILED_KEY: TListOf(TNonEmptyString)
743 72cd5493 Jose A. Lopes
    })