Statistics
| Branch: | Tag: | Revision:

root / lib / rapi / rlib1.py @ 21f04e5e

History | View | Annotate | Download (8.4 kB)

1
#
2
#
3

    
4
# Copyright (C) 2006, 2007, 2008 Google Inc.
5
#
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.
10
#
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.
15
#
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
19
# 02110-1301, USA.
20

    
21

    
22
"""Remote API version 1 resources library.
23

24
"""
25

    
26
import ganeti.cli
27
import ganeti.errors
28
import ganeti.opcodes
29

    
30
from ganeti import constants
31
from ganeti import http
32

    
33
from ganeti.rapi import baserlib
34

    
35

    
36
I_FIELDS = ["name", "os", "pnode", "snodes", "admin_state", "disk_template",
37
            "ip", "mac", "bridge", "sda_size", "sdb_size", "beparams",
38
            "oper_state", "status", "tags"]
39

    
40
N_FIELDS = ["name", "dtotal", "dfree",
41
            "mtotal", "mnode", "mfree",
42
            "pinst_cnt", "sinst_cnt", "tags"]
43

    
44

    
45
class R_version(baserlib.R_Generic):
46
  """/version resource.
47

48
  This resource should be used to determine the remote API version and to adapt
49
  clients accordingly.
50

51
  """
52
  DOC_URI = "/version"
53

    
54
  def GET(self):
55
    """Returns the remote API version.
56

57
    """
58
    return constants.RAPI_VERSION
59

    
60

    
61
class R_tags(baserlib.R_Generic):
62
  """/tags resource.
63

64
  Manages cluster tags.
65

66
  """
67
  DOC_URI = "/tags"
68

    
69
  def GET(self):
70
    """Returns a list of all cluster tags.
71

72
    Example: ["tag1", "tag2", "tag3"]
73

74
    """
75
    return baserlib._Tags_GET(constants.TAG_CLUSTER)
76

    
77

    
78
class R_info(baserlib.R_Generic):
79
  """Cluster info.
80

81
  """
82
  DOC_URI = "/info"
83

    
84
  def GET(self):
85
    """Returns cluster information.
86

87
    Example: {
88
      "config_version": 3,
89
      "name": "cluster1.example.com",
90
      "software_version": "1.2.4",
91
      "os_api_version": 5,
92
      "export_version": 0,
93
      "master": "node1.example.com",
94
      "architecture": [
95
        "64bit",
96
        "x86_64"
97
      ],
98
      "hypervisor_type": "xen-pvm",
99
      "protocol_version": 12
100
    }
101

102
    """
103
    op = ganeti.opcodes.OpQueryClusterInfo()
104
    return ganeti.cli.SubmitOpCode(op)
105

    
106

    
107
class R_nodes(baserlib.R_Generic):
108
  """/nodes resource.
109

110
  """
111
  DOC_URI = "/nodes"
112

    
113
  def GET(self):
114
    """Returns a list of all nodes.
115

116
    Returns:
117
      A dictionary with 'name' and 'uri' keys for each of them.
118

119
    Example: [
120
        {
121
          "name": "node1.example.com",
122
          "uri": "\/instances\/node1.example.com"
123
        },
124
        {
125
          "name": "node2.example.com",
126
          "uri": "\/instances\/node2.example.com"
127
        }]
128

129
    If the optional 'bulk' argument is provided and set to 'true'
130
    value (i.e '?bulk=1'), the output contains detailed
131
    information about nodes as a list.
132

133
    Example: [
134
        {
135
          "pinst_cnt": 1,
136
          "mfree": 31280,
137
          "mtotal": 32763,
138
          "name": "www.example.com",
139
          "tags": [],
140
          "mnode": 512,
141
          "dtotal": 5246208,
142
          "sinst_cnt": 2,
143
          "dfree": 5171712
144
        },
145
        ...
146
    ]
147

148
    """
149
    op = ganeti.opcodes.OpQueryNodes(output_fields=["name"], names=[])
150
    nodeslist = baserlib.ExtractField(ganeti.cli.SubmitOpCode(op), 0)
151

    
152
    if 'bulk' in self.queryargs:
153
      op = ganeti.opcodes.OpQueryNodes(output_fields=N_FIELDS,
154
                                       names=nodeslist)
155
      result = ganeti.cli.SubmitOpCode(op)
156
      return baserlib.MapBulkFields(result, N_FIELDS)
157

    
158
    return baserlib.BuildUriList(nodeslist, "/nodes/%s")
159

    
160

    
161
class R_nodes_name(baserlib.R_Generic):
162
  """/nodes/[node_name] resources.
163

164
  """
165
  DOC_URI = "/nodes/[node_name]"
166

    
167
  def GET(self):
168
    """Send information about a node.
169

170
    """
171
    node_name = self.items[0]
172
    op = ganeti.opcodes.OpQueryNodes(output_fields=N_FIELDS,
173
                                     names=[node_name])
174
    result = ganeti.cli.SubmitOpCode(op)
175

    
176
    return baserlib.MapFields(N_FIELDS, result[0])
177

    
178

    
179
class R_nodes_name_tags(baserlib.R_Generic):
180
  """/nodes/[node_name]/tags resource.
181

182
  Manages per-node tags.
183

184
  """
185
  DOC_URI = "/nodes/[node_name]/tags"
186

    
187
  def GET(self):
188
    """Returns a list of node tags.
189

190
    Example: ["tag1", "tag2", "tag3"]
191

192
    """
193
    return baserlib._Tags_GET(constants.TAG_NODE, name=self.items[0])
194

    
195

    
196
class R_instances(baserlib.R_Generic):
197
  """/instances resource.
198

199
  """
200
  DOC_URI = "/instances"
201

    
202

    
203
  def GET(self):
204
    """Returns a list of all available instances.
205

206
    Returns:
207
       A dictionary with 'name' and 'uri' keys for each of them.
208

209
    Example: [
210
        {
211
          "name": "web.example.com",
212
          "uri": "\/instances\/web.example.com"
213
        },
214
        {
215
          "name": "mail.example.com",
216
          "uri": "\/instances\/mail.example.com"
217
        }]
218

219
    If the optional 'bulk' argument is provided and set to 'true'
220
    value (i.e '?bulk=1'), the output contains detailed
221
    information about instances as a list.
222

223
    Example: [
224
        {
225
           "status": "running",
226
           "bridge": "xen-br0",
227
           "name": "web.example.com",
228
           "tags": ["tag1", "tag2"],
229
           "admin_ram": 512,
230
           "sda_size": 20480,
231
           "pnode": "node1.example.com",
232
           "mac": "01:23:45:67:89:01",
233
           "sdb_size": 4096,
234
           "snodes": ["node2.example.com"],
235
           "disk_template": "drbd",
236
           "ip": null,
237
           "admin_state": true,
238
           "os": "debian-etch",
239
           "vcpus": 2,
240
           "oper_state": true
241
        },
242
        ...
243
    ]
244

245
    """
246
    op = ganeti.opcodes.OpQueryInstances(output_fields=["name"], names=[])
247
    instanceslist = baserlib.ExtractField(ganeti.cli.SubmitOpCode(op), 0)
248

    
249
    if 'bulk' in self.queryargs:
250
      op = ganeti.opcodes.OpQueryInstances(output_fields=I_FIELDS,
251
                                           names=instanceslist)
252
      result = ganeti.cli.SubmitOpCode(op)
253
      return baserlib.MapBulkFields(result, I_FIELDS)
254

    
255

    
256
    else:
257
      return baserlib.BuildUriList(instanceslist, "/instances/%s")
258

    
259

    
260
class R_instances_name(baserlib.R_Generic):
261
  """/instances/[instance_name] resources.
262

263
  """
264
  DOC_URI = "/instances/[instance_name]"
265

    
266
  def GET(self):
267
    """Send information about an instance.
268

269
    """
270
    instance_name = self.items[0]
271
    op = ganeti.opcodes.OpQueryInstances(output_fields=I_FIELDS,
272
                                         names=[instance_name])
273
    result = ganeti.cli.SubmitOpCode(op)
274

    
275
    return baserlib.MapFields(I_FIELDS, result[0])
276

    
277
  def DELETE(self):
278
    """Removes an instance.
279

280
    """
281
    instance_name = self.items[0]
282
    op = ganeti.opcodes.OpRemoveInstance(instance_name=instance_name,
283
                                         ignore_failures=True)
284
    job_id = ganeti.cli.SendJob([op])
285

    
286
    return job_id
287

    
288
  def PUT(self):
289
    """Modify an instance.
290

291
    """
292
    instance_name = self.items[0]
293
    opts = {}
294

    
295
    for key in self.queryargs:
296
      opts[key] = self.queryargs[key][0]
297

    
298
    beparams = baserlib.MakeParamsDict(opts, constants.BES_PARAMETERS)
299
    hvparams = baserlib.MakeParamsDict(opts, constants.HVS_PARAMETERS)
300

    
301
    op = ganeti.opcodes.OpSetInstanceParams(
302
        instance_name=instance_name,
303
        ip=opts.get('ip', None),
304
        bridge=opts.get('bridge', None),
305
        mac=opts.get('mac', None),
306
        hvparams=hvparams,
307
        beparams=beparams,
308
        force=opts.get('force', None))
309

    
310
    job_id = ganeti.cli.SendJob([op])
311

    
312
    return job_id
313

    
314

    
315
class R_instances_name_tags(baserlib.R_Generic):
316
  """/instances/[instance_name]/tags resource.
317

318
  Manages per-instance tags.
319

320
  """
321
  DOC_URI = "/instances/[instance_name]/tags"
322

    
323
  def GET(self):
324
    """Returns a list of instance tags.
325

326
    Example: ["tag1", "tag2", "tag3"]
327

328
    """
329
    return baserlib._Tags_GET(constants.TAG_INSTANCE, name=self.items[0])
330

    
331

    
332
class R_os(baserlib.R_Generic):
333
  """/os resource.
334

335
  """
336
  DOC_URI = "/os"
337

    
338
  def GET(self):
339
    """Return a list of all OSes.
340

341
    Can return error 500 in case of a problem.
342

343
    Example: ["debian-etch"]
344

345
    """
346
    op = ganeti.opcodes.OpDiagnoseOS(output_fields=["name", "valid"],
347
                                     names=[])
348
    diagnose_data = ganeti.cli.SubmitOpCode(op)
349

    
350
    if not isinstance(diagnose_data, list):
351
      raise http.HTTPInternalError(message="Can't get OS list")
352

    
353
    return [row[0] for row in diagnose_data if row[1]]