Revision 4e5a68f8

b/Makefile.am
97 97
	lib/rapi/__init__.py \
98 98
	lib/rapi/baserlib.py \
99 99
	lib/rapi/connector.py \
100
	lib/rapi/rlib1.py \
101 100
	lib/rapi/rlib2.py
102 101

  
103 102
http_PYTHON = \
b/doc/build-rapi-resources-doc
26 26
import cgi
27 27
import inspect
28 28

  
29
from ganeti.rapi import rlib1
30 29
from ganeti.rapi import rlib2
31 30
from ganeti.rapi import connector
32 31

  
......
38 37
  # Get list of all resources
39 38
  all = list(connector.CONNECTOR.itervalues())
40 39

  
41
  # Sort rlib1 by URI
40
  # Sort rlib by URI
42 41
  all.sort(cmp=lambda a, b: cmp(a.DOC_URI, b.DOC_URI))
43 42

  
44 43
  print "<!-- Automatically generated, do not edit -->"
b/lib/rapi/connector.py
29 29
from ganeti import http
30 30

  
31 31
from ganeti.rapi import baserlib
32
from ganeti.rapi import rlib1
33 32
from ganeti.rapi import rlib2
34 33

  
35 34
# the connection map is created at the end of this file
......
152 151
CONNECTOR.update({
153 152
  "/": R_root,
154 153

  
155
  "/version": rlib1.R_version,
154
  "/version": rlib2.R_version,
156 155

  
157 156
  "/2": R_2,
158 157
  "/2/jobs": rlib2.R_2_jobs,
159 158
  "/2/nodes": rlib2.R_2_nodes,
159
  re.compile(r'^/2/nodes/([\w\._-]+)$'): rlib2.R_2_nodes_name,
160 160
  "/2/instances": rlib2.R_2_instances,
161
  re.compile(r'^/2/instances/([\w\._-]+)$'): rlib1.R_instances_name,
161
  re.compile(r'^/2/instances/([\w\._-]+)$'): rlib2.R_2_instances_name,
162 162
  re.compile(r'^/2/instances/([\w\._-]+)/tags$'): rlib2.R_2_instances_name_tags,
163 163
  re.compile(r'^/2/instances/([\w\._-]+)/reboot$'):
164 164
      rlib2.R_2_instances_name_reboot,
......
167 167
  re.compile(r'^/2/instances/([\w\._-]+)/startup$'):
168 168
      rlib2.R_2_instances_name_startup,
169 169
  re.compile(r'/2/jobs/(%s)$' % constants.JOB_ID_TEMPLATE): rlib2.R_2_jobs_id,
170
  "/2/tags": rlib2.R_2_tags,
171
  "/2/info": rlib2.R_2_info,
172
  "/2/os": rlib2.R_2_os,
170 173
  })
/dev/null
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
49
  to adapt 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

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

  
104
    """
105
    op = ganeti.opcodes.OpQueryClusterInfo()
106
    return ganeti.cli.SubmitOpCode(op)
107

  
108

  
109
class R_nodes_name(baserlib.R_Generic):
110
  """/nodes/[node_name] resources.
111

  
112
  """
113
  DOC_URI = "/nodes/[node_name]"
114

  
115
  def GET(self):
116
    """Send information about a node.
117

  
118
    """
119
    node_name = self.items[0]
120
    op = ganeti.opcodes.OpQueryNodes(output_fields=N_FIELDS,
121
                                     names=[node_name])
122
    result = ganeti.cli.SubmitOpCode(op)
123

  
124
    return baserlib.MapFields(N_FIELDS, result[0])
125

  
126

  
127
class R_nodes_name_tags(baserlib.R_Generic):
128
  """/nodes/[node_name]/tags resource.
129

  
130
  Manages per-node tags.
131

  
132
  """
133
  DOC_URI = "/nodes/[node_name]/tags"
134

  
135
  def GET(self):
136
    """Returns a list of node tags.
137

  
138
    Example: ["tag1", "tag2", "tag3"]
139

  
140
    """
141
    return baserlib._Tags_GET(constants.TAG_NODE, name=self.items[0])
142

  
143

  
144
class R_instances_name(baserlib.R_Generic):
145
  """/instances/[instance_name] resources.
146

  
147
  """
148
  DOC_URI = "/instances/[instance_name]"
149

  
150
  def GET(self):
151
    """Send information about an instance.
152

  
153
    """
154
    instance_name = self.items[0]
155
    op = ganeti.opcodes.OpQueryInstances(output_fields=I_FIELDS,
156
                                         names=[instance_name])
157
    result = ganeti.cli.SubmitOpCode(op)
158

  
159
    return baserlib.MapFields(I_FIELDS, result[0])
160

  
161
  def DELETE(self):
162
    """Removes an instance.
163

  
164
    """
165
    instance_name = self.items[0]
166
    op = ganeti.opcodes.OpRemoveInstance(instance_name=instance_name,
167
                                         ignore_failures=True)
168
    job_id = ganeti.cli.SendJob([op])
169

  
170
    return job_id
171

  
172
  def PUT(self):
173
    """Modify an instance.
174

  
175
    """
176
    instance_name = self.items[0]
177
    opts = {}
178

  
179
    for key in self.queryargs:
180
      opts[key] = self.queryargs[key][0]
181

  
182
    beparams = baserlib.MakeParamsDict(opts, constants.BES_PARAMETERS)
183
    hvparams = baserlib.MakeParamsDict(opts, constants.HVS_PARAMETERS)
184

  
185
    op = ganeti.opcodes.OpSetInstanceParams(
186
        instance_name=instance_name,
187
        ip=opts.get('ip', None),
188
        bridge=opts.get('bridge', None),
189
        mac=opts.get('mac', None),
190
        hvparams=hvparams,
191
        beparams=beparams,
192
        force=opts.get('force', None))
193

  
194
    job_id = ganeti.cli.SendJob([op])
195

  
196
    return job_id
197

  
198

  
199
class R_instances_name_tags(baserlib.R_Generic):
200
  """/instances/[instance_name]/tags resource.
201

  
202
  Manages per-instance tags.
203

  
204
  """
205
  DOC_URI = "/instances/[instance_name]/tags"
206

  
207
  def GET(self):
208
    """Returns a list of instance tags.
209

  
210
    Example: ["tag1", "tag2", "tag3"]
211

  
212
    """
213
    return baserlib._Tags_GET(constants.TAG_INSTANCE, name=self.items[0])
214

  
215

  
216
class R_os(baserlib.R_Generic):
217
  """/os resource.
218

  
219
  """
220
  DOC_URI = "/os"
221

  
222
  def GET(self):
223
    """Return a list of all OSes.
224

  
225
    Can return error 500 in case of a problem.
226

  
227
    Example: ["debian-etch"]
228

  
229
    """
230
    op = ganeti.opcodes.OpDiagnoseOS(output_fields=["name", "valid"],
231
                                     names=[])
232
    diagnose_data = ganeti.cli.SubmitOpCode(op)
233

  
234
    if not isinstance(diagnose_data, list):
235
      raise http.HttpInternalServerError(message="Can't get OS list")
236

  
237
    return [row[0] for row in diagnose_data if row[1]]
b/lib/rapi/rlib2.py
29 29
from ganeti import constants
30 30
from ganeti.rapi import baserlib
31 31

  
32
from ganeti.rapi.rlib1 import I_FIELDS, N_FIELDS
32

  
33
I_FIELDS = ["name", "os", "pnode", "snodes", "admin_state", "disk_template",
34
            "ip", "mac", "bridge", "sda_size", "sdb_size", "beparams",
35
            "oper_state", "status", "tags"]
36

  
37
N_FIELDS = ["name", "dtotal", "dfree",
38
            "mtotal", "mnode", "mfree",
39
            "pinst_cnt", "sinst_cnt", "tags"]
40

  
41

  
42
class R_version(baserlib.R_Generic):
43
  """/version resource.
44

  
45
  This resource should be used to determine the remote API version and
46
  to adapt clients accordingly.
47

  
48
  """
49
  DOC_URI = "/version"
50

  
51
  def GET(self):
52
    """Returns the remote API version.
53

  
54
    """
55
    return constants.RAPI_VERSION
56

  
57

  
58
class R_2_info(baserlib.R_Generic):
59
  """Cluster info.
60

  
61
  """
62
  DOC_URI = "/2/info"
63

  
64
  def GET(self):
65
    """Returns cluster information.
66

  
67
    Example::
68

  
69
      {
70
        "config_version": 3,
71
        "name": "cluster1.example.com",
72
        "software_version": "1.2.4",
73
        "os_api_version": 5,
74
        "export_version": 0,
75
        "master": "node1.example.com",
76
        "architecture": [
77
          "64bit",
78
          "x86_64"
79
        ],
80
        "hypervisor_type": "xen-pvm",
81
        "protocol_version": 12
82
      }
83

  
84
    """
85
    op = ganeti.opcodes.OpQueryClusterInfo()
86
    return ganeti.cli.SubmitOpCode(op)
87

  
88

  
89
class R_2_tags(baserlib.R_Generic):
90
  """/2/tags resource.
91

  
92
  Manages cluster tags.
93

  
94
  """
95
  DOC_URI = "/2/tags"
96

  
97
  def GET(self):
98
    """Returns a list of all cluster tags.
99

  
100
    Example: ["tag1", "tag2", "tag3"]
101

  
102
    """
103
    return baserlib._Tags_GET(constants.TAG_CLUSTER)
104

  
105

  
106
class R_2_os(baserlib.R_Generic):
107
  """/2/os resource.
108

  
109
  """
110
  DOC_URI = "/2/os"
111

  
112
  def GET(self):
113
    """Return a list of all OSes.
114

  
115
    Can return error 500 in case of a problem.
116

  
117
    Example: ["debian-etch"]
118

  
119
    """
120
    op = ganeti.opcodes.OpDiagnoseOS(output_fields=["name", "valid"],
121
                                     names=[])
122
    diagnose_data = ganeti.cli.SubmitOpCode(op)
123

  
124
    if not isinstance(diagnose_data, list):
125
      raise http.HttpInternalServerError(message="Can't get OS list")
126

  
127
    return [row[0] for row in diagnose_data if row[1]]
33 128

  
34 129

  
35 130
class R_2_jobs(baserlib.R_Generic):
......
141 236
                                 uri_fields=("id", "uri"))
142 237

  
143 238

  
144
class R_nodes(R_2_nodes):
145
  """/nodes resource
239
class R_2_nodes_name(baserlib.R_Generic):
240
  """/2/nodes/[node_name] resources.
146 241

  
147 242
  """
148
  # TODO: Temporary resource will be deprecated
149
  DOC_URI = "/nodes"
243
  DOC_URI = "/nodes/[node_name]"
244

  
245
  def GET(self):
246
    """Send information about a node.
247

  
248
    """
249
    node_name = self.items[0]
250
    op = ganeti.opcodes.OpQueryNodes(output_fields=N_FIELDS,
251
                                     names=[node_name])
252
    result = ganeti.cli.SubmitOpCode(op)
253

  
254
    return baserlib.MapFields(N_FIELDS, result[0])
150 255

  
151 256

  
152 257
class R_2_instances(baserlib.R_Generic):
......
254 359
    return job_id
255 360

  
256 361

  
257
class R_instances(R_2_instances):
258
  """/instances resource.
362
class R_2_instances_name(baserlib.R_Generic):
363
  """/2/instances/[instance_name] resources.
259 364

  
260 365
  """
261
  # TODO: Temporary resource will be deprecated
262
  DOC_URI = "/instances"
366
  DOC_URI = "/2/instances/[instance_name]"
367

  
368
  def GET(self):
369
    """Send information about an instance.
370

  
371
    """
372
    instance_name = self.items[0]
373
    op = ganeti.opcodes.OpQueryInstances(output_fields=I_FIELDS,
374
                                         names=[instance_name])
375
    result = ganeti.cli.SubmitOpCode(op)
376

  
377
    return baserlib.MapFields(I_FIELDS, result[0])
263 378

  
264 379

  
265 380
class R_2_instances_name_reboot(baserlib.R_Generic):
b/test/ganeti.rapi.resources_unittest.py
29 29
from ganeti import http
30 30

  
31 31
from ganeti.rapi import connector
32
from ganeti.rapi import rlib1
33 32
from ganeti.rapi import rlib2
34 33

  
35 34

  
......
50 49

  
51 50
    self._TestFailingUri("/tags")
52 51
    self._TestFailingUri("/instances")
53
    self._TestUri("/version", (rlib1.R_version, [], {}))
52
    self._TestUri("/version", (rlib2.R_version, [], {}))
54 53

  
55 54
    self._TestUri('/2/instances/www.test.com',
56
                  (rlib1.R_instances_name,
55
                  (rlib2.R_2_instances_name,
57 56
                   ['www.test.com'],
58 57
                   {}))
59 58

  

Also available in: Unified diff