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