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 | }) |