RAPI documentation: Assertion for console fields
[ganeti-local] / doc / rapi.rst
1 Ganeti remote API
2 =================
3
4 Documents Ganeti version |version|
5
6 .. contents::
7
8 Introduction
9 ------------
10
11 Ganeti supports a remote API for enable external tools to easily
12 retrieve information about a cluster's state. The remote API daemon,
13 *ganeti-rapi*, is automatically started on the master node. By default
14 it runs on TCP port 5080, but this can be changed either in
15 ``.../constants.py`` or via the command line parameter *-p*. SSL mode,
16 which is used by default, can also be disabled by passing command line
17 parameters.
18
19 .. _rapi-users:
20
21 Users and passwords
22 -------------------
23
24 ``ganeti-rapi`` reads users and passwords from a file (usually
25 ``/var/lib/ganeti/rapi/users``) on startup. Changes to the file will be
26 read automatically.
27
28 Lines starting with the hash sign (``#``) are treated as comments. Each
29 line consists of two or three fields separated by whitespace. The first
30 two fields are for username and password. The third field is optional
31 and can be used to specify per-user options (separated by comma without
32 spaces). Available options:
33
34 .. pyassert::
35
36   rapi.RAPI_ACCESS_ALL == set([
37     rapi.RAPI_ACCESS_WRITE,
38     rapi.RAPI_ACCESS_READ,
39     ])
40
41 :pyeval:`rapi.RAPI_ACCESS_WRITE`
42   Enables the user to execute operations modifying the cluster. Implies
43   :pyeval:`rapi.RAPI_ACCESS_READ` access.
44 :pyeval:`rapi.RAPI_ACCESS_READ`
45   Allow access to operations querying for information.
46
47 Passwords can either be written in clear text or as a hash. Clear text
48 passwords may not start with an opening brace (``{``) or they must be
49 prefixed with ``{cleartext}``. To use the hashed form, get the MD5 hash
50 of the string ``$username:Ganeti Remote API:$password`` (e.g. ``echo -n
51 'jack:Ganeti Remote API:abc123' | openssl md5``) [#pwhash]_ and prefix
52 it with ``{ha1}``. Using the scheme prefix for all passwords is
53 recommended. Scheme prefixes are not case sensitive.
54
55 Example::
56
57   # Give Jack and Fred read-only access
58   jack abc123
59   fred {cleartext}foo555
60
61   # Give write access to an imaginary instance creation script
62   autocreator xyz789 write
63
64   # Hashed password for Jessica
65   jessica {HA1}7046452df2cbb530877058712cf17bd4 write
66
67   # Monitoring can query for values
68   monitoring {HA1}ec018ffe72b8e75bb4d508ed5b6d079c read
69
70   # A user who can read and write (the former is implied by granting
71   # write access)
72   superuser {HA1}ec018ffe72b8e75bb4d508ed5b6d079c read,write
73
74
75 .. [#pwhash] Using the MD5 hash of username, realm and password is
76    described in :rfc:`2617` ("HTTP Authentication"), sections 3.2.2.2
77    and 3.3. The reason for using it over another algorithm is forward
78    compatibility. If ``ganeti-rapi`` were to implement HTTP Digest
79    authentication in the future, the same hash could be used.
80    In the current version ``ganeti-rapi``'s realm, ``Ganeti Remote
81    API``, can only be changed by modifying the source code.
82
83
84 Protocol
85 --------
86
87 The protocol used is JSON_ over HTTP designed after the REST_ principle.
88 HTTP Basic authentication as per :rfc:`2617` is supported.
89
90 .. _JSON: http://www.json.org/
91 .. _REST: http://en.wikipedia.org/wiki/Representational_State_Transfer
92
93 HTTP requests with a body (e.g. ``PUT`` or ``POST``) require the request
94 header ``Content-type`` be set to ``application/json`` (see :rfc:`2616`
95 (HTTP/1.1), section 7.2.1).
96
97
98 A note on JSON as used by RAPI
99 ++++++++++++++++++++++++++++++
100
101 JSON_ as used by Ganeti RAPI does not conform to the specification in
102 :rfc:`4627`. Section 2 defines a JSON text to be either an object
103 (``{"key": "value", …}``) or an array (``[1, 2, 3, …]``). In violation
104 of this RAPI uses plain strings (``"master-candidate"``, ``"1234"``) for
105 some requests or responses. Changing this now would likely break
106 existing clients and cause a lot of trouble.
107
108 .. highlight:: ruby
109
110 Unlike Python's `JSON encoder and decoder
111 <http://docs.python.org/library/json.html>`_, other programming
112 languages or libraries may only provide a strict implementation, not
113 allowing plain values. For those, responses can usually be wrapped in an
114 array whose first element is then used, e.g. the response ``"1234"``
115 becomes ``["1234"]``. This works equally well for more complex values.
116 Example in Ruby::
117
118   require "json"
119
120   # Insert code to get response here
121   response = "\"1234\""
122
123   decoded = JSON.parse("[#{response}]").first
124
125 Short of modifying the encoder to allow encoding to a less strict
126 format, requests will have to be formatted by hand. Newer RAPI requests
127 already use a dictionary as their input data and shouldn't cause any
128 problems.
129
130
131 PUT or POST?
132 ------------
133
134 According to :rfc:`2616` the main difference between PUT and POST is
135 that POST can create new resources but PUT can only create the resource
136 the URI was pointing to on the PUT request.
137
138 Unfortunately, due to historic reasons, the Ganeti RAPI library is not
139 consistent with this usage, so just use the methods as documented below
140 for each resource.
141
142 For more details have a look in the source code at
143 ``lib/rapi/rlib2.py``.
144
145
146 Generic parameter types
147 -----------------------
148
149 A few generic refered parameter types and the values they allow.
150
151 ``bool``
152 ++++++++
153
154 A boolean option will accept ``1`` or ``0`` as numbers but not
155 i.e. ``True`` or ``False``.
156
157 Generic parameters
158 ------------------
159
160 A few parameter mean the same thing across all resources which implement
161 it.
162
163 ``bulk``
164 ++++++++
165
166 Bulk-mode means that for the resources which usually return just a list
167 of child resources (e.g. ``/2/instances`` which returns just instance
168 names), the output will instead contain detailed data for all these
169 subresources. This is more efficient than query-ing the sub-resources
170 themselves.
171
172 ``dry-run``
173 +++++++++++
174
175 The boolean *dry-run* argument, if provided and set, signals to Ganeti
176 that the job should not be executed, only the pre-execution checks will
177 be done.
178
179 This is useful in trying to determine (without guarantees though, as in
180 the meantime the cluster state could have changed) if the operation is
181 likely to succeed or at least start executing.
182
183 ``force``
184 +++++++++++
185
186 Force operation to continue even if it will cause the cluster to become
187 inconsistent (e.g. because there are not enough master candidates).
188
189 Parameter details
190 -----------------
191
192 Some parameters are not straight forward, so we describe them in details
193 here.
194
195 .. _rapi-ipolicy:
196
197 ``ipolicy``
198 +++++++++++
199
200 The instance policy specification is a dict with the following fields:
201
202 .. pyassert::
203
204   constants.IPOLICY_ALL_KEYS == set([constants.ISPECS_MIN,
205                                      constants.ISPECS_MAX,
206                                      constants.ISPECS_STD,
207                                      constants.IPOLICY_DTS,
208                                      constants.IPOLICY_VCPU_RATIO,
209                                      constants.IPOLICY_SPINDLE_RATIO])
210
211
212 .. pyassert::
213
214   (set(constants.ISPECS_PARAMETER_TYPES.keys()) ==
215    set([constants.ISPEC_MEM_SIZE,
216         constants.ISPEC_DISK_SIZE,
217         constants.ISPEC_DISK_COUNT,
218         constants.ISPEC_CPU_COUNT,
219         constants.ISPEC_NIC_COUNT,
220         constants.ISPEC_SPINDLE_USE]))
221
222 .. |ispec-min| replace:: :pyeval:`constants.ISPECS_MIN`
223 .. |ispec-max| replace:: :pyeval:`constants.ISPECS_MAX`
224 .. |ispec-std| replace:: :pyeval:`constants.ISPECS_STD`
225
226
227 |ispec-min|, |ispec-max|, |ispec-std|
228   A sub- `dict` with the following fields, which sets the limit and standard
229   values of the instances:
230
231   :pyeval:`constants.ISPEC_MEM_SIZE`
232     The size in MiB of the memory used
233   :pyeval:`constants.ISPEC_DISK_SIZE`
234     The size in MiB of the disk used
235   :pyeval:`constants.ISPEC_DISK_COUNT`
236     The numbers of disks used
237   :pyeval:`constants.ISPEC_CPU_COUNT`
238     The numbers of cpus used
239   :pyeval:`constants.ISPEC_NIC_COUNT`
240     The numbers of nics used
241   :pyeval:`constants.ISPEC_SPINDLE_USE`
242     The numbers of virtual disk spindles used by this instance. They are
243     not real in the sense of actual HDD spindles, but useful for
244     accounting the spindle usage on the residing node
245 :pyeval:`constants.IPOLICY_DTS`
246   A `list` of disk templates allowed for instances using this policy
247 :pyeval:`constants.IPOLICY_VCPU_RATIO`
248   Maximum ratio of virtual to physical CPUs (`float`)
249 :pyeval:`constants.IPOLICY_SPINDLE_RATIO`
250   Maximum ratio of instances to their node's ``spindle_count`` (`float`)
251
252 Usage examples
253 --------------
254
255 You can access the API using your favorite programming language as long
256 as it supports network connections.
257
258 Ganeti RAPI client
259 ++++++++++++++++++
260
261 Ganeti includes a standalone RAPI client, ``lib/rapi/client.py``.
262
263 Shell
264 +++++
265
266 .. highlight:: shell-example
267
268 Using wget::
269
270    $ wget -q -O - https://%CLUSTERNAME%:5080/2/info
271
272 or curl::
273
274   $ curl https://%CLUSTERNAME%:5080/2/info
275
276
277 Python
278 ++++++
279
280 .. highlight:: python
281
282 ::
283
284   import urllib2
285   f = urllib2.urlopen('https://CLUSTERNAME:5080/2/info')
286   print f.read()
287
288
289 JavaScript
290 ++++++++++
291
292 .. warning:: While it's possible to use JavaScript, it poses several
293    potential problems, including browser blocking request due to
294    non-standard ports or different domain names. Fetching the data on
295    the webserver is easier.
296
297 .. highlight:: javascript
298
299 ::
300
301   var url = 'https://CLUSTERNAME:5080/2/info';
302   var info;
303   var xmlreq = new XMLHttpRequest();
304   xmlreq.onreadystatechange = function () {
305     if (xmlreq.readyState != 4) return;
306     if (xmlreq.status == 200) {
307       info = eval("(" + xmlreq.responseText + ")");
308       alert(info);
309     } else {
310       alert('Error fetching cluster info');
311     }
312     xmlreq = null;
313   };
314   xmlreq.open('GET', url, true);
315   xmlreq.send(null);
316
317 Resources
318 ---------
319
320 .. highlight:: javascript
321
322 ``/``
323 +++++
324
325 The root resource. Has no function, but for legacy reasons the ``GET``
326 method is supported.
327
328 ``/2``
329 ++++++
330
331 Has no function, but for legacy reasons the ``GET`` method is supported.
332
333 ``/2/info``
334 +++++++++++
335
336 Cluster information resource.
337
338 It supports the following commands: ``GET``.
339
340 ``GET``
341 ~~~~~~~
342
343 Returns cluster information.
344
345 Example::
346
347   {
348     "config_version": 2000000,
349     "name": "cluster",
350     "software_version": "2.0.0~beta2",
351     "os_api_version": 10,
352     "export_version": 0,
353     "candidate_pool_size": 10,
354     "enabled_hypervisors": [
355       "fake"
356     ],
357     "hvparams": {
358       "fake": {}
359      },
360     "default_hypervisor": "fake",
361     "master": "node1.example.com",
362     "architecture": [
363       "64bit",
364       "x86_64"
365     ],
366     "protocol_version": 20,
367     "beparams": {
368       "default": {
369         "auto_balance": true,
370         "vcpus": 1,
371         "memory": 128
372        }
373       },
374     …
375   }
376
377
378 ``/2/redistribute-config``
379 ++++++++++++++++++++++++++
380
381 Redistribute configuration to all nodes.
382
383 It supports the following commands: ``PUT``.
384
385 ``PUT``
386 ~~~~~~~
387
388 Redistribute configuration to all nodes. The result will be a job id.
389
390 Job result:
391
392 .. opcode_result:: OP_CLUSTER_REDIST_CONF
393
394
395 ``/2/features``
396 +++++++++++++++
397
398 ``GET``
399 ~~~~~~~
400
401 Returns a list of features supported by the RAPI server. Available
402 features:
403
404 .. pyassert::
405
406   rlib2.ALL_FEATURES == set([rlib2._INST_CREATE_REQV1,
407                              rlib2._INST_REINSTALL_REQV1,
408                              rlib2._NODE_MIGRATE_REQV1,
409                              rlib2._NODE_EVAC_RES1])
410
411 :pyeval:`rlib2._INST_CREATE_REQV1`
412   Instance creation request data version 1 supported
413 :pyeval:`rlib2._INST_REINSTALL_REQV1`
414   Instance reinstall supports body parameters
415 :pyeval:`rlib2._NODE_MIGRATE_REQV1`
416   Whether migrating a node (``/2/nodes/[node_name]/migrate``) supports
417   request body parameters
418 :pyeval:`rlib2._NODE_EVAC_RES1`
419   Whether evacuating a node (``/2/nodes/[node_name]/evacuate``) returns
420   a new-style result (see resource description)
421
422
423 ``/2/modify``
424 ++++++++++++++++++++++++++++++++++++++++
425
426 Modifies cluster parameters.
427
428 Supports the following commands: ``PUT``.
429
430 ``PUT``
431 ~~~~~~~
432
433 Returns a job ID.
434
435 Body parameters:
436
437 .. opcode_params:: OP_CLUSTER_SET_PARAMS
438
439 Job result:
440
441 .. opcode_result:: OP_CLUSTER_SET_PARAMS
442
443
444 ``/2/groups``
445 +++++++++++++
446
447 The groups resource.
448
449 It supports the following commands: ``GET``, ``POST``.
450
451 ``GET``
452 ~~~~~~~
453
454 Returns a list of all existing node groups.
455
456 Example::
457
458     [
459       {
460         "name": "group1",
461         "uri": "\/2\/groups\/group1"
462       },
463       {
464         "name": "group2",
465         "uri": "\/2\/groups\/group2"
466       }
467     ]
468
469 If the optional bool *bulk* argument is provided and set to a true value
470 (i.e ``?bulk=1``), the output contains detailed information about node
471 groups as a list.
472
473 Returned fields: :pyeval:`utils.CommaJoin(sorted(rlib2.G_FIELDS))`.
474
475 Example::
476
477     [
478       {
479         "name": "group1",
480         "node_cnt": 2,
481         "node_list": [
482           "node1.example.com",
483           "node2.example.com"
484         ],
485         "uuid": "0d7d407c-262e-49af-881a-6a430034bf43",
486         …
487       },
488       {
489         "name": "group2",
490         "node_cnt": 1,
491         "node_list": [
492           "node3.example.com"
493         ],
494         "uuid": "f5a277e7-68f9-44d3-a378-4b25ecb5df5c",
495         …
496       },
497       …
498     ]
499
500 ``POST``
501 ~~~~~~~~
502
503 Creates a node group.
504
505 If the optional bool *dry-run* argument is provided, the job will not be
506 actually executed, only the pre-execution checks will be done.
507
508 Returns: a job ID that can be used later for polling.
509
510 Body parameters:
511
512 .. opcode_params:: OP_GROUP_ADD
513
514 Earlier versions used a parameter named ``name`` which, while still
515 supported, has been renamed to ``group_name``.
516
517 Job result:
518
519 .. opcode_result:: OP_GROUP_ADD
520
521
522 ``/2/groups/[group_name]``
523 ++++++++++++++++++++++++++
524
525 Returns information about a node group.
526
527 It supports the following commands: ``GET``, ``DELETE``.
528
529 ``GET``
530 ~~~~~~~
531
532 Returns information about a node group, similar to the bulk output from
533 the node group list.
534
535 Returned fields: :pyeval:`utils.CommaJoin(sorted(rlib2.G_FIELDS))`.
536
537 ``DELETE``
538 ~~~~~~~~~~
539
540 Deletes a node group.
541
542 It supports the ``dry-run`` argument.
543
544 Job result:
545
546 .. opcode_result:: OP_GROUP_REMOVE
547
548
549 ``/2/groups/[group_name]/modify``
550 +++++++++++++++++++++++++++++++++
551
552 Modifies the parameters of a node group.
553
554 Supports the following commands: ``PUT``.
555
556 ``PUT``
557 ~~~~~~~
558
559 Returns a job ID.
560
561 Body parameters:
562
563 .. opcode_params:: OP_GROUP_SET_PARAMS
564    :exclude: group_name
565
566 Job result:
567
568 .. opcode_result:: OP_GROUP_SET_PARAMS
569
570
571 ``/2/groups/[group_name]/rename``
572 +++++++++++++++++++++++++++++++++
573
574 Renames a node group.
575
576 Supports the following commands: ``PUT``.
577
578 ``PUT``
579 ~~~~~~~
580
581 Returns a job ID.
582
583 Body parameters:
584
585 .. opcode_params:: OP_GROUP_RENAME
586    :exclude: group_name
587
588 Job result:
589
590 .. opcode_result:: OP_GROUP_RENAME
591
592
593 ``/2/groups/[group_name]/assign-nodes``
594 +++++++++++++++++++++++++++++++++++++++
595
596 Assigns nodes to a group.
597
598 Supports the following commands: ``PUT``.
599
600 ``PUT``
601 ~~~~~~~
602
603 Returns a job ID. It supports the ``dry-run`` and ``force`` arguments.
604
605 Body parameters:
606
607 .. opcode_params:: OP_GROUP_ASSIGN_NODES
608    :exclude: group_name, force, dry_run
609
610 Job result:
611
612 .. opcode_result:: OP_GROUP_ASSIGN_NODES
613
614
615 ``/2/groups/[group_name]/tags``
616 +++++++++++++++++++++++++++++++
617
618 Manages per-nodegroup tags.
619
620 Supports the following commands: ``GET``, ``PUT``, ``DELETE``.
621
622 ``GET``
623 ~~~~~~~
624
625 Returns a list of tags.
626
627 Example::
628
629     ["tag1", "tag2", "tag3"]
630
631 ``PUT``
632 ~~~~~~~
633
634 Add a set of tags.
635
636 The request as a list of strings should be ``PUT`` to this URI. The
637 result will be a job id.
638
639 It supports the ``dry-run`` argument.
640
641
642 ``DELETE``
643 ~~~~~~~~~~
644
645 Delete a tag.
646
647 In order to delete a set of tags, the DELETE request should be addressed
648 to URI like::
649
650     /tags?tag=[tag]&tag=[tag]
651
652 It supports the ``dry-run`` argument.
653
654
655 ``/2/networks``
656 +++++++++++++++
657
658 The networks resource.
659
660 It supports the following commands: ``GET``, ``POST``.
661
662 ``GET``
663 ~~~~~~~
664
665 Returns a list of all existing networks.
666
667 Example::
668
669     [
670       {
671         "name": "network1",
672         "uri": "\/2\/networks\/network1"
673       },
674       {
675         "name": "network2",
676         "uri": "\/2\/networks\/network2"
677       }
678     ]
679
680 If the optional bool *bulk* argument is provided and set to a true value
681 (i.e ``?bulk=1``), the output contains detailed information about networks
682 as a list.
683
684 Returned fields: :pyeval:`utils.CommaJoin(sorted(rlib2.NET_FIELDS))`.
685
686 Example::
687
688     [
689       {
690         'external_reservations': '10.0.0.0, 10.0.0.1, 10.0.0.15',
691         'free_count': 13,
692         'gateway': '10.0.0.1',
693         'gateway6': None,
694         'group_list': ['default(bridged, prv0)'],
695         'inst_list': [],
696         'mac_prefix': None,
697         'map': 'XX.............X',
698         'name': 'nat',
699         'network': '10.0.0.0/28',
700         'network6': None,
701         'reserved_count': 3,
702         'tags': ['nfdhcpd'],
703         …
704       },
705       …
706     ]
707
708 ``POST``
709 ~~~~~~~~
710
711 Creates a network.
712
713 If the optional bool *dry-run* argument is provided, the job will not be
714 actually executed, only the pre-execution checks will be done.
715
716 Returns: a job ID that can be used later for polling.
717
718 Body parameters:
719
720 .. opcode_params:: OP_NETWORK_ADD
721
722 Job result:
723
724 .. opcode_result:: OP_NETWORK_ADD
725
726
727 ``/2/networks/[network_name]``
728 ++++++++++++++++++++++++++++++
729
730 Returns information about a network.
731
732 It supports the following commands: ``GET``, ``DELETE``.
733
734 ``GET``
735 ~~~~~~~
736
737 Returns information about a network, similar to the bulk output from
738 the network list.
739
740 Returned fields: :pyeval:`utils.CommaJoin(sorted(rlib2.NET_FIELDS))`.
741
742 ``DELETE``
743 ~~~~~~~~~~
744
745 Deletes a network.
746
747 It supports the ``dry-run`` argument.
748
749 Job result:
750
751 .. opcode_result:: OP_NETWORK_REMOVE
752
753
754 ``/2/networks/[network_name]/modify``
755 +++++++++++++++++++++++++++++++++++++
756
757 Modifies the parameters of a network.
758
759 Supports the following commands: ``PUT``.
760
761 ``PUT``
762 ~~~~~~~
763
764 Returns a job ID.
765
766 Body parameters:
767
768 .. opcode_params:: OP_NETWORK_SET_PARAMS
769
770 Job result:
771
772 .. opcode_result:: OP_NETWORK_SET_PARAMS
773
774
775 ``/2/networks/[network_name]/connect``
776 ++++++++++++++++++++++++++++++++++++++
777
778 Connects a network to a nodegroup.
779
780 Supports the following commands: ``PUT``.
781
782 ``PUT``
783 ~~~~~~~
784
785 Returns a job ID. It supports the ``dry-run`` arguments.
786
787 Body parameters:
788
789 .. opcode_params:: OP_NETWORK_CONNECT
790
791 Job result:
792
793 .. opcode_result:: OP_NETWORK_CONNECT
794
795
796 ``/2/networks/[network_name]/disconnect``
797 +++++++++++++++++++++++++++++++++++++++++
798
799 Disonnects a network from a nodegroup.
800
801 Supports the following commands: ``PUT``.
802
803 ``PUT``
804 ~~~~~~~
805
806 Returns a job ID. It supports the ``dry-run`` arguments.
807
808 Body parameters:
809
810 .. opcode_params:: OP_NETWORK_DISCONNECT
811
812 Job result:
813
814 .. opcode_result:: OP_NETWORK_DISCONNECT
815
816
817 ``/2/networks/[network_name]/tags``
818 +++++++++++++++++++++++++++++++++++
819
820 Manages per-network tags.
821
822 Supports the following commands: ``GET``, ``PUT``, ``DELETE``.
823
824 ``GET``
825 ~~~~~~~
826
827 Returns a list of tags.
828
829 Example::
830
831     ["tag1", "tag2", "tag3"]
832
833 ``PUT``
834 ~~~~~~~
835
836 Add a set of tags.
837
838 The request as a list of strings should be ``PUT`` to this URI. The
839 result will be a job id.
840
841 It supports the ``dry-run`` argument.
842
843
844 ``DELETE``
845 ~~~~~~~~~~
846
847 Delete a tag.
848
849 In order to delete a set of tags, the DELETE request should be addressed
850 to URI like::
851
852     /tags?tag=[tag]&tag=[tag]
853
854 It supports the ``dry-run`` argument.
855
856
857 ``/2/instances-multi-alloc``
858 ++++++++++++++++++++++++++++
859
860 Tries to allocate multiple instances.
861
862 It supports the following commands: ``POST``
863
864 ``POST``
865 ~~~~~~~~
866
867 The parameters:
868
869 .. opcode_params:: OP_INSTANCE_MULTI_ALLOC
870
871 Job result:
872
873 .. opcode_result:: OP_INSTANCE_MULTI_ALLOC
874
875
876 ``/2/instances``
877 ++++++++++++++++
878
879 The instances resource.
880
881 It supports the following commands: ``GET``, ``POST``.
882
883 ``GET``
884 ~~~~~~~
885
886 Returns a list of all available instances.
887
888 Example::
889
890     [
891       {
892         "name": "web.example.com",
893         "uri": "\/instances\/web.example.com"
894       },
895       {
896         "name": "mail.example.com",
897         "uri": "\/instances\/mail.example.com"
898       }
899     ]
900
901 If the optional bool *bulk* argument is provided and set to a true value
902 (i.e ``?bulk=1``), the output contains detailed information about
903 instances as a list.
904
905 Returned fields: :pyeval:`utils.CommaJoin(sorted(rlib2.I_FIELDS))`.
906
907 Example::
908
909     [
910       {
911         "status": "running",
912         "disk_usage": 20480,
913         "nic.bridges": [
914           "xen-br0"
915         ],
916         "name": "web.example.com",
917         "tags": ["tag1", "tag2"],
918         "beparams": {
919           "vcpus": 2,
920           "memory": 512
921         },
922         "disk.sizes": [
923           20480
924         ],
925         "pnode": "node1.example.com",
926         "nic.macs": ["01:23:45:67:89:01"],
927         "snodes": ["node2.example.com"],
928         "disk_template": "drbd",
929         "admin_state": true,
930         "os": "debian-etch",
931         "oper_state": true,
932         …
933       },
934       …
935     ]
936
937
938 ``POST``
939 ~~~~~~~~
940
941 Creates an instance.
942
943 If the optional bool *dry-run* argument is provided, the job will not be
944 actually executed, only the pre-execution checks will be done. Query-ing
945 the job result will return, in both dry-run and normal case, the list of
946 nodes selected for the instance.
947
948 Returns: a job ID that can be used later for polling.
949
950 Body parameters:
951
952 ``__version__`` (int, required)
953   Must be ``1`` (older Ganeti versions used a different format for
954   instance creation requests, version ``0``, but that format is no
955   longer supported)
956
957 .. opcode_params:: OP_INSTANCE_CREATE
958
959 Earlier versions used parameters named ``name`` and ``os``. These have
960 been replaced by ``instance_name`` and ``os_type`` to match the
961 underlying opcode. The old names can still be used.
962
963 Job result:
964
965 .. opcode_result:: OP_INSTANCE_CREATE
966
967
968 ``/2/instances/[instance_name]``
969 ++++++++++++++++++++++++++++++++
970
971 Instance-specific resource.
972
973 It supports the following commands: ``GET``, ``DELETE``.
974
975 ``GET``
976 ~~~~~~~
977
978 Returns information about an instance, similar to the bulk output from
979 the instance list.
980
981 Returned fields: :pyeval:`utils.CommaJoin(sorted(rlib2.I_FIELDS))`.
982
983 ``DELETE``
984 ~~~~~~~~~~
985
986 Deletes an instance.
987
988 It supports the ``dry-run`` argument.
989
990 Job result:
991
992 .. opcode_result:: OP_INSTANCE_REMOVE
993
994
995 ``/2/instances/[instance_name]/info``
996 +++++++++++++++++++++++++++++++++++++++
997
998 It supports the following commands: ``GET``.
999
1000 ``GET``
1001 ~~~~~~~
1002
1003 Requests detailed information about the instance. An optional parameter,
1004 ``static`` (bool), can be set to return only static information from the
1005 configuration without querying the instance's nodes. The result will be
1006 a job id.
1007
1008 Job result:
1009
1010 .. opcode_result:: OP_INSTANCE_QUERY_DATA
1011
1012
1013 ``/2/instances/[instance_name]/reboot``
1014 +++++++++++++++++++++++++++++++++++++++
1015
1016 Reboots URI for an instance.
1017
1018 It supports the following commands: ``POST``.
1019
1020 ``POST``
1021 ~~~~~~~~
1022
1023 Reboots the instance.
1024
1025 The URI takes optional ``type=soft|hard|full`` and
1026 ``ignore_secondaries=0|1`` parameters.
1027
1028 ``type`` defines the reboot type. ``soft`` is just a normal reboot,
1029 without terminating the hypervisor. ``hard`` means full shutdown
1030 (including terminating the hypervisor process) and startup again.
1031 ``full`` is like ``hard`` but also recreates the configuration from
1032 ground up as if you would have done a ``gnt-instance shutdown`` and
1033 ``gnt-instance start`` on it.
1034
1035 ``ignore_secondaries`` is a bool argument indicating if we start the
1036 instance even if secondary disks are failing.
1037
1038 It supports the ``dry-run`` argument.
1039
1040 Job result:
1041
1042 .. opcode_result:: OP_INSTANCE_REBOOT
1043
1044
1045 ``/2/instances/[instance_name]/shutdown``
1046 +++++++++++++++++++++++++++++++++++++++++
1047
1048 Instance shutdown URI.
1049
1050 It supports the following commands: ``PUT``.
1051
1052 ``PUT``
1053 ~~~~~~~
1054
1055 Shutdowns an instance.
1056
1057 It supports the ``dry-run`` argument.
1058
1059 .. opcode_params:: OP_INSTANCE_SHUTDOWN
1060    :exclude: instance_name, dry_run
1061
1062 Job result:
1063
1064 .. opcode_result:: OP_INSTANCE_SHUTDOWN
1065
1066
1067 ``/2/instances/[instance_name]/startup``
1068 ++++++++++++++++++++++++++++++++++++++++
1069
1070 Instance startup URI.
1071
1072 It supports the following commands: ``PUT``.
1073
1074 ``PUT``
1075 ~~~~~~~
1076
1077 Startup an instance.
1078
1079 The URI takes an optional ``force=1|0`` parameter to start the
1080 instance even if secondary disks are failing.
1081
1082 It supports the ``dry-run`` argument.
1083
1084 Job result:
1085
1086 .. opcode_result:: OP_INSTANCE_STARTUP
1087
1088
1089 ``/2/instances/[instance_name]/reinstall``
1090 ++++++++++++++++++++++++++++++++++++++++++++++
1091
1092 Installs the operating system again.
1093
1094 It supports the following commands: ``POST``.
1095
1096 ``POST``
1097 ~~~~~~~~
1098
1099 Returns a job ID.
1100
1101 Body parameters:
1102
1103 ``os`` (string, required)
1104   Instance operating system.
1105 ``start`` (bool, defaults to true)
1106   Whether to start instance after reinstallation.
1107 ``osparams`` (dict)
1108   Dictionary with (temporary) OS parameters.
1109
1110 For backwards compatbility, this resource also takes the query
1111 parameters ``os`` (OS template name) and ``nostartup`` (bool). New
1112 clients should use the body parameters.
1113
1114
1115 ``/2/instances/[instance_name]/replace-disks``
1116 ++++++++++++++++++++++++++++++++++++++++++++++
1117
1118 Replaces disks on an instance.
1119
1120 It supports the following commands: ``POST``.
1121
1122 ``POST``
1123 ~~~~~~~~
1124
1125 Returns a job ID.
1126
1127 Body parameters:
1128
1129 .. opcode_params:: OP_INSTANCE_REPLACE_DISKS
1130    :exclude: instance_name
1131
1132 Ganeti 2.4 and below used query parameters. Those are deprecated and
1133 should no longer be used.
1134
1135 Job result:
1136
1137 .. opcode_result:: OP_INSTANCE_REPLACE_DISKS
1138
1139
1140 ``/2/instances/[instance_name]/activate-disks``
1141 +++++++++++++++++++++++++++++++++++++++++++++++
1142
1143 Activate disks on an instance.
1144
1145 It supports the following commands: ``PUT``.
1146
1147 ``PUT``
1148 ~~~~~~~
1149
1150 Takes the bool parameter ``ignore_size``. When set ignore the recorded
1151 size (useful for forcing activation when recorded size is wrong).
1152
1153 Job result:
1154
1155 .. opcode_result:: OP_INSTANCE_ACTIVATE_DISKS
1156
1157
1158 ``/2/instances/[instance_name]/deactivate-disks``
1159 +++++++++++++++++++++++++++++++++++++++++++++++++
1160
1161 Deactivate disks on an instance.
1162
1163 It supports the following commands: ``PUT``.
1164
1165 ``PUT``
1166 ~~~~~~~
1167
1168 Takes no parameters.
1169
1170 Job result:
1171
1172 .. opcode_result:: OP_INSTANCE_DEACTIVATE_DISKS
1173
1174
1175 ``/2/instances/[instance_name]/recreate-disks``
1176 +++++++++++++++++++++++++++++++++++++++++++++++++
1177
1178 Recreate disks of an instance. Supports the following commands:
1179 ``POST``.
1180
1181 ``POST``
1182 ~~~~~~~~
1183
1184 Returns a job ID.
1185
1186 Body parameters:
1187
1188 .. opcode_params:: OP_INSTANCE_RECREATE_DISKS
1189    :exclude: instance_name
1190
1191 Job result:
1192
1193 .. opcode_result:: OP_INSTANCE_RECREATE_DISKS
1194
1195
1196 ``/2/instances/[instance_name]/disk/[disk_index]/grow``
1197 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
1198
1199 Grows one disk of an instance.
1200
1201 Supports the following commands: ``POST``.
1202
1203 ``POST``
1204 ~~~~~~~~
1205
1206 Returns a job ID.
1207
1208 Body parameters:
1209
1210 .. opcode_params:: OP_INSTANCE_GROW_DISK
1211    :exclude: instance_name, disk
1212
1213 Job result:
1214
1215 .. opcode_result:: OP_INSTANCE_GROW_DISK
1216
1217
1218 ``/2/instances/[instance_name]/prepare-export``
1219 +++++++++++++++++++++++++++++++++++++++++++++++++
1220
1221 Prepares an export of an instance.
1222
1223 It supports the following commands: ``PUT``.
1224
1225 ``PUT``
1226 ~~~~~~~
1227
1228 Takes one parameter, ``mode``, for the export mode. Returns a job ID.
1229
1230 Job result:
1231
1232 .. opcode_result:: OP_BACKUP_PREPARE
1233
1234
1235 ``/2/instances/[instance_name]/export``
1236 +++++++++++++++++++++++++++++++++++++++++++++++++
1237
1238 Exports an instance.
1239
1240 It supports the following commands: ``PUT``.
1241
1242 ``PUT``
1243 ~~~~~~~
1244
1245 Returns a job ID.
1246
1247 Body parameters:
1248
1249 .. opcode_params:: OP_BACKUP_EXPORT
1250    :exclude: instance_name
1251    :alias: target_node=destination
1252
1253 Job result:
1254
1255 .. opcode_result:: OP_BACKUP_EXPORT
1256
1257
1258 ``/2/instances/[instance_name]/migrate``
1259 ++++++++++++++++++++++++++++++++++++++++
1260
1261 Migrates an instance.
1262
1263 Supports the following commands: ``PUT``.
1264
1265 ``PUT``
1266 ~~~~~~~
1267
1268 Returns a job ID.
1269
1270 Body parameters:
1271
1272 .. opcode_params:: OP_INSTANCE_MIGRATE
1273    :exclude: instance_name, live
1274
1275 Job result:
1276
1277 .. opcode_result:: OP_INSTANCE_MIGRATE
1278
1279
1280 ``/2/instances/[instance_name]/failover``
1281 +++++++++++++++++++++++++++++++++++++++++
1282
1283 Does a failover of an instance.
1284
1285 Supports the following commands: ``PUT``.
1286
1287 ``PUT``
1288 ~~~~~~~
1289
1290 Returns a job ID.
1291
1292 Body parameters:
1293
1294 .. opcode_params:: OP_INSTANCE_FAILOVER
1295    :exclude: instance_name
1296
1297 Job result:
1298
1299 .. opcode_result:: OP_INSTANCE_FAILOVER
1300
1301
1302 ``/2/instances/[instance_name]/rename``
1303 ++++++++++++++++++++++++++++++++++++++++
1304
1305 Renames an instance.
1306
1307 Supports the following commands: ``PUT``.
1308
1309 ``PUT``
1310 ~~~~~~~
1311
1312 Returns a job ID.
1313
1314 Body parameters:
1315
1316 .. opcode_params:: OP_INSTANCE_RENAME
1317    :exclude: instance_name
1318
1319 Job result:
1320
1321 .. opcode_result:: OP_INSTANCE_RENAME
1322
1323
1324 ``/2/instances/[instance_name]/modify``
1325 ++++++++++++++++++++++++++++++++++++++++
1326
1327 Modifies an instance.
1328
1329 Supports the following commands: ``PUT``.
1330
1331 ``PUT``
1332 ~~~~~~~
1333
1334 Returns a job ID.
1335
1336 Body parameters:
1337
1338 .. opcode_params:: OP_INSTANCE_SET_PARAMS
1339    :exclude: instance_name
1340
1341 Job result:
1342
1343 .. opcode_result:: OP_INSTANCE_SET_PARAMS
1344
1345
1346 ``/2/instances/[instance_name]/console``
1347 ++++++++++++++++++++++++++++++++++++++++
1348
1349 Request information for connecting to instance's console.
1350
1351 .. pyassert::
1352
1353   not (hasattr(rlib2.R_2_instances_name_console, "PUT") or
1354        hasattr(rlib2.R_2_instances_name_console, "POST") or
1355        hasattr(rlib2.R_2_instances_name_console, "DELETE"))
1356
1357 Supports the following commands: ``GET``. Requires authentication with
1358 one of the following options:
1359 :pyeval:`utils.CommaJoin(rlib2.R_2_instances_name_console.GET_ACCESS)`.
1360
1361 ``GET``
1362 ~~~~~~~
1363
1364 Returns a dictionary containing information about the instance's
1365 console. Contained keys:
1366
1367 .. pyassert::
1368
1369    constants.CONS_ALL == frozenset([
1370      constants.CONS_MESSAGE,
1371      constants.CONS_SSH,
1372      constants.CONS_VNC,
1373      constants.CONS_SPICE,
1374      ])
1375
1376 .. pyassert::
1377
1378   frozenset(objects.InstanceConsole.GetAllSlots()) == frozenset([
1379     "command",
1380     "display",
1381     "host",
1382     "instance",
1383     "kind",
1384     "message",
1385     "port",
1386     "user",
1387     ])
1388
1389
1390 ``instance``
1391   Instance name
1392 ``kind``
1393   Console type, one of :pyeval:`constants.CONS_SSH`,
1394   :pyeval:`constants.CONS_VNC`, :pyeval:`constants.CONS_SPICE`
1395   or :pyeval:`constants.CONS_MESSAGE`
1396 ``message``
1397   Message to display (:pyeval:`constants.CONS_MESSAGE` type only)
1398 ``host``
1399   Host to connect to (:pyeval:`constants.CONS_SSH`,
1400   :pyeval:`constants.CONS_VNC` or :pyeval:`constants.CONS_SPICE` only)
1401 ``port``
1402   TCP port to connect to (:pyeval:`constants.CONS_VNC` or
1403   :pyeval:`constants.CONS_SPICE` only)
1404 ``user``
1405   Username to use (:pyeval:`constants.CONS_SSH` only)
1406 ``command``
1407   Command to execute on machine (:pyeval:`constants.CONS_SSH` only)
1408 ``display``
1409   VNC display number (:pyeval:`constants.CONS_VNC` only)
1410
1411
1412 ``/2/instances/[instance_name]/tags``
1413 +++++++++++++++++++++++++++++++++++++
1414
1415 Manages per-instance tags.
1416
1417 It supports the following commands: ``GET``, ``PUT``, ``DELETE``.
1418
1419 ``GET``
1420 ~~~~~~~
1421
1422 Returns a list of tags.
1423
1424 Example::
1425
1426     ["tag1", "tag2", "tag3"]
1427
1428 ``PUT``
1429 ~~~~~~~
1430
1431 Add a set of tags.
1432
1433 The request as a list of strings should be ``PUT`` to this URI. The
1434 result will be a job id.
1435
1436 It supports the ``dry-run`` argument.
1437
1438
1439 ``DELETE``
1440 ~~~~~~~~~~
1441
1442 Delete a tag.
1443
1444 In order to delete a set of tags, the DELETE request should be addressed
1445 to URI like::
1446
1447     /tags?tag=[tag]&tag=[tag]
1448
1449 It supports the ``dry-run`` argument.
1450
1451
1452 ``/2/jobs``
1453 +++++++++++
1454
1455 The ``/2/jobs`` resource.
1456
1457 It supports the following commands: ``GET``.
1458
1459 ``GET``
1460 ~~~~~~~
1461
1462 Returns a dictionary of jobs.
1463
1464 Returns: a dictionary with jobs id and uri.
1465
1466 If the optional bool *bulk* argument is provided and set to a true value
1467 (i.e. ``?bulk=1``), the output contains detailed information about jobs
1468 as a list.
1469
1470 Returned fields for bulk requests (unlike other bulk requests, these
1471 fields are not the same as for per-job requests):
1472 :pyeval:`utils.CommaJoin(sorted(rlib2.J_FIELDS_BULK))`.
1473
1474 ``/2/jobs/[job_id]``
1475 ++++++++++++++++++++
1476
1477
1478 Individual job URI.
1479
1480 It supports the following commands: ``GET``, ``DELETE``.
1481
1482 ``GET``
1483 ~~~~~~~
1484
1485 Returns a dictionary with job parameters, containing the fields
1486 :pyeval:`utils.CommaJoin(sorted(rlib2.J_FIELDS))`.
1487
1488 The result includes:
1489
1490 - id: job ID as a number
1491 - status: current job status as a string
1492 - ops: involved OpCodes as a list of dictionaries for each opcodes in
1493   the job
1494 - opstatus: OpCodes status as a list
1495 - opresult: OpCodes results as a list
1496
1497 For a successful opcode, the ``opresult`` field corresponding to it will
1498 contain the raw result from its :term:`LogicalUnit`. In case an opcode
1499 has failed, its element in the opresult list will be a list of two
1500 elements:
1501
1502 - first element the error type (the Ganeti internal error name)
1503 - second element a list of either one or two elements:
1504
1505   - the first element is the textual error description
1506   - the second element, if any, will hold an error classification
1507
1508 The error classification is most useful for the ``OpPrereqError``
1509 error type - these errors happen before the OpCode has started
1510 executing, so it's possible to retry the OpCode without side
1511 effects. But whether it make sense to retry depends on the error
1512 classification:
1513
1514 .. pyassert::
1515
1516    errors.ECODE_ALL == set([errors.ECODE_RESOLVER, errors.ECODE_NORES,
1517      errors.ECODE_INVAL, errors.ECODE_STATE, errors.ECODE_NOENT,
1518      errors.ECODE_EXISTS, errors.ECODE_NOTUNIQUE, errors.ECODE_FAULT,
1519      errors.ECODE_ENVIRON, errors.ECODE_TEMP_NORES])
1520
1521 :pyeval:`errors.ECODE_RESOLVER`
1522   Resolver errors. This usually means that a name doesn't exist in DNS,
1523   so if it's a case of slow DNS propagation the operation can be retried
1524   later.
1525
1526 :pyeval:`errors.ECODE_NORES`
1527   Not enough resources (iallocator failure, disk space, memory,
1528   etc.). If the resources on the cluster increase, the operation might
1529   succeed.
1530
1531 :pyeval:`errors.ECODE_TEMP_NORES`
1532   Simliar to :pyeval:`errors.ECODE_NORES`, but indicating the operation
1533   should be attempted again after some time.
1534
1535 :pyeval:`errors.ECODE_INVAL`
1536   Wrong arguments (at syntax level). The operation will not ever be
1537   accepted unless the arguments change.
1538
1539 :pyeval:`errors.ECODE_STATE`
1540   Wrong entity state. For example, live migration has been requested for
1541   a down instance, or instance creation on an offline node. The
1542   operation can be retried once the resource has changed state.
1543
1544 :pyeval:`errors.ECODE_NOENT`
1545   Entity not found. For example, information has been requested for an
1546   unknown instance.
1547
1548 :pyeval:`errors.ECODE_EXISTS`
1549   Entity already exists. For example, instance creation has been
1550   requested for an already-existing instance.
1551
1552 :pyeval:`errors.ECODE_NOTUNIQUE`
1553   Resource not unique (e.g. MAC or IP duplication).
1554
1555 :pyeval:`errors.ECODE_FAULT`
1556   Internal cluster error. For example, a node is unreachable but not set
1557   offline, or the ganeti node daemons are not working, etc. A
1558   ``gnt-cluster verify`` should be run.
1559
1560 :pyeval:`errors.ECODE_ENVIRON`
1561   Environment error (e.g. node disk error). A ``gnt-cluster verify``
1562   should be run.
1563
1564 Note that in the above list, by entity we refer to a node or instance,
1565 while by a resource we refer to an instance's disk, or NIC, etc.
1566
1567
1568 ``DELETE``
1569 ~~~~~~~~~~
1570
1571 Cancel a not-yet-started job.
1572
1573
1574 ``/2/jobs/[job_id]/wait``
1575 +++++++++++++++++++++++++
1576
1577 ``GET``
1578 ~~~~~~~
1579
1580 Waits for changes on a job. Takes the following body parameters in a
1581 dict:
1582
1583 ``fields``
1584   The job fields on which to watch for changes
1585
1586 ``previous_job_info``
1587   Previously received field values or None if not yet available
1588
1589 ``previous_log_serial``
1590   Highest log serial number received so far or None if not yet
1591   available
1592
1593 Returns None if no changes have been detected and a dict with two keys,
1594 ``job_info`` and ``log_entries`` otherwise.
1595
1596
1597 ``/2/nodes``
1598 ++++++++++++
1599
1600 Nodes resource.
1601
1602 It supports the following commands: ``GET``.
1603
1604 ``GET``
1605 ~~~~~~~
1606
1607 Returns a list of all nodes.
1608
1609 Example::
1610
1611     [
1612       {
1613         "id": "node1.example.com",
1614         "uri": "\/nodes\/node1.example.com"
1615       },
1616       {
1617         "id": "node2.example.com",
1618         "uri": "\/nodes\/node2.example.com"
1619       }
1620     ]
1621
1622 If the optional bool *bulk* argument is provided and set to a true value
1623 (i.e ``?bulk=1``), the output contains detailed information about nodes
1624 as a list.
1625
1626 Returned fields: :pyeval:`utils.CommaJoin(sorted(rlib2.N_FIELDS))`.
1627
1628 Example::
1629
1630     [
1631       {
1632         "pinst_cnt": 1,
1633         "mfree": 31280,
1634         "mtotal": 32763,
1635         "name": "www.example.com",
1636         "tags": [],
1637         "mnode": 512,
1638         "dtotal": 5246208,
1639         "sinst_cnt": 2,
1640         "dfree": 5171712,
1641         "offline": false,
1642         …
1643       },
1644       …
1645     ]
1646
1647 ``/2/nodes/[node_name]``
1648 +++++++++++++++++++++++++++++++++
1649
1650 Returns information about a node.
1651
1652 It supports the following commands: ``GET``.
1653
1654 Returned fields: :pyeval:`utils.CommaJoin(sorted(rlib2.N_FIELDS))`.
1655
1656 ``/2/nodes/[node_name]/powercycle``
1657 +++++++++++++++++++++++++++++++++++
1658
1659 Powercycles a node. Supports the following commands: ``POST``.
1660
1661 ``POST``
1662 ~~~~~~~~
1663
1664 Returns a job ID.
1665
1666 Job result:
1667
1668 .. opcode_result:: OP_NODE_POWERCYCLE
1669
1670
1671 ``/2/nodes/[node_name]/evacuate``
1672 +++++++++++++++++++++++++++++++++
1673
1674 Evacuates instances off a node.
1675
1676 It supports the following commands: ``POST``.
1677
1678 ``POST``
1679 ~~~~~~~~
1680
1681 Returns a job ID. The result of the job will contain the IDs of the
1682 individual jobs submitted to evacuate the node.
1683
1684 Body parameters:
1685
1686 .. opcode_params:: OP_NODE_EVACUATE
1687    :exclude: nodes
1688
1689 Up to and including Ganeti 2.4 query arguments were used. Those are no
1690 longer supported. The new request can be detected by the presence of the
1691 :pyeval:`rlib2._NODE_EVAC_RES1` feature string.
1692
1693 Job result:
1694
1695 .. opcode_result:: OP_NODE_EVACUATE
1696
1697
1698 ``/2/nodes/[node_name]/migrate``
1699 +++++++++++++++++++++++++++++++++
1700
1701 Migrates all primary instances from a node.
1702
1703 It supports the following commands: ``POST``.
1704
1705 ``POST``
1706 ~~~~~~~~
1707
1708 If no mode is explicitly specified, each instances' hypervisor default
1709 migration mode will be used. Body parameters:
1710
1711 .. opcode_params:: OP_NODE_MIGRATE
1712    :exclude: node_name
1713
1714 The query arguments used up to and including Ganeti 2.4 are deprecated
1715 and should no longer be used. The new request format can be detected by
1716 the presence of the :pyeval:`rlib2._NODE_MIGRATE_REQV1` feature string.
1717
1718 Job result:
1719
1720 .. opcode_result:: OP_NODE_MIGRATE
1721
1722
1723 ``/2/nodes/[node_name]/role``
1724 +++++++++++++++++++++++++++++
1725
1726 Manages node role.
1727
1728 It supports the following commands: ``GET``, ``PUT``.
1729
1730 The role is always one of the following:
1731
1732   - drained
1733   - master-candidate
1734   - offline
1735   - regular
1736
1737 Note that the 'master' role is a special, and currently it can't be
1738 modified via RAPI, only via the command line (``gnt-cluster
1739 master-failover``).
1740
1741 ``GET``
1742 ~~~~~~~
1743
1744 Returns the current node role.
1745
1746 Example::
1747
1748     "master-candidate"
1749
1750 ``PUT``
1751 ~~~~~~~
1752
1753 Change the node role.
1754
1755 The request is a string which should be PUT to this URI. The result will
1756 be a job id.
1757
1758 It supports the bool ``force`` argument.
1759
1760 Job result:
1761
1762 .. opcode_result:: OP_NODE_SET_PARAMS
1763
1764
1765 ``/2/nodes/[node_name]/modify``
1766 +++++++++++++++++++++++++++++++
1767
1768 Modifies the parameters of a node. Supports the following commands:
1769 ``POST``.
1770
1771 ``POST``
1772 ~~~~~~~~
1773
1774 Returns a job ID.
1775
1776 Body parameters:
1777
1778 .. opcode_params:: OP_NODE_SET_PARAMS
1779    :exclude: node_name
1780
1781 Job result:
1782
1783 .. opcode_result:: OP_NODE_SET_PARAMS
1784
1785
1786 ``/2/nodes/[node_name]/storage``
1787 ++++++++++++++++++++++++++++++++
1788
1789 Manages storage units on the node.
1790
1791 ``GET``
1792 ~~~~~~~
1793
1794 .. pyassert::
1795
1796    constants.VALID_STORAGE_TYPES == set([constants.ST_FILE,
1797                                          constants.ST_LVM_PV,
1798                                          constants.ST_LVM_VG])
1799
1800 Requests a list of storage units on a node. Requires the parameters
1801 ``storage_type`` (one of :pyeval:`constants.ST_FILE`,
1802 :pyeval:`constants.ST_LVM_PV` or :pyeval:`constants.ST_LVM_VG`) and
1803 ``output_fields``. The result will be a job id, using which the result
1804 can be retrieved.
1805
1806 ``/2/nodes/[node_name]/storage/modify``
1807 +++++++++++++++++++++++++++++++++++++++
1808
1809 Modifies storage units on the node.
1810
1811 ``PUT``
1812 ~~~~~~~
1813
1814 Modifies parameters of storage units on the node. Requires the
1815 parameters ``storage_type`` (one of :pyeval:`constants.ST_FILE`,
1816 :pyeval:`constants.ST_LVM_PV` or :pyeval:`constants.ST_LVM_VG`)
1817 and ``name`` (name of the storage unit).  Parameters can be passed
1818 additionally. Currently only :pyeval:`constants.SF_ALLOCATABLE` (bool)
1819 is supported. The result will be a job id.
1820
1821 Job result:
1822
1823 .. opcode_result:: OP_NODE_MODIFY_STORAGE
1824
1825
1826 ``/2/nodes/[node_name]/storage/repair``
1827 +++++++++++++++++++++++++++++++++++++++
1828
1829 Repairs a storage unit on the node.
1830
1831 ``PUT``
1832 ~~~~~~~
1833
1834 .. pyassert::
1835
1836    constants.VALID_STORAGE_OPERATIONS == {
1837     constants.ST_LVM_VG: set([constants.SO_FIX_CONSISTENCY]),
1838     }
1839
1840 Repairs a storage unit on the node. Requires the parameters
1841 ``storage_type`` (currently only :pyeval:`constants.ST_LVM_VG` can be
1842 repaired) and ``name`` (name of the storage unit). The result will be a
1843 job id.
1844
1845 Job result:
1846
1847 .. opcode_result:: OP_REPAIR_NODE_STORAGE
1848
1849
1850 ``/2/nodes/[node_name]/tags``
1851 +++++++++++++++++++++++++++++
1852
1853 Manages per-node tags.
1854
1855 It supports the following commands: ``GET``, ``PUT``, ``DELETE``.
1856
1857 ``GET``
1858 ~~~~~~~
1859
1860 Returns a list of tags.
1861
1862 Example::
1863
1864     ["tag1", "tag2", "tag3"]
1865
1866 ``PUT``
1867 ~~~~~~~
1868
1869 Add a set of tags.
1870
1871 The request as a list of strings should be PUT to this URI. The result
1872 will be a job id.
1873
1874 It supports the ``dry-run`` argument.
1875
1876 ``DELETE``
1877 ~~~~~~~~~~
1878
1879 Deletes tags.
1880
1881 In order to delete a set of tags, the DELETE request should be addressed
1882 to URI like::
1883
1884     /tags?tag=[tag]&tag=[tag]
1885
1886 It supports the ``dry-run`` argument.
1887
1888
1889 ``/2/query/[resource]``
1890 +++++++++++++++++++++++
1891
1892 Requests resource information. Available fields can be found in man
1893 pages and using ``/2/query/[resource]/fields``. The resource is one of
1894 :pyeval:`utils.CommaJoin(constants.QR_VIA_RAPI)`. See the :doc:`query2
1895 design document <design-query2>` for more details.
1896
1897 .. pyassert::
1898
1899   (rlib2.R_2_query.GET_ACCESS == rlib2.R_2_query.PUT_ACCESS and
1900    not (hasattr(rlib2.R_2_query, "POST") or
1901         hasattr(rlib2.R_2_query, "DELETE")))
1902
1903 Supports the following commands: ``GET``, ``PUT``. Requires
1904 authentication with one of the following options:
1905 :pyeval:`utils.CommaJoin(rlib2.R_2_query.GET_ACCESS)`.
1906
1907 ``GET``
1908 ~~~~~~~
1909
1910 Returns list of included fields and actual data. Takes a query parameter
1911 named "fields", containing a comma-separated list of field names. Does
1912 not support filtering.
1913
1914 ``PUT``
1915 ~~~~~~~
1916
1917 Returns list of included fields and actual data. The list of requested
1918 fields can either be given as the query parameter "fields" or as a body
1919 parameter with the same name. The optional body parameter "filter" can
1920 be given and must be either ``null`` or a list containing filter
1921 operators.
1922
1923
1924 ``/2/query/[resource]/fields``
1925 ++++++++++++++++++++++++++++++
1926
1927 Request list of available fields for a resource. The resource is one of
1928 :pyeval:`utils.CommaJoin(constants.QR_VIA_RAPI)`. See the
1929 :doc:`query2 design document <design-query2>` for more details.
1930
1931 Supports the following commands: ``GET``.
1932
1933 ``GET``
1934 ~~~~~~~
1935
1936 Returns a list of field descriptions for available fields. Takes an
1937 optional query parameter named "fields", containing a comma-separated
1938 list of field names.
1939
1940
1941 ``/2/os``
1942 +++++++++
1943
1944 OS resource.
1945
1946 It supports the following commands: ``GET``.
1947
1948 ``GET``
1949 ~~~~~~~
1950
1951 Return a list of all OSes.
1952
1953 Can return error 500 in case of a problem. Since this is a costly
1954 operation for Ganeti 2.0, it is not recommended to execute it too often.
1955
1956 Example::
1957
1958     ["debian-etch"]
1959
1960 ``/2/tags``
1961 +++++++++++
1962
1963 Manages cluster tags.
1964
1965 It supports the following commands: ``GET``, ``PUT``, ``DELETE``.
1966
1967 ``GET``
1968 ~~~~~~~
1969
1970 Returns the cluster tags.
1971
1972 Example::
1973
1974     ["tag1", "tag2", "tag3"]
1975
1976 ``PUT``
1977 ~~~~~~~
1978
1979 Adds a set of tags.
1980
1981 The request as a list of strings should be PUT to this URI. The result
1982 will be a job id.
1983
1984 It supports the ``dry-run`` argument.
1985
1986
1987 ``DELETE``
1988 ~~~~~~~~~~
1989
1990 Deletes tags.
1991
1992 In order to delete a set of tags, the DELETE request should be addressed
1993 to URI like::
1994
1995     /tags?tag=[tag]&tag=[tag]
1996
1997 It supports the ``dry-run`` argument.
1998
1999
2000 ``/version``
2001 ++++++++++++
2002
2003 The version resource.
2004
2005 This resource should be used to determine the remote API version and to
2006 adapt clients accordingly.
2007
2008 It supports the following commands: ``GET``.
2009
2010 ``GET``
2011 ~~~~~~~
2012
2013 Returns the remote API version. Ganeti 1.2 returned ``1`` and Ganeti 2.0
2014 returns ``2``.
2015
2016 .. vim: set textwidth=72 :
2017 .. Local Variables:
2018 .. mode: rst
2019 .. fill-column: 72
2020 .. End: