Statistics
| Branch: | Tag: | Revision:

root / doc / rapi.rst @ cc67d8eb

History | View | Annotate | Download (37.2 kB)

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
Each line consists of two or three fields separated by whitespace. The
28
first two fields are for username and password. The third field is
29
optional and can be used to specify per-user options. Currently,
30
``write`` is the only option supported and enables the user to execute
31
operations modifying the cluster. Lines starting with the hash sign
32
(``#``) are treated as comments.
33

    
34
Passwords can either be written in clear text or as a hash. Clear text
35
passwords may not start with an opening brace (``{``) or they must be
36
prefixed with ``{cleartext}``. To use the hashed form, get the MD5 hash
37
of the string ``$username:Ganeti Remote API:$password`` (e.g. ``echo -n
38
'jack:Ganeti Remote API:abc123' | openssl md5``) [#pwhash]_ and prefix
39
it with ``{ha1}``. Using the scheme prefix for all passwords is
40
recommended. Scheme prefixes are not case sensitive.
41

    
42
Example::
43

    
44
  # Give Jack and Fred read-only access
45
  jack abc123
46
  fred {cleartext}foo555
47

    
48
  # Give write access to an imaginary instance creation script
49
  autocreator xyz789 write
50

    
51
  # Hashed password for Jessica
52
  jessica {HA1}7046452df2cbb530877058712cf17bd4 write
53

    
54

    
55
.. [#pwhash] Using the MD5 hash of username, realm and password is
56
   described in :rfc:`2617` ("HTTP Authentication"), sections 3.2.2.2
57
   and 3.3. The reason for using it over another algorithm is forward
58
   compatibility. If ``ganeti-rapi`` were to implement HTTP Digest
59
   authentication in the future, the same hash could be used.
60
   In the current version ``ganeti-rapi``'s realm, ``Ganeti Remote
61
   API``, can only be changed by modifying the source code.
62

    
63

    
64
Protocol
65
--------
66

    
67
The protocol used is JSON_ over HTTP designed after the REST_ principle.
68
HTTP Basic authentication as per :rfc:`2617` is supported.
69

    
70
.. _JSON: http://www.json.org/
71
.. _REST: http://en.wikipedia.org/wiki/Representational_State_Transfer
72

    
73
HTTP requests with a body (e.g. ``PUT`` or ``POST``) require the request
74
header ``Content-type`` be set to ``application/json`` (see :rfc:`2616`
75
(HTTP/1.1), section 7.2.1).
76

    
77

    
78
A note on JSON as used by RAPI
79
++++++++++++++++++++++++++++++
80

    
81
JSON_ as used by Ganeti RAPI does not conform to the specification in
82
:rfc:`4627`. Section 2 defines a JSON text to be either an object
83
(``{"key": "value", …}``) or an array (``[1, 2, 3, …]``). In violation
84
of this RAPI uses plain strings (``"master-candidate"``, ``"1234"``) for
85
some requests or responses. Changing this now would likely break
86
existing clients and cause a lot of trouble.
87

    
88
.. highlight:: ruby
89

    
90
Unlike Python's `JSON encoder and decoder
91
<http://docs.python.org/library/json.html>`_, other programming
92
languages or libraries may only provide a strict implementation, not
93
allowing plain values. For those, responses can usually be wrapped in an
94
array whose first element is then used, e.g. the response ``"1234"``
95
becomes ``["1234"]``. This works equally well for more complex values.
96
Example in Ruby::
97

    
98
  require "json"
99

    
100
  # Insert code to get response here
101
  response = "\"1234\""
102

    
103
  decoded = JSON.parse("[#{response}]").first
104

    
105
Short of modifying the encoder to allow encoding to a less strict
106
format, requests will have to be formatted by hand. Newer RAPI requests
107
already use a dictionary as their input data and shouldn't cause any
108
problems.
109

    
110

    
111
PUT or POST?
112
------------
113

    
114
According to :rfc:`2616` the main difference between PUT and POST is
115
that POST can create new resources but PUT can only create the resource
116
the URI was pointing to on the PUT request.
117

    
118
Unfortunately, due to historic reasons, the Ganeti RAPI library is not
119
consistent with this usage, so just use the methods as documented below
120
for each resource.
121

    
122
For more details have a look in the source code at
123
``lib/rapi/rlib2.py``.
124

    
125

    
126
Generic parameter types
127
-----------------------
128

    
129
A few generic refered parameter types and the values they allow.
130

    
131
``bool``
132
++++++++
133

    
134
A boolean option will accept ``1`` or ``0`` as numbers but not
135
i.e. ``True`` or ``False``.
136

    
137
Generic parameters
138
------------------
139

    
140
A few parameter mean the same thing across all resources which implement
141
it.
142

    
143
``bulk``
144
++++++++
145

    
146
Bulk-mode means that for the resources which usually return just a list
147
of child resources (e.g. ``/2/instances`` which returns just instance
148
names), the output will instead contain detailed data for all these
149
subresources. This is more efficient than query-ing the sub-resources
150
themselves.
151

    
152
``dry-run``
153
+++++++++++
154

    
155
The boolean *dry-run* argument, if provided and set, signals to Ganeti
156
that the job should not be executed, only the pre-execution checks will
157
be done.
158

    
159
This is useful in trying to determine (without guarantees though, as in
160
the meantime the cluster state could have changed) if the operation is
161
likely to succeed or at least start executing.
162

    
163
``force``
164
+++++++++++
165

    
166
Force operation to continue even if it will cause the cluster to become
167
inconsistent (e.g. because there are not enough master candidates).
168

    
169
Parameter details
170
-----------------
171

    
172
Some parameters are not straight forward, so we describe them in details
173
here.
174

    
175
.. _rapi-ipolicy:
176

    
177
``ipolicy``
178
+++++++++++
179

    
180
The instance policy specification is a dict with the following fields:
181

    
182
.. pyassert::
183

    
184
  constants.IPOLICY_ALL_KEYS == set([constants.ISPECS_MIN,
185
                                     constants.ISPECS_MAX,
186
                                     constants.ISPECS_STD,
187
                                     constants.IPOLICY_DTS,
188
                                     constants.IPOLICY_VCPU_RATIO,
189
                                     constants.IPOLICY_SPINDLE_RATIO])
190

    
191

    
192
.. pyassert::
193

    
194
  (set(constants.ISPECS_PARAMETER_TYPES.keys()) ==
195
   set([constants.ISPEC_MEM_SIZE,
196
        constants.ISPEC_DISK_SIZE,
197
        constants.ISPEC_DISK_COUNT,
198
        constants.ISPEC_CPU_COUNT,
199
        constants.ISPEC_NIC_COUNT]))
200

    
201
.. |ispec-min| replace:: :pyeval:`constants.ISPECS_MIN`
202
.. |ispec-max| replace:: :pyeval:`constants.ISPECS_MAX`
203
.. |ispec-std| replace:: :pyeval:`constants.ISPECS_STD`
204

    
205

    
206
|ispec-min|, |ispec-max|, |ispec-std|
207
  A sub- `dict` with the following fields, which sets the limit and standard
208
  values of the instances:
209

    
210
  :pyeval:`constants.ISPEC_MEM_SIZE`
211
    The size in MiB of the memory used
212
  :pyeval:`constants.ISPEC_DISK_SIZE`
213
    The size in MiB of the disk used
214
  :pyeval:`constants.ISPEC_DISK_COUNT`
215
    The numbers of disks used
216
  :pyeval:`constants.ISPEC_CPU_COUNT`
217
    The numbers of cpus used
218
  :pyeval:`constants.ISPEC_NIC_COUNT`
219
    The numbers of nics used
220
:pyeval:`constants.IPOLICY_DTS`
221
  A `list` of disk templates allowed for instances using this policy
222
:pyeval:`constants.IPOLICY_VCPU_RATIO`
223
  Maximum ratio of virtual to physical CPUs (`float`)
224
:pyeval:`constants.IPOLICY_SPINDLE_RATIO`
225
  Maximum ratio of instances to their node's ``spindle_count`` (`float`)
226

    
227
Usage examples
228
--------------
229

    
230
You can access the API using your favorite programming language as long
231
as it supports network connections.
232

    
233
Ganeti RAPI client
234
++++++++++++++++++
235

    
236
Ganeti includes a standalone RAPI client, ``lib/rapi/client.py``.
237

    
238
Shell
239
+++++
240

    
241
.. highlight:: sh
242

    
243
Using wget::
244

    
245
   wget -q -O - https://CLUSTERNAME:5080/2/info
246

    
247
or curl::
248

    
249
  curl https://CLUSTERNAME:5080/2/info
250

    
251

    
252
Python
253
++++++
254

    
255
.. highlight:: python
256

    
257
::
258

    
259
  import urllib2
260
  f = urllib2.urlopen('https://CLUSTERNAME:5080/2/info')
261
  print f.read()
262

    
263

    
264
JavaScript
265
++++++++++
266

    
267
.. warning:: While it's possible to use JavaScript, it poses several
268
   potential problems, including browser blocking request due to
269
   non-standard ports or different domain names. Fetching the data on
270
   the webserver is easier.
271

    
272
.. highlight:: javascript
273

    
274
::
275

    
276
  var url = 'https://CLUSTERNAME:5080/2/info';
277
  var info;
278
  var xmlreq = new XMLHttpRequest();
279
  xmlreq.onreadystatechange = function () {
280
    if (xmlreq.readyState != 4) return;
281
    if (xmlreq.status == 200) {
282
      info = eval("(" + xmlreq.responseText + ")");
283
      alert(info);
284
    } else {
285
      alert('Error fetching cluster info');
286
    }
287
    xmlreq = null;
288
  };
289
  xmlreq.open('GET', url, true);
290
  xmlreq.send(null);
291

    
292
Resources
293
---------
294

    
295
.. highlight:: javascript
296

    
297
``/``
298
+++++
299

    
300
The root resource. Has no function, but for legacy reasons the ``GET``
301
method is supported.
302

    
303
``/2``
304
++++++
305

    
306
Has no function, but for legacy reasons the ``GET`` method is supported.
307

    
308
``/2/info``
309
+++++++++++
310

    
311
Cluster information resource.
312

    
313
It supports the following commands: ``GET``.
314

    
315
``GET``
316
~~~~~~~
317

    
318
Returns cluster information.
319

    
320
Example::
321

    
322
  {
323
    "config_version": 2000000,
324
    "name": "cluster",
325
    "software_version": "2.0.0~beta2",
326
    "os_api_version": 10,
327
    "export_version": 0,
328
    "candidate_pool_size": 10,
329
    "enabled_hypervisors": [
330
      "fake"
331
    ],
332
    "hvparams": {
333
      "fake": {}
334
     },
335
    "default_hypervisor": "fake",
336
    "master": "node1.example.com",
337
    "architecture": [
338
      "64bit",
339
      "x86_64"
340
    ],
341
    "protocol_version": 20,
342
    "beparams": {
343
      "default": {
344
        "auto_balance": true,
345
        "vcpus": 1,
346
        "memory": 128
347
       }
348
      }
349
    }
350

    
351

    
352
``/2/redistribute-config``
353
++++++++++++++++++++++++++
354

    
355
Redistribute configuration to all nodes.
356

    
357
It supports the following commands: ``PUT``.
358

    
359
``PUT``
360
~~~~~~~
361

    
362
Redistribute configuration to all nodes. The result will be a job id.
363

    
364
Job result:
365

    
366
.. opcode_result:: OP_CLUSTER_REDIST_CONF
367

    
368

    
369
``/2/features``
370
+++++++++++++++
371

    
372
``GET``
373
~~~~~~~
374

    
375
Returns a list of features supported by the RAPI server. Available
376
features:
377

    
378
.. pyassert::
379

    
380
  rlib2.ALL_FEATURES == set([rlib2._INST_CREATE_REQV1,
381
                             rlib2._INST_REINSTALL_REQV1,
382
                             rlib2._NODE_MIGRATE_REQV1,
383
                             rlib2._NODE_EVAC_RES1])
384

    
385
:pyeval:`rlib2._INST_CREATE_REQV1`
386
  Instance creation request data version 1 supported.
387
:pyeval:`rlib2._INST_REINSTALL_REQV1`
388
  Instance reinstall supports body parameters.
389
:pyeval:`rlib2._NODE_MIGRATE_REQV1`
390
  Whether migrating a node (``/2/nodes/[node_name]/migrate``) supports
391
  request body parameters.
392
:pyeval:`rlib2._NODE_EVAC_RES1`
393
  Whether evacuating a node (``/2/nodes/[node_name]/evacuate``) returns
394
  a new-style result (see resource description)
395

    
396

    
397
``/2/modify``
398
++++++++++++++++++++++++++++++++++++++++
399

    
400
Modifies cluster parameters.
401

    
402
Supports the following commands: ``PUT``.
403

    
404
``PUT``
405
~~~~~~~
406

    
407
Returns a job ID.
408

    
409
Body parameters:
410

    
411
.. opcode_params:: OP_CLUSTER_SET_PARAMS
412

    
413
Job result:
414

    
415
.. opcode_result:: OP_CLUSTER_SET_PARAMS
416

    
417

    
418
``/2/groups``
419
+++++++++++++
420

    
421
The groups resource.
422

    
423
It supports the following commands: ``GET``, ``POST``.
424

    
425
``GET``
426
~~~~~~~
427

    
428
Returns a list of all existing node groups.
429

    
430
Example::
431

    
432
    [
433
      {
434
        "name": "group1",
435
        "uri": "\/2\/groups\/group1"
436
      },
437
      {
438
        "name": "group2",
439
        "uri": "\/2\/groups\/group2"
440
      }
441
    ]
442

    
443
If the optional bool *bulk* argument is provided and set to a true value
444
(i.e ``?bulk=1``), the output contains detailed information about node
445
groups as a list.
446

    
447
Returned fields: :pyeval:`utils.CommaJoin(sorted(rlib2.G_FIELDS))`
448

    
449
Example::
450

    
451
    [
452
      {
453
        "name": "group1",
454
        "node_cnt": 2,
455
        "node_list": [
456
          "node1.example.com",
457
          "node2.example.com"
458
        ],
459
        "uuid": "0d7d407c-262e-49af-881a-6a430034bf43"
460
      },
461
      {
462
        "name": "group2",
463
        "node_cnt": 1,
464
        "node_list": [
465
          "node3.example.com"
466
        ],
467
        "uuid": "f5a277e7-68f9-44d3-a378-4b25ecb5df5c"
468
      }
469
    ]
470

    
471
``POST``
472
~~~~~~~~
473

    
474
Creates a node group.
475

    
476
If the optional bool *dry-run* argument is provided, the job will not be
477
actually executed, only the pre-execution checks will be done.
478

    
479
Returns: a job ID that can be used later for polling.
480

    
481
Body parameters:
482

    
483
.. opcode_params:: OP_GROUP_ADD
484

    
485
Earlier versions used a parameter named ``name`` which, while still
486
supported, has been renamed to ``group_name``.
487

    
488
Job result:
489

    
490
.. opcode_result:: OP_GROUP_ADD
491

    
492

    
493
``/2/groups/[group_name]``
494
++++++++++++++++++++++++++
495

    
496
Returns information about a node group.
497

    
498
It supports the following commands: ``GET``, ``DELETE``.
499

    
500
``GET``
501
~~~~~~~
502

    
503
Returns information about a node group, similar to the bulk output from
504
the node group list.
505

    
506
Returned fields: :pyeval:`utils.CommaJoin(sorted(rlib2.G_FIELDS))`
507

    
508
``DELETE``
509
~~~~~~~~~~
510

    
511
Deletes a node group.
512

    
513
It supports the ``dry-run`` argument.
514

    
515
Job result:
516

    
517
.. opcode_result:: OP_GROUP_REMOVE
518

    
519

    
520
``/2/groups/[group_name]/modify``
521
+++++++++++++++++++++++++++++++++
522

    
523
Modifies the parameters of a node group.
524

    
525
Supports the following commands: ``PUT``.
526

    
527
``PUT``
528
~~~~~~~
529

    
530
Returns a job ID.
531

    
532
Body parameters:
533

    
534
.. opcode_params:: OP_GROUP_SET_PARAMS
535
   :exclude: group_name
536

    
537
Job result:
538

    
539
.. opcode_result:: OP_GROUP_SET_PARAMS
540

    
541

    
542
``/2/groups/[group_name]/rename``
543
+++++++++++++++++++++++++++++++++
544

    
545
Renames a node group.
546

    
547
Supports the following commands: ``PUT``.
548

    
549
``PUT``
550
~~~~~~~
551

    
552
Returns a job ID.
553

    
554
Body parameters:
555

    
556
.. opcode_params:: OP_GROUP_RENAME
557
   :exclude: group_name
558

    
559
Job result:
560

    
561
.. opcode_result:: OP_GROUP_RENAME
562

    
563

    
564
``/2/groups/[group_name]/assign-nodes``
565
+++++++++++++++++++++++++++++++++++++++
566

    
567
Assigns nodes to a group.
568

    
569
Supports the following commands: ``PUT``.
570

    
571
``PUT``
572
~~~~~~~
573

    
574
Returns a job ID. It supports the ``dry-run`` and ``force`` arguments.
575

    
576
Body parameters:
577

    
578
.. opcode_params:: OP_GROUP_ASSIGN_NODES
579
   :exclude: group_name, force, dry_run
580

    
581
Job result:
582

    
583
.. opcode_result:: OP_GROUP_ASSIGN_NODES
584

    
585

    
586
``/2/groups/[group_name]/tags``
587
+++++++++++++++++++++++++++++++
588

    
589
Manages per-nodegroup tags.
590

    
591
Supports the following commands: ``GET``, ``PUT``, ``DELETE``.
592

    
593
``GET``
594
~~~~~~~
595

    
596
Returns a list of tags.
597

    
598
Example::
599

    
600
    ["tag1", "tag2", "tag3"]
601

    
602
``PUT``
603
~~~~~~~
604

    
605
Add a set of tags.
606

    
607
The request as a list of strings should be ``PUT`` to this URI. The
608
result will be a job id.
609

    
610
It supports the ``dry-run`` argument.
611

    
612

    
613
``DELETE``
614
~~~~~~~~~~
615

    
616
Delete a tag.
617

    
618
In order to delete a set of tags, the DELETE request should be addressed
619
to URI like::
620

    
621
    /tags?tag=[tag]&tag=[tag]
622

    
623
It supports the ``dry-run`` argument.
624

    
625

    
626
``/2/instances``
627
++++++++++++++++
628

    
629
The instances resource.
630

    
631
It supports the following commands: ``GET``, ``POST``.
632

    
633
``GET``
634
~~~~~~~
635

    
636
Returns a list of all available instances.
637

    
638
Example::
639

    
640
    [
641
      {
642
        "name": "web.example.com",
643
        "uri": "\/instances\/web.example.com"
644
      },
645
      {
646
        "name": "mail.example.com",
647
        "uri": "\/instances\/mail.example.com"
648
      }
649
    ]
650

    
651
If the optional bool *bulk* argument is provided and set to a true value
652
(i.e ``?bulk=1``), the output contains detailed information about
653
instances as a list.
654

    
655
Returned fields: :pyeval:`utils.CommaJoin(sorted(rlib2.I_FIELDS))`
656

    
657
Example::
658

    
659
    [
660
      {
661
         "status": "running",
662
         "disk_usage": 20480,
663
         "nic.bridges": [
664
           "xen-br0"
665
          ],
666
         "name": "web.example.com",
667
         "tags": ["tag1", "tag2"],
668
         "beparams": {
669
           "vcpus": 2,
670
           "memory": 512
671
         },
672
         "disk.sizes": [
673
             20480
674
         ],
675
         "pnode": "node1.example.com",
676
         "nic.macs": ["01:23:45:67:89:01"],
677
         "snodes": ["node2.example.com"],
678
         "disk_template": "drbd",
679
         "admin_state": true,
680
         "os": "debian-etch",
681
         "oper_state": true
682
      },
683
      ...
684
    ]
685

    
686

    
687
``POST``
688
~~~~~~~~
689

    
690
Creates an instance.
691

    
692
If the optional bool *dry-run* argument is provided, the job will not be
693
actually executed, only the pre-execution checks will be done. Query-ing
694
the job result will return, in both dry-run and normal case, the list of
695
nodes selected for the instance.
696

    
697
Returns: a job ID that can be used later for polling.
698

    
699
Body parameters:
700

    
701
``__version__`` (int, required)
702
  Must be ``1`` (older Ganeti versions used a different format for
703
  instance creation requests, version ``0``, but that format is no
704
  longer supported)
705

    
706
.. opcode_params:: OP_INSTANCE_CREATE
707

    
708
Earlier versions used parameters named ``name`` and ``os``. These have
709
been replaced by ``instance_name`` and ``os_type`` to match the
710
underlying opcode. The old names can still be used.
711

    
712
Job result:
713

    
714
.. opcode_result:: OP_INSTANCE_CREATE
715

    
716

    
717
``/2/instances/[instance_name]``
718
++++++++++++++++++++++++++++++++
719

    
720
Instance-specific resource.
721

    
722
It supports the following commands: ``GET``, ``DELETE``.
723

    
724
``GET``
725
~~~~~~~
726

    
727
Returns information about an instance, similar to the bulk output from
728
the instance list.
729

    
730
Returned fields: :pyeval:`utils.CommaJoin(sorted(rlib2.I_FIELDS))`
731

    
732
``DELETE``
733
~~~~~~~~~~
734

    
735
Deletes an instance.
736

    
737
It supports the ``dry-run`` argument.
738

    
739
Job result:
740

    
741
.. opcode_result:: OP_INSTANCE_REMOVE
742

    
743

    
744
``/2/instances/[instance_name]/info``
745
+++++++++++++++++++++++++++++++++++++++
746

    
747
It supports the following commands: ``GET``.
748

    
749
``GET``
750
~~~~~~~
751

    
752
Requests detailed information about the instance. An optional parameter,
753
``static`` (bool), can be set to return only static information from the
754
configuration without querying the instance's nodes. The result will be
755
a job id.
756

    
757
Job result:
758

    
759
.. opcode_result:: OP_INSTANCE_QUERY_DATA
760

    
761

    
762
``/2/instances/[instance_name]/reboot``
763
+++++++++++++++++++++++++++++++++++++++
764

    
765
Reboots URI for an instance.
766

    
767
It supports the following commands: ``POST``.
768

    
769
``POST``
770
~~~~~~~~
771

    
772
Reboots the instance.
773

    
774
The URI takes optional ``type=soft|hard|full`` and
775
``ignore_secondaries=0|1`` parameters.
776

    
777
``type`` defines the reboot type. ``soft`` is just a normal reboot,
778
without terminating the hypervisor. ``hard`` means full shutdown
779
(including terminating the hypervisor process) and startup again.
780
``full`` is like ``hard`` but also recreates the configuration from
781
ground up as if you would have done a ``gnt-instance shutdown`` and
782
``gnt-instance start`` on it.
783

    
784
``ignore_secondaries`` is a bool argument indicating if we start the
785
instance even if secondary disks are failing.
786

    
787
It supports the ``dry-run`` argument.
788

    
789
Job result:
790

    
791
.. opcode_result:: OP_INSTANCE_REBOOT
792

    
793

    
794
``/2/instances/[instance_name]/shutdown``
795
+++++++++++++++++++++++++++++++++++++++++
796

    
797
Instance shutdown URI.
798

    
799
It supports the following commands: ``PUT``.
800

    
801
``PUT``
802
~~~~~~~
803

    
804
Shutdowns an instance.
805

    
806
It supports the ``dry-run`` argument.
807

    
808
.. opcode_params:: OP_INSTANCE_SHUTDOWN
809
   :exclude: instance_name, dry_run
810

    
811
Job result:
812

    
813
.. opcode_result:: OP_INSTANCE_SHUTDOWN
814

    
815

    
816
``/2/instances/[instance_name]/startup``
817
++++++++++++++++++++++++++++++++++++++++
818

    
819
Instance startup URI.
820

    
821
It supports the following commands: ``PUT``.
822

    
823
``PUT``
824
~~~~~~~
825

    
826
Startup an instance.
827

    
828
The URI takes an optional ``force=1|0`` parameter to start the
829
instance even if secondary disks are failing.
830

    
831
It supports the ``dry-run`` argument.
832

    
833
Job result:
834

    
835
.. opcode_result:: OP_INSTANCE_STARTUP
836

    
837

    
838
``/2/instances/[instance_name]/reinstall``
839
++++++++++++++++++++++++++++++++++++++++++++++
840

    
841
Installs the operating system again.
842

    
843
It supports the following commands: ``POST``.
844

    
845
``POST``
846
~~~~~~~~
847

    
848
Returns a job ID.
849

    
850
Body parameters:
851

    
852
``os`` (string, required)
853
  Instance operating system.
854
``start`` (bool, defaults to true)
855
  Whether to start instance after reinstallation.
856
``osparams`` (dict)
857
  Dictionary with (temporary) OS parameters.
858

    
859
For backwards compatbility, this resource also takes the query
860
parameters ``os`` (OS template name) and ``nostartup`` (bool). New
861
clients should use the body parameters.
862

    
863

    
864
``/2/instances/[instance_name]/replace-disks``
865
++++++++++++++++++++++++++++++++++++++++++++++
866

    
867
Replaces disks on an instance.
868

    
869
It supports the following commands: ``POST``.
870

    
871
``POST``
872
~~~~~~~~
873

    
874
Returns a job ID.
875

    
876
Body parameters:
877

    
878
.. opcode_params:: OP_INSTANCE_REPLACE_DISKS
879
   :exclude: instance_name
880

    
881
Ganeti 2.4 and below used query parameters. Those are deprecated and
882
should no longer be used.
883

    
884
Job result:
885

    
886
.. opcode_result:: OP_INSTANCE_REPLACE_DISKS
887

    
888

    
889
``/2/instances/[instance_name]/activate-disks``
890
+++++++++++++++++++++++++++++++++++++++++++++++
891

    
892
Activate disks on an instance.
893

    
894
It supports the following commands: ``PUT``.
895

    
896
``PUT``
897
~~~~~~~
898

    
899
Takes the bool parameter ``ignore_size``. When set ignore the recorded
900
size (useful for forcing activation when recorded size is wrong).
901

    
902
Job result:
903

    
904
.. opcode_result:: OP_INSTANCE_ACTIVATE_DISKS
905

    
906

    
907
``/2/instances/[instance_name]/deactivate-disks``
908
+++++++++++++++++++++++++++++++++++++++++++++++++
909

    
910
Deactivate disks on an instance.
911

    
912
It supports the following commands: ``PUT``.
913

    
914
``PUT``
915
~~~~~~~
916

    
917
Takes no parameters.
918

    
919
Job result:
920

    
921
.. opcode_result:: OP_INSTANCE_DEACTIVATE_DISKS
922

    
923

    
924
``/2/instances/[instance_name]/recreate-disks``
925
+++++++++++++++++++++++++++++++++++++++++++++++++
926

    
927
Recreate disks of an instance. Supports the following commands:
928
``POST``.
929

    
930
``POST``
931
~~~~~~~~
932

    
933
Returns a job ID.
934

    
935
Body parameters:
936

    
937
.. opcode_params:: OP_INSTANCE_RECREATE_DISKS
938
   :exclude: instance_name
939

    
940
Job result:
941

    
942
.. opcode_result:: OP_INSTANCE_RECREATE_DISKS
943

    
944

    
945
``/2/instances/[instance_name]/disk/[disk_index]/grow``
946
+++++++++++++++++++++++++++++++++++++++++++++++++++++++
947

    
948
Grows one disk of an instance.
949

    
950
Supports the following commands: ``POST``.
951

    
952
``POST``
953
~~~~~~~~
954

    
955
Returns a job ID.
956

    
957
Body parameters:
958

    
959
.. opcode_params:: OP_INSTANCE_GROW_DISK
960
   :exclude: instance_name, disk
961

    
962
Job result:
963

    
964
.. opcode_result:: OP_INSTANCE_GROW_DISK
965

    
966

    
967
``/2/instances/[instance_name]/prepare-export``
968
+++++++++++++++++++++++++++++++++++++++++++++++++
969

    
970
Prepares an export of an instance.
971

    
972
It supports the following commands: ``PUT``.
973

    
974
``PUT``
975
~~~~~~~
976

    
977
Takes one parameter, ``mode``, for the export mode. Returns a job ID.
978

    
979
Job result:
980

    
981
.. opcode_result:: OP_BACKUP_PREPARE
982

    
983

    
984
``/2/instances/[instance_name]/export``
985
+++++++++++++++++++++++++++++++++++++++++++++++++
986

    
987
Exports an instance.
988

    
989
It supports the following commands: ``PUT``.
990

    
991
``PUT``
992
~~~~~~~
993

    
994
Returns a job ID.
995

    
996
Body parameters:
997

    
998
.. opcode_params:: OP_BACKUP_EXPORT
999
   :exclude: instance_name
1000
   :alias: target_node=destination
1001

    
1002
Job result:
1003

    
1004
.. opcode_result:: OP_BACKUP_EXPORT
1005

    
1006

    
1007
``/2/instances/[instance_name]/migrate``
1008
++++++++++++++++++++++++++++++++++++++++
1009

    
1010
Migrates an instance.
1011

    
1012
Supports the following commands: ``PUT``.
1013

    
1014
``PUT``
1015
~~~~~~~
1016

    
1017
Returns a job ID.
1018

    
1019
Body parameters:
1020

    
1021
.. opcode_params:: OP_INSTANCE_MIGRATE
1022
   :exclude: instance_name, live
1023

    
1024
Job result:
1025

    
1026
.. opcode_result:: OP_INSTANCE_MIGRATE
1027

    
1028

    
1029
``/2/instances/[instance_name]/failover``
1030
+++++++++++++++++++++++++++++++++++++++++
1031

    
1032
Does a failover of an instance.
1033

    
1034
Supports the following commands: ``PUT``.
1035

    
1036
``PUT``
1037
~~~~~~~
1038

    
1039
Returns a job ID.
1040

    
1041
Body parameters:
1042

    
1043
.. opcode_params:: OP_INSTANCE_FAILOVER
1044
   :exclude: instance_name
1045

    
1046
Job result:
1047

    
1048
.. opcode_result:: OP_INSTANCE_FAILOVER
1049

    
1050

    
1051
``/2/instances/[instance_name]/rename``
1052
++++++++++++++++++++++++++++++++++++++++
1053

    
1054
Renames an instance.
1055

    
1056
Supports the following commands: ``PUT``.
1057

    
1058
``PUT``
1059
~~~~~~~
1060

    
1061
Returns a job ID.
1062

    
1063
Body parameters:
1064

    
1065
.. opcode_params:: OP_INSTANCE_RENAME
1066
   :exclude: instance_name
1067

    
1068
Job result:
1069

    
1070
.. opcode_result:: OP_INSTANCE_RENAME
1071

    
1072

    
1073
``/2/instances/[instance_name]/modify``
1074
++++++++++++++++++++++++++++++++++++++++
1075

    
1076
Modifies an instance.
1077

    
1078
Supports the following commands: ``PUT``.
1079

    
1080
``PUT``
1081
~~~~~~~
1082

    
1083
Returns a job ID.
1084

    
1085
Body parameters:
1086

    
1087
.. opcode_params:: OP_INSTANCE_SET_PARAMS
1088
   :exclude: instance_name
1089

    
1090
Job result:
1091

    
1092
.. opcode_result:: OP_INSTANCE_SET_PARAMS
1093

    
1094

    
1095
``/2/instances/[instance_name]/console``
1096
++++++++++++++++++++++++++++++++++++++++
1097

    
1098
Request information for connecting to instance's console.
1099

    
1100
Supports the following commands: ``GET``.
1101

    
1102
``GET``
1103
~~~~~~~
1104

    
1105
Returns a dictionary containing information about the instance's
1106
console. Contained keys:
1107

    
1108
.. pyassert::
1109

    
1110
   constants.CONS_ALL == frozenset([
1111
     constants.CONS_MESSAGE,
1112
     constants.CONS_SSH,
1113
     constants.CONS_VNC,
1114
     constants.CONS_SPICE,
1115
     ])
1116

    
1117
``instance``
1118
  Instance name.
1119
``kind``
1120
  Console type, one of :pyeval:`constants.CONS_SSH`,
1121
  :pyeval:`constants.CONS_VNC`, :pyeval:`constants.CONS_SPICE`
1122
  or :pyeval:`constants.CONS_MESSAGE`.
1123
``message``
1124
  Message to display (:pyeval:`constants.CONS_MESSAGE` type only).
1125
``host``
1126
  Host to connect to (:pyeval:`constants.CONS_SSH`,
1127
  :pyeval:`constants.CONS_VNC` or :pyeval:`constants.CONS_SPICE` only).
1128
``port``
1129
  TCP port to connect to (:pyeval:`constants.CONS_VNC` or
1130
  :pyeval:`constants.CONS_SPICE` only).
1131
``user``
1132
  Username to use (:pyeval:`constants.CONS_SSH` only).
1133
``command``
1134
  Command to execute on machine (:pyeval:`constants.CONS_SSH` only)
1135
``display``
1136
  VNC display number (:pyeval:`constants.CONS_VNC` only).
1137

    
1138

    
1139
``/2/instances/[instance_name]/tags``
1140
+++++++++++++++++++++++++++++++++++++
1141

    
1142
Manages per-instance tags.
1143

    
1144
It supports the following commands: ``GET``, ``PUT``, ``DELETE``.
1145

    
1146
``GET``
1147
~~~~~~~
1148

    
1149
Returns a list of tags.
1150

    
1151
Example::
1152

    
1153
    ["tag1", "tag2", "tag3"]
1154

    
1155
``PUT``
1156
~~~~~~~
1157

    
1158
Add a set of tags.
1159

    
1160
The request as a list of strings should be ``PUT`` to this URI. The
1161
result will be a job id.
1162

    
1163
It supports the ``dry-run`` argument.
1164

    
1165

    
1166
``DELETE``
1167
~~~~~~~~~~
1168

    
1169
Delete a tag.
1170

    
1171
In order to delete a set of tags, the DELETE request should be addressed
1172
to URI like::
1173

    
1174
    /tags?tag=[tag]&tag=[tag]
1175

    
1176
It supports the ``dry-run`` argument.
1177

    
1178

    
1179
``/2/jobs``
1180
+++++++++++
1181

    
1182
The ``/2/jobs`` resource.
1183

    
1184
It supports the following commands: ``GET``.
1185

    
1186
``GET``
1187
~~~~~~~
1188

    
1189
Returns a dictionary of jobs.
1190

    
1191
Returns: a dictionary with jobs id and uri.
1192

    
1193
If the optional bool *bulk* argument is provided and set to a true value
1194
(i.e. ``?bulk=1``), the output contains detailed information about jobs
1195
as a list.
1196

    
1197
Returned fields for bulk requests (unlike other bulk requests, these
1198
fields are not the same as for per-job requests):
1199
:pyeval:`utils.CommaJoin(sorted(rlib2.J_FIELDS_BULK))`
1200

    
1201
``/2/jobs/[job_id]``
1202
++++++++++++++++++++
1203

    
1204

    
1205
Individual job URI.
1206

    
1207
It supports the following commands: ``GET``, ``DELETE``.
1208

    
1209
``GET``
1210
~~~~~~~
1211

    
1212
Returns a dictionary with job parameters, containing the fields
1213
:pyeval:`utils.CommaJoin(sorted(rlib2.J_FIELDS))`.
1214

    
1215
The result includes:
1216

    
1217
- id: job ID as a number
1218
- status: current job status as a string
1219
- ops: involved OpCodes as a list of dictionaries for each opcodes in
1220
  the job
1221
- opstatus: OpCodes status as a list
1222
- opresult: OpCodes results as a list
1223

    
1224
For a successful opcode, the ``opresult`` field corresponding to it will
1225
contain the raw result from its :term:`LogicalUnit`. In case an opcode
1226
has failed, its element in the opresult list will be a list of two
1227
elements:
1228

    
1229
- first element the error type (the Ganeti internal error name)
1230
- second element a list of either one or two elements:
1231

    
1232
  - the first element is the textual error description
1233
  - the second element, if any, will hold an error classification
1234

    
1235
The error classification is most useful for the ``OpPrereqError``
1236
error type - these errors happen before the OpCode has started
1237
executing, so it's possible to retry the OpCode without side
1238
effects. But whether it make sense to retry depends on the error
1239
classification:
1240

    
1241
.. pyassert::
1242

    
1243
   errors.ECODE_ALL == set([errors.ECODE_RESOLVER, errors.ECODE_NORES,
1244
     errors.ECODE_INVAL, errors.ECODE_STATE, errors.ECODE_NOENT,
1245
     errors.ECODE_EXISTS, errors.ECODE_NOTUNIQUE, errors.ECODE_FAULT,
1246
     errors.ECODE_ENVIRON])
1247

    
1248
:pyeval:`errors.ECODE_RESOLVER`
1249
  Resolver errors. This usually means that a name doesn't exist in DNS,
1250
  so if it's a case of slow DNS propagation the operation can be retried
1251
  later.
1252

    
1253
:pyeval:`errors.ECODE_NORES`
1254
  Not enough resources (iallocator failure, disk space, memory,
1255
  etc.). If the resources on the cluster increase, the operation might
1256
  succeed.
1257

    
1258
:pyeval:`errors.ECODE_INVAL`
1259
  Wrong arguments (at syntax level). The operation will not ever be
1260
  accepted unless the arguments change.
1261

    
1262
:pyeval:`errors.ECODE_STATE`
1263
  Wrong entity state. For example, live migration has been requested for
1264
  a down instance, or instance creation on an offline node. The
1265
  operation can be retried once the resource has changed state.
1266

    
1267
:pyeval:`errors.ECODE_NOENT`
1268
  Entity not found. For example, information has been requested for an
1269
  unknown instance.
1270

    
1271
:pyeval:`errors.ECODE_EXISTS`
1272
  Entity already exists. For example, instance creation has been
1273
  requested for an already-existing instance.
1274

    
1275
:pyeval:`errors.ECODE_NOTUNIQUE`
1276
  Resource not unique (e.g. MAC or IP duplication).
1277

    
1278
:pyeval:`errors.ECODE_FAULT`
1279
  Internal cluster error. For example, a node is unreachable but not set
1280
  offline, or the ganeti node daemons are not working, etc. A
1281
  ``gnt-cluster verify`` should be run.
1282

    
1283
:pyeval:`errors.ECODE_ENVIRON`
1284
  Environment error (e.g. node disk error). A ``gnt-cluster verify``
1285
  should be run.
1286

    
1287
Note that in the above list, by entity we refer to a node or instance,
1288
while by a resource we refer to an instance's disk, or NIC, etc.
1289

    
1290

    
1291
``DELETE``
1292
~~~~~~~~~~
1293

    
1294
Cancel a not-yet-started job.
1295

    
1296

    
1297
``/2/jobs/[job_id]/wait``
1298
+++++++++++++++++++++++++
1299

    
1300
``GET``
1301
~~~~~~~
1302

    
1303
Waits for changes on a job. Takes the following body parameters in a
1304
dict:
1305

    
1306
``fields``
1307
  The job fields on which to watch for changes.
1308

    
1309
``previous_job_info``
1310
  Previously received field values or None if not yet available.
1311

    
1312
``previous_log_serial``
1313
  Highest log serial number received so far or None if not yet
1314
  available.
1315

    
1316
Returns None if no changes have been detected and a dict with two keys,
1317
``job_info`` and ``log_entries`` otherwise.
1318

    
1319

    
1320
``/2/nodes``
1321
++++++++++++
1322

    
1323
Nodes resource.
1324

    
1325
It supports the following commands: ``GET``.
1326

    
1327
``GET``
1328
~~~~~~~
1329

    
1330
Returns a list of all nodes.
1331

    
1332
Example::
1333

    
1334
    [
1335
      {
1336
        "id": "node1.example.com",
1337
        "uri": "\/nodes\/node1.example.com"
1338
      },
1339
      {
1340
        "id": "node2.example.com",
1341
        "uri": "\/nodes\/node2.example.com"
1342
      }
1343
    ]
1344

    
1345
If the optional bool *bulk* argument is provided and set to a true value
1346
(i.e ``?bulk=1``), the output contains detailed information about nodes
1347
as a list.
1348

    
1349
Returned fields: :pyeval:`utils.CommaJoin(sorted(rlib2.N_FIELDS))`
1350

    
1351
Example::
1352

    
1353
    [
1354
      {
1355
        "pinst_cnt": 1,
1356
        "mfree": 31280,
1357
        "mtotal": 32763,
1358
        "name": "www.example.com",
1359
        "tags": [],
1360
        "mnode": 512,
1361
        "dtotal": 5246208,
1362
        "sinst_cnt": 2,
1363
        "dfree": 5171712,
1364
        "offline": false
1365
      },
1366
      ...
1367
    ]
1368

    
1369
``/2/nodes/[node_name]``
1370
+++++++++++++++++++++++++++++++++
1371

    
1372
Returns information about a node.
1373

    
1374
It supports the following commands: ``GET``.
1375

    
1376
Returned fields: :pyeval:`utils.CommaJoin(sorted(rlib2.N_FIELDS))`
1377

    
1378
``/2/nodes/[node_name]/powercycle``
1379
+++++++++++++++++++++++++++++++++++
1380

    
1381
Powercycles a node. Supports the following commands: ``POST``.
1382

    
1383
``POST``
1384
~~~~~~~~
1385

    
1386
Returns a job ID.
1387

    
1388
Job result:
1389

    
1390
.. opcode_result:: OP_NODE_POWERCYCLE
1391

    
1392

    
1393
``/2/nodes/[node_name]/evacuate``
1394
+++++++++++++++++++++++++++++++++
1395

    
1396
Evacuates instances off a node.
1397

    
1398
It supports the following commands: ``POST``.
1399

    
1400
``POST``
1401
~~~~~~~~
1402

    
1403
Returns a job ID. The result of the job will contain the IDs of the
1404
individual jobs submitted to evacuate the node.
1405

    
1406
Body parameters:
1407

    
1408
.. opcode_params:: OP_NODE_EVACUATE
1409
   :exclude: nodes
1410

    
1411
Up to and including Ganeti 2.4 query arguments were used. Those are no
1412
longer supported. The new request can be detected by the presence of the
1413
:pyeval:`rlib2._NODE_EVAC_RES1` feature string.
1414

    
1415
Job result:
1416

    
1417
.. opcode_result:: OP_NODE_EVACUATE
1418

    
1419

    
1420
``/2/nodes/[node_name]/migrate``
1421
+++++++++++++++++++++++++++++++++
1422

    
1423
Migrates all primary instances from a node.
1424

    
1425
It supports the following commands: ``POST``.
1426

    
1427
``POST``
1428
~~~~~~~~
1429

    
1430
If no mode is explicitly specified, each instances' hypervisor default
1431
migration mode will be used. Body parameters:
1432

    
1433
.. opcode_params:: OP_NODE_MIGRATE
1434
   :exclude: node_name
1435

    
1436
The query arguments used up to and including Ganeti 2.4 are deprecated
1437
and should no longer be used. The new request format can be detected by
1438
the presence of the :pyeval:`rlib2._NODE_MIGRATE_REQV1` feature string.
1439

    
1440
Job result:
1441

    
1442
.. opcode_result:: OP_NODE_MIGRATE
1443

    
1444

    
1445
``/2/nodes/[node_name]/role``
1446
+++++++++++++++++++++++++++++
1447

    
1448
Manages node role.
1449

    
1450
It supports the following commands: ``GET``, ``PUT``.
1451

    
1452
The role is always one of the following:
1453

    
1454
  - drained
1455
  - master-candidate
1456
  - offline
1457
  - regular
1458

    
1459
Note that the 'master' role is a special, and currently it can't be
1460
modified via RAPI, only via the command line (``gnt-cluster
1461
master-failover``).
1462

    
1463
``GET``
1464
~~~~~~~
1465

    
1466
Returns the current node role.
1467

    
1468
Example::
1469

    
1470
    "master-candidate"
1471

    
1472
``PUT``
1473
~~~~~~~
1474

    
1475
Change the node role.
1476

    
1477
The request is a string which should be PUT to this URI. The result will
1478
be a job id.
1479

    
1480
It supports the bool ``force`` argument.
1481

    
1482
Job result:
1483

    
1484
.. opcode_result:: OP_NODE_SET_PARAMS
1485

    
1486

    
1487
``/2/nodes/[node_name]/modify``
1488
+++++++++++++++++++++++++++++++
1489

    
1490
Modifies the parameters of a node. Supports the following commands:
1491
``POST``.
1492

    
1493
``POST``
1494
~~~~~~~~
1495

    
1496
Returns a job ID.
1497

    
1498
Body parameters:
1499

    
1500
.. opcode_params:: OP_NODE_SET_PARAMS
1501
   :exclude: node_name
1502

    
1503
Job result:
1504

    
1505
.. opcode_result:: OP_NODE_SET_PARAMS
1506

    
1507

    
1508
``/2/nodes/[node_name]/storage``
1509
++++++++++++++++++++++++++++++++
1510

    
1511
Manages storage units on the node.
1512

    
1513
``GET``
1514
~~~~~~~
1515

    
1516
.. pyassert::
1517

    
1518
   constants.VALID_STORAGE_TYPES == set([constants.ST_FILE,
1519
                                         constants.ST_LVM_PV,
1520
                                         constants.ST_LVM_VG])
1521

    
1522
Requests a list of storage units on a node. Requires the parameters
1523
``storage_type`` (one of :pyeval:`constants.ST_FILE`,
1524
:pyeval:`constants.ST_LVM_PV` or :pyeval:`constants.ST_LVM_VG`) and
1525
``output_fields``. The result will be a job id, using which the result
1526
can be retrieved.
1527

    
1528
``/2/nodes/[node_name]/storage/modify``
1529
+++++++++++++++++++++++++++++++++++++++
1530

    
1531
Modifies storage units on the node.
1532

    
1533
``PUT``
1534
~~~~~~~
1535

    
1536
Modifies parameters of storage units on the node. Requires the
1537
parameters ``storage_type`` (one of :pyeval:`constants.ST_FILE`,
1538
:pyeval:`constants.ST_LVM_PV` or :pyeval:`constants.ST_LVM_VG`)
1539
and ``name`` (name of the storage unit).  Parameters can be passed
1540
additionally. Currently only :pyeval:`constants.SF_ALLOCATABLE` (bool)
1541
is supported. The result will be a job id.
1542

    
1543
Job result:
1544

    
1545
.. opcode_result:: OP_NODE_MODIFY_STORAGE
1546

    
1547

    
1548
``/2/nodes/[node_name]/storage/repair``
1549
+++++++++++++++++++++++++++++++++++++++
1550

    
1551
Repairs a storage unit on the node.
1552

    
1553
``PUT``
1554
~~~~~~~
1555

    
1556
.. pyassert::
1557

    
1558
   constants.VALID_STORAGE_OPERATIONS == {
1559
    constants.ST_LVM_VG: set([constants.SO_FIX_CONSISTENCY]),
1560
    }
1561

    
1562
Repairs a storage unit on the node. Requires the parameters
1563
``storage_type`` (currently only :pyeval:`constants.ST_LVM_VG` can be
1564
repaired) and ``name`` (name of the storage unit). The result will be a
1565
job id.
1566

    
1567
Job result:
1568

    
1569
.. opcode_result:: OP_REPAIR_NODE_STORAGE
1570

    
1571

    
1572
``/2/nodes/[node_name]/tags``
1573
+++++++++++++++++++++++++++++
1574

    
1575
Manages per-node tags.
1576

    
1577
It supports the following commands: ``GET``, ``PUT``, ``DELETE``.
1578

    
1579
``GET``
1580
~~~~~~~
1581

    
1582
Returns a list of tags.
1583

    
1584
Example::
1585

    
1586
    ["tag1", "tag2", "tag3"]
1587

    
1588
``PUT``
1589
~~~~~~~
1590

    
1591
Add a set of tags.
1592

    
1593
The request as a list of strings should be PUT to this URI. The result
1594
will be a job id.
1595

    
1596
It supports the ``dry-run`` argument.
1597

    
1598
``DELETE``
1599
~~~~~~~~~~
1600

    
1601
Deletes tags.
1602

    
1603
In order to delete a set of tags, the DELETE request should be addressed
1604
to URI like::
1605

    
1606
    /tags?tag=[tag]&tag=[tag]
1607

    
1608
It supports the ``dry-run`` argument.
1609

    
1610

    
1611
``/2/query/[resource]``
1612
+++++++++++++++++++++++
1613

    
1614
Requests resource information. Available fields can be found in man
1615
pages and using ``/2/query/[resource]/fields``. The resource is one of
1616
:pyeval:`utils.CommaJoin(constants.QR_VIA_RAPI)`. See the :doc:`query2
1617
design document <design-query2>` for more details.
1618

    
1619
Supports the following commands: ``GET``, ``PUT``.
1620

    
1621
``GET``
1622
~~~~~~~
1623

    
1624
Returns list of included fields and actual data. Takes a query parameter
1625
named "fields", containing a comma-separated list of field names. Does
1626
not support filtering.
1627

    
1628
``PUT``
1629
~~~~~~~
1630

    
1631
Returns list of included fields and actual data. The list of requested
1632
fields can either be given as the query parameter "fields" or as a body
1633
parameter with the same name. The optional body parameter "filter" can
1634
be given and must be either ``null`` or a list containing filter
1635
operators.
1636

    
1637

    
1638
``/2/query/[resource]/fields``
1639
++++++++++++++++++++++++++++++
1640

    
1641
Request list of available fields for a resource. The resource is one of
1642
:pyeval:`utils.CommaJoin(constants.QR_VIA_RAPI)`. See the
1643
:doc:`query2 design document <design-query2>` for more details.
1644

    
1645
Supports the following commands: ``GET``.
1646

    
1647
``GET``
1648
~~~~~~~
1649

    
1650
Returns a list of field descriptions for available fields. Takes an
1651
optional query parameter named "fields", containing a comma-separated
1652
list of field names.
1653

    
1654

    
1655
``/2/os``
1656
+++++++++
1657

    
1658
OS resource.
1659

    
1660
It supports the following commands: ``GET``.
1661

    
1662
``GET``
1663
~~~~~~~
1664

    
1665
Return a list of all OSes.
1666

    
1667
Can return error 500 in case of a problem. Since this is a costly
1668
operation for Ganeti 2.0, it is not recommended to execute it too often.
1669

    
1670
Example::
1671

    
1672
    ["debian-etch"]
1673

    
1674
``/2/tags``
1675
+++++++++++
1676

    
1677
Manages cluster tags.
1678

    
1679
It supports the following commands: ``GET``, ``PUT``, ``DELETE``.
1680

    
1681
``GET``
1682
~~~~~~~
1683

    
1684
Returns the cluster tags.
1685

    
1686
Example::
1687

    
1688
    ["tag1", "tag2", "tag3"]
1689

    
1690
``PUT``
1691
~~~~~~~
1692

    
1693
Adds a set of tags.
1694

    
1695
The request as a list of strings should be PUT to this URI. The result
1696
will be a job id.
1697

    
1698
It supports the ``dry-run`` argument.
1699

    
1700

    
1701
``DELETE``
1702
~~~~~~~~~~
1703

    
1704
Deletes tags.
1705

    
1706
In order to delete a set of tags, the DELETE request should be addressed
1707
to URI like::
1708

    
1709
    /tags?tag=[tag]&tag=[tag]
1710

    
1711
It supports the ``dry-run`` argument.
1712

    
1713

    
1714
``/version``
1715
++++++++++++
1716

    
1717
The version resource.
1718

    
1719
This resource should be used to determine the remote API version and to
1720
adapt clients accordingly.
1721

    
1722
It supports the following commands: ``GET``.
1723

    
1724
``GET``
1725
~~~~~~~
1726

    
1727
Returns the remote API version. Ganeti 1.2 returned ``1`` and Ganeti 2.0
1728
returns ``2``.
1729

    
1730
.. vim: set textwidth=72 :
1731
.. Local Variables:
1732
.. mode: rst
1733
.. fill-column: 72
1734
.. End: