Statistics
| Branch: | Tag: | Revision:

root / lib / rapi / rlib2.py @ 59b4eeef

History | View | Annotate | Download (14.7 kB)

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

24 10b207d4 Oleksiy Mishchenko
"""
25 10b207d4 Oleksiy Mishchenko
26 59b4eeef Iustin Pop
from ganeti import opcodes
27 15fd9fd5 Oleksiy Mishchenko
from ganeti import http
28 15fd9fd5 Oleksiy Mishchenko
from ganeti import constants
29 59b4eeef Iustin Pop
from ganeti import cli
30 38206f3c Iustin Pop
from ganeti.rapi import baserlib
31 10b207d4 Oleksiy Mishchenko
32 4e5a68f8 Oleksiy Mishchenko
33 59b4eeef Iustin Pop
34 9031ee8e Iustin Pop
I_FIELDS = ["name", "admin_state", "os",
35 9031ee8e Iustin Pop
            "pnode", "snodes",
36 9031ee8e Iustin Pop
            "disk_template",
37 9031ee8e Iustin Pop
            "nic.ips", "nic.macs", "nic.bridges",
38 a8b16c4e Tim Boring
            "network_port",
39 024e157f Iustin Pop
            "disk.sizes", "disk_usage",
40 a5b9d725 Iustin Pop
            "beparams", "hvparams",
41 9031ee8e Iustin Pop
            "oper_state", "oper_ram", "status",
42 9031ee8e Iustin Pop
            "tags"]
43 9031ee8e Iustin Pop
44 0b2454b9 Iustin Pop
N_FIELDS = ["name", "offline", "master_candidate", "drained",
45 9031ee8e Iustin Pop
            "dtotal", "dfree",
46 4e5a68f8 Oleksiy Mishchenko
            "mtotal", "mnode", "mfree",
47 0105bad3 Iustin Pop
            "pinst_cnt", "sinst_cnt", "tags",
48 0105bad3 Iustin Pop
            "ctotal", "cnodes", "csockets",
49 0105bad3 Iustin Pop
            ]
50 4e5a68f8 Oleksiy Mishchenko
51 4e5a68f8 Oleksiy Mishchenko
52 4e5a68f8 Oleksiy Mishchenko
class R_version(baserlib.R_Generic):
53 4e5a68f8 Oleksiy Mishchenko
  """/version resource.
54 4e5a68f8 Oleksiy Mishchenko

55 4e5a68f8 Oleksiy Mishchenko
  This resource should be used to determine the remote API version and
56 4e5a68f8 Oleksiy Mishchenko
  to adapt clients accordingly.
57 4e5a68f8 Oleksiy Mishchenko

58 4e5a68f8 Oleksiy Mishchenko
  """
59 4e5a68f8 Oleksiy Mishchenko
  DOC_URI = "/version"
60 4e5a68f8 Oleksiy Mishchenko
61 4e5a68f8 Oleksiy Mishchenko
  def GET(self):
62 4e5a68f8 Oleksiy Mishchenko
    """Returns the remote API version.
63 4e5a68f8 Oleksiy Mishchenko

64 4e5a68f8 Oleksiy Mishchenko
    """
65 4e5a68f8 Oleksiy Mishchenko
    return constants.RAPI_VERSION
66 4e5a68f8 Oleksiy Mishchenko
67 4e5a68f8 Oleksiy Mishchenko
68 4e5a68f8 Oleksiy Mishchenko
class R_2_info(baserlib.R_Generic):
69 4e5a68f8 Oleksiy Mishchenko
  """Cluster info.
70 4e5a68f8 Oleksiy Mishchenko

71 4e5a68f8 Oleksiy Mishchenko
  """
72 4e5a68f8 Oleksiy Mishchenko
  DOC_URI = "/2/info"
73 4e5a68f8 Oleksiy Mishchenko
74 4e5a68f8 Oleksiy Mishchenko
  def GET(self):
75 4e5a68f8 Oleksiy Mishchenko
    """Returns cluster information.
76 4e5a68f8 Oleksiy Mishchenko

77 4e5a68f8 Oleksiy Mishchenko
    Example::
78 4e5a68f8 Oleksiy Mishchenko

79 bf4a90af Iustin Pop
    {
80 bf4a90af Iustin Pop
      "config_version": 2000000,
81 bf4a90af Iustin Pop
      "name": "cluster",
82 74aa2478 Iustin Pop
      "software_version": "2.0.0~beta2",
83 bf4a90af Iustin Pop
      "os_api_version": 10,
84 bf4a90af Iustin Pop
      "export_version": 0,
85 bf4a90af Iustin Pop
      "candidate_pool_size": 10,
86 bf4a90af Iustin Pop
      "enabled_hypervisors": [
87 bf4a90af Iustin Pop
        "fake"
88 bf4a90af Iustin Pop
      ],
89 bf4a90af Iustin Pop
      "hvparams": {
90 bf4a90af Iustin Pop
        "fake": {}
91 bf4a90af Iustin Pop
       },
92 bf4a90af Iustin Pop
      "default_hypervisor": "fake",
93 bf4a90af Iustin Pop
      "master": "node1.example.com",
94 bf4a90af Iustin Pop
      "architecture": [
95 bf4a90af Iustin Pop
        "64bit",
96 bf4a90af Iustin Pop
        "x86_64"
97 bf4a90af Iustin Pop
      ],
98 bf4a90af Iustin Pop
      "protocol_version": 20,
99 bf4a90af Iustin Pop
      "beparams": {
100 bf4a90af Iustin Pop
        "default": {
101 bf4a90af Iustin Pop
          "auto_balance": true,
102 bf4a90af Iustin Pop
          "vcpus": 1,
103 bf4a90af Iustin Pop
          "memory": 128
104 bf4a90af Iustin Pop
         }
105 bf4a90af Iustin Pop
        }
106 4e5a68f8 Oleksiy Mishchenko
      }
107 4e5a68f8 Oleksiy Mishchenko

108 4e5a68f8 Oleksiy Mishchenko
    """
109 59b4eeef Iustin Pop
    client = baserlib.GetClient()
110 9031ee8e Iustin Pop
    return client.QueryClusterInfo()
111 4e5a68f8 Oleksiy Mishchenko
112 4e5a68f8 Oleksiy Mishchenko
113 4e5a68f8 Oleksiy Mishchenko
class R_2_os(baserlib.R_Generic):
114 4e5a68f8 Oleksiy Mishchenko
  """/2/os resource.
115 4e5a68f8 Oleksiy Mishchenko

116 4e5a68f8 Oleksiy Mishchenko
  """
117 4e5a68f8 Oleksiy Mishchenko
  DOC_URI = "/2/os"
118 4e5a68f8 Oleksiy Mishchenko
119 4e5a68f8 Oleksiy Mishchenko
  def GET(self):
120 4e5a68f8 Oleksiy Mishchenko
    """Return a list of all OSes.
121 4e5a68f8 Oleksiy Mishchenko

122 4e5a68f8 Oleksiy Mishchenko
    Can return error 500 in case of a problem.
123 4e5a68f8 Oleksiy Mishchenko

124 4e5a68f8 Oleksiy Mishchenko
    Example: ["debian-etch"]
125 4e5a68f8 Oleksiy Mishchenko

126 4e5a68f8 Oleksiy Mishchenko
    """
127 59b4eeef Iustin Pop
    cl = baserlib.GetClient()
128 59b4eeef Iustin Pop
    op = opcodes.OpDiagnoseOS(output_fields=["name", "valid"], names=[])
129 59b4eeef Iustin Pop
    job_id = baserlib.SubmitJob([op], cl)
130 59b4eeef Iustin Pop
    # we use custom feedback function, instead of print we log the status
131 59b4eeef Iustin Pop
    result = cli.PollJob(job_id, cl, feedback_fn=baserlib.FeedbackFn)
132 59b4eeef Iustin Pop
    diagnose_data = result[0]
133 4e5a68f8 Oleksiy Mishchenko
134 4e5a68f8 Oleksiy Mishchenko
    if not isinstance(diagnose_data, list):
135 59b4eeef Iustin Pop
      raise http.HttpBadGateway(message="Can't get OS list")
136 4e5a68f8 Oleksiy Mishchenko
137 4e5a68f8 Oleksiy Mishchenko
    return [row[0] for row in diagnose_data if row[1]]
138 51ee2f49 Oleksiy Mishchenko
139 10b207d4 Oleksiy Mishchenko
140 10b207d4 Oleksiy Mishchenko
class R_2_jobs(baserlib.R_Generic):
141 10b207d4 Oleksiy Mishchenko
  """/2/jobs resource.
142 10b207d4 Oleksiy Mishchenko

143 10b207d4 Oleksiy Mishchenko
  """
144 10b207d4 Oleksiy Mishchenko
  DOC_URI = "/2/jobs"
145 10b207d4 Oleksiy Mishchenko
146 10b207d4 Oleksiy Mishchenko
  def GET(self):
147 10b207d4 Oleksiy Mishchenko
    """Returns a dictionary of jobs.
148 10b207d4 Oleksiy Mishchenko

149 c41eea6e Iustin Pop
    @return: a dictionary with jobs id and uri.
150 38206f3c Iustin Pop

151 10b207d4 Oleksiy Mishchenko
    """
152 10b207d4 Oleksiy Mishchenko
    fields = ["id"]
153 59b4eeef Iustin Pop
    cl = baserlib.GetClient()
154 10b207d4 Oleksiy Mishchenko
    # Convert the list of lists to the list of ids
155 59b4eeef Iustin Pop
    result = [job_id for [job_id] in cl.QueryJobs(None, fields)]
156 9031ee8e Iustin Pop
    return baserlib.BuildUriList(result, "/2/jobs/%s",
157 9031ee8e Iustin Pop
                                 uri_fields=("id", "uri"))
158 10b207d4 Oleksiy Mishchenko
159 10b207d4 Oleksiy Mishchenko
160 10b207d4 Oleksiy Mishchenko
class R_2_jobs_id(baserlib.R_Generic):
161 10b207d4 Oleksiy Mishchenko
  """/2/jobs/[job_id] resource.
162 10b207d4 Oleksiy Mishchenko

163 10b207d4 Oleksiy Mishchenko
  """
164 10b207d4 Oleksiy Mishchenko
  DOC_URI = "/2/jobs/[job_id]"
165 10b207d4 Oleksiy Mishchenko
166 10b207d4 Oleksiy Mishchenko
  def GET(self):
167 10b207d4 Oleksiy Mishchenko
    """Returns a job status.
168 10b207d4 Oleksiy Mishchenko

169 c41eea6e Iustin Pop
    @return: a dictionary with job parameters.
170 c41eea6e Iustin Pop
        The result includes:
171 c41eea6e Iustin Pop
            - id: job ID as a number
172 c41eea6e Iustin Pop
            - status: current job status as a string
173 c41eea6e Iustin Pop
            - ops: involved OpCodes as a list of dictionaries for each
174 c41eea6e Iustin Pop
              opcodes in the job
175 c41eea6e Iustin Pop
            - opstatus: OpCodes status as a list
176 c41eea6e Iustin Pop
            - opresult: OpCodes results as a list of lists
177 38206f3c Iustin Pop

178 10b207d4 Oleksiy Mishchenko
    """
179 ee69c97f Iustin Pop
    fields = ["id", "ops", "status", "summary",
180 ee69c97f Iustin Pop
              "opstatus", "opresult", "oplog",
181 ee69c97f Iustin Pop
              "received_ts", "start_ts", "end_ts",
182 ee69c97f Iustin Pop
              ]
183 10b207d4 Oleksiy Mishchenko
    job_id = self.items[0]
184 59b4eeef Iustin Pop
    result = baserlib.GetClient().QueryJobs([job_id, ], fields)[0]
185 ee69c97f Iustin Pop
    if result is None:
186 ee69c97f Iustin Pop
      raise http.HttpNotFound()
187 10b207d4 Oleksiy Mishchenko
    return baserlib.MapFields(fields, result)
188 10b207d4 Oleksiy Mishchenko
189 c7f5f338 Oleksiy Mishchenko
  def DELETE(self):
190 c7f5f338 Oleksiy Mishchenko
    """Cancel not-yet-started job.
191 c7f5f338 Oleksiy Mishchenko

192 c7f5f338 Oleksiy Mishchenko
    """
193 c7f5f338 Oleksiy Mishchenko
    job_id = self.items[0]
194 59b4eeef Iustin Pop
    result = baserlib.GetClient().CancelJob(job_id)
195 c7f5f338 Oleksiy Mishchenko
    return result
196 c7f5f338 Oleksiy Mishchenko
197 10b207d4 Oleksiy Mishchenko
198 10b207d4 Oleksiy Mishchenko
class R_2_nodes(baserlib.R_Generic):
199 10b207d4 Oleksiy Mishchenko
  """/2/nodes resource.
200 10b207d4 Oleksiy Mishchenko

201 10b207d4 Oleksiy Mishchenko
  """
202 10b207d4 Oleksiy Mishchenko
  DOC_URI = "/2/nodes"
203 38206f3c Iustin Pop
204 10b207d4 Oleksiy Mishchenko
  def GET(self):
205 10b207d4 Oleksiy Mishchenko
    """Returns a list of all nodes.
206 38206f3c Iustin Pop

207 c41eea6e Iustin Pop
    Example::
208 10b207d4 Oleksiy Mishchenko

209 c41eea6e Iustin Pop
      [
210 10b207d4 Oleksiy Mishchenko
        {
211 10b207d4 Oleksiy Mishchenko
          "id": "node1.example.com",
212 10b207d4 Oleksiy Mishchenko
          "uri": "\/instances\/node1.example.com"
213 10b207d4 Oleksiy Mishchenko
        },
214 10b207d4 Oleksiy Mishchenko
        {
215 10b207d4 Oleksiy Mishchenko
          "id": "node2.example.com",
216 10b207d4 Oleksiy Mishchenko
          "uri": "\/instances\/node2.example.com"
217 c41eea6e Iustin Pop
        }
218 c41eea6e Iustin Pop
      ]
219 10b207d4 Oleksiy Mishchenko

220 38206f3c Iustin Pop
    If the optional 'bulk' argument is provided and set to 'true'
221 10b207d4 Oleksiy Mishchenko
    value (i.e '?bulk=1'), the output contains detailed
222 10b207d4 Oleksiy Mishchenko
    information about nodes as a list.
223 10b207d4 Oleksiy Mishchenko

224 c41eea6e Iustin Pop
    Example::
225 c41eea6e Iustin Pop

226 c41eea6e Iustin Pop
      [
227 10b207d4 Oleksiy Mishchenko
        {
228 10b207d4 Oleksiy Mishchenko
          "pinst_cnt": 1,
229 10b207d4 Oleksiy Mishchenko
          "mfree": 31280,
230 10b207d4 Oleksiy Mishchenko
          "mtotal": 32763,
231 10b207d4 Oleksiy Mishchenko
          "name": "www.example.com",
232 10b207d4 Oleksiy Mishchenko
          "tags": [],
233 10b207d4 Oleksiy Mishchenko
          "mnode": 512,
234 10b207d4 Oleksiy Mishchenko
          "dtotal": 5246208,
235 10b207d4 Oleksiy Mishchenko
          "sinst_cnt": 2,
236 9031ee8e Iustin Pop
          "dfree": 5171712,
237 9031ee8e Iustin Pop
          "offline": false
238 10b207d4 Oleksiy Mishchenko
        },
239 10b207d4 Oleksiy Mishchenko
        ...
240 c41eea6e Iustin Pop
      ]
241 c41eea6e Iustin Pop

242 c41eea6e Iustin Pop
    @return: a dictionary with 'name' and 'uri' keys for each of them
243 10b207d4 Oleksiy Mishchenko

244 10b207d4 Oleksiy Mishchenko
    """
245 59b4eeef Iustin Pop
    client = baserlib.GetClient()
246 38206f3c Iustin Pop
247 3d103742 Iustin Pop
    if self.useBulk():
248 9031ee8e Iustin Pop
      bulkdata = client.QueryNodes([], N_FIELDS, False)
249 a0dcf7c2 Oleksiy Mishchenko
      return baserlib.MapBulkFields(bulkdata, N_FIELDS)
250 9031ee8e Iustin Pop
    else:
251 9031ee8e Iustin Pop
      nodesdata = client.QueryNodes([], ["name"], False)
252 9031ee8e Iustin Pop
      nodeslist = [row[0] for row in nodesdata]
253 9031ee8e Iustin Pop
      return baserlib.BuildUriList(nodeslist, "/2/nodes/%s",
254 9031ee8e Iustin Pop
                                   uri_fields=("id", "uri"))
255 441e7cfd Oleksiy Mishchenko
256 441e7cfd Oleksiy Mishchenko
257 4e5a68f8 Oleksiy Mishchenko
class R_2_nodes_name(baserlib.R_Generic):
258 4e5a68f8 Oleksiy Mishchenko
  """/2/nodes/[node_name] resources.
259 028c6b76 Oleksiy Mishchenko

260 028c6b76 Oleksiy Mishchenko
  """
261 4e5a68f8 Oleksiy Mishchenko
  DOC_URI = "/nodes/[node_name]"
262 4e5a68f8 Oleksiy Mishchenko
263 4e5a68f8 Oleksiy Mishchenko
  def GET(self):
264 4e5a68f8 Oleksiy Mishchenko
    """Send information about a node.
265 4e5a68f8 Oleksiy Mishchenko

266 4e5a68f8 Oleksiy Mishchenko
    """
267 4e5a68f8 Oleksiy Mishchenko
    node_name = self.items[0]
268 59b4eeef Iustin Pop
    client = baserlib.GetClient()
269 9031ee8e Iustin Pop
    result = client.QueryNodes(names=[node_name], fields=N_FIELDS,
270 3d103742 Iustin Pop
                               use_locking=self.useLocking())
271 4e5a68f8 Oleksiy Mishchenko
272 4e5a68f8 Oleksiy Mishchenko
    return baserlib.MapFields(N_FIELDS, result[0])
273 028c6b76 Oleksiy Mishchenko
274 028c6b76 Oleksiy Mishchenko
275 441e7cfd Oleksiy Mishchenko
class R_2_instances(baserlib.R_Generic):
276 441e7cfd Oleksiy Mishchenko
  """/2/instances resource.
277 441e7cfd Oleksiy Mishchenko

278 441e7cfd Oleksiy Mishchenko
  """
279 441e7cfd Oleksiy Mishchenko
  DOC_URI = "/2/instances"
280 441e7cfd Oleksiy Mishchenko
281 441e7cfd Oleksiy Mishchenko
  def GET(self):
282 441e7cfd Oleksiy Mishchenko
    """Returns a list of all available instances.
283 441e7cfd Oleksiy Mishchenko

284 441e7cfd Oleksiy Mishchenko

285 c41eea6e Iustin Pop
    Example::
286 c41eea6e Iustin Pop

287 c41eea6e Iustin Pop
      [
288 441e7cfd Oleksiy Mishchenko
        {
289 441e7cfd Oleksiy Mishchenko
          "name": "web.example.com",
290 441e7cfd Oleksiy Mishchenko
          "uri": "\/instances\/web.example.com"
291 441e7cfd Oleksiy Mishchenko
        },
292 441e7cfd Oleksiy Mishchenko
        {
293 441e7cfd Oleksiy Mishchenko
          "name": "mail.example.com",
294 441e7cfd Oleksiy Mishchenko
          "uri": "\/instances\/mail.example.com"
295 c41eea6e Iustin Pop
        }
296 c41eea6e Iustin Pop
      ]
297 441e7cfd Oleksiy Mishchenko

298 441e7cfd Oleksiy Mishchenko
    If the optional 'bulk' argument is provided and set to 'true'
299 441e7cfd Oleksiy Mishchenko
    value (i.e '?bulk=1'), the output contains detailed
300 441e7cfd Oleksiy Mishchenko
    information about instances as a list.
301 441e7cfd Oleksiy Mishchenko

302 c41eea6e Iustin Pop
    Example::
303 c41eea6e Iustin Pop

304 c41eea6e Iustin Pop
      [
305 441e7cfd Oleksiy Mishchenko
        {
306 441e7cfd Oleksiy Mishchenko
           "status": "running",
307 bf4a90af Iustin Pop
           "disk_usage": 20480,
308 bf4a90af Iustin Pop
           "nic.bridges": [
309 bf4a90af Iustin Pop
             "xen-br0"
310 bf4a90af Iustin Pop
            ],
311 441e7cfd Oleksiy Mishchenko
           "name": "web.example.com",
312 441e7cfd Oleksiy Mishchenko
           "tags": ["tag1", "tag2"],
313 bf4a90af Iustin Pop
           "beparams": {
314 bf4a90af Iustin Pop
             "vcpus": 2,
315 bf4a90af Iustin Pop
             "memory": 512
316 bf4a90af Iustin Pop
           },
317 bf4a90af Iustin Pop
           "disk.sizes": [
318 bf4a90af Iustin Pop
               20480
319 bf4a90af Iustin Pop
           ],
320 441e7cfd Oleksiy Mishchenko
           "pnode": "node1.example.com",
321 bf4a90af Iustin Pop
           "nic.macs": ["01:23:45:67:89:01"],
322 441e7cfd Oleksiy Mishchenko
           "snodes": ["node2.example.com"],
323 441e7cfd Oleksiy Mishchenko
           "disk_template": "drbd",
324 441e7cfd Oleksiy Mishchenko
           "admin_state": true,
325 441e7cfd Oleksiy Mishchenko
           "os": "debian-etch",
326 441e7cfd Oleksiy Mishchenko
           "oper_state": true
327 441e7cfd Oleksiy Mishchenko
        },
328 441e7cfd Oleksiy Mishchenko
        ...
329 c41eea6e Iustin Pop
      ]
330 c41eea6e Iustin Pop

331 5fcc718f Iustin Pop
    @return: a dictionary with 'name' and 'uri' keys for each of them.
332 441e7cfd Oleksiy Mishchenko

333 441e7cfd Oleksiy Mishchenko
    """
334 59b4eeef Iustin Pop
    client = baserlib.GetClient()
335 441e7cfd Oleksiy Mishchenko
336 3d103742 Iustin Pop
    use_locking = self.useLocking()
337 3d103742 Iustin Pop
    if self.useBulk():
338 3d103742 Iustin Pop
      bulkdata = client.QueryInstances([], I_FIELDS, use_locking)
339 a0dcf7c2 Oleksiy Mishchenko
      return baserlib.MapBulkFields(bulkdata, I_FIELDS)
340 441e7cfd Oleksiy Mishchenko
    else:
341 3d103742 Iustin Pop
      instancesdata = client.QueryInstances([], ["name"], use_locking)
342 9031ee8e Iustin Pop
      instanceslist = [row[0] for row in instancesdata]
343 441e7cfd Oleksiy Mishchenko
      return baserlib.BuildUriList(instanceslist, "/2/instances/%s",
344 441e7cfd Oleksiy Mishchenko
                                   uri_fields=("id", "uri"))
345 441e7cfd Oleksiy Mishchenko
346 21f04e5e Oleksiy Mishchenko
  def POST(self):
347 2f7635f4 Oleksiy Mishchenko
    """Create an instance.
348 2f7635f4 Oleksiy Mishchenko

349 5fcc718f Iustin Pop
    @return: a job id
350 2f7635f4 Oleksiy Mishchenko

351 2f7635f4 Oleksiy Mishchenko
    """
352 6e99c5a0 Iustin Pop
    if not isinstance(self.req.request_body, dict):
353 6e99c5a0 Iustin Pop
      raise http.HttpBadRequest("Invalid body contents, not a dictionary")
354 6e99c5a0 Iustin Pop
355 6e99c5a0 Iustin Pop
    beparams = baserlib.MakeParamsDict(self.req.request_body,
356 6e99c5a0 Iustin Pop
                                       constants.BES_PARAMETERS)
357 6e99c5a0 Iustin Pop
    hvparams = baserlib.MakeParamsDict(self.req.request_body,
358 6e99c5a0 Iustin Pop
                                       constants.HVS_PARAMETERS)
359 6e99c5a0 Iustin Pop
    fn = self.getBodyParameter
360 6e99c5a0 Iustin Pop
361 6e99c5a0 Iustin Pop
    # disk processing
362 6e99c5a0 Iustin Pop
    disk_data = fn('disks')
363 6e99c5a0 Iustin Pop
    if not isinstance(disk_data, list):
364 6e99c5a0 Iustin Pop
      raise http.HttpBadRequest("The 'disks' parameter should be a list")
365 6e99c5a0 Iustin Pop
    disks = []
366 6e99c5a0 Iustin Pop
    for idx, d in enumerate(disk_data):
367 6e99c5a0 Iustin Pop
      if not isinstance(d, int):
368 6e99c5a0 Iustin Pop
        raise http.HttpBadRequest("Disk %d specification wrong: should"
369 6e99c5a0 Iustin Pop
                                  " be an integer")
370 6e99c5a0 Iustin Pop
      disks.append({"size": d})
371 6e99c5a0 Iustin Pop
    # nic processing (one nic only)
372 6e99c5a0 Iustin Pop
    nics = [{"mac": fn("mac", constants.VALUE_AUTO),
373 6e99c5a0 Iustin Pop
             "ip": fn("ip", None),
374 6e99c5a0 Iustin Pop
             "bridge": fn("bridge", None)}]
375 2f7635f4 Oleksiy Mishchenko
376 59b4eeef Iustin Pop
    op = opcodes.OpCreateInstance(
377 59b4eeef Iustin Pop
      mode=constants.INSTANCE_CREATE,
378 59b4eeef Iustin Pop
      instance_name=fn('name'),
379 59b4eeef Iustin Pop
      disks=disks,
380 59b4eeef Iustin Pop
      disk_template=fn('disk_template'),
381 59b4eeef Iustin Pop
      os_type=fn('os'),
382 59b4eeef Iustin Pop
      pnode=fn('pnode', None),
383 59b4eeef Iustin Pop
      snode=fn('snode', None),
384 59b4eeef Iustin Pop
      iallocator=fn('iallocator', None),
385 59b4eeef Iustin Pop
      nics=nics,
386 59b4eeef Iustin Pop
      start=fn('start', True),
387 59b4eeef Iustin Pop
      ip_check=fn('ip_check', True),
388 59b4eeef Iustin Pop
      wait_for_sync=True,
389 59b4eeef Iustin Pop
      hypervisor=fn('hypervisor', None),
390 59b4eeef Iustin Pop
      hvparams=hvparams,
391 59b4eeef Iustin Pop
      beparams=beparams,
392 59b4eeef Iustin Pop
      file_storage_dir=fn('file_storage_dir', None),
393 59b4eeef Iustin Pop
      file_driver=fn('file_driver', 'loop'),
394 59b4eeef Iustin Pop
      )
395 59b4eeef Iustin Pop
396 59b4eeef Iustin Pop
    return baserlib.SubmitJob([op])
397 2f7635f4 Oleksiy Mishchenko
398 441e7cfd Oleksiy Mishchenko
399 4e5a68f8 Oleksiy Mishchenko
class R_2_instances_name(baserlib.R_Generic):
400 4e5a68f8 Oleksiy Mishchenko
  """/2/instances/[instance_name] resources.
401 028c6b76 Oleksiy Mishchenko

402 028c6b76 Oleksiy Mishchenko
  """
403 4e5a68f8 Oleksiy Mishchenko
  DOC_URI = "/2/instances/[instance_name]"
404 4e5a68f8 Oleksiy Mishchenko
405 4e5a68f8 Oleksiy Mishchenko
  def GET(self):
406 4e5a68f8 Oleksiy Mishchenko
    """Send information about an instance.
407 4e5a68f8 Oleksiy Mishchenko

408 4e5a68f8 Oleksiy Mishchenko
    """
409 59b4eeef Iustin Pop
    client = baserlib.GetClient()
410 4e5a68f8 Oleksiy Mishchenko
    instance_name = self.items[0]
411 9031ee8e Iustin Pop
    result = client.QueryInstances(names=[instance_name], fields=I_FIELDS,
412 3d103742 Iustin Pop
                                   use_locking=self.useLocking())
413 4e5a68f8 Oleksiy Mishchenko
414 4e5a68f8 Oleksiy Mishchenko
    return baserlib.MapFields(I_FIELDS, result[0])
415 028c6b76 Oleksiy Mishchenko
416 6e99c5a0 Iustin Pop
  def DELETE(self):
417 6e99c5a0 Iustin Pop
    """Delete an instance.
418 6e99c5a0 Iustin Pop

419 6e99c5a0 Iustin Pop
    """
420 59b4eeef Iustin Pop
    op = opcodes.OpRemoveInstance(instance_name=self.items[0],
421 59b4eeef Iustin Pop
                                  ignore_failures=False)
422 59b4eeef Iustin Pop
    return baserlib.SubmitJob([op])
423 6e99c5a0 Iustin Pop
424 028c6b76 Oleksiy Mishchenko
425 2276aa29 Oleksiy Mishchenko
class R_2_instances_name_reboot(baserlib.R_Generic):
426 2276aa29 Oleksiy Mishchenko
  """/2/instances/[instance_name]/reboot resource.
427 2276aa29 Oleksiy Mishchenko

428 2276aa29 Oleksiy Mishchenko
  Implements an instance reboot.
429 2276aa29 Oleksiy Mishchenko

430 2276aa29 Oleksiy Mishchenko
  """
431 2276aa29 Oleksiy Mishchenko
432 2276aa29 Oleksiy Mishchenko
  DOC_URI = "/2/instances/[instance_name]/reboot"
433 2276aa29 Oleksiy Mishchenko
434 21f04e5e Oleksiy Mishchenko
  def POST(self):
435 2276aa29 Oleksiy Mishchenko
    """Reboot an instance.
436 2276aa29 Oleksiy Mishchenko

437 0c55c24b Oleksiy Mishchenko
    The URI takes type=[hard|soft|full] and
438 0c55c24b Oleksiy Mishchenko
    ignore_secondaries=[False|True] parameters.
439 0c55c24b Oleksiy Mishchenko

440 2276aa29 Oleksiy Mishchenko
    """
441 2276aa29 Oleksiy Mishchenko
    instance_name = self.items[0]
442 0c55c24b Oleksiy Mishchenko
    reboot_type = self.queryargs.get('type',
443 0c55c24b Oleksiy Mishchenko
                                     [constants.INSTANCE_REBOOT_HARD])[0]
444 0c55c24b Oleksiy Mishchenko
    ignore_secondaries = bool(self.queryargs.get('ignore_secondaries',
445 0c55c24b Oleksiy Mishchenko
                                                 [False])[0])
446 59b4eeef Iustin Pop
    op = opcodes.OpRebootInstance(instance_name=instance_name,
447 59b4eeef Iustin Pop
                                  reboot_type=reboot_type,
448 59b4eeef Iustin Pop
                                  ignore_secondaries=ignore_secondaries)
449 2276aa29 Oleksiy Mishchenko
450 59b4eeef Iustin Pop
    return baserlib.SubmitJob([op])
451 2276aa29 Oleksiy Mishchenko
452 2276aa29 Oleksiy Mishchenko
453 0c55c24b Oleksiy Mishchenko
class R_2_instances_name_startup(baserlib.R_Generic):
454 0c55c24b Oleksiy Mishchenko
  """/2/instances/[instance_name]/startup resource.
455 0c55c24b Oleksiy Mishchenko

456 0c55c24b Oleksiy Mishchenko
  Implements an instance startup.
457 0c55c24b Oleksiy Mishchenko

458 0c55c24b Oleksiy Mishchenko
  """
459 0c55c24b Oleksiy Mishchenko
460 0c55c24b Oleksiy Mishchenko
  DOC_URI = "/2/instances/[instance_name]/startup"
461 0c55c24b Oleksiy Mishchenko
462 21f04e5e Oleksiy Mishchenko
  def PUT(self):
463 0c55c24b Oleksiy Mishchenko
    """Startup an instance.
464 0c55c24b Oleksiy Mishchenko

465 c41eea6e Iustin Pop
    The URI takes force=[False|True] parameter to start the instance
466 c41eea6e Iustin Pop
    if even if secondary disks are failing.
467 0c55c24b Oleksiy Mishchenko

468 0c55c24b Oleksiy Mishchenko
    """
469 0c55c24b Oleksiy Mishchenko
    instance_name = self.items[0]
470 0c55c24b Oleksiy Mishchenko
    force_startup = bool(self.queryargs.get('force', [False])[0])
471 59b4eeef Iustin Pop
    op = opcodes.OpStartupInstance(instance_name=instance_name,
472 59b4eeef Iustin Pop
                                   force=force_startup)
473 0c55c24b Oleksiy Mishchenko
474 59b4eeef Iustin Pop
    return baserlib.SubmitJob([op])
475 0c55c24b Oleksiy Mishchenko
476 0c55c24b Oleksiy Mishchenko
477 0c55c24b Oleksiy Mishchenko
class R_2_instances_name_shutdown(baserlib.R_Generic):
478 0c55c24b Oleksiy Mishchenko
  """/2/instances/[instance_name]/shutdown resource.
479 0c55c24b Oleksiy Mishchenko

480 0c55c24b Oleksiy Mishchenko
  Implements an instance shutdown.
481 0c55c24b Oleksiy Mishchenko

482 0c55c24b Oleksiy Mishchenko
  """
483 0c55c24b Oleksiy Mishchenko
484 0c55c24b Oleksiy Mishchenko
  DOC_URI = "/2/instances/[instance_name]/shutdown"
485 0c55c24b Oleksiy Mishchenko
486 21f04e5e Oleksiy Mishchenko
  def PUT(self):
487 0c55c24b Oleksiy Mishchenko
    """Shutdown an instance.
488 0c55c24b Oleksiy Mishchenko

489 0c55c24b Oleksiy Mishchenko
    """
490 0c55c24b Oleksiy Mishchenko
    instance_name = self.items[0]
491 59b4eeef Iustin Pop
    op = opcodes.OpShutdownInstance(instance_name=instance_name)
492 0c55c24b Oleksiy Mishchenko
493 59b4eeef Iustin Pop
    return baserlib.SubmitJob([op])
494 0c55c24b Oleksiy Mishchenko
495 0c55c24b Oleksiy Mishchenko
496 18cb43a2 Oleksiy Mishchenko
class _R_Tags(baserlib.R_Generic):
497 18cb43a2 Oleksiy Mishchenko
  """ Quasiclass for tagging resources
498 441e7cfd Oleksiy Mishchenko

499 18cb43a2 Oleksiy Mishchenko
  Manages tags. Inheriting this class you suppose to define DOC_URI and
500 18cb43a2 Oleksiy Mishchenko
  TAG_LEVEL for it.
501 441e7cfd Oleksiy Mishchenko

502 441e7cfd Oleksiy Mishchenko
  """
503 7a6b9510 Iustin Pop
  TAG_LEVEL = None
504 18cb43a2 Oleksiy Mishchenko
505 18cb43a2 Oleksiy Mishchenko
  def __init__(self, items, queryargs, req):
506 18cb43a2 Oleksiy Mishchenko
    """A tag resource constructor.
507 18cb43a2 Oleksiy Mishchenko

508 18cb43a2 Oleksiy Mishchenko
    We have to override the default to sort out cluster naming case.
509 18cb43a2 Oleksiy Mishchenko

510 18cb43a2 Oleksiy Mishchenko
    """
511 18cb43a2 Oleksiy Mishchenko
    baserlib.R_Generic.__init__(self, items, queryargs, req)
512 18cb43a2 Oleksiy Mishchenko
513 18cb43a2 Oleksiy Mishchenko
    if self.TAG_LEVEL != constants.TAG_CLUSTER:
514 18cb43a2 Oleksiy Mishchenko
      self.name = items[0]
515 18cb43a2 Oleksiy Mishchenko
    else:
516 18cb43a2 Oleksiy Mishchenko
      self.name = ""
517 441e7cfd Oleksiy Mishchenko
518 441e7cfd Oleksiy Mishchenko
  def GET(self):
519 18cb43a2 Oleksiy Mishchenko
    """Returns a list of tags.
520 441e7cfd Oleksiy Mishchenko

521 441e7cfd Oleksiy Mishchenko
    Example: ["tag1", "tag2", "tag3"]
522 441e7cfd Oleksiy Mishchenko

523 441e7cfd Oleksiy Mishchenko
    """
524 18cb43a2 Oleksiy Mishchenko
    return baserlib._Tags_GET(self.TAG_LEVEL, name=self.name)
525 441e7cfd Oleksiy Mishchenko
526 21f04e5e Oleksiy Mishchenko
  def PUT(self):
527 18cb43a2 Oleksiy Mishchenko
    """Add a set of tags.
528 441e7cfd Oleksiy Mishchenko

529 c41eea6e Iustin Pop
    The request as a list of strings should be PUT to this URI. And
530 c41eea6e Iustin Pop
    you'll have back a job id.
531 441e7cfd Oleksiy Mishchenko

532 441e7cfd Oleksiy Mishchenko
    """
533 6e99c5a0 Iustin Pop
    if 'tag' not in self.queryargs:
534 6e99c5a0 Iustin Pop
      raise http.HttpBadRequest("Please specify tag(s) to add using the"
535 6e99c5a0 Iustin Pop
                                " the 'tag' parameter")
536 18cb43a2 Oleksiy Mishchenko
    return baserlib._Tags_PUT(self.TAG_LEVEL,
537 6e99c5a0 Iustin Pop
                              self.queryargs['tag'], name=self.name)
538 15fd9fd5 Oleksiy Mishchenko
539 15fd9fd5 Oleksiy Mishchenko
  def DELETE(self):
540 15fd9fd5 Oleksiy Mishchenko
    """Delete a tag.
541 15fd9fd5 Oleksiy Mishchenko

542 18cb43a2 Oleksiy Mishchenko
    In order to delete a set of tags, the DELETE
543 c41eea6e Iustin Pop
    request should be addressed to URI like:
544 18cb43a2 Oleksiy Mishchenko
    /tags?tag=[tag]&tag=[tag]
545 15fd9fd5 Oleksiy Mishchenko

546 15fd9fd5 Oleksiy Mishchenko
    """
547 15fd9fd5 Oleksiy Mishchenko
    if 'tag' not in self.queryargs:
548 18cb43a2 Oleksiy Mishchenko
      # no we not gonna delete all tags
549 6e99c5a0 Iustin Pop
      raise http.HttpBadRequest("Cannot delete all tags - please specify"
550 6e99c5a0 Iustin Pop
                                " tag(s) using the 'tag' parameter")
551 18cb43a2 Oleksiy Mishchenko
    return baserlib._Tags_DELETE(self.TAG_LEVEL,
552 15fd9fd5 Oleksiy Mishchenko
                                 self.queryargs['tag'],
553 18cb43a2 Oleksiy Mishchenko
                                 name=self.name)
554 18cb43a2 Oleksiy Mishchenko
555 18cb43a2 Oleksiy Mishchenko
556 18cb43a2 Oleksiy Mishchenko
class R_2_instances_name_tags(_R_Tags):
557 18cb43a2 Oleksiy Mishchenko
  """ /2/instances/[instance_name]/tags resource.
558 18cb43a2 Oleksiy Mishchenko

559 18cb43a2 Oleksiy Mishchenko
  Manages per-instance tags.
560 18cb43a2 Oleksiy Mishchenko

561 18cb43a2 Oleksiy Mishchenko
  """
562 18cb43a2 Oleksiy Mishchenko
  DOC_URI = "/2/instances/[instance_name]/tags"
563 18cb43a2 Oleksiy Mishchenko
  TAG_LEVEL = constants.TAG_INSTANCE
564 18cb43a2 Oleksiy Mishchenko
565 18cb43a2 Oleksiy Mishchenko
566 18cb43a2 Oleksiy Mishchenko
class R_2_nodes_name_tags(_R_Tags):
567 18cb43a2 Oleksiy Mishchenko
  """ /2/nodes/[node_name]/tags resource.
568 18cb43a2 Oleksiy Mishchenko

569 18cb43a2 Oleksiy Mishchenko
  Manages per-node tags.
570 18cb43a2 Oleksiy Mishchenko

571 18cb43a2 Oleksiy Mishchenko
  """
572 18cb43a2 Oleksiy Mishchenko
  DOC_URI = "/2/nodes/[node_name]/tags"
573 18cb43a2 Oleksiy Mishchenko
  TAG_LEVEL = constants.TAG_NODE
574 18cb43a2 Oleksiy Mishchenko
575 18cb43a2 Oleksiy Mishchenko
576 18cb43a2 Oleksiy Mishchenko
class R_2_tags(_R_Tags):
577 18cb43a2 Oleksiy Mishchenko
  """ /2/instances/tags resource.
578 18cb43a2 Oleksiy Mishchenko

579 18cb43a2 Oleksiy Mishchenko
  Manages cluster tags.
580 18cb43a2 Oleksiy Mishchenko

581 18cb43a2 Oleksiy Mishchenko
  """
582 18cb43a2 Oleksiy Mishchenko
  DOC_URI = "/2/tags"
583 18cb43a2 Oleksiy Mishchenko
  TAG_LEVEL = constants.TAG_CLUSTER