Statistics
| Branch: | Tag: | Revision:

root / doc / rapi.rst @ 5e12acfe

History | View | Annotate | Download (38.8 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
Lines starting with the hash sign (``#``) are treated as comments. Each
28
line consists of two or three fields separated by whitespace. The first
29
two fields are for username and password. The third field is optional
30
and can be used to specify per-user options (separated by comma without
31
spaces). Available options:
32

    
33
.. pyassert::
34

    
35
  rapi.RAPI_ACCESS_ALL == set([
36
    rapi.RAPI_ACCESS_WRITE,
37
    rapi.RAPI_ACCESS_READ,
38
    ])
39

    
40
:pyeval:`rapi.RAPI_ACCESS_WRITE`
41
  Enables the user to execute operations modifying the cluster. Implies
42
  :pyeval:`rapi.RAPI_ACCESS_READ` access.
43
:pyeval:`rapi.RAPI_ACCESS_READ`
44
  Allow access to operations querying for information.
45

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

    
54
Example::
55

    
56
  # Give Jack and Fred read-only access
57
  jack abc123
58
  fred {cleartext}foo555
59

    
60
  # Give write access to an imaginary instance creation script
61
  autocreator xyz789 write
62

    
63
  # Hashed password for Jessica
64
  jessica {HA1}7046452df2cbb530877058712cf17bd4 write
65

    
66
  # Monitoring can query for values
67
  monitoring {HA1}ec018ffe72b8e75bb4d508ed5b6d079c query
68

    
69
  # A user who can query and write
70
  superuser {HA1}ec018ffe72b8e75bb4d508ed5b6d079c query,write
71

    
72

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

    
81

    
82
Protocol
83
--------
84

    
85
The protocol used is JSON_ over HTTP designed after the REST_ principle.
86
HTTP Basic authentication as per :rfc:`2617` is supported.
87

    
88
.. _JSON: http://www.json.org/
89
.. _REST: http://en.wikipedia.org/wiki/Representational_State_Transfer
90

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

    
95

    
96
A note on JSON as used by RAPI
97
++++++++++++++++++++++++++++++
98

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

    
106
.. highlight:: ruby
107

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

    
116
  require "json"
117

    
118
  # Insert code to get response here
119
  response = "\"1234\""
120

    
121
  decoded = JSON.parse("[#{response}]").first
122

    
123
Short of modifying the encoder to allow encoding to a less strict
124
format, requests will have to be formatted by hand. Newer RAPI requests
125
already use a dictionary as their input data and shouldn't cause any
126
problems.
127

    
128

    
129
PUT or POST?
130
------------
131

    
132
According to :rfc:`2616` the main difference between PUT and POST is
133
that POST can create new resources but PUT can only create the resource
134
the URI was pointing to on the PUT request.
135

    
136
Unfortunately, due to historic reasons, the Ganeti RAPI library is not
137
consistent with this usage, so just use the methods as documented below
138
for each resource.
139

    
140
For more details have a look in the source code at
141
``lib/rapi/rlib2.py``.
142

    
143

    
144
Generic parameter types
145
-----------------------
146

    
147
A few generic refered parameter types and the values they allow.
148

    
149
``bool``
150
++++++++
151

    
152
A boolean option will accept ``1`` or ``0`` as numbers but not
153
i.e. ``True`` or ``False``.
154

    
155
Generic parameters
156
------------------
157

    
158
A few parameter mean the same thing across all resources which implement
159
it.
160

    
161
``bulk``
162
++++++++
163

    
164
Bulk-mode means that for the resources which usually return just a list
165
of child resources (e.g. ``/2/instances`` which returns just instance
166
names), the output will instead contain detailed data for all these
167
subresources. This is more efficient than query-ing the sub-resources
168
themselves.
169

    
170
``dry-run``
171
+++++++++++
172

    
173
The boolean *dry-run* argument, if provided and set, signals to Ganeti
174
that the job should not be executed, only the pre-execution checks will
175
be done.
176

    
177
This is useful in trying to determine (without guarantees though, as in
178
the meantime the cluster state could have changed) if the operation is
179
likely to succeed or at least start executing.
180

    
181
``force``
182
+++++++++++
183

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

    
187
Parameter details
188
-----------------
189

    
190
Some parameters are not straight forward, so we describe them in details
191
here.
192

    
193
.. _rapi-ipolicy:
194

    
195
``ipolicy``
196
+++++++++++
197

    
198
The instance policy specification is a dict with the following fields:
199

    
200
.. pyassert::
201

    
202
  constants.IPOLICY_ALL_KEYS == set([constants.ISPECS_MIN,
203
                                     constants.ISPECS_MAX,
204
                                     constants.ISPECS_STD,
205
                                     constants.IPOLICY_DTS,
206
                                     constants.IPOLICY_VCPU_RATIO,
207
                                     constants.IPOLICY_SPINDLE_RATIO])
208

    
209

    
210
.. pyassert::
211

    
212
  (set(constants.ISPECS_PARAMETER_TYPES.keys()) ==
213
   set([constants.ISPEC_MEM_SIZE,
214
        constants.ISPEC_DISK_SIZE,
215
        constants.ISPEC_DISK_COUNT,
216
        constants.ISPEC_CPU_COUNT,
217
        constants.ISPEC_NIC_COUNT,
218
        constants.ISPEC_SPINDLE_USE]))
219

    
220
.. |ispec-min| replace:: :pyeval:`constants.ISPECS_MIN`
221
.. |ispec-max| replace:: :pyeval:`constants.ISPECS_MAX`
222
.. |ispec-std| replace:: :pyeval:`constants.ISPECS_STD`
223

    
224

    
225
|ispec-min|, |ispec-max|, |ispec-std|
226
  A sub- `dict` with the following fields, which sets the limit and standard
227
  values of the instances:
228

    
229
  :pyeval:`constants.ISPEC_MEM_SIZE`
230
    The size in MiB of the memory used
231
  :pyeval:`constants.ISPEC_DISK_SIZE`
232
    The size in MiB of the disk used
233
  :pyeval:`constants.ISPEC_DISK_COUNT`
234
    The numbers of disks used
235
  :pyeval:`constants.ISPEC_CPU_COUNT`
236
    The numbers of cpus used
237
  :pyeval:`constants.ISPEC_NIC_COUNT`
238
    The numbers of nics used
239
  :pyeval:`constants.ISPEC_SPINDLE_USE`
240
    The numbers of virtual disk spindles used by this instance. They are
241
    not real in the sense of actual HDD spindles, but useful for
242
    accounting the spindle usage on the residing node
243
:pyeval:`constants.IPOLICY_DTS`
244
  A `list` of disk templates allowed for instances using this policy
245
:pyeval:`constants.IPOLICY_VCPU_RATIO`
246
  Maximum ratio of virtual to physical CPUs (`float`)
247
:pyeval:`constants.IPOLICY_SPINDLE_RATIO`
248
  Maximum ratio of instances to their node's ``spindle_count`` (`float`)
249

    
250
Usage examples
251
--------------
252

    
253
You can access the API using your favorite programming language as long
254
as it supports network connections.
255

    
256
Ganeti RAPI client
257
++++++++++++++++++
258

    
259
Ganeti includes a standalone RAPI client, ``lib/rapi/client.py``.
260

    
261
Shell
262
+++++
263

    
264
.. highlight:: shell-example
265

    
266
Using wget::
267

    
268
   $ wget -q -O - https://%CLUSTERNAME%:5080/2/info
269

    
270
or curl::
271

    
272
  $ curl https://%CLUSTERNAME%:5080/2/info
273

    
274

    
275
Python
276
++++++
277

    
278
.. highlight:: python
279

    
280
::
281

    
282
  import urllib2
283
  f = urllib2.urlopen('https://CLUSTERNAME:5080/2/info')
284
  print f.read()
285

    
286

    
287
JavaScript
288
++++++++++
289

    
290
.. warning:: While it's possible to use JavaScript, it poses several
291
   potential problems, including browser blocking request due to
292
   non-standard ports or different domain names. Fetching the data on
293
   the webserver is easier.
294

    
295
.. highlight:: javascript
296

    
297
::
298

    
299
  var url = 'https://CLUSTERNAME:5080/2/info';
300
  var info;
301
  var xmlreq = new XMLHttpRequest();
302
  xmlreq.onreadystatechange = function () {
303
    if (xmlreq.readyState != 4) return;
304
    if (xmlreq.status == 200) {
305
      info = eval("(" + xmlreq.responseText + ")");
306
      alert(info);
307
    } else {
308
      alert('Error fetching cluster info');
309
    }
310
    xmlreq = null;
311
  };
312
  xmlreq.open('GET', url, true);
313
  xmlreq.send(null);
314

    
315
Resources
316
---------
317

    
318
.. highlight:: javascript
319

    
320
``/``
321
+++++
322

    
323
The root resource. Has no function, but for legacy reasons the ``GET``
324
method is supported.
325

    
326
``/2``
327
++++++
328

    
329
Has no function, but for legacy reasons the ``GET`` method is supported.
330

    
331
``/2/info``
332
+++++++++++
333

    
334
Cluster information resource.
335

    
336
It supports the following commands: ``GET``.
337

    
338
``GET``
339
~~~~~~~
340

    
341
Returns cluster information.
342

    
343
Example::
344

    
345
  {
346
    "config_version": 2000000,
347
    "name": "cluster",
348
    "software_version": "2.0.0~beta2",
349
    "os_api_version": 10,
350
    "export_version": 0,
351
    "candidate_pool_size": 10,
352
    "enabled_hypervisors": [
353
      "fake"
354
    ],
355
    "hvparams": {
356
      "fake": {}
357
     },
358
    "default_hypervisor": "fake",
359
    "master": "node1.example.com",
360
    "architecture": [
361
      "64bit",
362
      "x86_64"
363
    ],
364
    "protocol_version": 20,
365
    "beparams": {
366
      "default": {
367
        "auto_balance": true,
368
        "vcpus": 1,
369
        "memory": 128
370
       }
371
      }
372
    }
373

    
374

    
375
``/2/redistribute-config``
376
++++++++++++++++++++++++++
377

    
378
Redistribute configuration to all nodes.
379

    
380
It supports the following commands: ``PUT``.
381

    
382
``PUT``
383
~~~~~~~
384

    
385
Redistribute configuration to all nodes. The result will be a job id.
386

    
387
Job result:
388

    
389
.. opcode_result:: OP_CLUSTER_REDIST_CONF
390

    
391

    
392
``/2/features``
393
+++++++++++++++
394

    
395
``GET``
396
~~~~~~~
397

    
398
Returns a list of features supported by the RAPI server. Available
399
features:
400

    
401
.. pyassert::
402

    
403
  rlib2.ALL_FEATURES == set([rlib2._INST_CREATE_REQV1,
404
                             rlib2._INST_REINSTALL_REQV1,
405
                             rlib2._NODE_MIGRATE_REQV1,
406
                             rlib2._NODE_EVAC_RES1])
407

    
408
:pyeval:`rlib2._INST_CREATE_REQV1`
409
  Instance creation request data version 1 supported
410
:pyeval:`rlib2._INST_REINSTALL_REQV1`
411
  Instance reinstall supports body parameters
412
:pyeval:`rlib2._NODE_MIGRATE_REQV1`
413
  Whether migrating a node (``/2/nodes/[node_name]/migrate``) supports
414
  request body parameters
415
:pyeval:`rlib2._NODE_EVAC_RES1`
416
  Whether evacuating a node (``/2/nodes/[node_name]/evacuate``) returns
417
  a new-style result (see resource description)
418

    
419

    
420
``/2/modify``
421
++++++++++++++++++++++++++++++++++++++++
422

    
423
Modifies cluster parameters.
424

    
425
Supports the following commands: ``PUT``.
426

    
427
``PUT``
428
~~~~~~~
429

    
430
Returns a job ID.
431

    
432
Body parameters:
433

    
434
.. opcode_params:: OP_CLUSTER_SET_PARAMS
435

    
436
Job result:
437

    
438
.. opcode_result:: OP_CLUSTER_SET_PARAMS
439

    
440

    
441
``/2/groups``
442
+++++++++++++
443

    
444
The groups resource.
445

    
446
It supports the following commands: ``GET``, ``POST``.
447

    
448
``GET``
449
~~~~~~~
450

    
451
Returns a list of all existing node groups.
452

    
453
Example::
454

    
455
    [
456
      {
457
        "name": "group1",
458
        "uri": "\/2\/groups\/group1"
459
      },
460
      {
461
        "name": "group2",
462
        "uri": "\/2\/groups\/group2"
463
      }
464
    ]
465

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

    
470
Returned fields: :pyeval:`utils.CommaJoin(sorted(rlib2.G_FIELDS))`.
471

    
472
Example::
473

    
474
    [
475
      {
476
        "name": "group1",
477
        "node_cnt": 2,
478
        "node_list": [
479
          "node1.example.com",
480
          "node2.example.com"
481
        ],
482
        "uuid": "0d7d407c-262e-49af-881a-6a430034bf43"
483
      },
484
      {
485
        "name": "group2",
486
        "node_cnt": 1,
487
        "node_list": [
488
          "node3.example.com"
489
        ],
490
        "uuid": "f5a277e7-68f9-44d3-a378-4b25ecb5df5c"
491
      }
492
    ]
493

    
494
``POST``
495
~~~~~~~~
496

    
497
Creates a node group.
498

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

    
502
Returns: a job ID that can be used later for polling.
503

    
504
Body parameters:
505

    
506
.. opcode_params:: OP_GROUP_ADD
507

    
508
Earlier versions used a parameter named ``name`` which, while still
509
supported, has been renamed to ``group_name``.
510

    
511
Job result:
512

    
513
.. opcode_result:: OP_GROUP_ADD
514

    
515

    
516
``/2/groups/[group_name]``
517
++++++++++++++++++++++++++
518

    
519
Returns information about a node group.
520

    
521
It supports the following commands: ``GET``, ``DELETE``.
522

    
523
``GET``
524
~~~~~~~
525

    
526
Returns information about a node group, similar to the bulk output from
527
the node group list.
528

    
529
Returned fields: :pyeval:`utils.CommaJoin(sorted(rlib2.G_FIELDS))`.
530

    
531
``DELETE``
532
~~~~~~~~~~
533

    
534
Deletes a node group.
535

    
536
It supports the ``dry-run`` argument.
537

    
538
Job result:
539

    
540
.. opcode_result:: OP_GROUP_REMOVE
541

    
542

    
543
``/2/groups/[group_name]/modify``
544
+++++++++++++++++++++++++++++++++
545

    
546
Modifies the parameters of a node group.
547

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

    
550
``PUT``
551
~~~~~~~
552

    
553
Returns a job ID.
554

    
555
Body parameters:
556

    
557
.. opcode_params:: OP_GROUP_SET_PARAMS
558
   :exclude: group_name
559

    
560
Job result:
561

    
562
.. opcode_result:: OP_GROUP_SET_PARAMS
563

    
564

    
565
``/2/groups/[group_name]/rename``
566
+++++++++++++++++++++++++++++++++
567

    
568
Renames a node group.
569

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

    
572
``PUT``
573
~~~~~~~
574

    
575
Returns a job ID.
576

    
577
Body parameters:
578

    
579
.. opcode_params:: OP_GROUP_RENAME
580
   :exclude: group_name
581

    
582
Job result:
583

    
584
.. opcode_result:: OP_GROUP_RENAME
585

    
586

    
587
``/2/groups/[group_name]/assign-nodes``
588
+++++++++++++++++++++++++++++++++++++++
589

    
590
Assigns nodes to a group.
591

    
592
Supports the following commands: ``PUT``.
593

    
594
``PUT``
595
~~~~~~~
596

    
597
Returns a job ID. It supports the ``dry-run`` and ``force`` arguments.
598

    
599
Body parameters:
600

    
601
.. opcode_params:: OP_GROUP_ASSIGN_NODES
602
   :exclude: group_name, force, dry_run
603

    
604
Job result:
605

    
606
.. opcode_result:: OP_GROUP_ASSIGN_NODES
607

    
608

    
609
``/2/groups/[group_name]/tags``
610
+++++++++++++++++++++++++++++++
611

    
612
Manages per-nodegroup tags.
613

    
614
Supports the following commands: ``GET``, ``PUT``, ``DELETE``.
615

    
616
``GET``
617
~~~~~~~
618

    
619
Returns a list of tags.
620

    
621
Example::
622

    
623
    ["tag1", "tag2", "tag3"]
624

    
625
``PUT``
626
~~~~~~~
627

    
628
Add a set of tags.
629

    
630
The request as a list of strings should be ``PUT`` to this URI. The
631
result will be a job id.
632

    
633
It supports the ``dry-run`` argument.
634

    
635

    
636
``DELETE``
637
~~~~~~~~~~
638

    
639
Delete a tag.
640

    
641
In order to delete a set of tags, the DELETE request should be addressed
642
to URI like::
643

    
644
    /tags?tag=[tag]&tag=[tag]
645

    
646
It supports the ``dry-run`` argument.
647

    
648

    
649
``/2/instances-multi-alloc``
650
++++++++++++++++++++++++++++
651

    
652
Tries to allocate multiple instances.
653

    
654
It supports the following commands: ``POST``
655

    
656
``POST``
657
~~~~~~~~
658

    
659
The parameters:
660

    
661
.. opcode_params:: OP_INSTANCE_MULTI_ALLOC
662

    
663
Job result:
664

    
665
.. opcode_result:: OP_INSTANCE_MULTI_ALLOC
666

    
667

    
668
``/2/instances``
669
++++++++++++++++
670

    
671
The instances resource.
672

    
673
It supports the following commands: ``GET``, ``POST``.
674

    
675
``GET``
676
~~~~~~~
677

    
678
Returns a list of all available instances.
679

    
680
Example::
681

    
682
    [
683
      {
684
        "name": "web.example.com",
685
        "uri": "\/instances\/web.example.com"
686
      },
687
      {
688
        "name": "mail.example.com",
689
        "uri": "\/instances\/mail.example.com"
690
      }
691
    ]
692

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

    
697
Returned fields: :pyeval:`utils.CommaJoin(sorted(rlib2.I_FIELDS))`.
698

    
699
Example::
700

    
701
    [
702
      {
703
         "status": "running",
704
         "disk_usage": 20480,
705
         "nic.bridges": [
706
           "xen-br0"
707
          ],
708
         "name": "web.example.com",
709
         "tags": ["tag1", "tag2"],
710
         "beparams": {
711
           "vcpus": 2,
712
           "memory": 512
713
         },
714
         "disk.sizes": [
715
             20480
716
         ],
717
         "pnode": "node1.example.com",
718
         "nic.macs": ["01:23:45:67:89:01"],
719
         "snodes": ["node2.example.com"],
720
         "disk_template": "drbd",
721
         "admin_state": true,
722
         "os": "debian-etch",
723
         "oper_state": true
724
      },
725
      ...
726
    ]
727

    
728

    
729
``POST``
730
~~~~~~~~
731

    
732
Creates an instance.
733

    
734
If the optional bool *dry-run* argument is provided, the job will not be
735
actually executed, only the pre-execution checks will be done. Query-ing
736
the job result will return, in both dry-run and normal case, the list of
737
nodes selected for the instance.
738

    
739
Returns: a job ID that can be used later for polling.
740

    
741
Body parameters:
742

    
743
``__version__`` (int, required)
744
  Must be ``1`` (older Ganeti versions used a different format for
745
  instance creation requests, version ``0``, but that format is no
746
  longer supported)
747

    
748
.. opcode_params:: OP_INSTANCE_CREATE
749

    
750
Earlier versions used parameters named ``name`` and ``os``. These have
751
been replaced by ``instance_name`` and ``os_type`` to match the
752
underlying opcode. The old names can still be used.
753

    
754
Job result:
755

    
756
.. opcode_result:: OP_INSTANCE_CREATE
757

    
758

    
759
``/2/instances/[instance_name]``
760
++++++++++++++++++++++++++++++++
761

    
762
Instance-specific resource.
763

    
764
It supports the following commands: ``GET``, ``DELETE``.
765

    
766
``GET``
767
~~~~~~~
768

    
769
Returns information about an instance, similar to the bulk output from
770
the instance list.
771

    
772
Returned fields: :pyeval:`utils.CommaJoin(sorted(rlib2.I_FIELDS))`.
773

    
774
``DELETE``
775
~~~~~~~~~~
776

    
777
Deletes an instance.
778

    
779
It supports the ``dry-run`` argument.
780

    
781
Job result:
782

    
783
.. opcode_result:: OP_INSTANCE_REMOVE
784

    
785

    
786
``/2/instances/[instance_name]/info``
787
+++++++++++++++++++++++++++++++++++++++
788

    
789
It supports the following commands: ``GET``.
790

    
791
``GET``
792
~~~~~~~
793

    
794
Requests detailed information about the instance. An optional parameter,
795
``static`` (bool), can be set to return only static information from the
796
configuration without querying the instance's nodes. The result will be
797
a job id.
798

    
799
Job result:
800

    
801
.. opcode_result:: OP_INSTANCE_QUERY_DATA
802

    
803

    
804
``/2/instances/[instance_name]/reboot``
805
+++++++++++++++++++++++++++++++++++++++
806

    
807
Reboots URI for an instance.
808

    
809
It supports the following commands: ``POST``.
810

    
811
``POST``
812
~~~~~~~~
813

    
814
Reboots the instance.
815

    
816
The URI takes optional ``type=soft|hard|full`` and
817
``ignore_secondaries=0|1`` parameters.
818

    
819
``type`` defines the reboot type. ``soft`` is just a normal reboot,
820
without terminating the hypervisor. ``hard`` means full shutdown
821
(including terminating the hypervisor process) and startup again.
822
``full`` is like ``hard`` but also recreates the configuration from
823
ground up as if you would have done a ``gnt-instance shutdown`` and
824
``gnt-instance start`` on it.
825

    
826
``ignore_secondaries`` is a bool argument indicating if we start the
827
instance even if secondary disks are failing.
828

    
829
It supports the ``dry-run`` argument.
830

    
831
Job result:
832

    
833
.. opcode_result:: OP_INSTANCE_REBOOT
834

    
835

    
836
``/2/instances/[instance_name]/shutdown``
837
+++++++++++++++++++++++++++++++++++++++++
838

    
839
Instance shutdown URI.
840

    
841
It supports the following commands: ``PUT``.
842

    
843
``PUT``
844
~~~~~~~
845

    
846
Shutdowns an instance.
847

    
848
It supports the ``dry-run`` argument.
849

    
850
.. opcode_params:: OP_INSTANCE_SHUTDOWN
851
   :exclude: instance_name, dry_run
852

    
853
Job result:
854

    
855
.. opcode_result:: OP_INSTANCE_SHUTDOWN
856

    
857

    
858
``/2/instances/[instance_name]/startup``
859
++++++++++++++++++++++++++++++++++++++++
860

    
861
Instance startup URI.
862

    
863
It supports the following commands: ``PUT``.
864

    
865
``PUT``
866
~~~~~~~
867

    
868
Startup an instance.
869

    
870
The URI takes an optional ``force=1|0`` parameter to start the
871
instance even if secondary disks are failing.
872

    
873
It supports the ``dry-run`` argument.
874

    
875
Job result:
876

    
877
.. opcode_result:: OP_INSTANCE_STARTUP
878

    
879

    
880
``/2/instances/[instance_name]/reinstall``
881
++++++++++++++++++++++++++++++++++++++++++++++
882

    
883
Installs the operating system again.
884

    
885
It supports the following commands: ``POST``.
886

    
887
``POST``
888
~~~~~~~~
889

    
890
Returns a job ID.
891

    
892
Body parameters:
893

    
894
``os`` (string, required)
895
  Instance operating system.
896
``start`` (bool, defaults to true)
897
  Whether to start instance after reinstallation.
898
``osparams`` (dict)
899
  Dictionary with (temporary) OS parameters.
900

    
901
For backwards compatbility, this resource also takes the query
902
parameters ``os`` (OS template name) and ``nostartup`` (bool). New
903
clients should use the body parameters.
904

    
905

    
906
``/2/instances/[instance_name]/replace-disks``
907
++++++++++++++++++++++++++++++++++++++++++++++
908

    
909
Replaces disks on an instance.
910

    
911
It supports the following commands: ``POST``.
912

    
913
``POST``
914
~~~~~~~~
915

    
916
Returns a job ID.
917

    
918
Body parameters:
919

    
920
.. opcode_params:: OP_INSTANCE_REPLACE_DISKS
921
   :exclude: instance_name
922

    
923
Ganeti 2.4 and below used query parameters. Those are deprecated and
924
should no longer be used.
925

    
926
Job result:
927

    
928
.. opcode_result:: OP_INSTANCE_REPLACE_DISKS
929

    
930

    
931
``/2/instances/[instance_name]/activate-disks``
932
+++++++++++++++++++++++++++++++++++++++++++++++
933

    
934
Activate disks on an instance.
935

    
936
It supports the following commands: ``PUT``.
937

    
938
``PUT``
939
~~~~~~~
940

    
941
Takes the bool parameter ``ignore_size``. When set ignore the recorded
942
size (useful for forcing activation when recorded size is wrong).
943

    
944
Job result:
945

    
946
.. opcode_result:: OP_INSTANCE_ACTIVATE_DISKS
947

    
948

    
949
``/2/instances/[instance_name]/deactivate-disks``
950
+++++++++++++++++++++++++++++++++++++++++++++++++
951

    
952
Deactivate disks on an instance.
953

    
954
It supports the following commands: ``PUT``.
955

    
956
``PUT``
957
~~~~~~~
958

    
959
Takes no parameters.
960

    
961
Job result:
962

    
963
.. opcode_result:: OP_INSTANCE_DEACTIVATE_DISKS
964

    
965

    
966
``/2/instances/[instance_name]/recreate-disks``
967
+++++++++++++++++++++++++++++++++++++++++++++++++
968

    
969
Recreate disks of an instance. Supports the following commands:
970
``POST``.
971

    
972
``POST``
973
~~~~~~~~
974

    
975
Returns a job ID.
976

    
977
Body parameters:
978

    
979
.. opcode_params:: OP_INSTANCE_RECREATE_DISKS
980
   :exclude: instance_name
981

    
982
Job result:
983

    
984
.. opcode_result:: OP_INSTANCE_RECREATE_DISKS
985

    
986

    
987
``/2/instances/[instance_name]/disk/[disk_index]/grow``
988
+++++++++++++++++++++++++++++++++++++++++++++++++++++++
989

    
990
Grows one disk of an instance.
991

    
992
Supports the following commands: ``POST``.
993

    
994
``POST``
995
~~~~~~~~
996

    
997
Returns a job ID.
998

    
999
Body parameters:
1000

    
1001
.. opcode_params:: OP_INSTANCE_GROW_DISK
1002
   :exclude: instance_name, disk
1003

    
1004
Job result:
1005

    
1006
.. opcode_result:: OP_INSTANCE_GROW_DISK
1007

    
1008

    
1009
``/2/instances/[instance_name]/prepare-export``
1010
+++++++++++++++++++++++++++++++++++++++++++++++++
1011

    
1012
Prepares an export of an instance.
1013

    
1014
It supports the following commands: ``PUT``.
1015

    
1016
``PUT``
1017
~~~~~~~
1018

    
1019
Takes one parameter, ``mode``, for the export mode. Returns a job ID.
1020

    
1021
Job result:
1022

    
1023
.. opcode_result:: OP_BACKUP_PREPARE
1024

    
1025

    
1026
``/2/instances/[instance_name]/export``
1027
+++++++++++++++++++++++++++++++++++++++++++++++++
1028

    
1029
Exports an instance.
1030

    
1031
It supports the following commands: ``PUT``.
1032

    
1033
``PUT``
1034
~~~~~~~
1035

    
1036
Returns a job ID.
1037

    
1038
Body parameters:
1039

    
1040
.. opcode_params:: OP_BACKUP_EXPORT
1041
   :exclude: instance_name
1042
   :alias: target_node=destination
1043

    
1044
Job result:
1045

    
1046
.. opcode_result:: OP_BACKUP_EXPORT
1047

    
1048

    
1049
``/2/instances/[instance_name]/migrate``
1050
++++++++++++++++++++++++++++++++++++++++
1051

    
1052
Migrates an instance.
1053

    
1054
Supports the following commands: ``PUT``.
1055

    
1056
``PUT``
1057
~~~~~~~
1058

    
1059
Returns a job ID.
1060

    
1061
Body parameters:
1062

    
1063
.. opcode_params:: OP_INSTANCE_MIGRATE
1064
   :exclude: instance_name, live
1065

    
1066
Job result:
1067

    
1068
.. opcode_result:: OP_INSTANCE_MIGRATE
1069

    
1070

    
1071
``/2/instances/[instance_name]/failover``
1072
+++++++++++++++++++++++++++++++++++++++++
1073

    
1074
Does a failover of an instance.
1075

    
1076
Supports the following commands: ``PUT``.
1077

    
1078
``PUT``
1079
~~~~~~~
1080

    
1081
Returns a job ID.
1082

    
1083
Body parameters:
1084

    
1085
.. opcode_params:: OP_INSTANCE_FAILOVER
1086
   :exclude: instance_name
1087

    
1088
Job result:
1089

    
1090
.. opcode_result:: OP_INSTANCE_FAILOVER
1091

    
1092

    
1093
``/2/instances/[instance_name]/rename``
1094
++++++++++++++++++++++++++++++++++++++++
1095

    
1096
Renames an instance.
1097

    
1098
Supports the following commands: ``PUT``.
1099

    
1100
``PUT``
1101
~~~~~~~
1102

    
1103
Returns a job ID.
1104

    
1105
Body parameters:
1106

    
1107
.. opcode_params:: OP_INSTANCE_RENAME
1108
   :exclude: instance_name
1109

    
1110
Job result:
1111

    
1112
.. opcode_result:: OP_INSTANCE_RENAME
1113

    
1114

    
1115
``/2/instances/[instance_name]/modify``
1116
++++++++++++++++++++++++++++++++++++++++
1117

    
1118
Modifies an instance.
1119

    
1120
Supports the following commands: ``PUT``.
1121

    
1122
``PUT``
1123
~~~~~~~
1124

    
1125
Returns a job ID.
1126

    
1127
Body parameters:
1128

    
1129
.. opcode_params:: OP_INSTANCE_SET_PARAMS
1130
   :exclude: instance_name
1131

    
1132
Job result:
1133

    
1134
.. opcode_result:: OP_INSTANCE_SET_PARAMS
1135

    
1136

    
1137
``/2/instances/[instance_name]/console``
1138
++++++++++++++++++++++++++++++++++++++++
1139

    
1140
Request information for connecting to instance's console.
1141

    
1142
.. pyassert::
1143

    
1144
  not (hasattr(rlib2.R_2_instances_name_console, "PUT") or
1145
       hasattr(rlib2.R_2_instances_name_console, "POST") or
1146
       hasattr(rlib2.R_2_instances_name_console, "DELETE"))
1147

    
1148
Supports the following commands: ``GET``. Requires authentication with
1149
one of the following options:
1150
:pyeval:`utils.CommaJoin(rlib2.R_2_instances_name_console.GET_ACCESS)`.
1151

    
1152
``GET``
1153
~~~~~~~
1154

    
1155
Returns a dictionary containing information about the instance's
1156
console. Contained keys:
1157

    
1158
.. pyassert::
1159

    
1160
   constants.CONS_ALL == frozenset([
1161
     constants.CONS_MESSAGE,
1162
     constants.CONS_SSH,
1163
     constants.CONS_VNC,
1164
     constants.CONS_SPICE,
1165
     ])
1166

    
1167
``instance``
1168
  Instance name
1169
``kind``
1170
  Console type, one of :pyeval:`constants.CONS_SSH`,
1171
  :pyeval:`constants.CONS_VNC`, :pyeval:`constants.CONS_SPICE`
1172
  or :pyeval:`constants.CONS_MESSAGE`
1173
``message``
1174
  Message to display (:pyeval:`constants.CONS_MESSAGE` type only)
1175
``host``
1176
  Host to connect to (:pyeval:`constants.CONS_SSH`,
1177
  :pyeval:`constants.CONS_VNC` or :pyeval:`constants.CONS_SPICE` only)
1178
``port``
1179
  TCP port to connect to (:pyeval:`constants.CONS_VNC` or
1180
  :pyeval:`constants.CONS_SPICE` only)
1181
``user``
1182
  Username to use (:pyeval:`constants.CONS_SSH` only)
1183
``command``
1184
  Command to execute on machine (:pyeval:`constants.CONS_SSH` only)
1185
``display``
1186
  VNC display number (:pyeval:`constants.CONS_VNC` only)
1187

    
1188

    
1189
``/2/instances/[instance_name]/tags``
1190
+++++++++++++++++++++++++++++++++++++
1191

    
1192
Manages per-instance tags.
1193

    
1194
It supports the following commands: ``GET``, ``PUT``, ``DELETE``.
1195

    
1196
``GET``
1197
~~~~~~~
1198

    
1199
Returns a list of tags.
1200

    
1201
Example::
1202

    
1203
    ["tag1", "tag2", "tag3"]
1204

    
1205
``PUT``
1206
~~~~~~~
1207

    
1208
Add a set of tags.
1209

    
1210
The request as a list of strings should be ``PUT`` to this URI. The
1211
result will be a job id.
1212

    
1213
It supports the ``dry-run`` argument.
1214

    
1215

    
1216
``DELETE``
1217
~~~~~~~~~~
1218

    
1219
Delete a tag.
1220

    
1221
In order to delete a set of tags, the DELETE request should be addressed
1222
to URI like::
1223

    
1224
    /tags?tag=[tag]&tag=[tag]
1225

    
1226
It supports the ``dry-run`` argument.
1227

    
1228

    
1229
``/2/jobs``
1230
+++++++++++
1231

    
1232
The ``/2/jobs`` resource.
1233

    
1234
It supports the following commands: ``GET``.
1235

    
1236
``GET``
1237
~~~~~~~
1238

    
1239
Returns a dictionary of jobs.
1240

    
1241
Returns: a dictionary with jobs id and uri.
1242

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

    
1247
Returned fields for bulk requests (unlike other bulk requests, these
1248
fields are not the same as for per-job requests):
1249
:pyeval:`utils.CommaJoin(sorted(rlib2.J_FIELDS_BULK))`.
1250

    
1251
``/2/jobs/[job_id]``
1252
++++++++++++++++++++
1253

    
1254

    
1255
Individual job URI.
1256

    
1257
It supports the following commands: ``GET``, ``DELETE``.
1258

    
1259
``GET``
1260
~~~~~~~
1261

    
1262
Returns a dictionary with job parameters, containing the fields
1263
:pyeval:`utils.CommaJoin(sorted(rlib2.J_FIELDS))`.
1264

    
1265
The result includes:
1266

    
1267
- id: job ID as a number
1268
- status: current job status as a string
1269
- ops: involved OpCodes as a list of dictionaries for each opcodes in
1270
  the job
1271
- opstatus: OpCodes status as a list
1272
- opresult: OpCodes results as a list
1273

    
1274
For a successful opcode, the ``opresult`` field corresponding to it will
1275
contain the raw result from its :term:`LogicalUnit`. In case an opcode
1276
has failed, its element in the opresult list will be a list of two
1277
elements:
1278

    
1279
- first element the error type (the Ganeti internal error name)
1280
- second element a list of either one or two elements:
1281

    
1282
  - the first element is the textual error description
1283
  - the second element, if any, will hold an error classification
1284

    
1285
The error classification is most useful for the ``OpPrereqError``
1286
error type - these errors happen before the OpCode has started
1287
executing, so it's possible to retry the OpCode without side
1288
effects. But whether it make sense to retry depends on the error
1289
classification:
1290

    
1291
.. pyassert::
1292

    
1293
   errors.ECODE_ALL == set([errors.ECODE_RESOLVER, errors.ECODE_NORES,
1294
     errors.ECODE_INVAL, errors.ECODE_STATE, errors.ECODE_NOENT,
1295
     errors.ECODE_EXISTS, errors.ECODE_NOTUNIQUE, errors.ECODE_FAULT,
1296
     errors.ECODE_ENVIRON])
1297

    
1298
:pyeval:`errors.ECODE_RESOLVER`
1299
  Resolver errors. This usually means that a name doesn't exist in DNS,
1300
  so if it's a case of slow DNS propagation the operation can be retried
1301
  later.
1302

    
1303
:pyeval:`errors.ECODE_NORES`
1304
  Not enough resources (iallocator failure, disk space, memory,
1305
  etc.). If the resources on the cluster increase, the operation might
1306
  succeed.
1307

    
1308
:pyeval:`errors.ECODE_INVAL`
1309
  Wrong arguments (at syntax level). The operation will not ever be
1310
  accepted unless the arguments change.
1311

    
1312
:pyeval:`errors.ECODE_STATE`
1313
  Wrong entity state. For example, live migration has been requested for
1314
  a down instance, or instance creation on an offline node. The
1315
  operation can be retried once the resource has changed state.
1316

    
1317
:pyeval:`errors.ECODE_NOENT`
1318
  Entity not found. For example, information has been requested for an
1319
  unknown instance.
1320

    
1321
:pyeval:`errors.ECODE_EXISTS`
1322
  Entity already exists. For example, instance creation has been
1323
  requested for an already-existing instance.
1324

    
1325
:pyeval:`errors.ECODE_NOTUNIQUE`
1326
  Resource not unique (e.g. MAC or IP duplication).
1327

    
1328
:pyeval:`errors.ECODE_FAULT`
1329
  Internal cluster error. For example, a node is unreachable but not set
1330
  offline, or the ganeti node daemons are not working, etc. A
1331
  ``gnt-cluster verify`` should be run.
1332

    
1333
:pyeval:`errors.ECODE_ENVIRON`
1334
  Environment error (e.g. node disk error). A ``gnt-cluster verify``
1335
  should be run.
1336

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

    
1340

    
1341
``DELETE``
1342
~~~~~~~~~~
1343

    
1344
Cancel a not-yet-started job.
1345

    
1346

    
1347
``/2/jobs/[job_id]/wait``
1348
+++++++++++++++++++++++++
1349

    
1350
``GET``
1351
~~~~~~~
1352

    
1353
Waits for changes on a job. Takes the following body parameters in a
1354
dict:
1355

    
1356
``fields``
1357
  The job fields on which to watch for changes
1358

    
1359
``previous_job_info``
1360
  Previously received field values or None if not yet available
1361

    
1362
``previous_log_serial``
1363
  Highest log serial number received so far or None if not yet
1364
  available
1365

    
1366
Returns None if no changes have been detected and a dict with two keys,
1367
``job_info`` and ``log_entries`` otherwise.
1368

    
1369

    
1370
``/2/nodes``
1371
++++++++++++
1372

    
1373
Nodes resource.
1374

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

    
1377
``GET``
1378
~~~~~~~
1379

    
1380
Returns a list of all nodes.
1381

    
1382
Example::
1383

    
1384
    [
1385
      {
1386
        "id": "node1.example.com",
1387
        "uri": "\/nodes\/node1.example.com"
1388
      },
1389
      {
1390
        "id": "node2.example.com",
1391
        "uri": "\/nodes\/node2.example.com"
1392
      }
1393
    ]
1394

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

    
1399
Returned fields: :pyeval:`utils.CommaJoin(sorted(rlib2.N_FIELDS))`.
1400

    
1401
Example::
1402

    
1403
    [
1404
      {
1405
        "pinst_cnt": 1,
1406
        "mfree": 31280,
1407
        "mtotal": 32763,
1408
        "name": "www.example.com",
1409
        "tags": [],
1410
        "mnode": 512,
1411
        "dtotal": 5246208,
1412
        "sinst_cnt": 2,
1413
        "dfree": 5171712,
1414
        "offline": false
1415
      },
1416
      ...
1417
    ]
1418

    
1419
``/2/nodes/[node_name]``
1420
+++++++++++++++++++++++++++++++++
1421

    
1422
Returns information about a node.
1423

    
1424
It supports the following commands: ``GET``.
1425

    
1426
Returned fields: :pyeval:`utils.CommaJoin(sorted(rlib2.N_FIELDS))`.
1427

    
1428
``/2/nodes/[node_name]/powercycle``
1429
+++++++++++++++++++++++++++++++++++
1430

    
1431
Powercycles a node. Supports the following commands: ``POST``.
1432

    
1433
``POST``
1434
~~~~~~~~
1435

    
1436
Returns a job ID.
1437

    
1438
Job result:
1439

    
1440
.. opcode_result:: OP_NODE_POWERCYCLE
1441

    
1442

    
1443
``/2/nodes/[node_name]/evacuate``
1444
+++++++++++++++++++++++++++++++++
1445

    
1446
Evacuates instances off a node.
1447

    
1448
It supports the following commands: ``POST``.
1449

    
1450
``POST``
1451
~~~~~~~~
1452

    
1453
Returns a job ID. The result of the job will contain the IDs of the
1454
individual jobs submitted to evacuate the node.
1455

    
1456
Body parameters:
1457

    
1458
.. opcode_params:: OP_NODE_EVACUATE
1459
   :exclude: nodes
1460

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

    
1465
Job result:
1466

    
1467
.. opcode_result:: OP_NODE_EVACUATE
1468

    
1469

    
1470
``/2/nodes/[node_name]/migrate``
1471
+++++++++++++++++++++++++++++++++
1472

    
1473
Migrates all primary instances from a node.
1474

    
1475
It supports the following commands: ``POST``.
1476

    
1477
``POST``
1478
~~~~~~~~
1479

    
1480
If no mode is explicitly specified, each instances' hypervisor default
1481
migration mode will be used. Body parameters:
1482

    
1483
.. opcode_params:: OP_NODE_MIGRATE
1484
   :exclude: node_name
1485

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

    
1490
Job result:
1491

    
1492
.. opcode_result:: OP_NODE_MIGRATE
1493

    
1494

    
1495
``/2/nodes/[node_name]/role``
1496
+++++++++++++++++++++++++++++
1497

    
1498
Manages node role.
1499

    
1500
It supports the following commands: ``GET``, ``PUT``.
1501

    
1502
The role is always one of the following:
1503

    
1504
  - drained
1505
  - master-candidate
1506
  - offline
1507
  - regular
1508

    
1509
Note that the 'master' role is a special, and currently it can't be
1510
modified via RAPI, only via the command line (``gnt-cluster
1511
master-failover``).
1512

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

    
1516
Returns the current node role.
1517

    
1518
Example::
1519

    
1520
    "master-candidate"
1521

    
1522
``PUT``
1523
~~~~~~~
1524

    
1525
Change the node role.
1526

    
1527
The request is a string which should be PUT to this URI. The result will
1528
be a job id.
1529

    
1530
It supports the bool ``force`` argument.
1531

    
1532
Job result:
1533

    
1534
.. opcode_result:: OP_NODE_SET_PARAMS
1535

    
1536

    
1537
``/2/nodes/[node_name]/modify``
1538
+++++++++++++++++++++++++++++++
1539

    
1540
Modifies the parameters of a node. Supports the following commands:
1541
``POST``.
1542

    
1543
``POST``
1544
~~~~~~~~
1545

    
1546
Returns a job ID.
1547

    
1548
Body parameters:
1549

    
1550
.. opcode_params:: OP_NODE_SET_PARAMS
1551
   :exclude: node_name
1552

    
1553
Job result:
1554

    
1555
.. opcode_result:: OP_NODE_SET_PARAMS
1556

    
1557

    
1558
``/2/nodes/[node_name]/storage``
1559
++++++++++++++++++++++++++++++++
1560

    
1561
Manages storage units on the node.
1562

    
1563
``GET``
1564
~~~~~~~
1565

    
1566
.. pyassert::
1567

    
1568
   constants.VALID_STORAGE_TYPES == set([constants.ST_FILE,
1569
                                         constants.ST_LVM_PV,
1570
                                         constants.ST_LVM_VG])
1571

    
1572
Requests a list of storage units on a node. Requires the parameters
1573
``storage_type`` (one of :pyeval:`constants.ST_FILE`,
1574
:pyeval:`constants.ST_LVM_PV` or :pyeval:`constants.ST_LVM_VG`) and
1575
``output_fields``. The result will be a job id, using which the result
1576
can be retrieved.
1577

    
1578
``/2/nodes/[node_name]/storage/modify``
1579
+++++++++++++++++++++++++++++++++++++++
1580

    
1581
Modifies storage units on the node.
1582

    
1583
``PUT``
1584
~~~~~~~
1585

    
1586
Modifies parameters of storage units on the node. Requires the
1587
parameters ``storage_type`` (one of :pyeval:`constants.ST_FILE`,
1588
:pyeval:`constants.ST_LVM_PV` or :pyeval:`constants.ST_LVM_VG`)
1589
and ``name`` (name of the storage unit).  Parameters can be passed
1590
additionally. Currently only :pyeval:`constants.SF_ALLOCATABLE` (bool)
1591
is supported. The result will be a job id.
1592

    
1593
Job result:
1594

    
1595
.. opcode_result:: OP_NODE_MODIFY_STORAGE
1596

    
1597

    
1598
``/2/nodes/[node_name]/storage/repair``
1599
+++++++++++++++++++++++++++++++++++++++
1600

    
1601
Repairs a storage unit on the node.
1602

    
1603
``PUT``
1604
~~~~~~~
1605

    
1606
.. pyassert::
1607

    
1608
   constants.VALID_STORAGE_OPERATIONS == {
1609
    constants.ST_LVM_VG: set([constants.SO_FIX_CONSISTENCY]),
1610
    }
1611

    
1612
Repairs a storage unit on the node. Requires the parameters
1613
``storage_type`` (currently only :pyeval:`constants.ST_LVM_VG` can be
1614
repaired) and ``name`` (name of the storage unit). The result will be a
1615
job id.
1616

    
1617
Job result:
1618

    
1619
.. opcode_result:: OP_REPAIR_NODE_STORAGE
1620

    
1621

    
1622
``/2/nodes/[node_name]/tags``
1623
+++++++++++++++++++++++++++++
1624

    
1625
Manages per-node tags.
1626

    
1627
It supports the following commands: ``GET``, ``PUT``, ``DELETE``.
1628

    
1629
``GET``
1630
~~~~~~~
1631

    
1632
Returns a list of tags.
1633

    
1634
Example::
1635

    
1636
    ["tag1", "tag2", "tag3"]
1637

    
1638
``PUT``
1639
~~~~~~~
1640

    
1641
Add a set of tags.
1642

    
1643
The request as a list of strings should be PUT to this URI. The result
1644
will be a job id.
1645

    
1646
It supports the ``dry-run`` argument.
1647

    
1648
``DELETE``
1649
~~~~~~~~~~
1650

    
1651
Deletes tags.
1652

    
1653
In order to delete a set of tags, the DELETE request should be addressed
1654
to URI like::
1655

    
1656
    /tags?tag=[tag]&tag=[tag]
1657

    
1658
It supports the ``dry-run`` argument.
1659

    
1660

    
1661
``/2/query/[resource]``
1662
+++++++++++++++++++++++
1663

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

    
1669
.. pyassert::
1670

    
1671
  (rlib2.R_2_query.GET_ACCESS == rlib2.R_2_query.PUT_ACCESS and
1672
   not (hasattr(rlib2.R_2_query, "POST") or
1673
        hasattr(rlib2.R_2_query, "DELETE")))
1674

    
1675
Supports the following commands: ``GET``, ``PUT``. Requires
1676
authentication with one of the following options:
1677
:pyeval:`utils.CommaJoin(rlib2.R_2_query.GET_ACCESS)`.
1678

    
1679
``GET``
1680
~~~~~~~
1681

    
1682
Returns list of included fields and actual data. Takes a query parameter
1683
named "fields", containing a comma-separated list of field names. Does
1684
not support filtering.
1685

    
1686
``PUT``
1687
~~~~~~~
1688

    
1689
Returns list of included fields and actual data. The list of requested
1690
fields can either be given as the query parameter "fields" or as a body
1691
parameter with the same name. The optional body parameter "filter" can
1692
be given and must be either ``null`` or a list containing filter
1693
operators.
1694

    
1695

    
1696
``/2/query/[resource]/fields``
1697
++++++++++++++++++++++++++++++
1698

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

    
1703
Supports the following commands: ``GET``.
1704

    
1705
``GET``
1706
~~~~~~~
1707

    
1708
Returns a list of field descriptions for available fields. Takes an
1709
optional query parameter named "fields", containing a comma-separated
1710
list of field names.
1711

    
1712

    
1713
``/2/os``
1714
+++++++++
1715

    
1716
OS resource.
1717

    
1718
It supports the following commands: ``GET``.
1719

    
1720
``GET``
1721
~~~~~~~
1722

    
1723
Return a list of all OSes.
1724

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

    
1728
Example::
1729

    
1730
    ["debian-etch"]
1731

    
1732
``/2/tags``
1733
+++++++++++
1734

    
1735
Manages cluster tags.
1736

    
1737
It supports the following commands: ``GET``, ``PUT``, ``DELETE``.
1738

    
1739
``GET``
1740
~~~~~~~
1741

    
1742
Returns the cluster tags.
1743

    
1744
Example::
1745

    
1746
    ["tag1", "tag2", "tag3"]
1747

    
1748
``PUT``
1749
~~~~~~~
1750

    
1751
Adds a set of tags.
1752

    
1753
The request as a list of strings should be PUT to this URI. The result
1754
will be a job id.
1755

    
1756
It supports the ``dry-run`` argument.
1757

    
1758

    
1759
``DELETE``
1760
~~~~~~~~~~
1761

    
1762
Deletes tags.
1763

    
1764
In order to delete a set of tags, the DELETE request should be addressed
1765
to URI like::
1766

    
1767
    /tags?tag=[tag]&tag=[tag]
1768

    
1769
It supports the ``dry-run`` argument.
1770

    
1771

    
1772
``/version``
1773
++++++++++++
1774

    
1775
The version resource.
1776

    
1777
This resource should be used to determine the remote API version and to
1778
adapt clients accordingly.
1779

    
1780
It supports the following commands: ``GET``.
1781

    
1782
``GET``
1783
~~~~~~~
1784

    
1785
Returns the remote API version. Ganeti 1.2 returned ``1`` and Ganeti 2.0
1786
returns ``2``.
1787

    
1788
.. vim: set textwidth=72 :
1789
.. Local Variables:
1790
.. mode: rst
1791
.. fill-column: 72
1792
.. End: