1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 """Remote API base resources library.
23
24 """
25
26
27
28
29
30 import logging
31
32 from ganeti import luxi
33 from ganeti import rapi
34 from ganeti import http
35 from ganeti import ssconf
36 from ganeti import constants
37 from ganeti import opcodes
38 from ganeti import errors
39
40
41
42 _DEFAULT = object()
43
44
45 -def BuildUriList(ids, uri_format, uri_fields=("name", "uri")):
46 """Builds a URI list as used by index resources.
47
48 @param ids: list of ids as strings
49 @param uri_format: format to be applied for URI
50 @param uri_fields: optional parameter for field IDs
51
52 """
53 (field_id, field_uri) = uri_fields
54
55 def _MapId(m_id):
56 return { field_id: m_id, field_uri: uri_format % m_id, }
57
58
59
60 ids.sort()
61
62 return map(_MapId, ids)
63
64
66 """Creates a list containing one column out of a list of lists.
67
68 @param sequence: sequence of lists
69 @param index: index of field
70
71 """
72 return map(lambda item: item[index], sequence)
73
74
76 """Maps two lists into one dictionary.
77
78 Example::
79 >>> MapFields(["a", "b"], ["foo", 123])
80 {'a': 'foo', 'b': 123}
81
82 @param names: field names (list of strings)
83 @param data: field data (list)
84
85 """
86 if len(names) != len(data):
87 raise AttributeError("Names and data must have the same length")
88 return dict(zip(names, data))
89
90
112
113
120
121
128
129
131 """Map value to field name in to one dictionary.
132
133 @param itemslist: a list of items values
134 @param fields: a list of items names
135
136 @return: a list of mapped dictionaries
137
138 """
139 items_details = []
140 for item in itemslist:
141 mapped = MapFields(fields, item)
142 items_details.append(mapped)
143 return items_details
144
145
147 """Makes params dictionary out of a option set.
148
149 This function returns a dictionary needed for hv or be parameters. But only
150 those fields which provided in the option set. Takes parameters frozensets
151 from constants.
152
153 @type opts: dict
154 @param opts: selected options
155 @type params: frozenset
156 @param params: subset of options
157 @rtype: dict
158 @return: dictionary of options, filtered by given subset.
159
160 """
161 result = {}
162
163 for p in params:
164 try:
165 value = opts[p]
166 except KeyError:
167 continue
168 result[p] = value
169
170 return result
171
172
200
201
213
214
226
227
229 """Feedback logging function for jobs.
230
231 We don't have a stdout for printing log messages, so log them to the
232 http log at least.
233
234 @param msg: the message
235
236 """
237 (_, log_type, log_msg) = msg
238 logging.info("%s: %s", log_type, log_msg)
239
240
242 """Abort request if value type doesn't match expected type.
243
244 @param value: Value
245 @type exptype: type
246 @param exptype: Expected type
247 @type descr: string
248 @param descr: Description of value
249 @return: Value (allows inline usage)
250
251 """
252 if not isinstance(value, exptype):
253 raise http.HttpBadRequest("%s: Type is '%s', but '%s' is expected" %
254 (descr, type(value).__name__, exptype.__name__))
255
256 return value
257
258
260 """Check and return the value for a given parameter.
261
262 If no default value was given and the parameter doesn't exist in the input
263 data, an error is raise.
264
265 @type data: dict
266 @param data: Dictionary containing input data
267 @type name: string
268 @param name: Parameter name
269 @param default: Default value (can be None)
270 @param exptype: Expected type (can be None)
271
272 """
273 try:
274 value = data[name]
275 except KeyError:
276 if default is not _DEFAULT:
277 return default
278
279 raise http.HttpBadRequest("Required parameter '%s' is missing" %
280 name)
281
282 if exptype is _DEFAULT:
283 return value
284
285 return CheckType(value, exptype, "'%s' parameter" % name)
286
287
289 """Generic class for resources.
290
291 """
292
293 GET_ACCESS = []
294 PUT_ACCESS = [rapi.RAPI_ACCESS_WRITE]
295 POST_ACCESS = [rapi.RAPI_ACCESS_WRITE]
296 DELETE_ACCESS = [rapi.RAPI_ACCESS_WRITE]
297
298 - def __init__(self, items, queryargs, req):
299 """Generic resource constructor.
300
301 @param items: a list with variables encoded in the URL
302 @param queryargs: a dictionary with additional options from URL
303
304 """
305 self.items = items
306 self.queryargs = queryargs
307 self._req = req
308
309 - def _GetRequestBody(self):
310 """Returns the body data.
311
312 """
313 return self._req.private.body_data
314
315 request_body = property(fget=_GetRequestBody)
316
318 """Return the parsed value of an int argument.
319
320 """
321 val = self.queryargs.get(name, default)
322 if isinstance(val, list):
323 if val:
324 val = val[0]
325 else:
326 val = default
327 try:
328 val = int(val)
329 except (ValueError, TypeError):
330 raise http.HttpBadRequest("Invalid value for the"
331 " '%s' parameter" % (name,))
332 return val
333
335 """Return the parsed value of an int argument.
336
337 """
338 val = self.queryargs.get(name, default)
339 if isinstance(val, list):
340 if val:
341 val = val[0]
342 else:
343 val = default
344 return val
345
346 - def getBodyParameter(self, name, *args):
347 """Check and return the value for a given parameter.
348
349 If a second parameter is not given, an error will be returned,
350 otherwise this parameter specifies the default value.
351
352 @param name: the required parameter
353
354 """
355 if args:
356 return CheckParameter(self.request_body, name, default=args[0])
357
358 return CheckParameter(self.request_body, name)
359
361 """Check if the request specifies locking.
362
363 """
364 return bool(self._checkIntVariable("lock"))
365
367 """Check if the request specifies bulk querying.
368
369 """
370 return bool(self._checkIntVariable("bulk"))
371
373 """Check if the request specifies a forced operation.
374
375 """
376 return bool(self._checkIntVariable("force"))
377
379 """Check if the request specifies dry-run mode.
380
381 """
382 return bool(self._checkIntVariable("dry-run"))
383