Revision 0f945c65
b/doc/rapi.rst | ||
---|---|---|
239 | 239 |
``/`` |
240 | 240 |
+++++ |
241 | 241 |
|
242 |
The root resource. |
|
243 |
|
|
244 |
It supports the following commands: ``GET``. |
|
245 |
|
|
246 |
``GET`` |
|
247 |
~~~~~~~ |
|
248 |
|
|
249 |
Shows the list of mapped resources. |
|
250 |
|
|
251 |
Returns: a dictionary with 'name' and 'uri' keys for each of them. |
|
252 |
|
|
253 |
``/2`` |
|
254 |
++++++ |
|
255 |
|
|
256 |
The ``/2`` resource, the root of the version 2 API. |
|
257 |
|
|
258 |
It supports the following commands: ``GET``. |
|
259 |
|
|
260 |
``GET`` |
|
261 |
~~~~~~~ |
|
262 |
|
|
263 |
Show the list of mapped resources. |
|
264 |
|
|
265 |
Returns: a dictionary with ``name`` and ``uri`` keys for each of them. |
|
242 |
The root resource. Has no function, but for legacy reasons the ``GET`` |
|
243 |
method is supported. |
|
266 | 244 |
|
267 | 245 |
``/2/info`` |
268 | 246 |
+++++++++++ |
b/lib/rapi/connector.py | ||
---|---|---|
33 | 33 |
from ganeti import http |
34 | 34 |
from ganeti import utils |
35 | 35 |
|
36 |
from ganeti.rapi import baserlib |
|
37 | 36 |
from ganeti.rapi import rlib2 |
38 | 37 |
|
39 | 38 |
|
... | ... | |
89 | 88 |
return (handler, groups, args) |
90 | 89 |
|
91 | 90 |
|
92 |
class R_root(baserlib.R_Generic): |
|
93 |
"""/ resource. |
|
94 |
|
|
95 |
""" |
|
96 |
_ROOT_PATTERN = re.compile("^R_([a-zA-Z0-9]+)$") |
|
97 |
|
|
98 |
@classmethod |
|
99 |
def GET(cls): |
|
100 |
"""Show the list of mapped resources. |
|
101 |
|
|
102 |
@return: a dictionary with 'name' and 'uri' keys for each of them. |
|
103 |
|
|
104 |
""" |
|
105 |
rootlist = [] |
|
106 |
for handler in CONNECTOR.values(): |
|
107 |
m = cls._ROOT_PATTERN.match(handler.__name__) |
|
108 |
if m: |
|
109 |
name = m.group(1) |
|
110 |
if name != "root": |
|
111 |
rootlist.append(name) |
|
112 |
|
|
113 |
return baserlib.BuildUriList(rootlist, "/%s") |
|
114 |
|
|
115 |
|
|
116 |
def _getResources(id_): |
|
117 |
"""Return a list of resources underneath given id. |
|
118 |
|
|
119 |
This is to generalize querying of version resources lists. |
|
120 |
|
|
121 |
@return: a list of resources names. |
|
122 |
|
|
123 |
""" |
|
124 |
r_pattern = re.compile("^R_%s_([a-zA-Z0-9]+)$" % id_) |
|
125 |
|
|
126 |
rlist = [] |
|
127 |
for handler in CONNECTOR.values(): |
|
128 |
m = r_pattern.match(handler.__name__) |
|
129 |
if m: |
|
130 |
name = m.group(1) |
|
131 |
rlist.append(name) |
|
132 |
|
|
133 |
return rlist |
|
134 |
|
|
135 |
|
|
136 |
class R_2(baserlib.R_Generic): |
|
137 |
"""/2 resource. |
|
138 |
|
|
139 |
This is the root of the version 2 API. |
|
140 |
|
|
141 |
""" |
|
142 |
@staticmethod |
|
143 |
def GET(): |
|
144 |
"""Show the list of mapped resources. |
|
145 |
|
|
146 |
@return: a dictionary with 'name' and 'uri' keys for each of them. |
|
147 |
|
|
148 |
""" |
|
149 |
return baserlib.BuildUriList(_getResources("2"), "/2/%s") |
|
150 |
|
|
151 |
|
|
152 | 91 |
def GetHandlers(node_name_pattern, instance_name_pattern, |
153 | 92 |
group_name_pattern, job_id_pattern, disk_pattern, |
154 | 93 |
query_res_pattern): |
... | ... | |
160 | 99 |
# is more flexible and future-compatible than versioning the whole remote |
161 | 100 |
# API. |
162 | 101 |
return { |
163 |
"/": R_root, |
|
102 |
"/": rlib2.R_root,
|
|
164 | 103 |
|
165 | 104 |
"/version": rlib2.R_version, |
166 | 105 |
|
167 |
"/2": R_2, |
|
168 |
|
|
169 | 106 |
"/2/nodes": rlib2.R_2_nodes, |
170 | 107 |
re.compile(r"^/2/nodes/(%s)$" % node_name_pattern): |
171 | 108 |
rlib2.R_2_nodes_name, |
b/lib/rapi/rlib2.py | ||
---|---|---|
148 | 148 |
_WFJC_TIMEOUT = 10 |
149 | 149 |
|
150 | 150 |
|
151 |
class R_root(baserlib.R_Generic): |
|
152 |
"""/ resource. |
|
153 |
|
|
154 |
""" |
|
155 |
@staticmethod |
|
156 |
def GET(): |
|
157 |
"""Supported for legacy reasons. |
|
158 |
|
|
159 |
""" |
|
160 |
return None |
|
161 |
|
|
162 |
|
|
151 | 163 |
class R_version(baserlib.R_Generic): |
152 | 164 |
"""/version resource. |
153 | 165 |
|
b/test/docs_unittest.py | ||
---|---|---|
142 | 142 |
|
143 | 143 |
prevline = line |
144 | 144 |
|
145 |
prefix_exception = frozenset(["/", "/version", "/2"])
|
|
145 |
prefix_exception = frozenset(["/", "/version"]) |
|
146 | 146 |
|
147 | 147 |
undocumented = [] |
148 | 148 |
used_uris = [] |
b/test/ganeti.rapi.client_unittest.py | ||
---|---|---|
45 | 45 |
|
46 | 46 |
# List of resource handlers which aren't used by the RAPI client |
47 | 47 |
_KNOWN_UNUSED = set([ |
48 |
connector.R_root, |
|
49 |
connector.R_2, |
|
48 |
rlib2.R_root, |
|
50 | 49 |
]) |
51 | 50 |
|
52 | 51 |
# Global variable for collecting used handlers |
b/test/ganeti.rapi.resources_unittest.py | ||
---|---|---|
69 | 69 |
self._TestFailingUri("/instances/does/not/exist") |
70 | 70 |
|
71 | 71 |
|
72 |
class R_RootTests(unittest.TestCase): |
|
73 |
"""Testing for R_root class.""" |
|
74 |
|
|
75 |
def setUp(self): |
|
76 |
self.root = connector.R_root(None, None, None) |
|
77 |
|
|
78 |
def testGet(self): |
|
79 |
expected = [ |
|
80 |
{'name': '2', 'uri': '/2'}, |
|
81 |
{'name': 'version', 'uri': '/version'}, |
|
82 |
] |
|
83 |
self.assertEquals(self.root.GET(), expected) |
|
84 |
|
|
85 |
|
|
86 | 72 |
if __name__ == '__main__': |
87 | 73 |
testutils.GanetiTestProgram() |
Also available in: Unified diff