Merge ~jsseidel/maas:jsseidel-annotation-w-examples into maas:master
- Git
- lp:~jsseidel/maas
- jsseidel-annotation-w-examples
- Merge into master
Status: | Merged |
---|---|
Approved by: | Newell Jensen |
Approved revision: | 79dfbe262404f9a8e39cc723e6f00cd430b96dd6 |
Merge reported by: | MAAS Lander |
Merged at revision: | not available |
Proposed branch: | ~jsseidel/maas:jsseidel-annotation-w-examples |
Merge into: | maas:master |
Diff against target: |
3360 lines (+2977/-93) 6 files modified
src/maasserver/api/annotations.py (+141/-10) src/maasserver/api/examples/for-tests.json (+5/-0) src/maasserver/api/examples/tags.json (+2513/-0) src/maasserver/api/tags.py (+227/-69) src/maasserver/api/tests/test_annotations.py (+83/-11) src/maasserver/api/tmpl-apidoc.rst (+8/-3) |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Newell Jensen (community) | Approve | ||
MAAS Lander | Approve | ||
Review via email: mp+358389@code.launchpad.net |
Commit message
Added a JSON 'examples' database lookup for storing API success examples. Updated tags.py to use the new lookup mechanism. Added tags.json in examples for lookups. Also updated the inline documentation to reflect this new feature.
Description of the change
'example' tags, e.g. @success-example, can reference example lookup keys (exkey) in their opts sections:
@success-example "someid" [exkey=mykey] placeholder
The code tries to find a json file to load in the examples directory that corresponds to the operation in the URI. E.g. /MAAS/api/
If a matching example is found, placeholder is ignored and replaced with a formatted version of the JSON object found that matches the given key (here, mykey) in the API docs (CLI help is not relevant here currently).
- 4f79b60... by Spencer Seidel
-
Fixed typo in tags docstring
MAAS Lander (maas-lander) wrote : | # |
UNIT TESTS
-b jsseidel-
STATUS: SUCCESS
COMMIT: 4f79b605f28bd20
Newell Jensen (newell-jensen) wrote : | # |
As we discussed in hangout (putting here for documentation purposes, pun intended :):
1. Change your usage of "somename" to something that is more reader friendly like "some-name".
2. Change the tags.json file to a readable version.
I will give a more thorough review in a bit.
- 4f1e525... by Spencer Seidel
-
Formatted json example files. Changed example variable names in tags.py to use hyphens to make them more readable.
- 1fbeb9d... by Spencer Seidel
-
Updated comment to reflect why indent=4 is used when loading examples from example json file.
MAAS Lander (maas-lander) wrote : | # |
UNIT TESTS
-b jsseidel-
STATUS: SUCCESS
COMMIT: 1fbeb9dd220dafb
Newell Jensen (newell-jensen) wrote : | # |
Looks good for the most but have a few things that I think should be changed. See inline.
- 79dfbe2... by Spencer Seidel
-
Cleaned up exkey logic and did some renaming of variables to make things cleaner.
Newell Jensen (newell-jensen) wrote : | # |
Looks good.
Preview Diff
1 | diff --git a/src/maasserver/api/annotations.py b/src/maasserver/api/annotations.py |
2 | index 8d02791..010d512 100644 |
3 | --- a/src/maasserver/api/annotations.py |
4 | +++ b/src/maasserver/api/annotations.py |
5 | @@ -44,10 +44,7 @@ In most cases, formatting is preserved when presenting output. |
6 | With the exception of the description tag, docstrings can |
7 | contain as many tags as necessary to describe an API call. |
8 | |
9 | -The [required=true|false] option is a requirement for the |
10 | -@param tag. |
11 | - |
12 | -Notes: |
13 | +Descriptions: |
14 | |
15 | Description annotations can be interpreted in a couple of ways: |
16 | |
17 | @@ -58,7 +55,10 @@ Description annotations can be interpreted in a couple of ways: |
18 | |
19 | Explicit title: |
20 | The APIDocstringParser also contains support for an explicit |
21 | - title, which the CLI-help code should honor if present. |
22 | + title (@description-title), which the CLI-help code should |
23 | + honor if present. |
24 | + |
25 | +Example tags: |
26 | |
27 | For an example tag to be successfully associated with |
28 | a tag, the name or ID fields of the annotations must match: |
29 | @@ -71,8 +71,42 @@ a tag, the name or ID fields of the annotations must match: |
30 | In this case, param "p1" and param-example "p1" will be |
31 | paired together in the output dictionary. |
32 | |
33 | +Options: |
34 | + |
35 | +The [required=true|false] option is a requirement for the |
36 | +@param tag. |
37 | + |
38 | +Example tags can either include formatted examples inline: |
39 | + |
40 | +@success-example "some-name" |
41 | + { |
42 | + "name": "value" |
43 | + } |
44 | + |
45 | +Or reference an example key for lookup in a JSON database |
46 | +in the examples directory based on the URI. For example: |
47 | + |
48 | + /MAAS/api/2.0/zone/{name}/ -> examples/zones.json |
49 | + /MAAS/api/2.0/zones/{name}/ -> examples/zones.json |
50 | + |
51 | +Use the "exkey" to do this: |
52 | + |
53 | +@success-example "some-name" [exkey=unique-key] ignored text |
54 | + |
55 | +Where: |
56 | + |
57 | +examples/zones.json contains: |
58 | + |
59 | +{ |
60 | + ... |
61 | + "unique-key": { ...some JSON object...}, |
62 | + ... |
63 | +} |
64 | + |
65 | +Notes: |
66 | + |
67 | This class is typically used in conjunction with the |
68 | -APITemplateRenderer class. |
69 | +APITemplateRenderer class (templates.py). |
70 | |
71 | OUTPUT: |
72 | |
73 | @@ -81,7 +115,7 @@ OUTPUT: |
74 | |
75 | { |
76 | "http_method": "GET", |
77 | - "uri": "/myuri/{foo}/", |
78 | + "uri": "/MAAS/api/2.0/myuri/{foo}/", |
79 | "operation": "arg1=foo&arg2=bar", |
80 | "description-title": "A brief, title-like description", |
81 | "description": "Some longer description.", |
82 | @@ -133,6 +167,8 @@ __all__ = [ |
83 | 'APIDocstringParser', |
84 | ] |
85 | |
86 | +import json |
87 | +import os |
88 | import re |
89 | from textwrap import indent |
90 | |
91 | @@ -311,10 +347,44 @@ class APIDocstringParser: |
92 | """ |
93 | return_list = [] |
94 | for tag in tags: |
95 | - e = self._get_named_example_for_named_tag( |
96 | + example = self._get_named_example_for_named_tag( |
97 | tag_cat, tag['name'], examples) |
98 | - if e: |
99 | - tag['example'] = e['description'] |
100 | + if example: |
101 | + # We default to the description for this example given in the |
102 | + # docstring. |
103 | + example_desc = example['description'] |
104 | + |
105 | + # If the user has given options, check for the presence of |
106 | + # 'exkey'. |
107 | + example_options = example['options'] |
108 | + if example_options is not None and 'exkey' in example_options: |
109 | + example_options_exkey = example_options['exkey'] |
110 | + # If the examples db is empty, since we have an exkey, |
111 | + # we need to warn. |
112 | + if self.examples_db is None: |
113 | + self._warn( |
114 | + "Found 'exkey'='%s' in example named '%s', but " |
115 | + "the examples database is empty." % |
116 | + (example_options_exkey, example['name'])) |
117 | + elif example_options_exkey in self.examples_db: |
118 | + # Use indent=4 in order to tell json to format |
119 | + # the outgoing string as opposed to keeping it on |
120 | + # one line. |
121 | + example_desc = json.dumps( |
122 | + self.examples_db[example['options']['exkey']], |
123 | + indent=4) |
124 | + else: |
125 | + self._warn( |
126 | + "Found 'exkey'='%s' in example named '%s', " |
127 | + "but found no corresponding entry in the the " |
128 | + "examples database." % |
129 | + (example['options']['exkey'], example['name'])) |
130 | + |
131 | + # example will contain either the description provided in the |
132 | + # docstring as is, or it will have been replaced with an |
133 | + # entry from the examples_db |
134 | + tag['example'] = example_desc |
135 | + |
136 | else: |
137 | tag['example'] = "" |
138 | |
139 | @@ -345,6 +415,8 @@ class APIDocstringParser: |
140 | self.error_examples = [] |
141 | # Clear out any collected warnings |
142 | self.warnings = "" |
143 | + # Clear the examples database |
144 | + self.examples_db = None |
145 | |
146 | # Strips multiple inline spaces, all newlines, and |
147 | # leading and trailing spaces |
148 | @@ -503,6 +575,61 @@ class APIDocstringParser: |
149 | |
150 | return "" |
151 | |
152 | + def _get_operation_from_uri(self, uri): |
153 | + """Parses out an operation name from a given URI. |
154 | + |
155 | + Given, for example, /MAAS/api/2.0/resourcepool/{id}/, this |
156 | + function returns "resourcepool". |
157 | + """ |
158 | + m = re.search("/MAAS/api/[0-9]+\.[0-9]+/([a-z\-]+)/", uri) |
159 | + if m: |
160 | + return m.group(1) |
161 | + |
162 | + # Note that *not* finding an operation in a URI is normal |
163 | + # and acceptable because sometimes we're parsing a docstring |
164 | + # that the user hasn't associated with a URI. |
165 | + |
166 | + return "" |
167 | + |
168 | + def _get_examples_dict(self, uri): |
169 | + """Returns a dictionary containing examples data or None |
170 | + |
171 | + Given an operation string like "zone" or "zones", this function tries |
172 | + to open and slurp in the JSON of a matching file in the api/examples |
173 | + directory (e.g. tags.json). Example objects look like this: |
174 | + |
175 | + "uniquekey": { |
176 | + ... any JSON object ... |
177 | + } |
178 | + |
179 | + If no database is associated with the operation, the function |
180 | + returns None. |
181 | + """ |
182 | + examples = {} |
183 | + |
184 | + operation = self._get_operation_from_uri(uri) |
185 | + |
186 | + if operation == "": |
187 | + return None |
188 | + |
189 | + # First, try the operation string as is: |
190 | + json_file = ("%s/examples/%s.json" % |
191 | + (os.path.dirname(__file__), operation)) |
192 | + |
193 | + if not os.path.isfile(json_file): |
194 | + # Not available, so try adding an 's' to make it plural |
195 | + json_file = ("%s/examples/%ss.json" % |
196 | + (os.path.dirname(__file__), operation)) |
197 | + |
198 | + if not os.path.isfile(json_file): |
199 | + # Give up |
200 | + return None |
201 | + |
202 | + with open(json_file, "r") as ex_db_file: |
203 | + examples = json.load(ex_db_file) |
204 | + |
205 | + return examples |
206 | + |
207 | def parse(self, docstring, http_method='', uri='', operation=''): |
208 | """State machine that parses annotated API docstrings. |
209 | |
210 | @@ -542,6 +669,10 @@ class APIDocstringParser: |
211 | self.operation = operation |
212 | self._clear_docstring_vars() |
213 | |
214 | + # Fetch and build a dictionary containing examples associated with |
215 | + # the given URI (if any) |
216 | + self.examples_db = self._get_examples_dict(uri) |
217 | + |
218 | # Init parse state |
219 | ps = ParseState.TAG |
220 | |
221 | diff --git a/src/maasserver/api/examples/for-tests.json b/src/maasserver/api/examples/for-tests.json |
222 | new file mode 100644 |
223 | index 0000000..5e259b9 |
224 | --- /dev/null |
225 | +++ b/src/maasserver/api/examples/for-tests.json |
226 | @@ -0,0 +1,5 @@ |
227 | +{ |
228 | + "key1": { |
229 | + "name": "value" |
230 | + } |
231 | +} |
232 | diff --git a/src/maasserver/api/examples/tags.json b/src/maasserver/api/examples/tags.json |
233 | new file mode 100644 |
234 | index 0000000..0c18c25 |
235 | --- /dev/null |
236 | +++ b/src/maasserver/api/examples/tags.json |
237 | @@ -0,0 +1,2513 @@ |
238 | +{ |
239 | + "get-tags": [ |
240 | + { |
241 | + "name": "virtual", |
242 | + "definition": "", |
243 | + "comment": "", |
244 | + "kernel_opts": null, |
245 | + "resource_uri": "/MAAS/api/2.0/tags/virtual/" |
246 | + } |
247 | + ], |
248 | + "get-tag-by-name": { |
249 | + "name": "virtual", |
250 | + "definition": "", |
251 | + "comment": "", |
252 | + "kernel_opts": null, |
253 | + "resource_uri": "/MAAS/api/2.0/tags/virtual/" |
254 | + }, |
255 | + "get-devices-by-tag": [ |
256 | + { |
257 | + "tag_names": [ |
258 | + "virtual" |
259 | + ], |
260 | + "interface_set": [ |
261 | + { |
262 | + "id": 130, |
263 | + "name": "eth-tNqklu", |
264 | + "tags": [ |
265 | + "tag-YYQK5S", |
266 | + "tag-MUmKRU", |
267 | + "tag-dh0kc2" |
268 | + ], |
269 | + "links": [], |
270 | + "firmware_version": null, |
271 | + "effective_mtu": 1500, |
272 | + "product": null, |
273 | + "mac_address": "bb:f7:55:fd:0f:34", |
274 | + "system_id": "nqg6dg", |
275 | + "parents": [], |
276 | + "children": [], |
277 | + "params": "", |
278 | + "enabled": true, |
279 | + "discovered": null, |
280 | + "vlan": { |
281 | + "vid": 0, |
282 | + "mtu": 1500, |
283 | + "dhcp_on": false, |
284 | + "external_dhcp": null, |
285 | + "relay_vlan": null, |
286 | + "id": 5013, |
287 | + "name": "untagged", |
288 | + "fabric": "fabric-9", |
289 | + "primary_rack": null, |
290 | + "fabric_id": 9, |
291 | + "secondary_rack": null, |
292 | + "space": "undefined", |
293 | + "resource_uri": "/MAAS/api/2.0/vlans/5013/" |
294 | + }, |
295 | + "vendor": null, |
296 | + "type": "physical", |
297 | + "resource_uri": "/MAAS/api/2.0/nodes/nqg6dg/interfaces/130/" |
298 | + } |
299 | + ], |
300 | + "zone": { |
301 | + "name": "default", |
302 | + "description": "", |
303 | + "id": 1, |
304 | + "resource_uri": "/MAAS/api/2.0/zones/default/" |
305 | + }, |
306 | + "node_type": 1, |
307 | + "hostname": "calm-bobcat", |
308 | + "system_id": "nqg6dg", |
309 | + "owner_data": {}, |
310 | + "parent": null, |
311 | + "address_ttl": null, |
312 | + "owner": null, |
313 | + "ip_addresses": [], |
314 | + "node_type_name": "Device", |
315 | + "fqdn": "calm-bobcat.maas", |
316 | + "domain": { |
317 | + "authoritative": true, |
318 | + "ttl": null, |
319 | + "id": 0, |
320 | + "name": "maas", |
321 | + "resource_record_count": 0, |
322 | + "is_default": true, |
323 | + "resource_uri": "/MAAS/api/2.0/domains/0/" |
324 | + }, |
325 | + "resource_uri": "/MAAS/api/2.0/devices/nqg6dg/" |
326 | + } |
327 | + ], |
328 | + "get-machines-by-tag": [ |
329 | + { |
330 | + "pool": { |
331 | + "name": "default", |
332 | + "description": "Default pool", |
333 | + "id": 0, |
334 | + "resource_uri": "/MAAS/api/2.0/resourcepool/0/" |
335 | + }, |
336 | + "storage": 3865.490432, |
337 | + "min_hwe_kernel": "", |
338 | + "interface_set": [ |
339 | + { |
340 | + "id": 94, |
341 | + "name": "eth-x2dFvx", |
342 | + "tags": [ |
343 | + "tag-fAzmsZ", |
344 | + "tag-doKrVe", |
345 | + "tag-ejryXL" |
346 | + ], |
347 | + "links": [ |
348 | + { |
349 | + "id": 39, |
350 | + "mode": "auto", |
351 | + "subnet": { |
352 | + "name": "name-rLI3eq", |
353 | + "vlan": { |
354 | + "vid": 0, |
355 | + "mtu": 1500, |
356 | + "dhcp_on": false, |
357 | + "external_dhcp": null, |
358 | + "relay_vlan": null, |
359 | + "id": 5001, |
360 | + "name": "untagged", |
361 | + "fabric": "fabric-0", |
362 | + "primary_rack": null, |
363 | + "fabric_id": 0, |
364 | + "secondary_rack": null, |
365 | + "space": "management", |
366 | + "resource_uri": "/MAAS/api/2.0/vlans/5001/" |
367 | + }, |
368 | + "cidr": "172.16.1.0/24", |
369 | + "rdns_mode": 2, |
370 | + "gateway_ip": "172.16.1.1", |
371 | + "dns_servers": [ |
372 | + "fd89:8724:81f1:5512:557f:99c3:6967:8d63" |
373 | + ], |
374 | + "allow_dns": true, |
375 | + "allow_proxy": true, |
376 | + "active_discovery": false, |
377 | + "managed": true, |
378 | + "id": 1, |
379 | + "space": "management", |
380 | + "resource_uri": "/MAAS/api/2.0/subnets/1/" |
381 | + } |
382 | + } |
383 | + ], |
384 | + "firmware_version": null, |
385 | + "effective_mtu": 1500, |
386 | + "product": null, |
387 | + "mac_address": "dd:c6:80:1a:c7:80", |
388 | + "system_id": "ssqcgt", |
389 | + "parents": [], |
390 | + "children": [ |
391 | + "eth-x2dFvx.10" |
392 | + ], |
393 | + "params": "", |
394 | + "enabled": true, |
395 | + "discovered": null, |
396 | + "vlan": { |
397 | + "vid": 0, |
398 | + "mtu": 1500, |
399 | + "dhcp_on": false, |
400 | + "external_dhcp": null, |
401 | + "relay_vlan": null, |
402 | + "id": 5001, |
403 | + "name": "untagged", |
404 | + "fabric": "fabric-0", |
405 | + "primary_rack": null, |
406 | + "fabric_id": 0, |
407 | + "secondary_rack": null, |
408 | + "space": "management", |
409 | + "resource_uri": "/MAAS/api/2.0/vlans/5001/" |
410 | + }, |
411 | + "vendor": null, |
412 | + "type": "physical", |
413 | + "resource_uri": "/MAAS/api/2.0/nodes/ssqcgt/interfaces/94/" |
414 | + }, |
415 | + { |
416 | + "id": 95, |
417 | + "name": "eth-gtMGIr", |
418 | + "tags": [ |
419 | + "tag-rW3Lmf", |
420 | + "tag-DdASuZ", |
421 | + "tag-MS8EYC" |
422 | + ], |
423 | + "links": [ |
424 | + { |
425 | + "id": 40, |
426 | + "mode": "auto", |
427 | + "subnet": { |
428 | + "name": "name-rLI3eq", |
429 | + "vlan": { |
430 | + "vid": 0, |
431 | + "mtu": 1500, |
432 | + "dhcp_on": false, |
433 | + "external_dhcp": null, |
434 | + "relay_vlan": null, |
435 | + "id": 5001, |
436 | + "name": "untagged", |
437 | + "fabric": "fabric-0", |
438 | + "primary_rack": null, |
439 | + "fabric_id": 0, |
440 | + "secondary_rack": null, |
441 | + "space": "management", |
442 | + "resource_uri": "/MAAS/api/2.0/vlans/5001/" |
443 | + }, |
444 | + "cidr": "172.16.1.0/24", |
445 | + "rdns_mode": 2, |
446 | + "gateway_ip": "172.16.1.1", |
447 | + "dns_servers": [ |
448 | + "fd89:8724:81f1:5512:557f:99c3:6967:8d63" |
449 | + ], |
450 | + "allow_dns": true, |
451 | + "allow_proxy": true, |
452 | + "active_discovery": false, |
453 | + "managed": true, |
454 | + "id": 1, |
455 | + "space": "management", |
456 | + "resource_uri": "/MAAS/api/2.0/subnets/1/" |
457 | + } |
458 | + } |
459 | + ], |
460 | + "firmware_version": null, |
461 | + "effective_mtu": 1500, |
462 | + "product": null, |
463 | + "mac_address": "52:db:98:ef:1e:b5", |
464 | + "system_id": "ssqcgt", |
465 | + "parents": [], |
466 | + "children": [ |
467 | + "eth-gtMGIr.10" |
468 | + ], |
469 | + "params": "", |
470 | + "enabled": true, |
471 | + "discovered": null, |
472 | + "vlan": { |
473 | + "vid": 0, |
474 | + "mtu": 1500, |
475 | + "dhcp_on": false, |
476 | + "external_dhcp": null, |
477 | + "relay_vlan": null, |
478 | + "id": 5001, |
479 | + "name": "untagged", |
480 | + "fabric": "fabric-0", |
481 | + "primary_rack": null, |
482 | + "fabric_id": 0, |
483 | + "secondary_rack": null, |
484 | + "space": "management", |
485 | + "resource_uri": "/MAAS/api/2.0/vlans/5001/" |
486 | + }, |
487 | + "vendor": null, |
488 | + "type": "physical", |
489 | + "resource_uri": "/MAAS/api/2.0/nodes/ssqcgt/interfaces/95/" |
490 | + }, |
491 | + { |
492 | + "id": 96, |
493 | + "name": "eth-3cXhBN", |
494 | + "tags": [ |
495 | + "tag-QisnXF", |
496 | + "tag-duMUg2", |
497 | + "tag-06ARMg" |
498 | + ], |
499 | + "links": [ |
500 | + { |
501 | + "id": 41, |
502 | + "mode": "static", |
503 | + "ip_address": "172.16.1.22", |
504 | + "subnet": { |
505 | + "name": "name-rLI3eq", |
506 | + "vlan": { |
507 | + "vid": 0, |
508 | + "mtu": 1500, |
509 | + "dhcp_on": false, |
510 | + "external_dhcp": null, |
511 | + "relay_vlan": null, |
512 | + "id": 5001, |
513 | + "name": "untagged", |
514 | + "fabric": "fabric-0", |
515 | + "primary_rack": null, |
516 | + "fabric_id": 0, |
517 | + "secondary_rack": null, |
518 | + "space": "management", |
519 | + "resource_uri": "/MAAS/api/2.0/vlans/5001/" |
520 | + }, |
521 | + "cidr": "172.16.1.0/24", |
522 | + "rdns_mode": 2, |
523 | + "gateway_ip": "172.16.1.1", |
524 | + "dns_servers": [ |
525 | + "fd89:8724:81f1:5512:557f:99c3:6967:8d63" |
526 | + ], |
527 | + "allow_dns": true, |
528 | + "allow_proxy": true, |
529 | + "active_discovery": false, |
530 | + "managed": true, |
531 | + "id": 1, |
532 | + "space": "management", |
533 | + "resource_uri": "/MAAS/api/2.0/subnets/1/" |
534 | + } |
535 | + } |
536 | + ], |
537 | + "firmware_version": null, |
538 | + "effective_mtu": 1500, |
539 | + "product": null, |
540 | + "mac_address": "e3:72:73:60:9a:b9", |
541 | + "system_id": "ssqcgt", |
542 | + "parents": [], |
543 | + "children": [ |
544 | + "eth-3cXhBN.10" |
545 | + ], |
546 | + "params": "", |
547 | + "enabled": true, |
548 | + "discovered": null, |
549 | + "vlan": { |
550 | + "vid": 0, |
551 | + "mtu": 1500, |
552 | + "dhcp_on": false, |
553 | + "external_dhcp": null, |
554 | + "relay_vlan": null, |
555 | + "id": 5001, |
556 | + "name": "untagged", |
557 | + "fabric": "fabric-0", |
558 | + "primary_rack": null, |
559 | + "fabric_id": 0, |
560 | + "secondary_rack": null, |
561 | + "space": "management", |
562 | + "resource_uri": "/MAAS/api/2.0/vlans/5001/" |
563 | + }, |
564 | + "vendor": null, |
565 | + "type": "physical", |
566 | + "resource_uri": "/MAAS/api/2.0/nodes/ssqcgt/interfaces/96/" |
567 | + }, |
568 | + { |
569 | + "id": 97, |
570 | + "name": "eth-x2dFvx.10", |
571 | + "tags": [ |
572 | + "tag-Y5zzv5", |
573 | + "tag-w5vECc", |
574 | + "tag-o4znE9" |
575 | + ], |
576 | + "links": [ |
577 | + { |
578 | + "id": 42, |
579 | + "mode": "static", |
580 | + "ip_address": "172.16.4.56", |
581 | + "subnet": { |
582 | + "name": "name-c2ULe1", |
583 | + "vlan": { |
584 | + "vid": 10, |
585 | + "mtu": 1500, |
586 | + "dhcp_on": false, |
587 | + "external_dhcp": null, |
588 | + "relay_vlan": null, |
589 | + "id": 5002, |
590 | + "name": "10", |
591 | + "fabric": "fabric-0", |
592 | + "primary_rack": null, |
593 | + "fabric_id": 0, |
594 | + "secondary_rack": null, |
595 | + "space": "internal", |
596 | + "resource_uri": "/MAAS/api/2.0/vlans/5002/" |
597 | + }, |
598 | + "cidr": "172.16.4.0/24", |
599 | + "rdns_mode": 2, |
600 | + "gateway_ip": "172.16.4.1", |
601 | + "dns_servers": [ |
602 | + "fd08:fef7:5c1f:a2e6:3d8e:6c3b:89f9:80cb", |
603 | + "fc67:ad6a:88fe:9192:62f9:e882:8bcc:339e", |
604 | + "255.59.162.158" |
605 | + ], |
606 | + "allow_dns": true, |
607 | + "allow_proxy": true, |
608 | + "active_discovery": false, |
609 | + "managed": true, |
610 | + "id": 4, |
611 | + "space": "internal", |
612 | + "resource_uri": "/MAAS/api/2.0/subnets/4/" |
613 | + } |
614 | + } |
615 | + ], |
616 | + "firmware_version": null, |
617 | + "effective_mtu": 1500, |
618 | + "product": null, |
619 | + "mac_address": "dd:c6:80:1a:c7:80", |
620 | + "system_id": "ssqcgt", |
621 | + "parents": [ |
622 | + "eth-x2dFvx" |
623 | + ], |
624 | + "children": [], |
625 | + "params": "", |
626 | + "enabled": true, |
627 | + "discovered": null, |
628 | + "vlan": { |
629 | + "vid": 10, |
630 | + "mtu": 1500, |
631 | + "dhcp_on": false, |
632 | + "external_dhcp": null, |
633 | + "relay_vlan": null, |
634 | + "id": 5002, |
635 | + "name": "10", |
636 | + "fabric": "fabric-0", |
637 | + "primary_rack": null, |
638 | + "fabric_id": 0, |
639 | + "secondary_rack": null, |
640 | + "space": "internal", |
641 | + "resource_uri": "/MAAS/api/2.0/vlans/5002/" |
642 | + }, |
643 | + "vendor": null, |
644 | + "type": "vlan", |
645 | + "resource_uri": "/MAAS/api/2.0/nodes/ssqcgt/interfaces/97/" |
646 | + }, |
647 | + { |
648 | + "id": 98, |
649 | + "name": "eth-gtMGIr.10", |
650 | + "tags": [ |
651 | + "tag-wS4OXL", |
652 | + "tag-Wm3I55", |
653 | + "tag-LE5UYY" |
654 | + ], |
655 | + "links": [ |
656 | + { |
657 | + "id": 43, |
658 | + "mode": "static", |
659 | + "ip_address": "172.16.3.102", |
660 | + "subnet": { |
661 | + "name": "name-zznp45", |
662 | + "vlan": { |
663 | + "vid": 10, |
664 | + "mtu": 1500, |
665 | + "dhcp_on": false, |
666 | + "external_dhcp": null, |
667 | + "relay_vlan": null, |
668 | + "id": 5002, |
669 | + "name": "10", |
670 | + "fabric": "fabric-0", |
671 | + "primary_rack": null, |
672 | + "fabric_id": 0, |
673 | + "secondary_rack": null, |
674 | + "space": "internal", |
675 | + "resource_uri": "/MAAS/api/2.0/vlans/5002/" |
676 | + }, |
677 | + "cidr": "172.16.3.0/24", |
678 | + "rdns_mode": 2, |
679 | + "gateway_ip": "172.16.3.1", |
680 | + "dns_servers": [ |
681 | + "fd98:8601:90d0:c8c:dd2e:ba51:fa5a:dcfa", |
682 | + "11.209.150.208", |
683 | + "fde6:f9ef:3ee9:c5de:2a66:1582:cc83:abaf" |
684 | + ], |
685 | + "allow_dns": true, |
686 | + "allow_proxy": true, |
687 | + "active_discovery": false, |
688 | + "managed": true, |
689 | + "id": 3, |
690 | + "space": "internal", |
691 | + "resource_uri": "/MAAS/api/2.0/subnets/3/" |
692 | + } |
693 | + } |
694 | + ], |
695 | + "firmware_version": null, |
696 | + "effective_mtu": 1500, |
697 | + "product": null, |
698 | + "mac_address": "52:db:98:ef:1e:b5", |
699 | + "system_id": "ssqcgt", |
700 | + "parents": [ |
701 | + "eth-gtMGIr" |
702 | + ], |
703 | + "children": [], |
704 | + "params": "", |
705 | + "enabled": true, |
706 | + "discovered": null, |
707 | + "vlan": { |
708 | + "vid": 10, |
709 | + "mtu": 1500, |
710 | + "dhcp_on": false, |
711 | + "external_dhcp": null, |
712 | + "relay_vlan": null, |
713 | + "id": 5002, |
714 | + "name": "10", |
715 | + "fabric": "fabric-0", |
716 | + "primary_rack": null, |
717 | + "fabric_id": 0, |
718 | + "secondary_rack": null, |
719 | + "space": "internal", |
720 | + "resource_uri": "/MAAS/api/2.0/vlans/5002/" |
721 | + }, |
722 | + "vendor": null, |
723 | + "type": "vlan", |
724 | + "resource_uri": "/MAAS/api/2.0/nodes/ssqcgt/interfaces/98/" |
725 | + }, |
726 | + { |
727 | + "id": 99, |
728 | + "name": "eth-3cXhBN.10", |
729 | + "tags": [ |
730 | + "tag-Zp22Uh", |
731 | + "tag-PhIZjP", |
732 | + "tag-QtYg8x" |
733 | + ], |
734 | + "links": [ |
735 | + { |
736 | + "id": 44, |
737 | + "mode": "static", |
738 | + "ip_address": "172.16.3.23", |
739 | + "subnet": { |
740 | + "name": "name-zznp45", |
741 | + "vlan": { |
742 | + "vid": 10, |
743 | + "mtu": 1500, |
744 | + "dhcp_on": false, |
745 | + "external_dhcp": null, |
746 | + "relay_vlan": null, |
747 | + "id": 5002, |
748 | + "name": "10", |
749 | + "fabric": "fabric-0", |
750 | + "primary_rack": null, |
751 | + "fabric_id": 0, |
752 | + "secondary_rack": null, |
753 | + "space": "internal", |
754 | + "resource_uri": "/MAAS/api/2.0/vlans/5002/" |
755 | + }, |
756 | + "cidr": "172.16.3.0/24", |
757 | + "rdns_mode": 2, |
758 | + "gateway_ip": "172.16.3.1", |
759 | + "dns_servers": [ |
760 | + "fd98:8601:90d0:c8c:dd2e:ba51:fa5a:dcfa", |
761 | + "11.209.150.208", |
762 | + "fde6:f9ef:3ee9:c5de:2a66:1582:cc83:abaf" |
763 | + ], |
764 | + "allow_dns": true, |
765 | + "allow_proxy": true, |
766 | + "active_discovery": false, |
767 | + "managed": true, |
768 | + "id": 3, |
769 | + "space": "internal", |
770 | + "resource_uri": "/MAAS/api/2.0/subnets/3/" |
771 | + } |
772 | + } |
773 | + ], |
774 | + "firmware_version": null, |
775 | + "effective_mtu": 1500, |
776 | + "product": null, |
777 | + "mac_address": "e3:72:73:60:9a:b9", |
778 | + "system_id": "ssqcgt", |
779 | + "parents": [ |
780 | + "eth-3cXhBN" |
781 | + ], |
782 | + "children": [], |
783 | + "params": "", |
784 | + "enabled": true, |
785 | + "discovered": null, |
786 | + "vlan": { |
787 | + "vid": 10, |
788 | + "mtu": 1500, |
789 | + "dhcp_on": false, |
790 | + "external_dhcp": null, |
791 | + "relay_vlan": null, |
792 | + "id": 5002, |
793 | + "name": "10", |
794 | + "fabric": "fabric-0", |
795 | + "primary_rack": null, |
796 | + "fabric_id": 0, |
797 | + "secondary_rack": null, |
798 | + "space": "internal", |
799 | + "resource_uri": "/MAAS/api/2.0/vlans/5002/" |
800 | + }, |
801 | + "vendor": null, |
802 | + "type": "vlan", |
803 | + "resource_uri": "/MAAS/api/2.0/nodes/ssqcgt/interfaces/99/" |
804 | + } |
805 | + ], |
806 | + "iscsiblockdevice_set": [], |
807 | + "node_type": 0, |
808 | + "memory_test_status_name": "Failed", |
809 | + "bcaches": [], |
810 | + "memory_test_status": 3, |
811 | + "ip_addresses": [ |
812 | + "172.16.1.22", |
813 | + "172.16.4.56", |
814 | + "172.16.3.102", |
815 | + "172.16.3.23" |
816 | + ], |
817 | + "swap_size": null, |
818 | + "volume_groups": [], |
819 | + "testing_status": 3, |
820 | + "node_type_name": "Machine", |
821 | + "current_testing_result_id": 153, |
822 | + "power_type": "virsh", |
823 | + "fqdn": "chief-hippo.ubnt", |
824 | + "storage_test_status_name": "Failed", |
825 | + "storage_test_status": 3, |
826 | + "status_name": "Rescue mode", |
827 | + "locked": false, |
828 | + "netboot": true, |
829 | + "tag_names": [ |
830 | + "virtual" |
831 | + ], |
832 | + "zone": { |
833 | + "name": "zone-north", |
834 | + "description": "xsMaq90fRE", |
835 | + "id": 2, |
836 | + "resource_uri": "/MAAS/api/2.0/zones/zone-north/" |
837 | + }, |
838 | + "boot_disk": { |
839 | + "firmware_version": "firmware_version-rszebt", |
840 | + "uuid": null, |
841 | + "id": 65, |
842 | + "model": "model-u038bu", |
843 | + "name": "name-2V9gLL", |
844 | + "tags": [ |
845 | + "tag-wSvQ4O", |
846 | + "tag-52MbPv", |
847 | + "tag-JKilHY" |
848 | + ], |
849 | + "partitions": [], |
850 | + "partition_table_type": null, |
851 | + "used_size": 0, |
852 | + "storage_pool": "pool_id-aMRZUu", |
853 | + "id_path": null, |
854 | + "system_id": "ssqcgt", |
855 | + "block_size": 512, |
856 | + "filesystem": null, |
857 | + "used_for": "Unused", |
858 | + "serial": "serial-Lh6Yv9", |
859 | + "path": "/dev/disk/by-dname/name-2V9gLL", |
860 | + "type": "physical", |
861 | + "size": 3865490432, |
862 | + "available_size": 3865490432, |
863 | + "resource_uri": "/MAAS/api/2.0/nodes/ssqcgt/blockdevices/65/" |
864 | + }, |
865 | + "commissioning_status": 2, |
866 | + "cpu_test_status": 3, |
867 | + "current_installation_result_id": null, |
868 | + "owner_data": {}, |
869 | + "power_state": "on", |
870 | + "current_commissioning_result_id": 152, |
871 | + "status": 16, |
872 | + "hwe_kernel": null, |
873 | + "boot_interface": { |
874 | + "id": 94, |
875 | + "name": "eth-x2dFvx", |
876 | + "tags": [ |
877 | + "tag-fAzmsZ", |
878 | + "tag-doKrVe", |
879 | + "tag-ejryXL" |
880 | + ], |
881 | + "links": [ |
882 | + { |
883 | + "id": 39, |
884 | + "mode": "auto", |
885 | + "subnet": { |
886 | + "name": "name-rLI3eq", |
887 | + "vlan": { |
888 | + "vid": 0, |
889 | + "mtu": 1500, |
890 | + "dhcp_on": false, |
891 | + "external_dhcp": null, |
892 | + "relay_vlan": null, |
893 | + "id": 5001, |
894 | + "name": "untagged", |
895 | + "fabric": "fabric-0", |
896 | + "primary_rack": null, |
897 | + "fabric_id": 0, |
898 | + "secondary_rack": null, |
899 | + "space": "management", |
900 | + "resource_uri": "/MAAS/api/2.0/vlans/5001/" |
901 | + }, |
902 | + "cidr": "172.16.1.0/24", |
903 | + "rdns_mode": 2, |
904 | + "gateway_ip": "172.16.1.1", |
905 | + "dns_servers": [ |
906 | + "fd89:8724:81f1:5512:557f:99c3:6967:8d63" |
907 | + ], |
908 | + "allow_dns": true, |
909 | + "allow_proxy": true, |
910 | + "active_discovery": false, |
911 | + "managed": true, |
912 | + "id": 1, |
913 | + "space": "management", |
914 | + "resource_uri": "/MAAS/api/2.0/subnets/1/" |
915 | + } |
916 | + } |
917 | + ], |
918 | + "firmware_version": null, |
919 | + "effective_mtu": 1500, |
920 | + "product": null, |
921 | + "mac_address": "dd:c6:80:1a:c7:80", |
922 | + "system_id": "ssqcgt", |
923 | + "parents": [], |
924 | + "children": [ |
925 | + "eth-x2dFvx.10" |
926 | + ], |
927 | + "params": "", |
928 | + "enabled": true, |
929 | + "discovered": null, |
930 | + "vlan": { |
931 | + "vid": 0, |
932 | + "mtu": 1500, |
933 | + "dhcp_on": false, |
934 | + "external_dhcp": null, |
935 | + "relay_vlan": null, |
936 | + "id": 5001, |
937 | + "name": "untagged", |
938 | + "fabric": "fabric-0", |
939 | + "primary_rack": null, |
940 | + "fabric_id": 0, |
941 | + "secondary_rack": null, |
942 | + "space": "management", |
943 | + "resource_uri": "/MAAS/api/2.0/vlans/5001/" |
944 | + }, |
945 | + "vendor": null, |
946 | + "type": "physical", |
947 | + "resource_uri": "/MAAS/api/2.0/nodes/ssqcgt/interfaces/94/" |
948 | + }, |
949 | + "special_filesystems": [], |
950 | + "cpu_speed": 0, |
951 | + "architecture": "amd64/generic", |
952 | + "blockdevice_set": [ |
953 | + { |
954 | + "id_path": null, |
955 | + "size": 3865490432, |
956 | + "block_size": 512, |
957 | + "tags": [ |
958 | + "tag-wSvQ4O", |
959 | + "tag-52MbPv", |
960 | + "tag-JKilHY" |
961 | + ], |
962 | + "uuid": null, |
963 | + "id": 65, |
964 | + "model": "model-u038bu", |
965 | + "name": "name-2V9gLL", |
966 | + "partitions": [], |
967 | + "partition_table_type": null, |
968 | + "used_size": 0, |
969 | + "storage_pool": "pool_id-aMRZUu", |
970 | + "system_id": "ssqcgt", |
971 | + "filesystem": null, |
972 | + "used_for": "Unused", |
973 | + "serial": "serial-Lh6Yv9", |
974 | + "path": "/dev/disk/by-dname/name-2V9gLL", |
975 | + "type": "physical", |
976 | + "available_size": 3865490432, |
977 | + "resource_uri": "/MAAS/api/2.0/nodes/ssqcgt/blockdevices/65/" |
978 | + } |
979 | + ], |
980 | + "cpu_test_status_name": "Failed", |
981 | + "other_test_status": 2, |
982 | + "hostname": "chief-hippo", |
983 | + "memory": 4096, |
984 | + "default_gateways": { |
985 | + "ipv4": { |
986 | + "gateway_ip": "172.16.1.1", |
987 | + "link_id": null |
988 | + }, |
989 | + "ipv6": { |
990 | + "gateway_ip": null, |
991 | + "link_id": null |
992 | + } |
993 | + }, |
994 | + "distro_series": "", |
995 | + "status_action": "action-ft28IH", |
996 | + "owner": "user1", |
997 | + "commissioning_status_name": "Passed", |
998 | + "hardware_info": { |
999 | + "system_vendor": "Unknown", |
1000 | + "system_product": "Unknown", |
1001 | + "system_version": "Unknown", |
1002 | + "system_serial": "Unknown", |
1003 | + "cpu_model": "Unknown", |
1004 | + "mainboard_vendor": "Unknown", |
1005 | + "mainboard_product": "Unknown", |
1006 | + "mainboard_firmware_version": "Unknown", |
1007 | + "mainboard_firmware_date": "Unknown" |
1008 | + }, |
1009 | + "pod": { |
1010 | + "id": 5, |
1011 | + "name": "normal-trout", |
1012 | + "resource_uri": "/MAAS/api/2.0/pods/5/" |
1013 | + }, |
1014 | + "cache_sets": [], |
1015 | + "testing_status_name": "Failed", |
1016 | + "disable_ipv4": false, |
1017 | + "physicalblockdevice_set": [ |
1018 | + { |
1019 | + "firmware_version": "firmware_version-rszebt", |
1020 | + "uuid": null, |
1021 | + "id": 65, |
1022 | + "model": "model-u038bu", |
1023 | + "name": "name-2V9gLL", |
1024 | + "tags": [ |
1025 | + "tag-wSvQ4O", |
1026 | + "tag-52MbPv", |
1027 | + "tag-JKilHY" |
1028 | + ], |
1029 | + "partitions": [], |
1030 | + "partition_table_type": null, |
1031 | + "used_size": 0, |
1032 | + "storage_pool": "pool_id-aMRZUu", |
1033 | + "id_path": null, |
1034 | + "system_id": "ssqcgt", |
1035 | + "block_size": 512, |
1036 | + "filesystem": null, |
1037 | + "used_for": "Unused", |
1038 | + "serial": "serial-Lh6Yv9", |
1039 | + "path": "/dev/disk/by-dname/name-2V9gLL", |
1040 | + "type": "physical", |
1041 | + "size": 3865490432, |
1042 | + "available_size": 3865490432, |
1043 | + "resource_uri": "/MAAS/api/2.0/nodes/ssqcgt/blockdevices/65/" |
1044 | + } |
1045 | + ], |
1046 | + "osystem": "", |
1047 | + "system_id": "ssqcgt", |
1048 | + "address_ttl": null, |
1049 | + "raids": [], |
1050 | + "cpu_count": 5, |
1051 | + "virtualblockdevice_set": [], |
1052 | + "other_test_status_name": "Passed", |
1053 | + "status_message": "desc-SfeEsi", |
1054 | + "domain": { |
1055 | + "authoritative": true, |
1056 | + "ttl": null, |
1057 | + "id": 2, |
1058 | + "name": "ubnt", |
1059 | + "resource_record_count": 0, |
1060 | + "is_default": false, |
1061 | + "resource_uri": "/MAAS/api/2.0/domains/2/" |
1062 | + }, |
1063 | + "resource_uri": "/MAAS/api/2.0/machines/ssqcgt/" |
1064 | + } |
1065 | + ], |
1066 | + "get-nodes-by-tag": [ |
1067 | + { |
1068 | + "interface_set": [ |
1069 | + { |
1070 | + "id": 1, |
1071 | + "name": "ens3", |
1072 | + "tags": [ |
1073 | + "tag-0wj45r", |
1074 | + "tag-ylwPaA", |
1075 | + "tag-s8HCFS" |
1076 | + ], |
1077 | + "links": [ |
1078 | + { |
1079 | + "id": 59, |
1080 | + "mode": "static", |
1081 | + "ip_address": "10.55.32.42", |
1082 | + "subnet": { |
1083 | + "name": "10.55.32.0/20", |
1084 | + "vlan": { |
1085 | + "vid": 0, |
1086 | + "mtu": 1500, |
1087 | + "dhcp_on": false, |
1088 | + "external_dhcp": null, |
1089 | + "relay_vlan": null, |
1090 | + "id": 5001, |
1091 | + "name": "untagged", |
1092 | + "fabric": "fabric-0", |
1093 | + "primary_rack": null, |
1094 | + "fabric_id": 0, |
1095 | + "secondary_rack": null, |
1096 | + "space": "management", |
1097 | + "resource_uri": "/MAAS/api/2.0/vlans/5001/" |
1098 | + }, |
1099 | + "cidr": "10.55.32.0/20", |
1100 | + "rdns_mode": 2, |
1101 | + "gateway_ip": "10.55.32.1", |
1102 | + "dns_servers": [], |
1103 | + "allow_dns": true, |
1104 | + "allow_proxy": true, |
1105 | + "active_discovery": false, |
1106 | + "managed": true, |
1107 | + "id": 6, |
1108 | + "space": "management", |
1109 | + "resource_uri": "/MAAS/api/2.0/subnets/6/" |
1110 | + } |
1111 | + } |
1112 | + ], |
1113 | + "firmware_version": "N/A", |
1114 | + "effective_mtu": 1500, |
1115 | + "product": "OpenStack Nova", |
1116 | + "mac_address": "fa:16:3e:3d:03:02", |
1117 | + "system_id": "7xtf67", |
1118 | + "parents": [], |
1119 | + "children": [], |
1120 | + "params": "", |
1121 | + "enabled": true, |
1122 | + "discovered": null, |
1123 | + "vlan": { |
1124 | + "vid": 0, |
1125 | + "mtu": 1500, |
1126 | + "dhcp_on": false, |
1127 | + "external_dhcp": null, |
1128 | + "relay_vlan": null, |
1129 | + "id": 5001, |
1130 | + "name": "untagged", |
1131 | + "fabric": "fabric-0", |
1132 | + "primary_rack": null, |
1133 | + "fabric_id": 0, |
1134 | + "secondary_rack": null, |
1135 | + "space": "management", |
1136 | + "resource_uri": "/MAAS/api/2.0/vlans/5001/" |
1137 | + }, |
1138 | + "vendor": "OpenStack Foundation", |
1139 | + "type": "physical", |
1140 | + "resource_uri": "/MAAS/api/2.0/nodes/7xtf67/interfaces/1/" |
1141 | + }, |
1142 | + { |
1143 | + "id": 134, |
1144 | + "name": "virbr0", |
1145 | + "tags": [], |
1146 | + "links": [ |
1147 | + { |
1148 | + "id": 60, |
1149 | + "mode": "static", |
1150 | + "ip_address": "192.168.122.1", |
1151 | + "subnet": { |
1152 | + "name": "192.168.122.0/24", |
1153 | + "vlan": { |
1154 | + "vid": 0, |
1155 | + "mtu": 1500, |
1156 | + "dhcp_on": false, |
1157 | + "external_dhcp": null, |
1158 | + "relay_vlan": null, |
1159 | + "id": 5017, |
1160 | + "name": "untagged", |
1161 | + "fabric": "fabric-13", |
1162 | + "primary_rack": null, |
1163 | + "fabric_id": 13, |
1164 | + "secondary_rack": null, |
1165 | + "space": "undefined", |
1166 | + "resource_uri": "/MAAS/api/2.0/vlans/5017/" |
1167 | + }, |
1168 | + "cidr": "192.168.122.0/24", |
1169 | + "rdns_mode": 2, |
1170 | + "gateway_ip": null, |
1171 | + "dns_servers": [], |
1172 | + "allow_dns": true, |
1173 | + "allow_proxy": true, |
1174 | + "active_discovery": false, |
1175 | + "managed": true, |
1176 | + "id": 7, |
1177 | + "space": "undefined", |
1178 | + "resource_uri": "/MAAS/api/2.0/subnets/7/" |
1179 | + } |
1180 | + } |
1181 | + ], |
1182 | + "firmware_version": "N/A", |
1183 | + "effective_mtu": 1500, |
1184 | + "product": "OpenStack Nova", |
1185 | + "mac_address": "52:54:00:95:f3:f3", |
1186 | + "system_id": "7xtf67", |
1187 | + "parents": [], |
1188 | + "children": [], |
1189 | + "params": "", |
1190 | + "enabled": true, |
1191 | + "discovered": null, |
1192 | + "vlan": { |
1193 | + "vid": 0, |
1194 | + "mtu": 1500, |
1195 | + "dhcp_on": false, |
1196 | + "external_dhcp": null, |
1197 | + "relay_vlan": null, |
1198 | + "id": 5017, |
1199 | + "name": "untagged", |
1200 | + "fabric": "fabric-13", |
1201 | + "primary_rack": null, |
1202 | + "fabric_id": 13, |
1203 | + "secondary_rack": null, |
1204 | + "space": "undefined", |
1205 | + "resource_uri": "/MAAS/api/2.0/vlans/5017/" |
1206 | + }, |
1207 | + "vendor": "OpenStack Foundation", |
1208 | + "type": "bridge", |
1209 | + "resource_uri": "/MAAS/api/2.0/nodes/7xtf67/interfaces/134/" |
1210 | + } |
1211 | + ], |
1212 | + "node_type": 4, |
1213 | + "memory_test_status_name": "Unknown", |
1214 | + "memory_test_status": -1, |
1215 | + "ip_addresses": [ |
1216 | + "10.55.32.42", |
1217 | + "192.168.122.1" |
1218 | + ], |
1219 | + "swap_size": null, |
1220 | + "testing_status": -1, |
1221 | + "node_type_name": "Region and rack controller", |
1222 | + "current_testing_result_id": null, |
1223 | + "power_type": "virsh", |
1224 | + "fqdn": "spence-devmaas.maas", |
1225 | + "storage_test_status_name": "Unknown", |
1226 | + "storage_test_status": -1, |
1227 | + "tag_names": [ |
1228 | + "virtual" |
1229 | + ], |
1230 | + "zone": { |
1231 | + "name": "zone-obryVj", |
1232 | + "description": "qRwvQuFIpM", |
1233 | + "id": 4, |
1234 | + "resource_uri": "/MAAS/api/2.0/zones/zone-obryVj/" |
1235 | + }, |
1236 | + "commissioning_status": 2, |
1237 | + "cpu_test_status": -1, |
1238 | + "current_installation_result_id": null, |
1239 | + "power_state": "on", |
1240 | + "current_commissioning_result_id": 228, |
1241 | + "cpu_speed": 2500, |
1242 | + "architecture": "amd64/generic", |
1243 | + "cpu_test_status_name": "Unknown", |
1244 | + "other_test_status": -1, |
1245 | + "hostname": "spence-devmaas", |
1246 | + "memory": 8192, |
1247 | + "commissioning_status_name": "Passed", |
1248 | + "distro_series": "bionic", |
1249 | + "status_action": "", |
1250 | + "hardware_info": { |
1251 | + "system_vendor": "OpenStack Foundation", |
1252 | + "system_product": "OpenStack Nova", |
1253 | + "system_version": "2013.2.3", |
1254 | + "system_serial": "30353036-3837-5a43-3331-353234584a58", |
1255 | + "cpu_model": "Westmere E56xx/L56xx/X56xx (Nehalem-C)", |
1256 | + "mainboard_vendor": "Unknown", |
1257 | + "mainboard_product": "Unknown", |
1258 | + "mainboard_firmware_version": "Bochs", |
1259 | + "mainboard_firmware_date": "01/01/2011" |
1260 | + }, |
1261 | + "service_set": [ |
1262 | + { |
1263 | + "name": "proxy", |
1264 | + "status": "unknown", |
1265 | + "status_info": "" |
1266 | + }, |
1267 | + { |
1268 | + "name": "proxy_rack", |
1269 | + "status": "unknown", |
1270 | + "status_info": "" |
1271 | + }, |
1272 | + { |
1273 | + "name": "dhcpd6", |
1274 | + "status": "dead", |
1275 | + "status_info": "" |
1276 | + }, |
1277 | + { |
1278 | + "name": "ntp_rack", |
1279 | + "status": "dead", |
1280 | + "status_info": "" |
1281 | + }, |
1282 | + { |
1283 | + "name": "syslog_region", |
1284 | + "status": "unknown", |
1285 | + "status_info": "" |
1286 | + }, |
1287 | + { |
1288 | + "name": "http", |
1289 | + "status": "unknown", |
1290 | + "status_info": "" |
1291 | + }, |
1292 | + { |
1293 | + "name": "tftp", |
1294 | + "status": "dead", |
1295 | + "status_info": "" |
1296 | + }, |
1297 | + { |
1298 | + "name": "bind9", |
1299 | + "status": "unknown", |
1300 | + "status_info": "" |
1301 | + }, |
1302 | + { |
1303 | + "name": "rackd", |
1304 | + "status": "dead", |
1305 | + "status_info": "" |
1306 | + }, |
1307 | + { |
1308 | + "name": "ntp_region", |
1309 | + "status": "unknown", |
1310 | + "status_info": "" |
1311 | + }, |
1312 | + { |
1313 | + "name": "regiond", |
1314 | + "status": "running", |
1315 | + "status_info": "" |
1316 | + }, |
1317 | + { |
1318 | + "name": "dns_rack", |
1319 | + "status": "unknown", |
1320 | + "status_info": "" |
1321 | + }, |
1322 | + { |
1323 | + "name": "syslog_rack", |
1324 | + "status": "unknown", |
1325 | + "status_info": "" |
1326 | + }, |
1327 | + { |
1328 | + "name": "dhcpd", |
1329 | + "status": "dead", |
1330 | + "status_info": "" |
1331 | + } |
1332 | + ], |
1333 | + "testing_status_name": "Unknown", |
1334 | + "osystem": "ubuntu", |
1335 | + "version": "", |
1336 | + "system_id": "7xtf67", |
1337 | + "cpu_count": 4, |
1338 | + "other_test_status_name": "Unknown", |
1339 | + "domain": { |
1340 | + "authoritative": true, |
1341 | + "ttl": null, |
1342 | + "id": 0, |
1343 | + "name": "maas", |
1344 | + "resource_record_count": 0, |
1345 | + "is_default": true, |
1346 | + "resource_uri": "/MAAS/api/2.0/domains/0/" |
1347 | + }, |
1348 | + "resource_uri": "/MAAS/api/2.0/rackcontrollers/7xtf67/" |
1349 | + }, |
1350 | + { |
1351 | + "pool": { |
1352 | + "name": "default", |
1353 | + "description": "Default pool", |
1354 | + "id": 0, |
1355 | + "resource_uri": "/MAAS/api/2.0/resourcepool/0/" |
1356 | + }, |
1357 | + "storage": 3865.490432, |
1358 | + "min_hwe_kernel": "", |
1359 | + "interface_set": [ |
1360 | + { |
1361 | + "id": 94, |
1362 | + "name": "eth-x2dFvx", |
1363 | + "tags": [ |
1364 | + "tag-fAzmsZ", |
1365 | + "tag-doKrVe", |
1366 | + "tag-ejryXL" |
1367 | + ], |
1368 | + "links": [ |
1369 | + { |
1370 | + "id": 39, |
1371 | + "mode": "auto", |
1372 | + "subnet": { |
1373 | + "name": "name-rLI3eq", |
1374 | + "vlan": { |
1375 | + "vid": 0, |
1376 | + "mtu": 1500, |
1377 | + "dhcp_on": false, |
1378 | + "external_dhcp": null, |
1379 | + "relay_vlan": null, |
1380 | + "id": 5001, |
1381 | + "name": "untagged", |
1382 | + "fabric": "fabric-0", |
1383 | + "primary_rack": null, |
1384 | + "fabric_id": 0, |
1385 | + "secondary_rack": null, |
1386 | + "space": "management", |
1387 | + "resource_uri": "/MAAS/api/2.0/vlans/5001/" |
1388 | + }, |
1389 | + "cidr": "172.16.1.0/24", |
1390 | + "rdns_mode": 2, |
1391 | + "gateway_ip": "172.16.1.1", |
1392 | + "dns_servers": [ |
1393 | + "fd89:8724:81f1:5512:557f:99c3:6967:8d63" |
1394 | + ], |
1395 | + "allow_dns": true, |
1396 | + "allow_proxy": true, |
1397 | + "active_discovery": false, |
1398 | + "managed": true, |
1399 | + "id": 1, |
1400 | + "space": "management", |
1401 | + "resource_uri": "/MAAS/api/2.0/subnets/1/" |
1402 | + } |
1403 | + } |
1404 | + ], |
1405 | + "firmware_version": null, |
1406 | + "effective_mtu": 1500, |
1407 | + "product": null, |
1408 | + "mac_address": "dd:c6:80:1a:c7:80", |
1409 | + "system_id": "ssqcgt", |
1410 | + "parents": [], |
1411 | + "children": [ |
1412 | + "eth-x2dFvx.10" |
1413 | + ], |
1414 | + "params": "", |
1415 | + "enabled": true, |
1416 | + "discovered": null, |
1417 | + "vlan": { |
1418 | + "vid": 0, |
1419 | + "mtu": 1500, |
1420 | + "dhcp_on": false, |
1421 | + "external_dhcp": null, |
1422 | + "relay_vlan": null, |
1423 | + "id": 5001, |
1424 | + "name": "untagged", |
1425 | + "fabric": "fabric-0", |
1426 | + "primary_rack": null, |
1427 | + "fabric_id": 0, |
1428 | + "secondary_rack": null, |
1429 | + "space": "management", |
1430 | + "resource_uri": "/MAAS/api/2.0/vlans/5001/" |
1431 | + }, |
1432 | + "vendor": null, |
1433 | + "type": "physical", |
1434 | + "resource_uri": "/MAAS/api/2.0/nodes/ssqcgt/interfaces/94/" |
1435 | + }, |
1436 | + { |
1437 | + "id": 95, |
1438 | + "name": "eth-gtMGIr", |
1439 | + "tags": [ |
1440 | + "tag-rW3Lmf", |
1441 | + "tag-DdASuZ", |
1442 | + "tag-MS8EYC" |
1443 | + ], |
1444 | + "links": [ |
1445 | + { |
1446 | + "id": 40, |
1447 | + "mode": "auto", |
1448 | + "subnet": { |
1449 | + "name": "name-rLI3eq", |
1450 | + "vlan": { |
1451 | + "vid": 0, |
1452 | + "mtu": 1500, |
1453 | + "dhcp_on": false, |
1454 | + "external_dhcp": null, |
1455 | + "relay_vlan": null, |
1456 | + "id": 5001, |
1457 | + "name": "untagged", |
1458 | + "fabric": "fabric-0", |
1459 | + "primary_rack": null, |
1460 | + "fabric_id": 0, |
1461 | + "secondary_rack": null, |
1462 | + "space": "management", |
1463 | + "resource_uri": "/MAAS/api/2.0/vlans/5001/" |
1464 | + }, |
1465 | + "cidr": "172.16.1.0/24", |
1466 | + "rdns_mode": 2, |
1467 | + "gateway_ip": "172.16.1.1", |
1468 | + "dns_servers": [ |
1469 | + "fd89:8724:81f1:5512:557f:99c3:6967:8d63" |
1470 | + ], |
1471 | + "allow_dns": true, |
1472 | + "allow_proxy": true, |
1473 | + "active_discovery": false, |
1474 | + "managed": true, |
1475 | + "id": 1, |
1476 | + "space": "management", |
1477 | + "resource_uri": "/MAAS/api/2.0/subnets/1/" |
1478 | + } |
1479 | + } |
1480 | + ], |
1481 | + "firmware_version": null, |
1482 | + "effective_mtu": 1500, |
1483 | + "product": null, |
1484 | + "mac_address": "52:db:98:ef:1e:b5", |
1485 | + "system_id": "ssqcgt", |
1486 | + "parents": [], |
1487 | + "children": [ |
1488 | + "eth-gtMGIr.10" |
1489 | + ], |
1490 | + "params": "", |
1491 | + "enabled": true, |
1492 | + "discovered": null, |
1493 | + "vlan": { |
1494 | + "vid": 0, |
1495 | + "mtu": 1500, |
1496 | + "dhcp_on": false, |
1497 | + "external_dhcp": null, |
1498 | + "relay_vlan": null, |
1499 | + "id": 5001, |
1500 | + "name": "untagged", |
1501 | + "fabric": "fabric-0", |
1502 | + "primary_rack": null, |
1503 | + "fabric_id": 0, |
1504 | + "secondary_rack": null, |
1505 | + "space": "management", |
1506 | + "resource_uri": "/MAAS/api/2.0/vlans/5001/" |
1507 | + }, |
1508 | + "vendor": null, |
1509 | + "type": "physical", |
1510 | + "resource_uri": "/MAAS/api/2.0/nodes/ssqcgt/interfaces/95/" |
1511 | + }, |
1512 | + { |
1513 | + "id": 96, |
1514 | + "name": "eth-3cXhBN", |
1515 | + "tags": [ |
1516 | + "tag-QisnXF", |
1517 | + "tag-duMUg2", |
1518 | + "tag-06ARMg" |
1519 | + ], |
1520 | + "links": [ |
1521 | + { |
1522 | + "id": 41, |
1523 | + "mode": "static", |
1524 | + "ip_address": "172.16.1.22", |
1525 | + "subnet": { |
1526 | + "name": "name-rLI3eq", |
1527 | + "vlan": { |
1528 | + "vid": 0, |
1529 | + "mtu": 1500, |
1530 | + "dhcp_on": false, |
1531 | + "external_dhcp": null, |
1532 | + "relay_vlan": null, |
1533 | + "id": 5001, |
1534 | + "name": "untagged", |
1535 | + "fabric": "fabric-0", |
1536 | + "primary_rack": null, |
1537 | + "fabric_id": 0, |
1538 | + "secondary_rack": null, |
1539 | + "space": "management", |
1540 | + "resource_uri": "/MAAS/api/2.0/vlans/5001/" |
1541 | + }, |
1542 | + "cidr": "172.16.1.0/24", |
1543 | + "rdns_mode": 2, |
1544 | + "gateway_ip": "172.16.1.1", |
1545 | + "dns_servers": [ |
1546 | + "fd89:8724:81f1:5512:557f:99c3:6967:8d63" |
1547 | + ], |
1548 | + "allow_dns": true, |
1549 | + "allow_proxy": true, |
1550 | + "active_discovery": false, |
1551 | + "managed": true, |
1552 | + "id": 1, |
1553 | + "space": "management", |
1554 | + "resource_uri": "/MAAS/api/2.0/subnets/1/" |
1555 | + } |
1556 | + } |
1557 | + ], |
1558 | + "firmware_version": null, |
1559 | + "effective_mtu": 1500, |
1560 | + "product": null, |
1561 | + "mac_address": "e3:72:73:60:9a:b9", |
1562 | + "system_id": "ssqcgt", |
1563 | + "parents": [], |
1564 | + "children": [ |
1565 | + "eth-3cXhBN.10" |
1566 | + ], |
1567 | + "params": "", |
1568 | + "enabled": true, |
1569 | + "discovered": null, |
1570 | + "vlan": { |
1571 | + "vid": 0, |
1572 | + "mtu": 1500, |
1573 | + "dhcp_on": false, |
1574 | + "external_dhcp": null, |
1575 | + "relay_vlan": null, |
1576 | + "id": 5001, |
1577 | + "name": "untagged", |
1578 | + "fabric": "fabric-0", |
1579 | + "primary_rack": null, |
1580 | + "fabric_id": 0, |
1581 | + "secondary_rack": null, |
1582 | + "space": "management", |
1583 | + "resource_uri": "/MAAS/api/2.0/vlans/5001/" |
1584 | + }, |
1585 | + "vendor": null, |
1586 | + "type": "physical", |
1587 | + "resource_uri": "/MAAS/api/2.0/nodes/ssqcgt/interfaces/96/" |
1588 | + }, |
1589 | + { |
1590 | + "id": 97, |
1591 | + "name": "eth-x2dFvx.10", |
1592 | + "tags": [ |
1593 | + "tag-Y5zzv5", |
1594 | + "tag-w5vECc", |
1595 | + "tag-o4znE9" |
1596 | + ], |
1597 | + "links": [ |
1598 | + { |
1599 | + "id": 42, |
1600 | + "mode": "static", |
1601 | + "ip_address": "172.16.4.56", |
1602 | + "subnet": { |
1603 | + "name": "name-c2ULe1", |
1604 | + "vlan": { |
1605 | + "vid": 10, |
1606 | + "mtu": 1500, |
1607 | + "dhcp_on": false, |
1608 | + "external_dhcp": null, |
1609 | + "relay_vlan": null, |
1610 | + "id": 5002, |
1611 | + "name": "10", |
1612 | + "fabric": "fabric-0", |
1613 | + "primary_rack": null, |
1614 | + "fabric_id": 0, |
1615 | + "secondary_rack": null, |
1616 | + "space": "internal", |
1617 | + "resource_uri": "/MAAS/api/2.0/vlans/5002/" |
1618 | + }, |
1619 | + "cidr": "172.16.4.0/24", |
1620 | + "rdns_mode": 2, |
1621 | + "gateway_ip": "172.16.4.1", |
1622 | + "dns_servers": [ |
1623 | + "fd08:fef7:5c1f:a2e6:3d8e:6c3b:89f9:80cb", |
1624 | + "fc67:ad6a:88fe:9192:62f9:e882:8bcc:339e", |
1625 | + "255.59.162.158" |
1626 | + ], |
1627 | + "allow_dns": true, |
1628 | + "allow_proxy": true, |
1629 | + "active_discovery": false, |
1630 | + "managed": true, |
1631 | + "id": 4, |
1632 | + "space": "internal", |
1633 | + "resource_uri": "/MAAS/api/2.0/subnets/4/" |
1634 | + } |
1635 | + } |
1636 | + ], |
1637 | + "firmware_version": null, |
1638 | + "effective_mtu": 1500, |
1639 | + "product": null, |
1640 | + "mac_address": "dd:c6:80:1a:c7:80", |
1641 | + "system_id": "ssqcgt", |
1642 | + "parents": [ |
1643 | + "eth-x2dFvx" |
1644 | + ], |
1645 | + "children": [], |
1646 | + "params": "", |
1647 | + "enabled": true, |
1648 | + "discovered": null, |
1649 | + "vlan": { |
1650 | + "vid": 10, |
1651 | + "mtu": 1500, |
1652 | + "dhcp_on": false, |
1653 | + "external_dhcp": null, |
1654 | + "relay_vlan": null, |
1655 | + "id": 5002, |
1656 | + "name": "10", |
1657 | + "fabric": "fabric-0", |
1658 | + "primary_rack": null, |
1659 | + "fabric_id": 0, |
1660 | + "secondary_rack": null, |
1661 | + "space": "internal", |
1662 | + "resource_uri": "/MAAS/api/2.0/vlans/5002/" |
1663 | + }, |
1664 | + "vendor": null, |
1665 | + "type": "vlan", |
1666 | + "resource_uri": "/MAAS/api/2.0/nodes/ssqcgt/interfaces/97/" |
1667 | + }, |
1668 | + { |
1669 | + "id": 98, |
1670 | + "name": "eth-gtMGIr.10", |
1671 | + "tags": [ |
1672 | + "tag-wS4OXL", |
1673 | + "tag-Wm3I55", |
1674 | + "tag-LE5UYY" |
1675 | + ], |
1676 | + "links": [ |
1677 | + { |
1678 | + "id": 43, |
1679 | + "mode": "static", |
1680 | + "ip_address": "172.16.3.102", |
1681 | + "subnet": { |
1682 | + "name": "name-zznp45", |
1683 | + "vlan": { |
1684 | + "vid": 10, |
1685 | + "mtu": 1500, |
1686 | + "dhcp_on": false, |
1687 | + "external_dhcp": null, |
1688 | + "relay_vlan": null, |
1689 | + "id": 5002, |
1690 | + "name": "10", |
1691 | + "fabric": "fabric-0", |
1692 | + "primary_rack": null, |
1693 | + "fabric_id": 0, |
1694 | + "secondary_rack": null, |
1695 | + "space": "internal", |
1696 | + "resource_uri": "/MAAS/api/2.0/vlans/5002/" |
1697 | + }, |
1698 | + "cidr": "172.16.3.0/24", |
1699 | + "rdns_mode": 2, |
1700 | + "gateway_ip": "172.16.3.1", |
1701 | + "dns_servers": [ |
1702 | + "fd98:8601:90d0:c8c:dd2e:ba51:fa5a:dcfa", |
1703 | + "11.209.150.208", |
1704 | + "fde6:f9ef:3ee9:c5de:2a66:1582:cc83:abaf" |
1705 | + ], |
1706 | + "allow_dns": true, |
1707 | + "allow_proxy": true, |
1708 | + "active_discovery": false, |
1709 | + "managed": true, |
1710 | + "id": 3, |
1711 | + "space": "internal", |
1712 | + "resource_uri": "/MAAS/api/2.0/subnets/3/" |
1713 | + } |
1714 | + } |
1715 | + ], |
1716 | + "firmware_version": null, |
1717 | + "effective_mtu": 1500, |
1718 | + "product": null, |
1719 | + "mac_address": "52:db:98:ef:1e:b5", |
1720 | + "system_id": "ssqcgt", |
1721 | + "parents": [ |
1722 | + "eth-gtMGIr" |
1723 | + ], |
1724 | + "children": [], |
1725 | + "params": "", |
1726 | + "enabled": true, |
1727 | + "discovered": null, |
1728 | + "vlan": { |
1729 | + "vid": 10, |
1730 | + "mtu": 1500, |
1731 | + "dhcp_on": false, |
1732 | + "external_dhcp": null, |
1733 | + "relay_vlan": null, |
1734 | + "id": 5002, |
1735 | + "name": "10", |
1736 | + "fabric": "fabric-0", |
1737 | + "primary_rack": null, |
1738 | + "fabric_id": 0, |
1739 | + "secondary_rack": null, |
1740 | + "space": "internal", |
1741 | + "resource_uri": "/MAAS/api/2.0/vlans/5002/" |
1742 | + }, |
1743 | + "vendor": null, |
1744 | + "type": "vlan", |
1745 | + "resource_uri": "/MAAS/api/2.0/nodes/ssqcgt/interfaces/98/" |
1746 | + }, |
1747 | + { |
1748 | + "id": 99, |
1749 | + "name": "eth-3cXhBN.10", |
1750 | + "tags": [ |
1751 | + "tag-Zp22Uh", |
1752 | + "tag-PhIZjP", |
1753 | + "tag-QtYg8x" |
1754 | + ], |
1755 | + "links": [ |
1756 | + { |
1757 | + "id": 44, |
1758 | + "mode": "static", |
1759 | + "ip_address": "172.16.3.23", |
1760 | + "subnet": { |
1761 | + "name": "name-zznp45", |
1762 | + "vlan": { |
1763 | + "vid": 10, |
1764 | + "mtu": 1500, |
1765 | + "dhcp_on": false, |
1766 | + "external_dhcp": null, |
1767 | + "relay_vlan": null, |
1768 | + "id": 5002, |
1769 | + "name": "10", |
1770 | + "fabric": "fabric-0", |
1771 | + "primary_rack": null, |
1772 | + "fabric_id": 0, |
1773 | + "secondary_rack": null, |
1774 | + "space": "internal", |
1775 | + "resource_uri": "/MAAS/api/2.0/vlans/5002/" |
1776 | + }, |
1777 | + "cidr": "172.16.3.0/24", |
1778 | + "rdns_mode": 2, |
1779 | + "gateway_ip": "172.16.3.1", |
1780 | + "dns_servers": [ |
1781 | + "fd98:8601:90d0:c8c:dd2e:ba51:fa5a:dcfa", |
1782 | + "11.209.150.208", |
1783 | + "fde6:f9ef:3ee9:c5de:2a66:1582:cc83:abaf" |
1784 | + ], |
1785 | + "allow_dns": true, |
1786 | + "allow_proxy": true, |
1787 | + "active_discovery": false, |
1788 | + "managed": true, |
1789 | + "id": 3, |
1790 | + "space": "internal", |
1791 | + "resource_uri": "/MAAS/api/2.0/subnets/3/" |
1792 | + } |
1793 | + } |
1794 | + ], |
1795 | + "firmware_version": null, |
1796 | + "effective_mtu": 1500, |
1797 | + "product": null, |
1798 | + "mac_address": "e3:72:73:60:9a:b9", |
1799 | + "system_id": "ssqcgt", |
1800 | + "parents": [ |
1801 | + "eth-3cXhBN" |
1802 | + ], |
1803 | + "children": [], |
1804 | + "params": "", |
1805 | + "enabled": true, |
1806 | + "discovered": null, |
1807 | + "vlan": { |
1808 | + "vid": 10, |
1809 | + "mtu": 1500, |
1810 | + "dhcp_on": false, |
1811 | + "external_dhcp": null, |
1812 | + "relay_vlan": null, |
1813 | + "id": 5002, |
1814 | + "name": "10", |
1815 | + "fabric": "fabric-0", |
1816 | + "primary_rack": null, |
1817 | + "fabric_id": 0, |
1818 | + "secondary_rack": null, |
1819 | + "space": "internal", |
1820 | + "resource_uri": "/MAAS/api/2.0/vlans/5002/" |
1821 | + }, |
1822 | + "vendor": null, |
1823 | + "type": "vlan", |
1824 | + "resource_uri": "/MAAS/api/2.0/nodes/ssqcgt/interfaces/99/" |
1825 | + } |
1826 | + ], |
1827 | + "iscsiblockdevice_set": [], |
1828 | + "node_type": 0, |
1829 | + "memory_test_status_name": "Failed", |
1830 | + "bcaches": [], |
1831 | + "memory_test_status": 3, |
1832 | + "ip_addresses": [ |
1833 | + "172.16.1.22", |
1834 | + "172.16.4.56", |
1835 | + "172.16.3.102", |
1836 | + "172.16.3.23" |
1837 | + ], |
1838 | + "swap_size": null, |
1839 | + "volume_groups": [], |
1840 | + "testing_status": 3, |
1841 | + "node_type_name": "Machine", |
1842 | + "current_testing_result_id": 153, |
1843 | + "power_type": "virsh", |
1844 | + "fqdn": "chief-hippo.ubnt", |
1845 | + "storage_test_status_name": "Failed", |
1846 | + "storage_test_status": 3, |
1847 | + "status_name": "Rescue mode", |
1848 | + "locked": false, |
1849 | + "netboot": true, |
1850 | + "tag_names": [ |
1851 | + "virtual" |
1852 | + ], |
1853 | + "zone": { |
1854 | + "name": "zone-north", |
1855 | + "description": "xsMaq90fRE", |
1856 | + "id": 2, |
1857 | + "resource_uri": "/MAAS/api/2.0/zones/zone-north/" |
1858 | + }, |
1859 | + "boot_disk": { |
1860 | + "firmware_version": "firmware_version-rszebt", |
1861 | + "uuid": null, |
1862 | + "id": 65, |
1863 | + "model": "model-u038bu", |
1864 | + "name": "name-2V9gLL", |
1865 | + "tags": [ |
1866 | + "tag-wSvQ4O", |
1867 | + "tag-52MbPv", |
1868 | + "tag-JKilHY" |
1869 | + ], |
1870 | + "partitions": [], |
1871 | + "partition_table_type": null, |
1872 | + "used_size": 0, |
1873 | + "storage_pool": "pool_id-aMRZUu", |
1874 | + "id_path": null, |
1875 | + "system_id": "ssqcgt", |
1876 | + "block_size": 512, |
1877 | + "filesystem": null, |
1878 | + "used_for": "Unused", |
1879 | + "serial": "serial-Lh6Yv9", |
1880 | + "path": "/dev/disk/by-dname/name-2V9gLL", |
1881 | + "type": "physical", |
1882 | + "size": 3865490432, |
1883 | + "available_size": 3865490432, |
1884 | + "resource_uri": "/MAAS/api/2.0/nodes/ssqcgt/blockdevices/65/" |
1885 | + }, |
1886 | + "commissioning_status": 2, |
1887 | + "cpu_test_status": 3, |
1888 | + "current_installation_result_id": null, |
1889 | + "owner_data": {}, |
1890 | + "power_state": "on", |
1891 | + "current_commissioning_result_id": 152, |
1892 | + "status": 16, |
1893 | + "hwe_kernel": null, |
1894 | + "boot_interface": { |
1895 | + "id": 94, |
1896 | + "name": "eth-x2dFvx", |
1897 | + "tags": [ |
1898 | + "tag-fAzmsZ", |
1899 | + "tag-doKrVe", |
1900 | + "tag-ejryXL" |
1901 | + ], |
1902 | + "links": [ |
1903 | + { |
1904 | + "id": 39, |
1905 | + "mode": "auto", |
1906 | + "subnet": { |
1907 | + "name": "name-rLI3eq", |
1908 | + "vlan": { |
1909 | + "vid": 0, |
1910 | + "mtu": 1500, |
1911 | + "dhcp_on": false, |
1912 | + "external_dhcp": null, |
1913 | + "relay_vlan": null, |
1914 | + "id": 5001, |
1915 | + "name": "untagged", |
1916 | + "fabric": "fabric-0", |
1917 | + "primary_rack": null, |
1918 | + "fabric_id": 0, |
1919 | + "secondary_rack": null, |
1920 | + "space": "management", |
1921 | + "resource_uri": "/MAAS/api/2.0/vlans/5001/" |
1922 | + }, |
1923 | + "cidr": "172.16.1.0/24", |
1924 | + "rdns_mode": 2, |
1925 | + "gateway_ip": "172.16.1.1", |
1926 | + "dns_servers": [ |
1927 | + "fd89:8724:81f1:5512:557f:99c3:6967:8d63" |
1928 | + ], |
1929 | + "allow_dns": true, |
1930 | + "allow_proxy": true, |
1931 | + "active_discovery": false, |
1932 | + "managed": true, |
1933 | + "id": 1, |
1934 | + "space": "management", |
1935 | + "resource_uri": "/MAAS/api/2.0/subnets/1/" |
1936 | + } |
1937 | + } |
1938 | + ], |
1939 | + "firmware_version": null, |
1940 | + "effective_mtu": 1500, |
1941 | + "product": null, |
1942 | + "mac_address": "dd:c6:80:1a:c7:80", |
1943 | + "system_id": "ssqcgt", |
1944 | + "parents": [], |
1945 | + "children": [ |
1946 | + "eth-x2dFvx.10" |
1947 | + ], |
1948 | + "params": "", |
1949 | + "enabled": true, |
1950 | + "discovered": null, |
1951 | + "vlan": { |
1952 | + "vid": 0, |
1953 | + "mtu": 1500, |
1954 | + "dhcp_on": false, |
1955 | + "external_dhcp": null, |
1956 | + "relay_vlan": null, |
1957 | + "id": 5001, |
1958 | + "name": "untagged", |
1959 | + "fabric": "fabric-0", |
1960 | + "primary_rack": null, |
1961 | + "fabric_id": 0, |
1962 | + "secondary_rack": null, |
1963 | + "space": "management", |
1964 | + "resource_uri": "/MAAS/api/2.0/vlans/5001/" |
1965 | + }, |
1966 | + "vendor": null, |
1967 | + "type": "physical", |
1968 | + "resource_uri": "/MAAS/api/2.0/nodes/ssqcgt/interfaces/94/" |
1969 | + }, |
1970 | + "special_filesystems": [], |
1971 | + "cpu_speed": 0, |
1972 | + "architecture": "amd64/generic", |
1973 | + "blockdevice_set": [ |
1974 | + { |
1975 | + "id_path": null, |
1976 | + "size": 3865490432, |
1977 | + "block_size": 512, |
1978 | + "tags": [ |
1979 | + "tag-wSvQ4O", |
1980 | + "tag-52MbPv", |
1981 | + "tag-JKilHY" |
1982 | + ], |
1983 | + "uuid": null, |
1984 | + "id": 65, |
1985 | + "model": "model-u038bu", |
1986 | + "name": "name-2V9gLL", |
1987 | + "partitions": [], |
1988 | + "partition_table_type": null, |
1989 | + "used_size": 0, |
1990 | + "storage_pool": "pool_id-aMRZUu", |
1991 | + "system_id": "ssqcgt", |
1992 | + "filesystem": null, |
1993 | + "used_for": "Unused", |
1994 | + "serial": "serial-Lh6Yv9", |
1995 | + "path": "/dev/disk/by-dname/name-2V9gLL", |
1996 | + "type": "physical", |
1997 | + "available_size": 3865490432, |
1998 | + "resource_uri": "/MAAS/api/2.0/nodes/ssqcgt/blockdevices/65/" |
1999 | + } |
2000 | + ], |
2001 | + "cpu_test_status_name": "Failed", |
2002 | + "other_test_status": 2, |
2003 | + "hostname": "chief-hippo", |
2004 | + "memory": 4096, |
2005 | + "default_gateways": { |
2006 | + "ipv4": { |
2007 | + "gateway_ip": "172.16.1.1", |
2008 | + "link_id": null |
2009 | + }, |
2010 | + "ipv6": { |
2011 | + "gateway_ip": null, |
2012 | + "link_id": null |
2013 | + } |
2014 | + }, |
2015 | + "distro_series": "", |
2016 | + "status_action": "action-ft28IH", |
2017 | + "owner": "user1", |
2018 | + "commissioning_status_name": "Passed", |
2019 | + "hardware_info": { |
2020 | + "system_vendor": "Unknown", |
2021 | + "system_product": "Unknown", |
2022 | + "system_version": "Unknown", |
2023 | + "system_serial": "Unknown", |
2024 | + "cpu_model": "Unknown", |
2025 | + "mainboard_vendor": "Unknown", |
2026 | + "mainboard_product": "Unknown", |
2027 | + "mainboard_firmware_version": "Unknown", |
2028 | + "mainboard_firmware_date": "Unknown" |
2029 | + }, |
2030 | + "pod": { |
2031 | + "id": 5, |
2032 | + "name": "normal-trout", |
2033 | + "resource_uri": "/MAAS/api/2.0/pods/5/" |
2034 | + }, |
2035 | + "cache_sets": [], |
2036 | + "testing_status_name": "Failed", |
2037 | + "disable_ipv4": false, |
2038 | + "physicalblockdevice_set": [ |
2039 | + { |
2040 | + "firmware_version": "firmware_version-rszebt", |
2041 | + "uuid": null, |
2042 | + "id": 65, |
2043 | + "model": "model-u038bu", |
2044 | + "name": "name-2V9gLL", |
2045 | + "tags": [ |
2046 | + "tag-wSvQ4O", |
2047 | + "tag-52MbPv", |
2048 | + "tag-JKilHY" |
2049 | + ], |
2050 | + "partitions": [], |
2051 | + "partition_table_type": null, |
2052 | + "used_size": 0, |
2053 | + "storage_pool": "pool_id-aMRZUu", |
2054 | + "id_path": null, |
2055 | + "system_id": "ssqcgt", |
2056 | + "block_size": 512, |
2057 | + "filesystem": null, |
2058 | + "used_for": "Unused", |
2059 | + "serial": "serial-Lh6Yv9", |
2060 | + "path": "/dev/disk/by-dname/name-2V9gLL", |
2061 | + "type": "physical", |
2062 | + "size": 3865490432, |
2063 | + "available_size": 3865490432, |
2064 | + "resource_uri": "/MAAS/api/2.0/nodes/ssqcgt/blockdevices/65/" |
2065 | + } |
2066 | + ], |
2067 | + "osystem": "", |
2068 | + "system_id": "ssqcgt", |
2069 | + "address_ttl": null, |
2070 | + "raids": [], |
2071 | + "cpu_count": 5, |
2072 | + "virtualblockdevice_set": [], |
2073 | + "other_test_status_name": "Passed", |
2074 | + "status_message": "desc-SfeEsi", |
2075 | + "domain": { |
2076 | + "authoritative": true, |
2077 | + "ttl": null, |
2078 | + "id": 2, |
2079 | + "name": "ubnt", |
2080 | + "resource_record_count": 0, |
2081 | + "is_default": false, |
2082 | + "resource_uri": "/MAAS/api/2.0/domains/2/" |
2083 | + }, |
2084 | + "resource_uri": "/MAAS/api/2.0/machines/ssqcgt/" |
2085 | + }, |
2086 | + { |
2087 | + "tag_names": [ |
2088 | + "virtual" |
2089 | + ], |
2090 | + "interface_set": [ |
2091 | + { |
2092 | + "id": 130, |
2093 | + "name": "eth-tNqklu", |
2094 | + "tags": [ |
2095 | + "tag-YYQK5S", |
2096 | + "tag-MUmKRU", |
2097 | + "tag-dh0kc2" |
2098 | + ], |
2099 | + "links": [], |
2100 | + "firmware_version": null, |
2101 | + "effective_mtu": 1500, |
2102 | + "product": null, |
2103 | + "mac_address": "bb:f7:55:fd:0f:34", |
2104 | + "system_id": "nqg6dg", |
2105 | + "parents": [], |
2106 | + "children": [], |
2107 | + "params": "", |
2108 | + "enabled": true, |
2109 | + "discovered": null, |
2110 | + "vlan": { |
2111 | + "vid": 0, |
2112 | + "mtu": 1500, |
2113 | + "dhcp_on": false, |
2114 | + "external_dhcp": null, |
2115 | + "relay_vlan": null, |
2116 | + "id": 5013, |
2117 | + "name": "untagged", |
2118 | + "fabric": "fabric-9", |
2119 | + "primary_rack": null, |
2120 | + "fabric_id": 9, |
2121 | + "secondary_rack": null, |
2122 | + "space": "undefined", |
2123 | + "resource_uri": "/MAAS/api/2.0/vlans/5013/" |
2124 | + }, |
2125 | + "vendor": null, |
2126 | + "type": "physical", |
2127 | + "resource_uri": "/MAAS/api/2.0/nodes/nqg6dg/interfaces/130/" |
2128 | + } |
2129 | + ], |
2130 | + "zone": { |
2131 | + "name": "default", |
2132 | + "description": "", |
2133 | + "id": 1, |
2134 | + "resource_uri": "/MAAS/api/2.0/zones/default/" |
2135 | + }, |
2136 | + "node_type": 1, |
2137 | + "hostname": "calm-bobcat", |
2138 | + "system_id": "nqg6dg", |
2139 | + "owner_data": {}, |
2140 | + "parent": null, |
2141 | + "address_ttl": null, |
2142 | + "owner": null, |
2143 | + "ip_addresses": [], |
2144 | + "node_type_name": "Device", |
2145 | + "fqdn": "calm-bobcat.maas", |
2146 | + "domain": { |
2147 | + "authoritative": true, |
2148 | + "ttl": null, |
2149 | + "id": 0, |
2150 | + "name": "maas", |
2151 | + "resource_record_count": 0, |
2152 | + "is_default": true, |
2153 | + "resource_uri": "/MAAS/api/2.0/domains/0/" |
2154 | + }, |
2155 | + "resource_uri": "/MAAS/api/2.0/devices/nqg6dg/" |
2156 | + } |
2157 | + ], |
2158 | + "get-rackc-by-tag": [ |
2159 | + { |
2160 | + "interface_set": [ |
2161 | + { |
2162 | + "id": 1, |
2163 | + "name": "ens3", |
2164 | + "tags": [ |
2165 | + "tag-0wj45r", |
2166 | + "tag-ylwPaA", |
2167 | + "tag-s8HCFS" |
2168 | + ], |
2169 | + "links": [ |
2170 | + { |
2171 | + "id": 59, |
2172 | + "mode": "static", |
2173 | + "ip_address": "10.55.32.42", |
2174 | + "subnet": { |
2175 | + "name": "10.55.32.0/20", |
2176 | + "vlan": { |
2177 | + "vid": 0, |
2178 | + "mtu": 1500, |
2179 | + "dhcp_on": false, |
2180 | + "external_dhcp": null, |
2181 | + "relay_vlan": null, |
2182 | + "id": 5001, |
2183 | + "name": "untagged", |
2184 | + "fabric": "fabric-0", |
2185 | + "primary_rack": null, |
2186 | + "fabric_id": 0, |
2187 | + "secondary_rack": null, |
2188 | + "space": "management", |
2189 | + "resource_uri": "/MAAS/api/2.0/vlans/5001/" |
2190 | + }, |
2191 | + "cidr": "10.55.32.0/20", |
2192 | + "rdns_mode": 2, |
2193 | + "gateway_ip": "10.55.32.1", |
2194 | + "dns_servers": [], |
2195 | + "allow_dns": true, |
2196 | + "allow_proxy": true, |
2197 | + "active_discovery": false, |
2198 | + "managed": true, |
2199 | + "id": 6, |
2200 | + "space": "management", |
2201 | + "resource_uri": "/MAAS/api/2.0/subnets/6/" |
2202 | + } |
2203 | + } |
2204 | + ], |
2205 | + "firmware_version": "N/A", |
2206 | + "effective_mtu": 1500, |
2207 | + "product": "OpenStack Nova", |
2208 | + "mac_address": "fa:16:3e:3d:03:02", |
2209 | + "system_id": "7xtf67", |
2210 | + "parents": [], |
2211 | + "children": [], |
2212 | + "params": "", |
2213 | + "enabled": true, |
2214 | + "discovered": null, |
2215 | + "vlan": { |
2216 | + "vid": 0, |
2217 | + "mtu": 1500, |
2218 | + "dhcp_on": false, |
2219 | + "external_dhcp": null, |
2220 | + "relay_vlan": null, |
2221 | + "id": 5001, |
2222 | + "name": "untagged", |
2223 | + "fabric": "fabric-0", |
2224 | + "primary_rack": null, |
2225 | + "fabric_id": 0, |
2226 | + "secondary_rack": null, |
2227 | + "space": "management", |
2228 | + "resource_uri": "/MAAS/api/2.0/vlans/5001/" |
2229 | + }, |
2230 | + "vendor": "OpenStack Foundation", |
2231 | + "type": "physical", |
2232 | + "resource_uri": "/MAAS/api/2.0/nodes/7xtf67/interfaces/1/" |
2233 | + }, |
2234 | + { |
2235 | + "id": 134, |
2236 | + "name": "virbr0", |
2237 | + "tags": [], |
2238 | + "links": [ |
2239 | + { |
2240 | + "id": 60, |
2241 | + "mode": "static", |
2242 | + "ip_address": "192.168.122.1", |
2243 | + "subnet": { |
2244 | + "name": "192.168.122.0/24", |
2245 | + "vlan": { |
2246 | + "vid": 0, |
2247 | + "mtu": 1500, |
2248 | + "dhcp_on": false, |
2249 | + "external_dhcp": null, |
2250 | + "relay_vlan": null, |
2251 | + "id": 5017, |
2252 | + "name": "untagged", |
2253 | + "fabric": "fabric-13", |
2254 | + "primary_rack": null, |
2255 | + "fabric_id": 13, |
2256 | + "secondary_rack": null, |
2257 | + "space": "undefined", |
2258 | + "resource_uri": "/MAAS/api/2.0/vlans/5017/" |
2259 | + }, |
2260 | + "cidr": "192.168.122.0/24", |
2261 | + "rdns_mode": 2, |
2262 | + "gateway_ip": null, |
2263 | + "dns_servers": [], |
2264 | + "allow_dns": true, |
2265 | + "allow_proxy": true, |
2266 | + "active_discovery": false, |
2267 | + "managed": true, |
2268 | + "id": 7, |
2269 | + "space": "undefined", |
2270 | + "resource_uri": "/MAAS/api/2.0/subnets/7/" |
2271 | + } |
2272 | + } |
2273 | + ], |
2274 | + "firmware_version": "N/A", |
2275 | + "effective_mtu": 1500, |
2276 | + "product": "OpenStack Nova", |
2277 | + "mac_address": "52:54:00:95:f3:f3", |
2278 | + "system_id": "7xtf67", |
2279 | + "parents": [], |
2280 | + "children": [], |
2281 | + "params": "", |
2282 | + "enabled": true, |
2283 | + "discovered": null, |
2284 | + "vlan": { |
2285 | + "vid": 0, |
2286 | + "mtu": 1500, |
2287 | + "dhcp_on": false, |
2288 | + "external_dhcp": null, |
2289 | + "relay_vlan": null, |
2290 | + "id": 5017, |
2291 | + "name": "untagged", |
2292 | + "fabric": "fabric-13", |
2293 | + "primary_rack": null, |
2294 | + "fabric_id": 13, |
2295 | + "secondary_rack": null, |
2296 | + "space": "undefined", |
2297 | + "resource_uri": "/MAAS/api/2.0/vlans/5017/" |
2298 | + }, |
2299 | + "vendor": "OpenStack Foundation", |
2300 | + "type": "bridge", |
2301 | + "resource_uri": "/MAAS/api/2.0/nodes/7xtf67/interfaces/134/" |
2302 | + } |
2303 | + ], |
2304 | + "node_type": 4, |
2305 | + "memory_test_status_name": "Unknown", |
2306 | + "memory_test_status": -1, |
2307 | + "ip_addresses": [ |
2308 | + "10.55.32.42", |
2309 | + "192.168.122.1" |
2310 | + ], |
2311 | + "swap_size": null, |
2312 | + "testing_status": -1, |
2313 | + "node_type_name": "Region and rack controller", |
2314 | + "current_testing_result_id": null, |
2315 | + "power_type": "virsh", |
2316 | + "fqdn": "spence-devmaas.maas", |
2317 | + "storage_test_status_name": "Unknown", |
2318 | + "storage_test_status": -1, |
2319 | + "tag_names": [ |
2320 | + "virtual" |
2321 | + ], |
2322 | + "zone": { |
2323 | + "name": "zone-obryVj", |
2324 | + "description": "qRwvQuFIpM", |
2325 | + "id": 4, |
2326 | + "resource_uri": "/MAAS/api/2.0/zones/zone-obryVj/" |
2327 | + }, |
2328 | + "commissioning_status": 2, |
2329 | + "cpu_test_status": -1, |
2330 | + "current_installation_result_id": null, |
2331 | + "power_state": "on", |
2332 | + "current_commissioning_result_id": 228, |
2333 | + "cpu_speed": 2500, |
2334 | + "architecture": "amd64/generic", |
2335 | + "cpu_test_status_name": "Unknown", |
2336 | + "other_test_status": -1, |
2337 | + "hostname": "spence-devmaas", |
2338 | + "memory": 8192, |
2339 | + "commissioning_status_name": "Passed", |
2340 | + "distro_series": "bionic", |
2341 | + "status_action": "", |
2342 | + "hardware_info": { |
2343 | + "system_vendor": "OpenStack Foundation", |
2344 | + "system_product": "OpenStack Nova", |
2345 | + "system_version": "2013.2.3", |
2346 | + "system_serial": "30353036-3837-5a43-3331-353234584a58", |
2347 | + "cpu_model": "Westmere E56xx/L56xx/X56xx (Nehalem-C)", |
2348 | + "mainboard_vendor": "Unknown", |
2349 | + "mainboard_product": "Unknown", |
2350 | + "mainboard_firmware_version": "Bochs", |
2351 | + "mainboard_firmware_date": "01/01/2011" |
2352 | + }, |
2353 | + "service_set": [ |
2354 | + { |
2355 | + "name": "proxy", |
2356 | + "status": "unknown", |
2357 | + "status_info": "" |
2358 | + }, |
2359 | + { |
2360 | + "name": "proxy_rack", |
2361 | + "status": "unknown", |
2362 | + "status_info": "" |
2363 | + }, |
2364 | + { |
2365 | + "name": "dhcpd6", |
2366 | + "status": "dead", |
2367 | + "status_info": "" |
2368 | + }, |
2369 | + { |
2370 | + "name": "ntp_rack", |
2371 | + "status": "dead", |
2372 | + "status_info": "" |
2373 | + }, |
2374 | + { |
2375 | + "name": "syslog_region", |
2376 | + "status": "unknown", |
2377 | + "status_info": "" |
2378 | + }, |
2379 | + { |
2380 | + "name": "http", |
2381 | + "status": "unknown", |
2382 | + "status_info": "" |
2383 | + }, |
2384 | + { |
2385 | + "name": "tftp", |
2386 | + "status": "dead", |
2387 | + "status_info": "" |
2388 | + }, |
2389 | + { |
2390 | + "name": "bind9", |
2391 | + "status": "unknown", |
2392 | + "status_info": "" |
2393 | + }, |
2394 | + { |
2395 | + "name": "rackd", |
2396 | + "status": "dead", |
2397 | + "status_info": "" |
2398 | + }, |
2399 | + { |
2400 | + "name": "ntp_region", |
2401 | + "status": "unknown", |
2402 | + "status_info": "" |
2403 | + }, |
2404 | + { |
2405 | + "name": "regiond", |
2406 | + "status": "running", |
2407 | + "status_info": "" |
2408 | + }, |
2409 | + { |
2410 | + "name": "dns_rack", |
2411 | + "status": "unknown", |
2412 | + "status_info": "" |
2413 | + }, |
2414 | + { |
2415 | + "name": "syslog_rack", |
2416 | + "status": "unknown", |
2417 | + "status_info": "" |
2418 | + }, |
2419 | + { |
2420 | + "name": "dhcpd", |
2421 | + "status": "dead", |
2422 | + "status_info": "" |
2423 | + } |
2424 | + ], |
2425 | + "testing_status_name": "Unknown", |
2426 | + "osystem": "ubuntu", |
2427 | + "version": "", |
2428 | + "system_id": "7xtf67", |
2429 | + "cpu_count": 4, |
2430 | + "other_test_status_name": "Unknown", |
2431 | + "domain": { |
2432 | + "authoritative": true, |
2433 | + "ttl": null, |
2434 | + "id": 0, |
2435 | + "name": "maas", |
2436 | + "resource_record_count": 0, |
2437 | + "is_default": true, |
2438 | + "resource_uri": "/MAAS/api/2.0/domains/0/" |
2439 | + }, |
2440 | + "resource_uri": "/MAAS/api/2.0/rackcontrollers/7xtf67/" |
2441 | + } |
2442 | + ], |
2443 | + "get-regionc-by-tag": [ |
2444 | + { |
2445 | + "interface_set": [ |
2446 | + { |
2447 | + "id": 1, |
2448 | + "name": "ens3", |
2449 | + "tags": [ |
2450 | + "tag-0wj45r", |
2451 | + "tag-ylwPaA", |
2452 | + "tag-s8HCFS" |
2453 | + ], |
2454 | + "links": [ |
2455 | + { |
2456 | + "id": 59, |
2457 | + "mode": "static", |
2458 | + "ip_address": "10.55.32.42", |
2459 | + "subnet": { |
2460 | + "name": "10.55.32.0/20", |
2461 | + "vlan": { |
2462 | + "vid": 0, |
2463 | + "mtu": 1500, |
2464 | + "dhcp_on": false, |
2465 | + "external_dhcp": null, |
2466 | + "relay_vlan": null, |
2467 | + "id": 5001, |
2468 | + "name": "untagged", |
2469 | + "fabric": "fabric-0", |
2470 | + "primary_rack": null, |
2471 | + "fabric_id": 0, |
2472 | + "secondary_rack": null, |
2473 | + "space": "management", |
2474 | + "resource_uri": "/MAAS/api/2.0/vlans/5001/" |
2475 | + }, |
2476 | + "cidr": "10.55.32.0/20", |
2477 | + "rdns_mode": 2, |
2478 | + "gateway_ip": "10.55.32.1", |
2479 | + "dns_servers": [], |
2480 | + "allow_dns": true, |
2481 | + "allow_proxy": true, |
2482 | + "active_discovery": false, |
2483 | + "managed": true, |
2484 | + "id": 6, |
2485 | + "space": "management", |
2486 | + "resource_uri": "/MAAS/api/2.0/subnets/6/" |
2487 | + } |
2488 | + } |
2489 | + ], |
2490 | + "firmware_version": "N/A", |
2491 | + "effective_mtu": 1500, |
2492 | + "product": "OpenStack Nova", |
2493 | + "mac_address": "fa:16:3e:3d:03:02", |
2494 | + "system_id": "7xtf67", |
2495 | + "parents": [], |
2496 | + "children": [], |
2497 | + "params": "", |
2498 | + "enabled": true, |
2499 | + "discovered": null, |
2500 | + "vlan": { |
2501 | + "vid": 0, |
2502 | + "mtu": 1500, |
2503 | + "dhcp_on": false, |
2504 | + "external_dhcp": null, |
2505 | + "relay_vlan": null, |
2506 | + "id": 5001, |
2507 | + "name": "untagged", |
2508 | + "fabric": "fabric-0", |
2509 | + "primary_rack": null, |
2510 | + "fabric_id": 0, |
2511 | + "secondary_rack": null, |
2512 | + "space": "management", |
2513 | + "resource_uri": "/MAAS/api/2.0/vlans/5001/" |
2514 | + }, |
2515 | + "vendor": "OpenStack Foundation", |
2516 | + "type": "physical", |
2517 | + "resource_uri": "/MAAS/api/2.0/nodes/7xtf67/interfaces/1/" |
2518 | + }, |
2519 | + { |
2520 | + "id": 134, |
2521 | + "name": "virbr0", |
2522 | + "tags": [], |
2523 | + "links": [ |
2524 | + { |
2525 | + "id": 60, |
2526 | + "mode": "static", |
2527 | + "ip_address": "192.168.122.1", |
2528 | + "subnet": { |
2529 | + "name": "192.168.122.0/24", |
2530 | + "vlan": { |
2531 | + "vid": 0, |
2532 | + "mtu": 1500, |
2533 | + "dhcp_on": false, |
2534 | + "external_dhcp": null, |
2535 | + "relay_vlan": null, |
2536 | + "id": 5017, |
2537 | + "name": "untagged", |
2538 | + "fabric": "fabric-13", |
2539 | + "primary_rack": null, |
2540 | + "fabric_id": 13, |
2541 | + "secondary_rack": null, |
2542 | + "space": "undefined", |
2543 | + "resource_uri": "/MAAS/api/2.0/vlans/5017/" |
2544 | + }, |
2545 | + "cidr": "192.168.122.0/24", |
2546 | + "rdns_mode": 2, |
2547 | + "gateway_ip": null, |
2548 | + "dns_servers": [], |
2549 | + "allow_dns": true, |
2550 | + "allow_proxy": true, |
2551 | + "active_discovery": false, |
2552 | + "managed": true, |
2553 | + "id": 7, |
2554 | + "space": "undefined", |
2555 | + "resource_uri": "/MAAS/api/2.0/subnets/7/" |
2556 | + } |
2557 | + } |
2558 | + ], |
2559 | + "firmware_version": "N/A", |
2560 | + "effective_mtu": 1500, |
2561 | + "product": "OpenStack Nova", |
2562 | + "mac_address": "52:54:00:95:f3:f3", |
2563 | + "system_id": "7xtf67", |
2564 | + "parents": [], |
2565 | + "children": [], |
2566 | + "params": "", |
2567 | + "enabled": true, |
2568 | + "discovered": null, |
2569 | + "vlan": { |
2570 | + "vid": 0, |
2571 | + "mtu": 1500, |
2572 | + "dhcp_on": false, |
2573 | + "external_dhcp": null, |
2574 | + "relay_vlan": null, |
2575 | + "id": 5017, |
2576 | + "name": "untagged", |
2577 | + "fabric": "fabric-13", |
2578 | + "primary_rack": null, |
2579 | + "fabric_id": 13, |
2580 | + "secondary_rack": null, |
2581 | + "space": "undefined", |
2582 | + "resource_uri": "/MAAS/api/2.0/vlans/5017/" |
2583 | + }, |
2584 | + "vendor": "OpenStack Foundation", |
2585 | + "type": "bridge", |
2586 | + "resource_uri": "/MAAS/api/2.0/nodes/7xtf67/interfaces/134/" |
2587 | + } |
2588 | + ], |
2589 | + "node_type": 4, |
2590 | + "memory_test_status_name": "Unknown", |
2591 | + "memory_test_status": -1, |
2592 | + "ip_addresses": [ |
2593 | + "10.55.32.42", |
2594 | + "192.168.122.1" |
2595 | + ], |
2596 | + "swap_size": null, |
2597 | + "testing_status": -1, |
2598 | + "node_type_name": "Region and rack controller", |
2599 | + "current_testing_result_id": null, |
2600 | + "power_type": "virsh", |
2601 | + "fqdn": "spence-devmaas.maas", |
2602 | + "storage_test_status_name": "Unknown", |
2603 | + "storage_test_status": -1, |
2604 | + "tag_names": [ |
2605 | + "virtual" |
2606 | + ], |
2607 | + "zone": { |
2608 | + "name": "zone-obryVj", |
2609 | + "description": "qRwvQuFIpM", |
2610 | + "id": 4, |
2611 | + "resource_uri": "/MAAS/api/2.0/zones/zone-obryVj/" |
2612 | + }, |
2613 | + "commissioning_status": 2, |
2614 | + "cpu_test_status": -1, |
2615 | + "current_installation_result_id": null, |
2616 | + "power_state": "on", |
2617 | + "current_commissioning_result_id": 228, |
2618 | + "cpu_speed": 2500, |
2619 | + "architecture": "amd64/generic", |
2620 | + "cpu_test_status_name": "Unknown", |
2621 | + "other_test_status": -1, |
2622 | + "hostname": "spence-devmaas", |
2623 | + "memory": 8192, |
2624 | + "commissioning_status_name": "Passed", |
2625 | + "distro_series": "bionic", |
2626 | + "status_action": "", |
2627 | + "hardware_info": { |
2628 | + "system_vendor": "OpenStack Foundation", |
2629 | + "system_product": "OpenStack Nova", |
2630 | + "system_version": "2013.2.3", |
2631 | + "system_serial": "30353036-3837-5a43-3331-353234584a58", |
2632 | + "cpu_model": "Westmere E56xx/L56xx/X56xx (Nehalem-C)", |
2633 | + "mainboard_vendor": "Unknown", |
2634 | + "mainboard_product": "Unknown", |
2635 | + "mainboard_firmware_version": "Bochs", |
2636 | + "mainboard_firmware_date": "01/01/2011" |
2637 | + }, |
2638 | + "service_set": [ |
2639 | + { |
2640 | + "name": "proxy", |
2641 | + "status": "unknown", |
2642 | + "status_info": "" |
2643 | + }, |
2644 | + { |
2645 | + "name": "proxy_rack", |
2646 | + "status": "unknown", |
2647 | + "status_info": "" |
2648 | + }, |
2649 | + { |
2650 | + "name": "dhcpd6", |
2651 | + "status": "dead", |
2652 | + "status_info": "" |
2653 | + }, |
2654 | + { |
2655 | + "name": "ntp_rack", |
2656 | + "status": "dead", |
2657 | + "status_info": "" |
2658 | + }, |
2659 | + { |
2660 | + "name": "syslog_region", |
2661 | + "status": "unknown", |
2662 | + "status_info": "" |
2663 | + }, |
2664 | + { |
2665 | + "name": "http", |
2666 | + "status": "unknown", |
2667 | + "status_info": "" |
2668 | + }, |
2669 | + { |
2670 | + "name": "tftp", |
2671 | + "status": "dead", |
2672 | + "status_info": "" |
2673 | + }, |
2674 | + { |
2675 | + "name": "bind9", |
2676 | + "status": "unknown", |
2677 | + "status_info": "" |
2678 | + }, |
2679 | + { |
2680 | + "name": "rackd", |
2681 | + "status": "dead", |
2682 | + "status_info": "" |
2683 | + }, |
2684 | + { |
2685 | + "name": "ntp_region", |
2686 | + "status": "unknown", |
2687 | + "status_info": "" |
2688 | + }, |
2689 | + { |
2690 | + "name": "regiond", |
2691 | + "status": "running", |
2692 | + "status_info": "" |
2693 | + }, |
2694 | + { |
2695 | + "name": "dns_rack", |
2696 | + "status": "unknown", |
2697 | + "status_info": "" |
2698 | + }, |
2699 | + { |
2700 | + "name": "syslog_rack", |
2701 | + "status": "unknown", |
2702 | + "status_info": "" |
2703 | + }, |
2704 | + { |
2705 | + "name": "dhcpd", |
2706 | + "status": "dead", |
2707 | + "status_info": "" |
2708 | + } |
2709 | + ], |
2710 | + "testing_status_name": "Unknown", |
2711 | + "osystem": "ubuntu", |
2712 | + "version": "", |
2713 | + "system_id": "7xtf67", |
2714 | + "cpu_count": 4, |
2715 | + "other_test_status_name": "Unknown", |
2716 | + "domain": { |
2717 | + "authoritative": true, |
2718 | + "ttl": null, |
2719 | + "id": 0, |
2720 | + "name": "maas", |
2721 | + "resource_record_count": 0, |
2722 | + "is_default": true, |
2723 | + "resource_uri": "/MAAS/api/2.0/domains/0/" |
2724 | + }, |
2725 | + "resource_uri": "/MAAS/api/2.0/rackcontrollers/7xtf67/" |
2726 | + } |
2727 | + ], |
2728 | + "add-tag": { |
2729 | + "name": "footag", |
2730 | + "definition": "", |
2731 | + "comment": "some comment", |
2732 | + "kernel_opts": "", |
2733 | + "resource_uri": "/MAAS/api/2.0/tags/footag/" |
2734 | + }, |
2735 | + "rebuild-tag": { |
2736 | + "rebuilding": "footag" |
2737 | + }, |
2738 | + "update-nodes-tag": { |
2739 | + "added": 1, |
2740 | + "removed": 0 |
2741 | + }, |
2742 | + "update-tag": { |
2743 | + "name": "my_tag", |
2744 | + "definition": "", |
2745 | + "comment": "a comment about this tag", |
2746 | + "kernel_opts": "", |
2747 | + "resource_uri": "/MAAS/api/2.0/tags/my_tag/" |
2748 | + }, |
2749 | + "delete-tag": "No content" |
2750 | +} |
2751 | diff --git a/src/maasserver/api/tags.py b/src/maasserver/api/tags.py |
2752 | index 91cf52f..f4dcf54 100644 |
2753 | --- a/src/maasserver/api/tags.py |
2754 | +++ b/src/maasserver/api/tags.py |
2755 | @@ -74,8 +74,7 @@ def check_rack_controller_access(request, rack_controller): |
2756 | |
2757 | |
2758 | class TagHandler(OperationsHandler): |
2759 | - """Manage a Tag. |
2760 | - |
2761 | + """ |
2762 | Tags are properties that can be associated with a Node and serve as |
2763 | criteria for selecting and allocating nodes. |
2764 | |
2765 | @@ -92,23 +91,52 @@ class TagHandler(OperationsHandler): |
2766 | ) |
2767 | |
2768 | def read(self, request, name): |
2769 | - """Read a specific Tag. |
2770 | - |
2771 | - Returns 404 if the tag is not found. |
2772 | + """@description-title Read a specific tag |
2773 | + @description Returns a JSON object containing information about a |
2774 | + specific tag. |
2775 | + |
2776 | + @param (url-string) "{name}" [required=true] A tag name. |
2777 | + @param-example "{name}" virtual |
2778 | + |
2779 | + @success (http-status-code) "server-success" 200 |
2780 | + @success (json) "success-json" A JSON object containing |
2781 | + information about the requested tag. |
2782 | + @success-example "success-json" [exkey=get-tag-by-name] placeholder |
2783 | + |
2784 | + @error (http-status-code) "404" 404 |
2785 | + @error (content) "not-found" The requested tag name is not found. |
2786 | + @error-example "not-found" |
2787 | + Not Found |
2788 | """ |
2789 | return Tag.objects.get_tag_or_404(name=name, user=request.user) |
2790 | |
2791 | def update(self, request, name): |
2792 | - """Update a specific Tag. |
2793 | - |
2794 | - :param name: The name of the Tag to be created. This should be a short |
2795 | - name, and will be used in the URL of the tag. |
2796 | - :param comment: A long form description of what the tag is meant for. |
2797 | - It is meant as a human readable description of the tag. |
2798 | - :param definition: An XPATH query that will be evaluated against the |
2799 | - hardware_details stored for all nodes (output of `lshw -xml`). |
2800 | - |
2801 | - Returns 404 if the tag is not found. |
2802 | + """@description-title Update a tag |
2803 | + @description Update elements of a given tag. |
2804 | + |
2805 | + @param (url-string) "{name}" [required=true] The tag to update. |
2806 | + @param-example "{name}" oldname |
2807 | + @param (string) "name" [required=false] The new tag name. Because |
2808 | + the name will be used in urls, it should be short. |
2809 | + @param-example "name" virtual |
2810 | + @param (string) "comment" [required=false] A description of what the |
2811 | + the tag will be used for in natural language. |
2812 | + @param-example "comment" The 'virtual' tag represents virtual |
2813 | + machines. |
2814 | + @param (string) "definition" [required=false] An XPATH query that is |
2815 | + evaluated against the hardware_details stored for all nodes |
2816 | + (i.e. the output of ``lshw -xml``). |
2817 | + @param-example "definition" |
2818 | + //node[@id="display"]/'clock units="Hz"' > 1000000000 |
2819 | + |
2820 | + @success (http-status-code) "200" 200 |
2821 | + @success (json) "success-json" A JSON tag object. |
2822 | + @success-example "success-json" [exkey=update-tag] placeholder |
2823 | + |
2824 | + @error (http-status-code) "404" 404 |
2825 | + @error (content) "not-found" The requested tag name is not found. |
2826 | + @error-example "not-found" |
2827 | + Not Found |
2828 | """ |
2829 | tag = Tag.objects.get_tag_or_404( |
2830 | name=name, user=request.user, to_edit=True) |
2831 | @@ -125,10 +153,18 @@ class TagHandler(OperationsHandler): |
2832 | raise MAASAPIValidationError(form.errors) |
2833 | |
2834 | def delete(self, request, name): |
2835 | - """Delete a specific Tag. |
2836 | + """@description-title Delete a tag |
2837 | + @description Deletes a tag by name. |
2838 | |
2839 | - Returns 404 if the tag is not found. |
2840 | - Returns 204 if the tag is successfully deleted. |
2841 | + @param (url-string) "{name}" [required=true] A tag name. |
2842 | + @param-example "{name}" virtual |
2843 | + |
2844 | + @success (http-status-code) "204" 204 |
2845 | + |
2846 | + @error (http-status-code) "404" 404 |
2847 | + @error (content) "not-found" The requested tag name is not found. |
2848 | + @error-example "not-found" |
2849 | + Not Found |
2850 | """ |
2851 | tag = Tag.objects.get_tag_or_404( |
2852 | name=name, user=request.user, to_edit=True) |
2853 | @@ -160,41 +196,101 @@ class TagHandler(OperationsHandler): |
2854 | |
2855 | @operation(idempotent=True) |
2856 | def nodes(self, request, name): |
2857 | - """Get the list of nodes that have this tag. |
2858 | + """@description-title List nodes by tag |
2859 | + @description Get a JSON list containing node objects that match |
2860 | + the given tag name. |
2861 | + |
2862 | + @param (url-string) "{name}" [required=true] A tag name. |
2863 | + @param-example "{name}" virtual |
2864 | |
2865 | - Returns 404 if the tag is not found. |
2866 | + @success (json) "success-json" A JSON list containing node objects |
2867 | + that match the given tag name. |
2868 | + @success-example "success-json" [exkey=get-nodes-by-tag] placeholder |
2869 | + |
2870 | + @error (http-status-code) "404" 404 |
2871 | + @error (content) "not-found" The requested tag name is not found. |
2872 | + @error-example "not-found" |
2873 | + Not Found |
2874 | """ |
2875 | return self._get_node_type(Node, request, name) |
2876 | |
2877 | @operation(idempotent=True) |
2878 | def machines(self, request, name): |
2879 | - """Get the list of machines that have this tag. |
2880 | + """@description-title List machines by tag |
2881 | + @description Get a JSON list containing machine objects that match |
2882 | + the given tag name. |
2883 | + |
2884 | + @param (url-string) "{name}" [required=true] A tag name. |
2885 | + @param-example "{name}" virtual |
2886 | |
2887 | - Returns 404 if the tag is not found. |
2888 | + @success (json) "success-json" A JSON list containing machine objects |
2889 | + that match the given tag name. |
2890 | + @success-example "success-json" [exkey=get-machines-by-tag] placeholder |
2891 | + |
2892 | + @error (http-status-code) "404" 404 |
2893 | + @error (content) "not-found" The requested tag name is not found. |
2894 | + @error-example "not-found" |
2895 | + Not Found |
2896 | """ |
2897 | return self._get_node_type(Machine, request, name) |
2898 | |
2899 | @operation(idempotent=True) |
2900 | def devices(self, request, name): |
2901 | - """Get the list of devices that have this tag. |
2902 | + """@description-title List devices by tag |
2903 | + @description Get a JSON list containing device objects that match |
2904 | + the given tag name. |
2905 | + |
2906 | + @param (url-string) "{name}" [required=true] A tag name. |
2907 | + @param-example "{name}" virtual |
2908 | + |
2909 | + @success (json) "success-json" A JSON list containing device objects |
2910 | + that match the given tag name. |
2911 | + @success-example "success-json" [exkey=get-devices-by-tag] placeholder |
2912 | |
2913 | - Returns 404 if the tag is not found. |
2914 | + @error (http-status-code) "404" 404 |
2915 | + @error (content) "not-found" The requested tag name is not found. |
2916 | + @error-example "not-found" |
2917 | + Not Found |
2918 | """ |
2919 | return self._get_node_type(Device, request, name) |
2920 | |
2921 | @operation(idempotent=True) |
2922 | def rack_controllers(self, request, name): |
2923 | - """Get the list of rack controllers that have this tag. |
2924 | + """@description-title List rack controllers by tag |
2925 | + @description Get a JSON list containing rack-controller objects |
2926 | + that match the given tag name. |
2927 | + |
2928 | + @param (url-string) "{name}" [required=true] A tag name. |
2929 | + @param-example "{name}" virtual |
2930 | + |
2931 | + @success (json) "success-json" A JSON list containing rack-controller |
2932 | + objects that match the given tag name. |
2933 | + @success-example "success-json" [exkey=get-rackc-by-tag] placeholder |
2934 | |
2935 | - Returns 404 if the tag is not found. |
2936 | + @error (http-status-code) "404" 404 |
2937 | + @error (content) "not-found" The requested tag name is not found. |
2938 | + @error-example "not-found" |
2939 | + Not Found |
2940 | """ |
2941 | return self._get_node_type(RackController, request, name) |
2942 | |
2943 | @operation(idempotent=True) |
2944 | def region_controllers(self, request, name): |
2945 | - """Get the list of region controllers that have this tag. |
2946 | + """@description-title List region controllers by tag |
2947 | + @description Get a JSON list containing region-controller objects |
2948 | + that match the given tag name. |
2949 | |
2950 | - Returns 404 if the tag is not found. |
2951 | + @param (url-string) "{name}" [required=true] A tag name. |
2952 | + @param-example "{name}" virtual |
2953 | + |
2954 | + @success (json) "success-json" A JSON list containing region-controller |
2955 | + objects that match the given tag name. |
2956 | + @success-example "success-json" [exkey=get-regionc-by-tag] placeholder |
2957 | + |
2958 | + @error (http-status-code) "404" 404 |
2959 | + @error (content) "not-found" The requested tag name is not found. |
2960 | + @error-example "not-found" |
2961 | + Not Found |
2962 | """ |
2963 | return self._get_node_type(RegionController, request, name) |
2964 | |
2965 | @@ -208,13 +304,23 @@ class TagHandler(OperationsHandler): |
2966 | |
2967 | @operation(idempotent=False) |
2968 | def rebuild(self, request, name): |
2969 | - """Manually trigger a rebuild the tag <=> node mapping. |
2970 | - |
2971 | - This is considered a maintenance operation, which should normally not |
2972 | - be necessary. Adding nodes or updating a tag's definition should |
2973 | - automatically trigger the appropriate changes. |
2974 | - |
2975 | - Returns 404 if the tag is not found. |
2976 | + """@description-title Trigger a tag-node mapping rebuild |
2977 | + @description Tells MAAS to rebuild the tag-to-node mappings. |
2978 | + This is a maintenance operation and should not be necessary under |
2979 | + normal circumstances. Adding nodes or updating a tag definition |
2980 | + should automatically trigger the mapping rebuild. |
2981 | + |
2982 | + @param (url-string) "{name}" [required=true] A tag name. |
2983 | + @param-example "{name}" virtual |
2984 | + |
2985 | + @success (json) "success-json" A JSON object indicating which tag-to- |
2986 | + node mapping is being rebuilt. |
2987 | + @success-example "success-json" [exkey=rebuild-tag] placeholder |
2988 | + |
2989 | + @error (http-status-code) "404" 404 |
2990 | + @error (content) "not-found" The requested tag name is not found. |
2991 | + @error-example "not-found" |
2992 | + Not Found |
2993 | """ |
2994 | tag = Tag.objects.get_tag_or_404(name=name, user=request.user, |
2995 | to_edit=True) |
2996 | @@ -223,22 +329,52 @@ class TagHandler(OperationsHandler): |
2997 | |
2998 | @operation(idempotent=False) |
2999 | def update_nodes(self, request, name): |
3000 | - """Add or remove nodes being associated with this tag. |
3001 | - |
3002 | - :param add: system_ids of nodes to add to this tag. |
3003 | - :param remove: system_ids of nodes to remove from this tag. |
3004 | - :param definition: (optional) If supplied, the definition will be |
3005 | - validated against the current definition of the tag. If the value |
3006 | - does not match, then the update will be dropped (assuming this was |
3007 | - just a case of a worker being out-of-date) |
3008 | - :param rack_controller: A system ID of a rack controller that did the |
3009 | - processing. This value is optional. If not supplied, the requester |
3010 | - must be a superuser. If supplied, then the requester must be the |
3011 | - rack controller. |
3012 | - |
3013 | - Returns 404 if the tag is not found. |
3014 | - Returns 401 if the user does not have permission to update the nodes. |
3015 | - Returns 409 if 'definition' doesn't match the current definition. |
3016 | + """@description-title Add or remove nodes by tag |
3017 | + @description Add or remove nodes associated with the given tag. |
3018 | + Note that you must supply either the ``add`` or ``remove`` |
3019 | + parameter. |
3020 | + |
3021 | + @param (url-string) "{name}" [required=true] A tag name. |
3022 | + @param-example "{name}" virtual |
3023 | + |
3024 | + @param (string) "add" [required=false] The system_id to tag. |
3025 | + @param-example "add" ``fptcnd`` |
3026 | + |
3027 | + @param (string) "remove" [required=false] The system_id to untag. |
3028 | + @param-example "remove" ``xbpf3n`` |
3029 | + |
3030 | + @param (string) "definition" [required=false] If given, the |
3031 | + definition (XPATH expression) will be validated against the |
3032 | + current definition of the tag. If the value does not match, MAAS |
3033 | + assumes the worker is out of date and will drop the update. |
3034 | + @param-example "definition" |
3035 | + //node[@id="display"]/'clock units="Hz"' > 1000000000 |
3036 | + |
3037 | + @param (string) "rack_controller" [required=false] The system ID |
3038 | + of the rack controller that processed the given tag initially. |
3039 | + If not given, the requester must be a MAAS admin. If given, |
3040 | + the requester must be the rack controller. |
3041 | + |
3042 | + @success (json) "success-json" A JSON object representing the |
3043 | + updated node. |
3044 | + @success-example "success-json" [exkey=update-nodes-tag] placeholder |
3045 | + |
3046 | + @error (http-status-code) "403" 403 |
3047 | + @error (content) "no-perms" The user does not have the permissions |
3048 | + required to update the nodes. |
3049 | + @error-example "no-perms" |
3050 | + Must be a superuser or supply a rack_controller. |
3051 | + |
3052 | + @error (http-status-code) "409" 409 |
3053 | + @error (content) "no-def-match" The supplied definition doesn't match |
3054 | + the current definition. |
3055 | + @error-example "no-def-match" |
3056 | + Definition supplied 'foobar' doesn't match current definition '' |
3057 | + |
3058 | + @error (http-status-code) "404" 404 |
3059 | + @error (content) "not-found" The requested tag name is not found. |
3060 | + @error-example "not-found" |
3061 | + Not Found |
3062 | """ |
3063 | tag = Tag.objects.get_tag_or_404(name=name, user=request.user) |
3064 | rack_controller = None |
3065 | @@ -278,26 +414,44 @@ class TagHandler(OperationsHandler): |
3066 | |
3067 | |
3068 | class TagsHandler(OperationsHandler): |
3069 | - """Manage the collection of all the Tags in this MAAS.""" |
3070 | + """Manage all tags known to MAAS.""" |
3071 | api_doc_section_name = "Tags" |
3072 | update = delete = None |
3073 | |
3074 | def create(self, request): |
3075 | - """Create a new Tag. |
3076 | - |
3077 | - :param name: The name of the Tag to be created. This should be a short |
3078 | - name, and will be used in the URL of the tag. |
3079 | - :param comment: A long form description of what the tag is meant for. |
3080 | - It is meant as a human readable description of the tag. |
3081 | - :param definition: An XPATH query that will be evaluated against the |
3082 | - hardware_details stored for all nodes (output of `lshw -xml`). |
3083 | - :param kernel_opts: Can be None. If set, nodes associated with this tag |
3084 | - will add this string to their kernel options when booting. The |
3085 | - value overrides the global 'kernel_opts' setting. If more than one |
3086 | - tag is associated with a node, the one with the lowest alphabetical |
3087 | - name will be picked (eg 01-my-tag will be taken over 99-tag-name). |
3088 | - |
3089 | - Returns 401 if the user is not an admin. |
3090 | + """@description-title Create a new tag |
3091 | + @description Create a new tag. |
3092 | + |
3093 | + @param (string) "name" [required=true] The new tag name. Because |
3094 | + the name will be used in urls, it should be short. |
3095 | + @param-example "name" virtual |
3096 | + @param (string) "comment" [required=false] A description of what the |
3097 | + the tag will be used for in natural language. |
3098 | + @param-example "comment" The 'virtual' tag represents virtual |
3099 | + machines. |
3100 | + @param (string) "definition" [required=false] An XPATH query that is |
3101 | + evaluated against the hardware_details stored for all nodes |
3102 | + (i.e. the output of ``lshw -xml``). |
3103 | + @param-example "definition" |
3104 | + //node[@id="display"]/'clock units="Hz"' > 1000000000 |
3105 | + @param (string) "kernel_opts" [required=false] Nodes associated |
3106 | + with this tag will add this string to their kernel options |
3107 | + when booting. The value overrides the global ``kernel_opts`` |
3108 | + setting. If more than one tag is associated with a node, the |
3109 | + one with the lower alphabetical name will be picked. For example, |
3110 | + ``01-my-tag`` will be chosen instead of ``99-tag-name``. |
3111 | + @param-example "kernel_opts" |
3112 | + nouveau.noaccel=1 |
3113 | + |
3114 | + @success (json) "success-json" A JSON object representing the |
3115 | + new tag. |
3116 | + @success-example "success-json" [exkey=add-tag] placeholder |
3117 | + |
3118 | + @error (http-status-code) "403" 403 |
3119 | + @error (content) "no-perms" The user does not have the permissions |
3120 | + required to create a tag. |
3121 | + @error-example "no-perms" |
3122 | + No content |
3123 | """ |
3124 | if not request.user.is_superuser: |
3125 | raise PermissionDenied() |
3126 | @@ -308,9 +462,13 @@ class TagsHandler(OperationsHandler): |
3127 | raise MAASAPIValidationError(form.errors) |
3128 | |
3129 | def read(self, request): |
3130 | - """List Tags. |
3131 | + """@description-title List tags |
3132 | + @description Outputs a JSON object containing an array of all |
3133 | + currently defined tag objects. |
3134 | |
3135 | - Get a listing of all tags that are currently defined. |
3136 | + @success (json) "success-json" A JSON object containing an array |
3137 | + of all currently defined tag objects. |
3138 | + @success-example "success-json" [exkey=get-tags] placeholder |
3139 | """ |
3140 | return Tag.objects.all() |
3141 | |
3142 | diff --git a/src/maasserver/api/tests/test_annotations.py b/src/maasserver/api/tests/test_annotations.py |
3143 | index 5a5eea7..de8886d 100644 |
3144 | --- a/src/maasserver/api/tests/test_annotations.py |
3145 | +++ b/src/maasserver/api/tests/test_annotations.py |
3146 | @@ -5,6 +5,7 @@ |
3147 | |
3148 | __all__ = [] |
3149 | |
3150 | + |
3151 | from maasserver.api.annotations import APIDocstringParser |
3152 | from maasserver.testing.api import APITestCase |
3153 | |
3154 | @@ -17,6 +18,18 @@ class TestAPIAnnotations(APITestCase.ForUser): |
3155 | # Allowed types |
3156 | allowed_types = APIDocstringParser.allowed_types |
3157 | |
3158 | + # URI templates for testing the examples database. The parser uses the |
3159 | + # URI template to name an examples database. So, here, the parser would |
3160 | + # look for "examples/for-tests.json". We have plural and singular beause |
3161 | + # the API often references both plural and singular operations. E.g. |
3162 | + # zone and zones. Both should use the same examples database. |
3163 | + # |
3164 | + # Also, we need to pass this to every parse method call so that we don't |
3165 | + # see spurious API warnings when the parse cannot find an examples database |
3166 | + # that the sample_api_annotated_docstring is referencing. |
3167 | + test_uri_singular = "/MAAS/api/2.0/for-test/{foobar}/" |
3168 | + test_uri_plural = "/MAAS/api/2.0/for-tests/{foobar}/" |
3169 | + |
3170 | # Use this sample and modify it in various ways |
3171 | # inline to perform tests. Note that all allowed |
3172 | # types/tags are (and should be) represented here, and |
3173 | @@ -44,6 +57,9 @@ class TestAPIAnnotations(APITestCase.ForUser): |
3174 | @success (content) "success_name" success description |
3175 | @success-example "success_name" success content |
3176 | |
3177 | + @success (content) "success_with_exdb" success description |
3178 | + @success-example "success_with_exdb" [exkey=key1] ignored content |
3179 | + |
3180 | @error (http-status-code) "error_name" error description |
3181 | @error-example "error_name" error content |
3182 | """ |
3183 | @@ -70,7 +86,7 @@ class TestAPIAnnotations(APITestCase.ForUser): |
3184 | self.assertTrue(pdict['warnings'].find("API_SYNTAX_ERROR") != -1) |
3185 | |
3186 | def do_parse(self, api_docstring_parser, docstring): |
3187 | - api_docstring_parser.parse(docstring) |
3188 | + api_docstring_parser.parse(docstring, uri=self.test_uri_singular) |
3189 | return api_docstring_parser.get_dict() |
3190 | |
3191 | def test_all_allowed_tags_are_represented_in_test(self): |
3192 | @@ -92,16 +108,18 @@ class TestAPIAnnotations(APITestCase.ForUser): |
3193 | |
3194 | docstring = self.sample_api_annotated_docstring |
3195 | api_docstring_parser = APIDocstringParser() |
3196 | - api_docstring_parser.parse(docstring, "method", "uri", "operation") |
3197 | + api_docstring_parser.parse(docstring, http_method="mymethod", |
3198 | + uri=self.test_uri_singular, |
3199 | + operation="myoperation") |
3200 | d = api_docstring_parser.get_dict() |
3201 | |
3202 | params = d['params'] |
3203 | successes = d['successes'] |
3204 | errors = d['errors'] |
3205 | |
3206 | - self.assertEqual(d['http_method'], "method") |
3207 | - self.assertEqual(d['uri'], "uri") |
3208 | - self.assertEqual(d['operation'], "operation") |
3209 | + self.assertEqual(d['http_method'], "mymethod") |
3210 | + self.assertEqual(d['uri'], self.test_uri_singular) |
3211 | + self.assertEqual(d['operation'], "myoperation") |
3212 | self.assertEqual(d['description_title'], "Docstring title") |
3213 | self.assertEqual( |
3214 | " ".join(d['description'].split()), |
3215 | @@ -164,7 +182,8 @@ class TestAPIAnnotations(APITestCase.ForUser): |
3216 | """Replace a good tag with a bad one and get a syntax error.""" |
3217 | docstring = self.sample_api_annotated_docstring |
3218 | api_docstring_parser = APIDocstringParser() |
3219 | - api_docstring_parser.parse(docstring.replace("@param", "@bad")) |
3220 | + api_docstring_parser.parse(docstring.replace("@param", "@bad"), |
3221 | + uri=self.test_uri_singular) |
3222 | d = api_docstring_parser.get_dict() |
3223 | self.assert_has_syntax_error(d) |
3224 | |
3225 | @@ -180,21 +199,21 @@ class TestAPIAnnotations(APITestCase.ForUser): |
3226 | docstring = docstring.replace( |
3227 | "@param-example \"param_name\"", |
3228 | "@param-example \"param_name_bad\"") |
3229 | - api_docstring_parser.parse(docstring) |
3230 | + api_docstring_parser.parse(docstring, uri=self.test_uri_singular) |
3231 | d = api_docstring_parser.get_dict() |
3232 | self.assert_has_api_warning(d) |
3233 | |
3234 | docstring = docstring.replace( |
3235 | "@error-example \"error_name\"", |
3236 | "@error-example \"error_name_bad\"") |
3237 | - api_docstring_parser.parse(docstring) |
3238 | + api_docstring_parser.parse(docstring, uri=self.test_uri_singular) |
3239 | d = api_docstring_parser.get_dict() |
3240 | self.assert_has_api_warning(d) |
3241 | |
3242 | docstring = docstring.replace( |
3243 | "@success-example \"success_name\"", |
3244 | "@success-example \"success_name_bad\"") |
3245 | - api_docstring_parser.parse(docstring) |
3246 | + api_docstring_parser.parse(docstring, uri=self.test_uri_singular) |
3247 | d = api_docstring_parser.get_dict() |
3248 | self.assert_has_api_warning(d) |
3249 | |
3250 | @@ -206,7 +225,7 @@ class TestAPIAnnotations(APITestCase.ForUser): |
3251 | " multiple lines.\n\n " |
3252 | ) |
3253 | api_docstring_parser = APIDocstringParser() |
3254 | - api_docstring_parser.parse(docstring) |
3255 | + api_docstring_parser.parse(docstring, uri=self.test_uri_singular) |
3256 | d = api_docstring_parser.get_dict() |
3257 | |
3258 | # Note that we only test one description here because the |
3259 | @@ -224,7 +243,7 @@ class TestAPIAnnotations(APITestCase.ForUser): |
3260 | " }\n\n " |
3261 | ) |
3262 | api_docstring_parser = APIDocstringParser() |
3263 | - api_docstring_parser.parse(docstring) |
3264 | + api_docstring_parser.parse(docstring, uri=self.test_uri_singular) |
3265 | d = api_docstring_parser.get_dict() |
3266 | |
3267 | # Note that we only test one example here because the |
3268 | @@ -486,3 +505,56 @@ class TestAPIAnnotations(APITestCase.ForUser): |
3269 | |
3270 | self.assert_has_api_warning( |
3271 | self.do_parse(api_docstring_parser, ds_md)) |
3272 | + |
3273 | + def test_find_examples_db(self): |
3274 | + """Ensure parser correctly finds example databases.""" |
3275 | + ds = self.sample_api_annotated_docstring |
3276 | + |
3277 | + api_docstring_parser = APIDocstringParser() |
3278 | + api_docstring_parser.parse(ds, uri=self.test_uri_singular) |
3279 | + d = api_docstring_parser.get_dict() |
3280 | + |
3281 | + s = d['successes'][1] |
3282 | + |
3283 | + self.assertEqual(" ".join(s['example'].split()), '{ "name": "value" }') |
3284 | + |
3285 | + api_docstring_parser.parse(ds, uri=self.test_uri_plural) |
3286 | + d = api_docstring_parser.get_dict() |
3287 | + |
3288 | + s = d['successes'][1] |
3289 | + |
3290 | + self.assertEqual(" ".join(s['example'].split()), '{ "name": "value" }') |
3291 | + |
3292 | + def test_warn_on_missing_example_db_entry(self): |
3293 | + """Ensure we see a warning if there is a missing examples db entry.""" |
3294 | + ds_orig = self.sample_api_annotated_docstring |
3295 | + |
3296 | + ds_bad_exkey = ds_orig.replace( |
3297 | + '"success_with_exdb" [exkey=key1]', |
3298 | + '"success_with_exdb" [exkey=badkey]') |
3299 | + |
3300 | + api_docstring_parser = APIDocstringParser() |
3301 | + api_docstring_parser.parse(ds_bad_exkey, uri=self.test_uri_singular) |
3302 | + d = api_docstring_parser.get_dict() |
3303 | + |
3304 | + self.assert_has_api_warning(d) |
3305 | + |
3306 | + def test_warn_on_missing_example_db_when_entry_referenced(self): |
3307 | + """Missing examples db. |
3308 | + |
3309 | + If an examples db does not exist for some given URI (like when it |
3310 | + simply hasn't been created yet) and a key from that missing DB is |
3311 | + referenced by the API, we should see a warning. |
3312 | + |
3313 | + Note that _not_ having an examples db for a particular operation is a |
3314 | + normal and acceptable condition (it takes a while to create one). It |
3315 | + only becomes an error condition when the API tries to reference |
3316 | + something inside a non-existent examples database. |
3317 | + """ |
3318 | + ds = self.sample_api_annotated_docstring |
3319 | + |
3320 | + api_docstring_parser = APIDocstringParser() |
3321 | + api_docstring_parser.parse(ds, uri="bad_uri") |
3322 | + d = api_docstring_parser.get_dict() |
3323 | + |
3324 | + self.assert_has_api_warning(d) |
3325 | diff --git a/src/maasserver/api/tmpl-apidoc.rst b/src/maasserver/api/tmpl-apidoc.rst |
3326 | index 3198bba..a31139a 100644 |
3327 | --- a/src/maasserver/api/tmpl-apidoc.rst |
3328 | +++ b/src/maasserver/api/tmpl-apidoc.rst |
3329 | @@ -1,7 +1,7 @@ |
3330 | .. raw:: html |
3331 | |
3332 | <details> |
3333 | - <summary>``{{ http_method }} {{ uri }}{{if operation != ""}}?op={{ operation }}{{endif}}``</summary> |
3334 | + <summary>``{{ http_method }} {{ uri }}{{if operation != ""}}?{{ operation }}{{endif}}``</summary> |
3335 | |
3336 | ###################################################################################################### |
3337 | |
3338 | @@ -58,9 +58,14 @@ THERE ARE PROBLEMS WITH THE DOCSTRING: |
3339 | |
3340 | *{{ p['type'] }}* |
3341 | |
3342 | +{{py: |
3343 | +from textwrap import indent |
3344 | +example = indent(p['example'], ' ') |
3345 | +}} |
3346 | + |
3347 | :: |
3348 | |
3349 | - {{ p['example'] }} |
3350 | +{{ example }} |
3351 | |
3352 | {{endif}} |
3353 | |
3354 | @@ -93,5 +98,5 @@ THERE ARE PROBLEMS WITH THE DOCSTRING: |
3355 | |
3356 | .. raw:: html |
3357 | |
3358 | + <p> </p> |
3359 | </details> |
3360 | - |
UNIT TESTS annotation- w-examples lp:~jsseidel/maas/+git/maas into -b master lp:~maas-committers/maas
-b jsseidel-
STATUS: SUCCESS 85158f0f8a383b6 30f730368b
COMMIT: 78baad5412292fa