Statistics
| Branch: | Tag: | Revision:

root / doc / rapi.rst @ 553cb5f7

History | View | Annotate | Download (37.4 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
        constants.ISPEC_SPINDLE_USE]))
201

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

    
206

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

    
211
  :pyeval:`constants.ISPEC_MEM_SIZE`
212
    The size in MiB of the memory used
213
  :pyeval:`constants.ISPEC_DISK_SIZE`
214
    The size in MiB of the disk used
215
  :pyeval:`constants.ISPEC_DISK_COUNT`
216
    The numbers of disks used
217
  :pyeval:`constants.ISPEC_CPU_COUNT`
218
    The numbers of cpus used
219
  :pyeval:`constants.ISPEC_NIC_COUNT`
220
    The numbers of nics used
221
  :pyeval:`constants.ISPEC_SPINDLE_USE`
222
    The numbers of virtual disk spindles used by this instance. They are
223
    not real, but useful for account the spindle usage on the residing
224
    node.
225
:pyeval:`constants.IPOLICY_DTS`
226
  A `list` of disk templates allowed for instances using this policy
227
:pyeval:`constants.IPOLICY_VCPU_RATIO`
228
  Maximum ratio of virtual to physical CPUs (`float`)
229
:pyeval:`constants.IPOLICY_SPINDLE_RATIO`
230
  Maximum ratio of instances to their node's ``spindle_count`` (`float`)
231

    
232
Usage examples
233
--------------
234

    
235
You can access the API using your favorite programming language as long
236
as it supports network connections.
237

    
238
Ganeti RAPI client
239
++++++++++++++++++
240

    
241
Ganeti includes a standalone RAPI client, ``lib/rapi/client.py``.
242

    
243
Shell
244
+++++
245

    
246
.. highlight:: sh
247

    
248
Using wget::
249

    
250
   wget -q -O - https://CLUSTERNAME:5080/2/info
251

    
252
or curl::
253

    
254
  curl https://CLUSTERNAME:5080/2/info
255

    
256

    
257
Python
258
++++++
259

    
260
.. highlight:: python
261

    
262
::
263

    
264
  import urllib2
265
  f = urllib2.urlopen('https://CLUSTERNAME:5080/2/info')
266
  print f.read()
267

    
268

    
269
JavaScript
270
++++++++++
271

    
272
.. warning:: While it's possible to use JavaScript, it poses several
273
   potential problems, including browser blocking request due to
274
   non-standard ports or different domain names. Fetching the data on
275
   the webserver is easier.
276

    
277
.. highlight:: javascript
278

    
279
::
280

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

    
297
Resources
298
---------
299

    
300
.. highlight:: javascript
301

    
302
``/``
303
+++++
304

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

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

    
311
Has no function, but for legacy reasons the ``GET`` method is supported.
312

    
313
``/2/info``
314
+++++++++++
315

    
316
Cluster information resource.
317

    
318
It supports the following commands: ``GET``.
319

    
320
``GET``
321
~~~~~~~
322

    
323
Returns cluster information.
324

    
325
Example::
326

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

    
356

    
357
``/2/redistribute-config``
358
++++++++++++++++++++++++++
359

    
360
Redistribute configuration to all nodes.
361

    
362
It supports the following commands: ``PUT``.
363

    
364
``PUT``
365
~~~~~~~
366

    
367
Redistribute configuration to all nodes. The result will be a job id.
368

    
369
Job result:
370

    
371
.. opcode_result:: OP_CLUSTER_REDIST_CONF
372

    
373

    
374
``/2/features``
375
+++++++++++++++
376

    
377
``GET``
378
~~~~~~~
379

    
380
Returns a list of features supported by the RAPI server. Available
381
features:
382

    
383
.. pyassert::
384

    
385
  rlib2.ALL_FEATURES == set([rlib2._INST_CREATE_REQV1,
386
                             rlib2._INST_REINSTALL_REQV1,
387
                             rlib2._NODE_MIGRATE_REQV1,
388
                             rlib2._NODE_EVAC_RES1])
389

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

    
401

    
402
``/2/modify``
403
++++++++++++++++++++++++++++++++++++++++
404

    
405
Modifies cluster parameters.
406

    
407
Supports the following commands: ``PUT``.
408

    
409
``PUT``
410
~~~~~~~
411

    
412
Returns a job ID.
413

    
414
Body parameters:
415

    
416
.. opcode_params:: OP_CLUSTER_SET_PARAMS
417

    
418
Job result:
419

    
420
.. opcode_result:: OP_CLUSTER_SET_PARAMS
421

    
422

    
423
``/2/groups``
424
+++++++++++++
425

    
426
The groups resource.
427

    
428
It supports the following commands: ``GET``, ``POST``.
429

    
430
``GET``
431
~~~~~~~
432

    
433
Returns a list of all existing node groups.
434

    
435
Example::
436

    
437
    [
438
      {
439
        "name": "group1",
440
        "uri": "\/2\/groups\/group1"
441
      },
442
      {
443
        "name": "group2",
444
        "uri": "\/2\/groups\/group2"
445
      }
446
    ]
447

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

    
452
Returned fields: :pyeval:`utils.CommaJoin(sorted(rlib2.G_FIELDS))`
453

    
454
Example::
455

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

    
476
``POST``
477
~~~~~~~~
478

    
479
Creates a node group.
480

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

    
484
Returns: a job ID that can be used later for polling.
485

    
486
Body parameters:
487

    
488
.. opcode_params:: OP_GROUP_ADD
489

    
490
Earlier versions used a parameter named ``name`` which, while still
491
supported, has been renamed to ``group_name``.
492

    
493
Job result:
494

    
495
.. opcode_result:: OP_GROUP_ADD
496

    
497

    
498
``/2/groups/[group_name]``
499
++++++++++++++++++++++++++
500

    
501
Returns information about a node group.
502

    
503
It supports the following commands: ``GET``, ``DELETE``.
504

    
505
``GET``
506
~~~~~~~
507

    
508
Returns information about a node group, similar to the bulk output from
509
the node group list.
510

    
511
Returned fields: :pyeval:`utils.CommaJoin(sorted(rlib2.G_FIELDS))`
512

    
513
``DELETE``
514
~~~~~~~~~~
515

    
516
Deletes a node group.
517

    
518
It supports the ``dry-run`` argument.
519

    
520
Job result:
521

    
522
.. opcode_result:: OP_GROUP_REMOVE
523

    
524

    
525
``/2/groups/[group_name]/modify``
526
+++++++++++++++++++++++++++++++++
527

    
528
Modifies the parameters of a node group.
529

    
530
Supports the following commands: ``PUT``.
531

    
532
``PUT``
533
~~~~~~~
534

    
535
Returns a job ID.
536

    
537
Body parameters:
538

    
539
.. opcode_params:: OP_GROUP_SET_PARAMS
540
   :exclude: group_name
541

    
542
Job result:
543

    
544
.. opcode_result:: OP_GROUP_SET_PARAMS
545

    
546

    
547
``/2/groups/[group_name]/rename``
548
+++++++++++++++++++++++++++++++++
549

    
550
Renames 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_RENAME
562
   :exclude: group_name
563

    
564
Job result:
565

    
566
.. opcode_result:: OP_GROUP_RENAME
567

    
568

    
569
``/2/groups/[group_name]/assign-nodes``
570
+++++++++++++++++++++++++++++++++++++++
571

    
572
Assigns nodes to a group.
573

    
574
Supports the following commands: ``PUT``.
575

    
576
``PUT``
577
~~~~~~~
578

    
579
Returns a job ID. It supports the ``dry-run`` and ``force`` arguments.
580

    
581
Body parameters:
582

    
583
.. opcode_params:: OP_GROUP_ASSIGN_NODES
584
   :exclude: group_name, force, dry_run
585

    
586
Job result:
587

    
588
.. opcode_result:: OP_GROUP_ASSIGN_NODES
589

    
590

    
591
``/2/groups/[group_name]/tags``
592
+++++++++++++++++++++++++++++++
593

    
594
Manages per-nodegroup tags.
595

    
596
Supports the following commands: ``GET``, ``PUT``, ``DELETE``.
597

    
598
``GET``
599
~~~~~~~
600

    
601
Returns a list of tags.
602

    
603
Example::
604

    
605
    ["tag1", "tag2", "tag3"]
606

    
607
``PUT``
608
~~~~~~~
609

    
610
Add a set of tags.
611

    
612
The request as a list of strings should be ``PUT`` to this URI. The
613
result will be a job id.
614

    
615
It supports the ``dry-run`` argument.
616

    
617

    
618
``DELETE``
619
~~~~~~~~~~
620

    
621
Delete a tag.
622

    
623
In order to delete a set of tags, the DELETE request should be addressed
624
to URI like::
625

    
626
    /tags?tag=[tag]&tag=[tag]
627

    
628
It supports the ``dry-run`` argument.
629

    
630

    
631
``/2/instances``
632
++++++++++++++++
633

    
634
The instances resource.
635

    
636
It supports the following commands: ``GET``, ``POST``.
637

    
638
``GET``
639
~~~~~~~
640

    
641
Returns a list of all available instances.
642

    
643
Example::
644

    
645
    [
646
      {
647
        "name": "web.example.com",
648
        "uri": "\/instances\/web.example.com"
649
      },
650
      {
651
        "name": "mail.example.com",
652
        "uri": "\/instances\/mail.example.com"
653
      }
654
    ]
655

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

    
660
Returned fields: :pyeval:`utils.CommaJoin(sorted(rlib2.I_FIELDS))`
661

    
662
Example::
663

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

    
691

    
692
``POST``
693
~~~~~~~~
694

    
695
Creates an instance.
696

    
697
If the optional bool *dry-run* argument is provided, the job will not be
698
actually executed, only the pre-execution checks will be done. Query-ing
699
the job result will return, in both dry-run and normal case, the list of
700
nodes selected for the instance.
701

    
702
Returns: a job ID that can be used later for polling.
703

    
704
Body parameters:
705

    
706
``__version__`` (int, required)
707
  Must be ``1`` (older Ganeti versions used a different format for
708
  instance creation requests, version ``0``, but that format is no
709
  longer supported)
710

    
711
.. opcode_params:: OP_INSTANCE_CREATE
712

    
713
Earlier versions used parameters named ``name`` and ``os``. These have
714
been replaced by ``instance_name`` and ``os_type`` to match the
715
underlying opcode. The old names can still be used.
716

    
717
Job result:
718

    
719
.. opcode_result:: OP_INSTANCE_CREATE
720

    
721

    
722
``/2/instances/[instance_name]``
723
++++++++++++++++++++++++++++++++
724

    
725
Instance-specific resource.
726

    
727
It supports the following commands: ``GET``, ``DELETE``.
728

    
729
``GET``
730
~~~~~~~
731

    
732
Returns information about an instance, similar to the bulk output from
733
the instance list.
734

    
735
Returned fields: :pyeval:`utils.CommaJoin(sorted(rlib2.I_FIELDS))`
736

    
737
``DELETE``
738
~~~~~~~~~~
739

    
740
Deletes an instance.
741

    
742
It supports the ``dry-run`` argument.
743

    
744
Job result:
745

    
746
.. opcode_result:: OP_INSTANCE_REMOVE
747

    
748

    
749
``/2/instances/[instance_name]/info``
750
+++++++++++++++++++++++++++++++++++++++
751

    
752
It supports the following commands: ``GET``.
753

    
754
``GET``
755
~~~~~~~
756

    
757
Requests detailed information about the instance. An optional parameter,
758
``static`` (bool), can be set to return only static information from the
759
configuration without querying the instance's nodes. The result will be
760
a job id.
761

    
762
Job result:
763

    
764
.. opcode_result:: OP_INSTANCE_QUERY_DATA
765

    
766

    
767
``/2/instances/[instance_name]/reboot``
768
+++++++++++++++++++++++++++++++++++++++
769

    
770
Reboots URI for an instance.
771

    
772
It supports the following commands: ``POST``.
773

    
774
``POST``
775
~~~~~~~~
776

    
777
Reboots the instance.
778

    
779
The URI takes optional ``type=soft|hard|full`` and
780
``ignore_secondaries=0|1`` parameters.
781

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

    
789
``ignore_secondaries`` is a bool argument indicating if we start the
790
instance even if secondary disks are failing.
791

    
792
It supports the ``dry-run`` argument.
793

    
794
Job result:
795

    
796
.. opcode_result:: OP_INSTANCE_REBOOT
797

    
798

    
799
``/2/instances/[instance_name]/shutdown``
800
+++++++++++++++++++++++++++++++++++++++++
801

    
802
Instance shutdown URI.
803

    
804
It supports the following commands: ``PUT``.
805

    
806
``PUT``
807
~~~~~~~
808

    
809
Shutdowns an instance.
810

    
811
It supports the ``dry-run`` argument.
812

    
813
.. opcode_params:: OP_INSTANCE_SHUTDOWN
814
   :exclude: instance_name, dry_run
815

    
816
Job result:
817

    
818
.. opcode_result:: OP_INSTANCE_SHUTDOWN
819

    
820

    
821
``/2/instances/[instance_name]/startup``
822
++++++++++++++++++++++++++++++++++++++++
823

    
824
Instance startup URI.
825

    
826
It supports the following commands: ``PUT``.
827

    
828
``PUT``
829
~~~~~~~
830

    
831
Startup an instance.
832

    
833
The URI takes an optional ``force=1|0`` parameter to start the
834
instance even if secondary disks are failing.
835

    
836
It supports the ``dry-run`` argument.
837

    
838
Job result:
839

    
840
.. opcode_result:: OP_INSTANCE_STARTUP
841

    
842

    
843
``/2/instances/[instance_name]/reinstall``
844
++++++++++++++++++++++++++++++++++++++++++++++
845

    
846
Installs the operating system again.
847

    
848
It supports the following commands: ``POST``.
849

    
850
``POST``
851
~~~~~~~~
852

    
853
Returns a job ID.
854

    
855
Body parameters:
856

    
857
``os`` (string, required)
858
  Instance operating system.
859
``start`` (bool, defaults to true)
860
  Whether to start instance after reinstallation.
861
``osparams`` (dict)
862
  Dictionary with (temporary) OS parameters.
863

    
864
For backwards compatbility, this resource also takes the query
865
parameters ``os`` (OS template name) and ``nostartup`` (bool). New
866
clients should use the body parameters.
867

    
868

    
869
``/2/instances/[instance_name]/replace-disks``
870
++++++++++++++++++++++++++++++++++++++++++++++
871

    
872
Replaces disks on an instance.
873

    
874
It supports the following commands: ``POST``.
875

    
876
``POST``
877
~~~~~~~~
878

    
879
Returns a job ID.
880

    
881
Body parameters:
882

    
883
.. opcode_params:: OP_INSTANCE_REPLACE_DISKS
884
   :exclude: instance_name
885

    
886
Ganeti 2.4 and below used query parameters. Those are deprecated and
887
should no longer be used.
888

    
889
Job result:
890

    
891
.. opcode_result:: OP_INSTANCE_REPLACE_DISKS
892

    
893

    
894
``/2/instances/[instance_name]/activate-disks``
895
+++++++++++++++++++++++++++++++++++++++++++++++
896

    
897
Activate disks on an instance.
898

    
899
It supports the following commands: ``PUT``.
900

    
901
``PUT``
902
~~~~~~~
903

    
904
Takes the bool parameter ``ignore_size``. When set ignore the recorded
905
size (useful for forcing activation when recorded size is wrong).
906

    
907
Job result:
908

    
909
.. opcode_result:: OP_INSTANCE_ACTIVATE_DISKS
910

    
911

    
912
``/2/instances/[instance_name]/deactivate-disks``
913
+++++++++++++++++++++++++++++++++++++++++++++++++
914

    
915
Deactivate disks on an instance.
916

    
917
It supports the following commands: ``PUT``.
918

    
919
``PUT``
920
~~~~~~~
921

    
922
Takes no parameters.
923

    
924
Job result:
925

    
926
.. opcode_result:: OP_INSTANCE_DEACTIVATE_DISKS
927

    
928

    
929
``/2/instances/[instance_name]/recreate-disks``
930
+++++++++++++++++++++++++++++++++++++++++++++++++
931

    
932
Recreate disks of an instance. Supports the following commands:
933
``POST``.
934

    
935
``POST``
936
~~~~~~~~
937

    
938
Returns a job ID.
939

    
940
Body parameters:
941

    
942
.. opcode_params:: OP_INSTANCE_RECREATE_DISKS
943
   :exclude: instance_name
944

    
945
Job result:
946

    
947
.. opcode_result:: OP_INSTANCE_RECREATE_DISKS
948

    
949

    
950
``/2/instances/[instance_name]/disk/[disk_index]/grow``
951
+++++++++++++++++++++++++++++++++++++++++++++++++++++++
952

    
953
Grows one disk of an instance.
954

    
955
Supports the following commands: ``POST``.
956

    
957
``POST``
958
~~~~~~~~
959

    
960
Returns a job ID.
961

    
962
Body parameters:
963

    
964
.. opcode_params:: OP_INSTANCE_GROW_DISK
965
   :exclude: instance_name, disk
966

    
967
Job result:
968

    
969
.. opcode_result:: OP_INSTANCE_GROW_DISK
970

    
971

    
972
``/2/instances/[instance_name]/prepare-export``
973
+++++++++++++++++++++++++++++++++++++++++++++++++
974

    
975
Prepares an export of an instance.
976

    
977
It supports the following commands: ``PUT``.
978

    
979
``PUT``
980
~~~~~~~
981

    
982
Takes one parameter, ``mode``, for the export mode. Returns a job ID.
983

    
984
Job result:
985

    
986
.. opcode_result:: OP_BACKUP_PREPARE
987

    
988

    
989
``/2/instances/[instance_name]/export``
990
+++++++++++++++++++++++++++++++++++++++++++++++++
991

    
992
Exports an instance.
993

    
994
It supports the following commands: ``PUT``.
995

    
996
``PUT``
997
~~~~~~~
998

    
999
Returns a job ID.
1000

    
1001
Body parameters:
1002

    
1003
.. opcode_params:: OP_BACKUP_EXPORT
1004
   :exclude: instance_name
1005
   :alias: target_node=destination
1006

    
1007
Job result:
1008

    
1009
.. opcode_result:: OP_BACKUP_EXPORT
1010

    
1011

    
1012
``/2/instances/[instance_name]/migrate``
1013
++++++++++++++++++++++++++++++++++++++++
1014

    
1015
Migrates an instance.
1016

    
1017
Supports the following commands: ``PUT``.
1018

    
1019
``PUT``
1020
~~~~~~~
1021

    
1022
Returns a job ID.
1023

    
1024
Body parameters:
1025

    
1026
.. opcode_params:: OP_INSTANCE_MIGRATE
1027
   :exclude: instance_name, live
1028

    
1029
Job result:
1030

    
1031
.. opcode_result:: OP_INSTANCE_MIGRATE
1032

    
1033

    
1034
``/2/instances/[instance_name]/failover``
1035
+++++++++++++++++++++++++++++++++++++++++
1036

    
1037
Does a failover of an instance.
1038

    
1039
Supports the following commands: ``PUT``.
1040

    
1041
``PUT``
1042
~~~~~~~
1043

    
1044
Returns a job ID.
1045

    
1046
Body parameters:
1047

    
1048
.. opcode_params:: OP_INSTANCE_FAILOVER
1049
   :exclude: instance_name
1050

    
1051
Job result:
1052

    
1053
.. opcode_result:: OP_INSTANCE_FAILOVER
1054

    
1055

    
1056
``/2/instances/[instance_name]/rename``
1057
++++++++++++++++++++++++++++++++++++++++
1058

    
1059
Renames an instance.
1060

    
1061
Supports the following commands: ``PUT``.
1062

    
1063
``PUT``
1064
~~~~~~~
1065

    
1066
Returns a job ID.
1067

    
1068
Body parameters:
1069

    
1070
.. opcode_params:: OP_INSTANCE_RENAME
1071
   :exclude: instance_name
1072

    
1073
Job result:
1074

    
1075
.. opcode_result:: OP_INSTANCE_RENAME
1076

    
1077

    
1078
``/2/instances/[instance_name]/modify``
1079
++++++++++++++++++++++++++++++++++++++++
1080

    
1081
Modifies an instance.
1082

    
1083
Supports the following commands: ``PUT``.
1084

    
1085
``PUT``
1086
~~~~~~~
1087

    
1088
Returns a job ID.
1089

    
1090
Body parameters:
1091

    
1092
.. opcode_params:: OP_INSTANCE_SET_PARAMS
1093
   :exclude: instance_name
1094

    
1095
Job result:
1096

    
1097
.. opcode_result:: OP_INSTANCE_SET_PARAMS
1098

    
1099

    
1100
``/2/instances/[instance_name]/console``
1101
++++++++++++++++++++++++++++++++++++++++
1102

    
1103
Request information for connecting to instance's console.
1104

    
1105
Supports the following commands: ``GET``.
1106

    
1107
``GET``
1108
~~~~~~~
1109

    
1110
Returns a dictionary containing information about the instance's
1111
console. Contained keys:
1112

    
1113
.. pyassert::
1114

    
1115
   constants.CONS_ALL == frozenset([
1116
     constants.CONS_MESSAGE,
1117
     constants.CONS_SSH,
1118
     constants.CONS_VNC,
1119
     constants.CONS_SPICE,
1120
     ])
1121

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

    
1143

    
1144
``/2/instances/[instance_name]/tags``
1145
+++++++++++++++++++++++++++++++++++++
1146

    
1147
Manages per-instance tags.
1148

    
1149
It supports the following commands: ``GET``, ``PUT``, ``DELETE``.
1150

    
1151
``GET``
1152
~~~~~~~
1153

    
1154
Returns a list of tags.
1155

    
1156
Example::
1157

    
1158
    ["tag1", "tag2", "tag3"]
1159

    
1160
``PUT``
1161
~~~~~~~
1162

    
1163
Add a set of tags.
1164

    
1165
The request as a list of strings should be ``PUT`` to this URI. The
1166
result will be a job id.
1167

    
1168
It supports the ``dry-run`` argument.
1169

    
1170

    
1171
``DELETE``
1172
~~~~~~~~~~
1173

    
1174
Delete a tag.
1175

    
1176
In order to delete a set of tags, the DELETE request should be addressed
1177
to URI like::
1178

    
1179
    /tags?tag=[tag]&tag=[tag]
1180

    
1181
It supports the ``dry-run`` argument.
1182

    
1183

    
1184
``/2/jobs``
1185
+++++++++++
1186

    
1187
The ``/2/jobs`` resource.
1188

    
1189
It supports the following commands: ``GET``.
1190

    
1191
``GET``
1192
~~~~~~~
1193

    
1194
Returns a dictionary of jobs.
1195

    
1196
Returns: a dictionary with jobs id and uri.
1197

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

    
1202
Returned fields for bulk requests (unlike other bulk requests, these
1203
fields are not the same as for per-job requests):
1204
:pyeval:`utils.CommaJoin(sorted(rlib2.J_FIELDS_BULK))`
1205

    
1206
``/2/jobs/[job_id]``
1207
++++++++++++++++++++
1208

    
1209

    
1210
Individual job URI.
1211

    
1212
It supports the following commands: ``GET``, ``DELETE``.
1213

    
1214
``GET``
1215
~~~~~~~
1216

    
1217
Returns a dictionary with job parameters, containing the fields
1218
:pyeval:`utils.CommaJoin(sorted(rlib2.J_FIELDS))`.
1219

    
1220
The result includes:
1221

    
1222
- id: job ID as a number
1223
- status: current job status as a string
1224
- ops: involved OpCodes as a list of dictionaries for each opcodes in
1225
  the job
1226
- opstatus: OpCodes status as a list
1227
- opresult: OpCodes results as a list
1228

    
1229
For a successful opcode, the ``opresult`` field corresponding to it will
1230
contain the raw result from its :term:`LogicalUnit`. In case an opcode
1231
has failed, its element in the opresult list will be a list of two
1232
elements:
1233

    
1234
- first element the error type (the Ganeti internal error name)
1235
- second element a list of either one or two elements:
1236

    
1237
  - the first element is the textual error description
1238
  - the second element, if any, will hold an error classification
1239

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

    
1246
.. pyassert::
1247

    
1248
   errors.ECODE_ALL == set([errors.ECODE_RESOLVER, errors.ECODE_NORES,
1249
     errors.ECODE_INVAL, errors.ECODE_STATE, errors.ECODE_NOENT,
1250
     errors.ECODE_EXISTS, errors.ECODE_NOTUNIQUE, errors.ECODE_FAULT,
1251
     errors.ECODE_ENVIRON])
1252

    
1253
:pyeval:`errors.ECODE_RESOLVER`
1254
  Resolver errors. This usually means that a name doesn't exist in DNS,
1255
  so if it's a case of slow DNS propagation the operation can be retried
1256
  later.
1257

    
1258
:pyeval:`errors.ECODE_NORES`
1259
  Not enough resources (iallocator failure, disk space, memory,
1260
  etc.). If the resources on the cluster increase, the operation might
1261
  succeed.
1262

    
1263
:pyeval:`errors.ECODE_INVAL`
1264
  Wrong arguments (at syntax level). The operation will not ever be
1265
  accepted unless the arguments change.
1266

    
1267
:pyeval:`errors.ECODE_STATE`
1268
  Wrong entity state. For example, live migration has been requested for
1269
  a down instance, or instance creation on an offline node. The
1270
  operation can be retried once the resource has changed state.
1271

    
1272
:pyeval:`errors.ECODE_NOENT`
1273
  Entity not found. For example, information has been requested for an
1274
  unknown instance.
1275

    
1276
:pyeval:`errors.ECODE_EXISTS`
1277
  Entity already exists. For example, instance creation has been
1278
  requested for an already-existing instance.
1279

    
1280
:pyeval:`errors.ECODE_NOTUNIQUE`
1281
  Resource not unique (e.g. MAC or IP duplication).
1282

    
1283
:pyeval:`errors.ECODE_FAULT`
1284
  Internal cluster error. For example, a node is unreachable but not set
1285
  offline, or the ganeti node daemons are not working, etc. A
1286
  ``gnt-cluster verify`` should be run.
1287

    
1288
:pyeval:`errors.ECODE_ENVIRON`
1289
  Environment error (e.g. node disk error). A ``gnt-cluster verify``
1290
  should be run.
1291

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

    
1295

    
1296
``DELETE``
1297
~~~~~~~~~~
1298

    
1299
Cancel a not-yet-started job.
1300

    
1301

    
1302
``/2/jobs/[job_id]/wait``
1303
+++++++++++++++++++++++++
1304

    
1305
``GET``
1306
~~~~~~~
1307

    
1308
Waits for changes on a job. Takes the following body parameters in a
1309
dict:
1310

    
1311
``fields``
1312
  The job fields on which to watch for changes.
1313

    
1314
``previous_job_info``
1315
  Previously received field values or None if not yet available.
1316

    
1317
``previous_log_serial``
1318
  Highest log serial number received so far or None if not yet
1319
  available.
1320

    
1321
Returns None if no changes have been detected and a dict with two keys,
1322
``job_info`` and ``log_entries`` otherwise.
1323

    
1324

    
1325
``/2/nodes``
1326
++++++++++++
1327

    
1328
Nodes resource.
1329

    
1330
It supports the following commands: ``GET``.
1331

    
1332
``GET``
1333
~~~~~~~
1334

    
1335
Returns a list of all nodes.
1336

    
1337
Example::
1338

    
1339
    [
1340
      {
1341
        "id": "node1.example.com",
1342
        "uri": "\/nodes\/node1.example.com"
1343
      },
1344
      {
1345
        "id": "node2.example.com",
1346
        "uri": "\/nodes\/node2.example.com"
1347
      }
1348
    ]
1349

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

    
1354
Returned fields: :pyeval:`utils.CommaJoin(sorted(rlib2.N_FIELDS))`
1355

    
1356
Example::
1357

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

    
1374
``/2/nodes/[node_name]``
1375
+++++++++++++++++++++++++++++++++
1376

    
1377
Returns information about a node.
1378

    
1379
It supports the following commands: ``GET``.
1380

    
1381
Returned fields: :pyeval:`utils.CommaJoin(sorted(rlib2.N_FIELDS))`
1382

    
1383
``/2/nodes/[node_name]/powercycle``
1384
+++++++++++++++++++++++++++++++++++
1385

    
1386
Powercycles a node. Supports the following commands: ``POST``.
1387

    
1388
``POST``
1389
~~~~~~~~
1390

    
1391
Returns a job ID.
1392

    
1393
Job result:
1394

    
1395
.. opcode_result:: OP_NODE_POWERCYCLE
1396

    
1397

    
1398
``/2/nodes/[node_name]/evacuate``
1399
+++++++++++++++++++++++++++++++++
1400

    
1401
Evacuates instances off a node.
1402

    
1403
It supports the following commands: ``POST``.
1404

    
1405
``POST``
1406
~~~~~~~~
1407

    
1408
Returns a job ID. The result of the job will contain the IDs of the
1409
individual jobs submitted to evacuate the node.
1410

    
1411
Body parameters:
1412

    
1413
.. opcode_params:: OP_NODE_EVACUATE
1414
   :exclude: nodes
1415

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

    
1420
Job result:
1421

    
1422
.. opcode_result:: OP_NODE_EVACUATE
1423

    
1424

    
1425
``/2/nodes/[node_name]/migrate``
1426
+++++++++++++++++++++++++++++++++
1427

    
1428
Migrates all primary instances from a node.
1429

    
1430
It supports the following commands: ``POST``.
1431

    
1432
``POST``
1433
~~~~~~~~
1434

    
1435
If no mode is explicitly specified, each instances' hypervisor default
1436
migration mode will be used. Body parameters:
1437

    
1438
.. opcode_params:: OP_NODE_MIGRATE
1439
   :exclude: node_name
1440

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

    
1445
Job result:
1446

    
1447
.. opcode_result:: OP_NODE_MIGRATE
1448

    
1449

    
1450
``/2/nodes/[node_name]/role``
1451
+++++++++++++++++++++++++++++
1452

    
1453
Manages node role.
1454

    
1455
It supports the following commands: ``GET``, ``PUT``.
1456

    
1457
The role is always one of the following:
1458

    
1459
  - drained
1460
  - master-candidate
1461
  - offline
1462
  - regular
1463

    
1464
Note that the 'master' role is a special, and currently it can't be
1465
modified via RAPI, only via the command line (``gnt-cluster
1466
master-failover``).
1467

    
1468
``GET``
1469
~~~~~~~
1470

    
1471
Returns the current node role.
1472

    
1473
Example::
1474

    
1475
    "master-candidate"
1476

    
1477
``PUT``
1478
~~~~~~~
1479

    
1480
Change the node role.
1481

    
1482
The request is a string which should be PUT to this URI. The result will
1483
be a job id.
1484

    
1485
It supports the bool ``force`` argument.
1486

    
1487
Job result:
1488

    
1489
.. opcode_result:: OP_NODE_SET_PARAMS
1490

    
1491

    
1492
``/2/nodes/[node_name]/modify``
1493
+++++++++++++++++++++++++++++++
1494

    
1495
Modifies the parameters of a node. Supports the following commands:
1496
``POST``.
1497

    
1498
``POST``
1499
~~~~~~~~
1500

    
1501
Returns a job ID.
1502

    
1503
Body parameters:
1504

    
1505
.. opcode_params:: OP_NODE_SET_PARAMS
1506
   :exclude: node_name
1507

    
1508
Job result:
1509

    
1510
.. opcode_result:: OP_NODE_SET_PARAMS
1511

    
1512

    
1513
``/2/nodes/[node_name]/storage``
1514
++++++++++++++++++++++++++++++++
1515

    
1516
Manages storage units on the node.
1517

    
1518
``GET``
1519
~~~~~~~
1520

    
1521
.. pyassert::
1522

    
1523
   constants.VALID_STORAGE_TYPES == set([constants.ST_FILE,
1524
                                         constants.ST_LVM_PV,
1525
                                         constants.ST_LVM_VG])
1526

    
1527
Requests a list of storage units on a node. Requires the parameters
1528
``storage_type`` (one of :pyeval:`constants.ST_FILE`,
1529
:pyeval:`constants.ST_LVM_PV` or :pyeval:`constants.ST_LVM_VG`) and
1530
``output_fields``. The result will be a job id, using which the result
1531
can be retrieved.
1532

    
1533
``/2/nodes/[node_name]/storage/modify``
1534
+++++++++++++++++++++++++++++++++++++++
1535

    
1536
Modifies storage units on the node.
1537

    
1538
``PUT``
1539
~~~~~~~
1540

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

    
1548
Job result:
1549

    
1550
.. opcode_result:: OP_NODE_MODIFY_STORAGE
1551

    
1552

    
1553
``/2/nodes/[node_name]/storage/repair``
1554
+++++++++++++++++++++++++++++++++++++++
1555

    
1556
Repairs a storage unit on the node.
1557

    
1558
``PUT``
1559
~~~~~~~
1560

    
1561
.. pyassert::
1562

    
1563
   constants.VALID_STORAGE_OPERATIONS == {
1564
    constants.ST_LVM_VG: set([constants.SO_FIX_CONSISTENCY]),
1565
    }
1566

    
1567
Repairs a storage unit on the node. Requires the parameters
1568
``storage_type`` (currently only :pyeval:`constants.ST_LVM_VG` can be
1569
repaired) and ``name`` (name of the storage unit). The result will be a
1570
job id.
1571

    
1572
Job result:
1573

    
1574
.. opcode_result:: OP_REPAIR_NODE_STORAGE
1575

    
1576

    
1577
``/2/nodes/[node_name]/tags``
1578
+++++++++++++++++++++++++++++
1579

    
1580
Manages per-node tags.
1581

    
1582
It supports the following commands: ``GET``, ``PUT``, ``DELETE``.
1583

    
1584
``GET``
1585
~~~~~~~
1586

    
1587
Returns a list of tags.
1588

    
1589
Example::
1590

    
1591
    ["tag1", "tag2", "tag3"]
1592

    
1593
``PUT``
1594
~~~~~~~
1595

    
1596
Add a set of tags.
1597

    
1598
The request as a list of strings should be PUT to this URI. The result
1599
will be a job id.
1600

    
1601
It supports the ``dry-run`` argument.
1602

    
1603
``DELETE``
1604
~~~~~~~~~~
1605

    
1606
Deletes tags.
1607

    
1608
In order to delete a set of tags, the DELETE request should be addressed
1609
to URI like::
1610

    
1611
    /tags?tag=[tag]&tag=[tag]
1612

    
1613
It supports the ``dry-run`` argument.
1614

    
1615

    
1616
``/2/query/[resource]``
1617
+++++++++++++++++++++++
1618

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

    
1624
Supports the following commands: ``GET``, ``PUT``.
1625

    
1626
``GET``
1627
~~~~~~~
1628

    
1629
Returns list of included fields and actual data. Takes a query parameter
1630
named "fields", containing a comma-separated list of field names. Does
1631
not support filtering.
1632

    
1633
``PUT``
1634
~~~~~~~
1635

    
1636
Returns list of included fields and actual data. The list of requested
1637
fields can either be given as the query parameter "fields" or as a body
1638
parameter with the same name. The optional body parameter "filter" can
1639
be given and must be either ``null`` or a list containing filter
1640
operators.
1641

    
1642

    
1643
``/2/query/[resource]/fields``
1644
++++++++++++++++++++++++++++++
1645

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

    
1650
Supports the following commands: ``GET``.
1651

    
1652
``GET``
1653
~~~~~~~
1654

    
1655
Returns a list of field descriptions for available fields. Takes an
1656
optional query parameter named "fields", containing a comma-separated
1657
list of field names.
1658

    
1659

    
1660
``/2/os``
1661
+++++++++
1662

    
1663
OS resource.
1664

    
1665
It supports the following commands: ``GET``.
1666

    
1667
``GET``
1668
~~~~~~~
1669

    
1670
Return a list of all OSes.
1671

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

    
1675
Example::
1676

    
1677
    ["debian-etch"]
1678

    
1679
``/2/tags``
1680
+++++++++++
1681

    
1682
Manages cluster tags.
1683

    
1684
It supports the following commands: ``GET``, ``PUT``, ``DELETE``.
1685

    
1686
``GET``
1687
~~~~~~~
1688

    
1689
Returns the cluster tags.
1690

    
1691
Example::
1692

    
1693
    ["tag1", "tag2", "tag3"]
1694

    
1695
``PUT``
1696
~~~~~~~
1697

    
1698
Adds a set of tags.
1699

    
1700
The request as a list of strings should be PUT to this URI. The result
1701
will be a job id.
1702

    
1703
It supports the ``dry-run`` argument.
1704

    
1705

    
1706
``DELETE``
1707
~~~~~~~~~~
1708

    
1709
Deletes tags.
1710

    
1711
In order to delete a set of tags, the DELETE request should be addressed
1712
to URI like::
1713

    
1714
    /tags?tag=[tag]&tag=[tag]
1715

    
1716
It supports the ``dry-run`` argument.
1717

    
1718

    
1719
``/version``
1720
++++++++++++
1721

    
1722
The version resource.
1723

    
1724
This resource should be used to determine the remote API version and to
1725
adapt clients accordingly.
1726

    
1727
It supports the following commands: ``GET``.
1728

    
1729
``GET``
1730
~~~~~~~
1731

    
1732
Returns the remote API version. Ganeti 1.2 returned ``1`` and Ganeti 2.0
1733
returns ``2``.
1734

    
1735
.. vim: set textwidth=72 :
1736
.. Local Variables:
1737
.. mode: rst
1738
.. fill-column: 72
1739
.. End: