4 # Copyright (C) 2006, 2007, 2008 Google Inc.
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2 of the License, or
9 # (at your option) any later version.
11 # This program is distributed in the hope that it will be useful, but
12 # WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 # General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22 """Remote API base resources library.
29 from ganeti import luxi
30 from ganeti import rapi
31 from ganeti import http
34 def BuildUriList(ids, uri_format, uri_fields=("name", "uri")):
35 """Builds a URI list as used by index resources.
37 @param ids: list of ids as strings
38 @param uri_format: format to be applied for URI
39 @param uri_fields: optional parameter for field IDs
42 (field_id, field_uri) = uri_fields
45 return { field_id: m_id, field_uri: uri_format % m_id, }
47 # Make sure the result is sorted, makes it nicer to look at and simplifies
51 return map(_MapId, ids)
54 def ExtractField(sequence, index):
55 """Creates a list containing one column out of a list of lists.
57 @param sequence: sequence of lists
58 @param index: index of field
61 return map(lambda item: item[index], sequence)
64 def MapFields(names, data):
65 """Maps two lists into one dictionary.
68 >>> MapFields(["a", "b"], ["foo", 123])
69 {'a': 'foo', 'b': 123}
71 @param names: field names (list of strings)
72 @param data: field data (list)
75 if len(names) != len(data):
76 raise AttributeError("Names and data must have the same length")
77 return dict(zip(names, data))
80 def _Tags_GET(kind, name=""):
81 """Helper function to retrieve tags.
84 op = ganeti.opcodes.OpGetTags(kind=kind, name=name)
85 tags = ganeti.cli.SubmitOpCode(op)
89 def _Tags_PUT(kind, tags, name=""):
90 """Helper function to set tags.
94 return cl.SubmitJob([ganeti.opcodes.OpAddTags(kind=kind, name=name,
98 def _Tags_DELETE(kind, tags, name=""):
99 """Helper function to delete tags.
103 return cl.SubmitJob([ganeti.opcodes.OpDelTags(kind=kind, name=name,
107 def MapBulkFields(itemslist, fields):
108 """Map value to field name in to one dictionary.
110 @param itemslist: a list of items values
111 @param fields: a list of items names
113 @return: a list of mapped dictionaries
117 for item in itemslist:
118 mapped = MapFields(fields, item)
119 items_details.append(mapped)
123 def MakeParamsDict(opts, params):
124 """Makes params dictionary out of a option set.
126 This function returns a dictionary needed for hv or be parameters. But only
127 those fields which provided in the option set. Takes parameters frozensets
131 @param opts: selected options
132 @type params: frozenset
133 @param params: subset of options
135 @return: dictionary of options, filtered by given subset.
150 class R_Generic(object):
151 """Generic class for resources.
154 # Default permission requirements
156 PUT_ACCESS = [rapi.RAPI_ACCESS_WRITE]
157 POST_ACCESS = [rapi.RAPI_ACCESS_WRITE]
158 DELETE_ACCESS = [rapi.RAPI_ACCESS_WRITE]
160 def __init__(self, items, queryargs, req):
161 """Generic resource constructor.
163 @param items: a list with variables encoded in the URL
164 @param queryargs: a dictionary with additional options from URL
168 self.queryargs = queryargs
172 def getSerialNumber(self):
173 """Get Serial Number.
178 def _checkIntVariable(self, name):
179 """Return the parsed value of an int argument.
182 val = self.queryargs.get(name, 0)
183 if isinstance(val, list):
190 except (ValueError, TypeError), err:
191 raise http.HttpBadRequest("Invalid value for the"
192 " '%s' parameter" % (name,))
195 def getBodyParameter(self, name, *args):
196 """Check and return the value for a given parameter.
198 If a second parameter is not given, an error will be returned,
199 otherwise this parameter specifies the default value.
201 @param name: the required parameter
204 if name in self.req.request_body:
205 return self.req.request_body[name]
209 raise http.HttpBadRequest("Required parameter '%s' is missing" %
212 def useLocking(self):
213 """Check if the request specifies locking.
216 return self._checkIntVariable('lock')
219 """Check if the request specifies bulk querying.
222 return self._checkIntVariable('bulk')