Statistics
| Branch: | Tag: | Revision:

root / doc / rapi.rst @ bfcd1652

History | View | Annotate | Download (43.3 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
.. _rapi-users:
20

    
21
Users and passwords
22
-------------------
23

    
24
``ganeti-rapi`` reads users and passwords from a file (usually
25
``/var/lib/ganeti/rapi/users``) on startup. Changes to the file will be
26
read automatically.
27

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

    
34
.. pyassert::
35

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

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

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

    
55
Example::
56

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

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

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

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

    
70
  # A user who can read and write (the former is implied by granting
71
  # write access)
72
  superuser {HA1}ec018ffe72b8e75bb4d508ed5b6d079c read,write
73

    
74
When using the RAPI, username and password can be sent to the server
75
by using the standard HTTP basic access authentication. This means that
76
for accessing the protected URL ``https://cluster.example.com/resource``,
77
the address ``https://username:password@cluster.example.com/resource`` should
78
be used instead. Alternatively, the appropriate parameter of your HTTP client
79
(such as ``-u`` for ``curl``) can be used.
80

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

    
89

    
90
Protocol
91
--------
92

    
93
The protocol used is JSON_ over HTTP designed after the REST_ principle.
94
HTTP Basic authentication as per :rfc:`2617` is supported.
95

    
96
.. _JSON: http://www.json.org/
97
.. _REST: http://en.wikipedia.org/wiki/Representational_State_Transfer
98

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

    
103

    
104
A note on JSON as used by RAPI
105
++++++++++++++++++++++++++++++
106

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

    
114
.. highlight:: ruby
115

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

    
124
  require "json"
125

    
126
  # Insert code to get response here
127
  response = "\"1234\""
128

    
129
  decoded = JSON.parse("[#{response}]").first
130

    
131
Short of modifying the encoder to allow encoding to a less strict
132
format, requests will have to be formatted by hand. Newer RAPI requests
133
already use a dictionary as their input data and shouldn't cause any
134
problems.
135

    
136

    
137
PUT or POST?
138
------------
139

    
140
According to :rfc:`2616` the main difference between PUT and POST is
141
that POST can create new resources but PUT can only create the resource
142
the URI was pointing to on the PUT request.
143

    
144
Unfortunately, due to historic reasons, the Ganeti RAPI library is not
145
consistent with this usage, so just use the methods as documented below
146
for each resource.
147

    
148
For more details have a look in the source code at
149
``lib/rapi/rlib2.py``.
150

    
151

    
152
Generic parameter types
153
-----------------------
154

    
155
A few generic refered parameter types and the values they allow.
156

    
157
``bool``
158
++++++++
159

    
160
A boolean option will accept ``1`` or ``0`` as numbers but not
161
i.e. ``True`` or ``False``.
162

    
163
Generic parameters
164
------------------
165

    
166
A few parameter mean the same thing across all resources which implement
167
it.
168

    
169
``bulk``
170
++++++++
171

    
172
Bulk-mode means that for the resources which usually return just a list
173
of child resources (e.g. ``/2/instances`` which returns just instance
174
names), the output will instead contain detailed data for all these
175
subresources. This is more efficient than query-ing the sub-resources
176
themselves.
177

    
178
``dry-run``
179
+++++++++++
180

    
181
The boolean *dry-run* argument, if provided and set, signals to Ganeti
182
that the job should not be executed, only the pre-execution checks will
183
be done.
184

    
185
This is useful in trying to determine (without guarantees though, as in
186
the meantime the cluster state could have changed) if the operation is
187
likely to succeed or at least start executing.
188

    
189
``force``
190
+++++++++++
191

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

    
195
Parameter details
196
-----------------
197

    
198
Some parameters are not straight forward, so we describe them in details
199
here.
200

    
201
.. _rapi-ipolicy:
202

    
203
``ipolicy``
204
+++++++++++
205

    
206
The instance policy specification is a dict with the following fields:
207

    
208
.. pyassert::
209

    
210
  constants.IPOLICY_ALL_KEYS == set([constants.ISPECS_MIN,
211
                                     constants.ISPECS_MAX,
212
                                     constants.ISPECS_STD,
213
                                     constants.IPOLICY_DTS,
214
                                     constants.IPOLICY_VCPU_RATIO,
215
                                     constants.IPOLICY_SPINDLE_RATIO])
216

    
217

    
218
.. pyassert::
219

    
220
  (set(constants.ISPECS_PARAMETER_TYPES.keys()) ==
221
   set([constants.ISPEC_MEM_SIZE,
222
        constants.ISPEC_DISK_SIZE,
223
        constants.ISPEC_DISK_COUNT,
224
        constants.ISPEC_CPU_COUNT,
225
        constants.ISPEC_NIC_COUNT,
226
        constants.ISPEC_SPINDLE_USE]))
227

    
228
.. |ispec-min| replace:: :pyeval:`constants.ISPECS_MIN`
229
.. |ispec-max| replace:: :pyeval:`constants.ISPECS_MAX`
230
.. |ispec-std| replace:: :pyeval:`constants.ISPECS_STD`
231

    
232

    
233
|ispec-min|, |ispec-max|, |ispec-std|
234
  A sub- `dict` with the following fields, which sets the limit and standard
235
  values of the instances:
236

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

    
258
Usage examples
259
--------------
260

    
261
You can access the API using your favorite programming language as long
262
as it supports network connections.
263

    
264
Ganeti RAPI client
265
++++++++++++++++++
266

    
267
Ganeti includes a standalone RAPI client, ``lib/rapi/client.py``.
268

    
269
Shell
270
+++++
271

    
272
.. highlight:: shell-example
273

    
274
Using ``wget``::
275

    
276
   $ wget -q -O - https://%CLUSTERNAME%:5080/2/info
277

    
278
or ``curl``::
279

    
280
  $ curl https://%CLUSTERNAME%:5080/2/info
281

    
282
Note: with ``curl``, the request method (GET, POST, PUT) can be specified
283
using the ``-X`` command line option, and the username/password can be
284
specified with the ``-u`` option. In case of POST requests with a body, the
285
Content-Type can be set to JSON (as per the Protocol_ section) using the
286
parameter ``-H "Content-Type: application/json"``.
287

    
288
Python
289
++++++
290

    
291
.. highlight:: python
292

    
293
::
294

    
295
  import urllib2
296
  f = urllib2.urlopen('https://CLUSTERNAME:5080/2/info')
297
  print f.read()
298

    
299

    
300
JavaScript
301
++++++++++
302

    
303
.. warning:: While it's possible to use JavaScript, it poses several
304
   potential problems, including browser blocking request due to
305
   non-standard ports or different domain names. Fetching the data on
306
   the webserver is easier.
307

    
308
.. highlight:: javascript
309

    
310
::
311

    
312
  var url = 'https://CLUSTERNAME:5080/2/info';
313
  var info;
314
  var xmlreq = new XMLHttpRequest();
315
  xmlreq.onreadystatechange = function () {
316
    if (xmlreq.readyState != 4) return;
317
    if (xmlreq.status == 200) {
318
      info = eval("(" + xmlreq.responseText + ")");
319
      alert(info);
320
    } else {
321
      alert('Error fetching cluster info');
322
    }
323
    xmlreq = null;
324
  };
325
  xmlreq.open('GET', url, true);
326
  xmlreq.send(null);
327

    
328
Resources
329
---------
330

    
331
.. highlight:: javascript
332

    
333
``/``
334
+++++
335

    
336
The root resource. Has no function, but for legacy reasons the ``GET``
337
method is supported.
338

    
339
``/2``
340
++++++
341

    
342
Has no function, but for legacy reasons the ``GET`` method is supported.
343

    
344
``/2/info``
345
+++++++++++
346

    
347
Cluster information resource.
348

    
349
It supports the following commands: ``GET``.
350

    
351
``GET``
352
~~~~~~~
353

    
354
Returns cluster information.
355

    
356
Example::
357

    
358
  {
359
    "config_version": 2000000,
360
    "name": "cluster",
361
    "software_version": "2.0.0~beta2",
362
    "os_api_version": 10,
363
    "export_version": 0,
364
    "candidate_pool_size": 10,
365
    "enabled_hypervisors": [
366
      "fake"
367
    ],
368
    "hvparams": {
369
      "fake": {}
370
     },
371
    "default_hypervisor": "fake",
372
    "master": "node1.example.com",
373
    "architecture": [
374
      "64bit",
375
      "x86_64"
376
    ],
377
    "protocol_version": 20,
378
    "beparams": {
379
      "default": {
380
        "auto_balance": true,
381
        "vcpus": 1,
382
        "memory": 128
383
       }
384
      },
385
386
  }
387

    
388

    
389
``/2/redistribute-config``
390
++++++++++++++++++++++++++
391

    
392
Redistribute configuration to all nodes.
393

    
394
It supports the following commands: ``PUT``.
395

    
396
``PUT``
397
~~~~~~~
398

    
399
Redistribute configuration to all nodes. The result will be a job id.
400

    
401
Job result:
402

    
403
.. opcode_result:: OP_CLUSTER_REDIST_CONF
404

    
405

    
406
``/2/features``
407
+++++++++++++++
408

    
409
``GET``
410
~~~~~~~
411

    
412
Returns a list of features supported by the RAPI server. Available
413
features:
414

    
415
.. pyassert::
416

    
417
  rlib2.ALL_FEATURES == set([rlib2._INST_CREATE_REQV1,
418
                             rlib2._INST_REINSTALL_REQV1,
419
                             rlib2._NODE_MIGRATE_REQV1,
420
                             rlib2._NODE_EVAC_RES1])
421

    
422
:pyeval:`rlib2._INST_CREATE_REQV1`
423
  Instance creation request data version 1 supported
424
:pyeval:`rlib2._INST_REINSTALL_REQV1`
425
  Instance reinstall supports body parameters
426
:pyeval:`rlib2._NODE_MIGRATE_REQV1`
427
  Whether migrating a node (``/2/nodes/[node_name]/migrate``) supports
428
  request body parameters
429
:pyeval:`rlib2._NODE_EVAC_RES1`
430
  Whether evacuating a node (``/2/nodes/[node_name]/evacuate``) returns
431
  a new-style result (see resource description)
432

    
433

    
434
``/2/modify``
435
++++++++++++++++++++++++++++++++++++++++
436

    
437
Modifies cluster parameters.
438

    
439
Supports the following commands: ``PUT``.
440

    
441
``PUT``
442
~~~~~~~
443

    
444
Returns a job ID.
445

    
446
Body parameters:
447

    
448
.. opcode_params:: OP_CLUSTER_SET_PARAMS
449

    
450
Job result:
451

    
452
.. opcode_result:: OP_CLUSTER_SET_PARAMS
453

    
454

    
455
``/2/groups``
456
+++++++++++++
457

    
458
The groups resource.
459

    
460
It supports the following commands: ``GET``, ``POST``.
461

    
462
``GET``
463
~~~~~~~
464

    
465
Returns a list of all existing node groups.
466

    
467
Example::
468

    
469
    [
470
      {
471
        "name": "group1",
472
        "uri": "\/2\/groups\/group1"
473
      },
474
      {
475
        "name": "group2",
476
        "uri": "\/2\/groups\/group2"
477
      }
478
    ]
479

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

    
484
Returned fields: :pyeval:`utils.CommaJoin(sorted(rlib2.G_FIELDS))`.
485

    
486
Example::
487

    
488
    [
489
      {
490
        "name": "group1",
491
        "node_cnt": 2,
492
        "node_list": [
493
          "node1.example.com",
494
          "node2.example.com"
495
        ],
496
        "uuid": "0d7d407c-262e-49af-881a-6a430034bf43",
497
498
      },
499
      {
500
        "name": "group2",
501
        "node_cnt": 1,
502
        "node_list": [
503
          "node3.example.com"
504
        ],
505
        "uuid": "f5a277e7-68f9-44d3-a378-4b25ecb5df5c",
506
507
      },
508
509
    ]
510

    
511
``POST``
512
~~~~~~~~
513

    
514
Creates a node group.
515

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

    
519
Returns: a job ID that can be used later for polling.
520

    
521
Body parameters:
522

    
523
.. opcode_params:: OP_GROUP_ADD
524

    
525
Earlier versions used a parameter named ``name`` which, while still
526
supported, has been renamed to ``group_name``.
527

    
528
Job result:
529

    
530
.. opcode_result:: OP_GROUP_ADD
531

    
532

    
533
``/2/groups/[group_name]``
534
++++++++++++++++++++++++++
535

    
536
Returns information about a node group.
537

    
538
It supports the following commands: ``GET``, ``DELETE``.
539

    
540
``GET``
541
~~~~~~~
542

    
543
Returns information about a node group, similar to the bulk output from
544
the node group list.
545

    
546
Returned fields: :pyeval:`utils.CommaJoin(sorted(rlib2.G_FIELDS))`.
547

    
548
``DELETE``
549
~~~~~~~~~~
550

    
551
Deletes a node group.
552

    
553
It supports the ``dry-run`` argument.
554

    
555
Job result:
556

    
557
.. opcode_result:: OP_GROUP_REMOVE
558

    
559

    
560
``/2/groups/[group_name]/modify``
561
+++++++++++++++++++++++++++++++++
562

    
563
Modifies the parameters of a node group.
564

    
565
Supports the following commands: ``PUT``.
566

    
567
``PUT``
568
~~~~~~~
569

    
570
Returns a job ID.
571

    
572
Body parameters:
573

    
574
.. opcode_params:: OP_GROUP_SET_PARAMS
575
   :exclude: group_name
576

    
577
Job result:
578

    
579
.. opcode_result:: OP_GROUP_SET_PARAMS
580

    
581

    
582
``/2/groups/[group_name]/rename``
583
+++++++++++++++++++++++++++++++++
584

    
585
Renames a node group.
586

    
587
Supports the following commands: ``PUT``.
588

    
589
``PUT``
590
~~~~~~~
591

    
592
Returns a job ID.
593

    
594
Body parameters:
595

    
596
.. opcode_params:: OP_GROUP_RENAME
597
   :exclude: group_name
598

    
599
Job result:
600

    
601
.. opcode_result:: OP_GROUP_RENAME
602

    
603

    
604
``/2/groups/[group_name]/assign-nodes``
605
+++++++++++++++++++++++++++++++++++++++
606

    
607
Assigns nodes to a group.
608

    
609
Supports the following commands: ``PUT``.
610

    
611
``PUT``
612
~~~~~~~
613

    
614
Returns a job ID. It supports the ``dry-run`` and ``force`` arguments.
615

    
616
Body parameters:
617

    
618
.. opcode_params:: OP_GROUP_ASSIGN_NODES
619
   :exclude: group_name, force, dry_run
620

    
621
Job result:
622

    
623
.. opcode_result:: OP_GROUP_ASSIGN_NODES
624

    
625

    
626
``/2/groups/[group_name]/tags``
627
+++++++++++++++++++++++++++++++
628

    
629
Manages per-nodegroup tags.
630

    
631
Supports the following commands: ``GET``, ``PUT``, ``DELETE``.
632

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

    
636
Returns a list of tags.
637

    
638
Example::
639

    
640
    ["tag1", "tag2", "tag3"]
641

    
642
``PUT``
643
~~~~~~~
644

    
645
Add a set of tags.
646

    
647
The request as a list of strings should be ``PUT`` to this URI. The
648
result will be a job id.
649

    
650
It supports the ``dry-run`` argument.
651

    
652

    
653
``DELETE``
654
~~~~~~~~~~
655

    
656
Delete a tag.
657

    
658
In order to delete a set of tags, the DELETE request should be addressed
659
to URI like::
660

    
661
    /tags?tag=[tag]&tag=[tag]
662

    
663
It supports the ``dry-run`` argument.
664

    
665

    
666
``/2/networks``
667
+++++++++++++++
668

    
669
The networks resource.
670

    
671
It supports the following commands: ``GET``, ``POST``.
672

    
673
``GET``
674
~~~~~~~
675

    
676
Returns a list of all existing networks.
677

    
678
Example::
679

    
680
    [
681
      {
682
        "name": "network1",
683
        "uri": "\/2\/networks\/network1"
684
      },
685
      {
686
        "name": "network2",
687
        "uri": "\/2\/networks\/network2"
688
      }
689
    ]
690

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

    
695
Returned fields: :pyeval:`utils.CommaJoin(sorted(rlib2.NET_FIELDS))`.
696

    
697
Example::
698

    
699
    [
700
      {
701
        'external_reservations': '10.0.0.0, 10.0.0.1, 10.0.0.15',
702
        'free_count': 13,
703
        'gateway': '10.0.0.1',
704
        'gateway6': None,
705
        'group_list': ['default(bridged, prv0)'],
706
        'inst_list': [],
707
        'mac_prefix': None,
708
        'map': 'XX.............X',
709
        'name': 'nat',
710
        'network': '10.0.0.0/28',
711
        'network6': None,
712
        'reserved_count': 3,
713
        'tags': ['nfdhcpd'],
714
715
      },
716
717
    ]
718

    
719
``POST``
720
~~~~~~~~
721

    
722
Creates a network.
723

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

    
727
Returns: a job ID that can be used later for polling.
728

    
729
Body parameters:
730

    
731
.. opcode_params:: OP_NETWORK_ADD
732

    
733
Job result:
734

    
735
.. opcode_result:: OP_NETWORK_ADD
736

    
737

    
738
``/2/networks/[network_name]``
739
++++++++++++++++++++++++++++++
740

    
741
Returns information about a network.
742

    
743
It supports the following commands: ``GET``, ``DELETE``.
744

    
745
``GET``
746
~~~~~~~
747

    
748
Returns information about a network, similar to the bulk output from
749
the network list.
750

    
751
Returned fields: :pyeval:`utils.CommaJoin(sorted(rlib2.NET_FIELDS))`.
752

    
753
``DELETE``
754
~~~~~~~~~~
755

    
756
Deletes a network.
757

    
758
It supports the ``dry-run`` argument.
759

    
760
Job result:
761

    
762
.. opcode_result:: OP_NETWORK_REMOVE
763

    
764

    
765
``/2/networks/[network_name]/modify``
766
+++++++++++++++++++++++++++++++++++++
767

    
768
Modifies the parameters of a network.
769

    
770
Supports the following commands: ``PUT``.
771

    
772
``PUT``
773
~~~~~~~
774

    
775
Returns a job ID.
776

    
777
Body parameters:
778

    
779
.. opcode_params:: OP_NETWORK_SET_PARAMS
780

    
781
Job result:
782

    
783
.. opcode_result:: OP_NETWORK_SET_PARAMS
784

    
785

    
786
``/2/networks/[network_name]/connect``
787
++++++++++++++++++++++++++++++++++++++
788

    
789
Connects a network to a nodegroup.
790

    
791
Supports the following commands: ``PUT``.
792

    
793
``PUT``
794
~~~~~~~
795

    
796
Returns a job ID. It supports the ``dry-run`` arguments.
797

    
798
Body parameters:
799

    
800
.. opcode_params:: OP_NETWORK_CONNECT
801

    
802
Job result:
803

    
804
.. opcode_result:: OP_NETWORK_CONNECT
805

    
806

    
807
``/2/networks/[network_name]/disconnect``
808
+++++++++++++++++++++++++++++++++++++++++
809

    
810
Disonnects a network from a nodegroup.
811

    
812
Supports the following commands: ``PUT``.
813

    
814
``PUT``
815
~~~~~~~
816

    
817
Returns a job ID. It supports the ``dry-run`` arguments.
818

    
819
Body parameters:
820

    
821
.. opcode_params:: OP_NETWORK_DISCONNECT
822

    
823
Job result:
824

    
825
.. opcode_result:: OP_NETWORK_DISCONNECT
826

    
827

    
828
``/2/networks/[network_name]/tags``
829
+++++++++++++++++++++++++++++++++++
830

    
831
Manages per-network tags.
832

    
833
Supports the following commands: ``GET``, ``PUT``, ``DELETE``.
834

    
835
``GET``
836
~~~~~~~
837

    
838
Returns a list of tags.
839

    
840
Example::
841

    
842
    ["tag1", "tag2", "tag3"]
843

    
844
``PUT``
845
~~~~~~~
846

    
847
Add a set of tags.
848

    
849
The request as a list of strings should be ``PUT`` to this URI. The
850
result will be a job id.
851

    
852
It supports the ``dry-run`` argument.
853

    
854

    
855
``DELETE``
856
~~~~~~~~~~
857

    
858
Delete a tag.
859

    
860
In order to delete a set of tags, the DELETE request should be addressed
861
to URI like::
862

    
863
    /tags?tag=[tag]&tag=[tag]
864

    
865
It supports the ``dry-run`` argument.
866

    
867

    
868
``/2/instances-multi-alloc``
869
++++++++++++++++++++++++++++
870

    
871
Tries to allocate multiple instances.
872

    
873
It supports the following commands: ``POST``
874

    
875
``POST``
876
~~~~~~~~
877

    
878
The parameters:
879

    
880
.. opcode_params:: OP_INSTANCE_MULTI_ALLOC
881

    
882
Job result:
883

    
884
.. opcode_result:: OP_INSTANCE_MULTI_ALLOC
885

    
886

    
887
``/2/instances``
888
++++++++++++++++
889

    
890
The instances resource.
891

    
892
It supports the following commands: ``GET``, ``POST``.
893

    
894
``GET``
895
~~~~~~~
896

    
897
Returns a list of all available instances.
898

    
899
Example::
900

    
901
    [
902
      {
903
        "name": "web.example.com",
904
        "uri": "\/instances\/web.example.com"
905
      },
906
      {
907
        "name": "mail.example.com",
908
        "uri": "\/instances\/mail.example.com"
909
      }
910
    ]
911

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

    
916
Returned fields: :pyeval:`utils.CommaJoin(sorted(rlib2.I_FIELDS))`.
917

    
918
Example::
919

    
920
    [
921
      {
922
        "status": "running",
923
        "disk_usage": 20480,
924
        "nic.bridges": [
925
          "xen-br0"
926
        ],
927
        "name": "web.example.com",
928
        "tags": ["tag1", "tag2"],
929
        "beparams": {
930
          "vcpus": 2,
931
          "memory": 512
932
        },
933
        "disk.sizes": [
934
          20480
935
        ],
936
        "pnode": "node1.example.com",
937
        "nic.macs": ["01:23:45:67:89:01"],
938
        "snodes": ["node2.example.com"],
939
        "disk_template": "drbd",
940
        "admin_state": true,
941
        "os": "debian-etch",
942
        "oper_state": true,
943
944
      },
945
946
    ]
947

    
948

    
949
``POST``
950
~~~~~~~~
951

    
952
Creates an instance.
953

    
954
If the optional bool *dry-run* argument is provided, the job will not be
955
actually executed, only the pre-execution checks will be done. Query-ing
956
the job result will return, in both dry-run and normal case, the list of
957
nodes selected for the instance.
958

    
959
Returns: a job ID that can be used later for polling.
960

    
961
Body parameters:
962

    
963
``__version__`` (int, required)
964
  Must be ``1`` (older Ganeti versions used a different format for
965
  instance creation requests, version ``0``, but that format is no
966
  longer supported)
967

    
968
.. opcode_params:: OP_INSTANCE_CREATE
969

    
970
Earlier versions used parameters named ``name`` and ``os``. These have
971
been replaced by ``instance_name`` and ``os_type`` to match the
972
underlying opcode. The old names can still be used.
973

    
974
Job result:
975

    
976
.. opcode_result:: OP_INSTANCE_CREATE
977

    
978

    
979
``/2/instances/[instance_name]``
980
++++++++++++++++++++++++++++++++
981

    
982
Instance-specific resource.
983

    
984
It supports the following commands: ``GET``, ``DELETE``.
985

    
986
``GET``
987
~~~~~~~
988

    
989
Returns information about an instance, similar to the bulk output from
990
the instance list.
991

    
992
Returned fields: :pyeval:`utils.CommaJoin(sorted(rlib2.I_FIELDS))`.
993

    
994
``DELETE``
995
~~~~~~~~~~
996

    
997
Deletes an instance.
998

    
999
It supports the ``dry-run`` argument.
1000

    
1001
Job result:
1002

    
1003
.. opcode_result:: OP_INSTANCE_REMOVE
1004

    
1005

    
1006
``/2/instances/[instance_name]/info``
1007
+++++++++++++++++++++++++++++++++++++++
1008

    
1009
It supports the following commands: ``GET``.
1010

    
1011
``GET``
1012
~~~~~~~
1013

    
1014
Requests detailed information about the instance. An optional parameter,
1015
``static`` (bool), can be set to return only static information from the
1016
configuration without querying the instance's nodes. The result will be
1017
a job id.
1018

    
1019
Job result:
1020

    
1021
.. opcode_result:: OP_INSTANCE_QUERY_DATA
1022

    
1023

    
1024
``/2/instances/[instance_name]/reboot``
1025
+++++++++++++++++++++++++++++++++++++++
1026

    
1027
Reboots URI for an instance.
1028

    
1029
It supports the following commands: ``POST``.
1030

    
1031
``POST``
1032
~~~~~~~~
1033

    
1034
Reboots the instance.
1035

    
1036
The URI takes optional ``type=soft|hard|full`` and
1037
``ignore_secondaries=0|1`` parameters.
1038

    
1039
``type`` defines the reboot type. ``soft`` is just a normal reboot,
1040
without terminating the hypervisor. ``hard`` means full shutdown
1041
(including terminating the hypervisor process) and startup again.
1042
``full`` is like ``hard`` but also recreates the configuration from
1043
ground up as if you would have done a ``gnt-instance shutdown`` and
1044
``gnt-instance start`` on it.
1045

    
1046
``ignore_secondaries`` is a bool argument indicating if we start the
1047
instance even if secondary disks are failing.
1048

    
1049
It supports the ``dry-run`` argument.
1050

    
1051
Job result:
1052

    
1053
.. opcode_result:: OP_INSTANCE_REBOOT
1054

    
1055

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

    
1059
Instance shutdown URI.
1060

    
1061
It supports the following commands: ``PUT``.
1062

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

    
1066
Shutdowns an instance.
1067

    
1068
It supports the ``dry-run`` argument.
1069

    
1070
.. opcode_params:: OP_INSTANCE_SHUTDOWN
1071
   :exclude: instance_name, dry_run
1072

    
1073
Job result:
1074

    
1075
.. opcode_result:: OP_INSTANCE_SHUTDOWN
1076

    
1077

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

    
1081
Instance startup URI.
1082

    
1083
It supports the following commands: ``PUT``.
1084

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

    
1088
Startup an instance.
1089

    
1090
The URI takes an optional ``force=1|0`` parameter to start the
1091
instance even if secondary disks are failing.
1092

    
1093
It supports the ``dry-run`` argument.
1094

    
1095
Job result:
1096

    
1097
.. opcode_result:: OP_INSTANCE_STARTUP
1098

    
1099

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

    
1103
Installs the operating system again.
1104

    
1105
It supports the following commands: ``POST``.
1106

    
1107
``POST``
1108
~~~~~~~~
1109

    
1110
Returns a job ID.
1111

    
1112
Body parameters:
1113

    
1114
``os`` (string, required)
1115
  Instance operating system.
1116
``start`` (bool, defaults to true)
1117
  Whether to start instance after reinstallation.
1118
``osparams`` (dict)
1119
  Dictionary with (temporary) OS parameters.
1120

    
1121
For backwards compatbility, this resource also takes the query
1122
parameters ``os`` (OS template name) and ``nostartup`` (bool). New
1123
clients should use the body parameters.
1124

    
1125

    
1126
``/2/instances/[instance_name]/replace-disks``
1127
++++++++++++++++++++++++++++++++++++++++++++++
1128

    
1129
Replaces disks on an instance.
1130

    
1131
It supports the following commands: ``POST``.
1132

    
1133
``POST``
1134
~~~~~~~~
1135

    
1136
Returns a job ID.
1137

    
1138
Body parameters:
1139

    
1140
.. opcode_params:: OP_INSTANCE_REPLACE_DISKS
1141
   :exclude: instance_name
1142

    
1143
Ganeti 2.4 and below used query parameters. Those are deprecated and
1144
should no longer be used.
1145

    
1146
Job result:
1147

    
1148
.. opcode_result:: OP_INSTANCE_REPLACE_DISKS
1149

    
1150

    
1151
``/2/instances/[instance_name]/activate-disks``
1152
+++++++++++++++++++++++++++++++++++++++++++++++
1153

    
1154
Activate disks on an instance.
1155

    
1156
It supports the following commands: ``PUT``.
1157

    
1158
``PUT``
1159
~~~~~~~
1160

    
1161
Takes the bool parameter ``ignore_size``. When set ignore the recorded
1162
size (useful for forcing activation when recorded size is wrong).
1163

    
1164
Job result:
1165

    
1166
.. opcode_result:: OP_INSTANCE_ACTIVATE_DISKS
1167

    
1168

    
1169
``/2/instances/[instance_name]/deactivate-disks``
1170
+++++++++++++++++++++++++++++++++++++++++++++++++
1171

    
1172
Deactivate disks on an instance.
1173

    
1174
It supports the following commands: ``PUT``.
1175

    
1176
``PUT``
1177
~~~~~~~
1178

    
1179
Takes no parameters.
1180

    
1181
Job result:
1182

    
1183
.. opcode_result:: OP_INSTANCE_DEACTIVATE_DISKS
1184

    
1185

    
1186
``/2/instances/[instance_name]/recreate-disks``
1187
+++++++++++++++++++++++++++++++++++++++++++++++++
1188

    
1189
Recreate disks of an instance. Supports the following commands:
1190
``POST``.
1191

    
1192
``POST``
1193
~~~~~~~~
1194

    
1195
Returns a job ID.
1196

    
1197
Body parameters:
1198

    
1199
.. opcode_params:: OP_INSTANCE_RECREATE_DISKS
1200
   :exclude: instance_name
1201

    
1202
Job result:
1203

    
1204
.. opcode_result:: OP_INSTANCE_RECREATE_DISKS
1205

    
1206

    
1207
``/2/instances/[instance_name]/disk/[disk_index]/grow``
1208
+++++++++++++++++++++++++++++++++++++++++++++++++++++++
1209

    
1210
Grows one disk of an instance.
1211

    
1212
Supports the following commands: ``POST``.
1213

    
1214
``POST``
1215
~~~~~~~~
1216

    
1217
Returns a job ID.
1218

    
1219
Body parameters:
1220

    
1221
.. opcode_params:: OP_INSTANCE_GROW_DISK
1222
   :exclude: instance_name, disk
1223

    
1224
Job result:
1225

    
1226
.. opcode_result:: OP_INSTANCE_GROW_DISK
1227

    
1228

    
1229
``/2/instances/[instance_name]/prepare-export``
1230
+++++++++++++++++++++++++++++++++++++++++++++++++
1231

    
1232
Prepares an export of an instance.
1233

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

    
1236
``PUT``
1237
~~~~~~~
1238

    
1239
Takes one parameter, ``mode``, for the export mode. Returns a job ID.
1240

    
1241
Job result:
1242

    
1243
.. opcode_result:: OP_BACKUP_PREPARE
1244

    
1245

    
1246
``/2/instances/[instance_name]/export``
1247
+++++++++++++++++++++++++++++++++++++++++++++++++
1248

    
1249
Exports an instance.
1250

    
1251
It supports the following commands: ``PUT``.
1252

    
1253
``PUT``
1254
~~~~~~~
1255

    
1256
Returns a job ID.
1257

    
1258
Body parameters:
1259

    
1260
.. opcode_params:: OP_BACKUP_EXPORT
1261
   :exclude: instance_name
1262
   :alias: target_node=destination
1263

    
1264
Job result:
1265

    
1266
.. opcode_result:: OP_BACKUP_EXPORT
1267

    
1268

    
1269
``/2/instances/[instance_name]/migrate``
1270
++++++++++++++++++++++++++++++++++++++++
1271

    
1272
Migrates an instance.
1273

    
1274
Supports the following commands: ``PUT``.
1275

    
1276
``PUT``
1277
~~~~~~~
1278

    
1279
Returns a job ID.
1280

    
1281
Body parameters:
1282

    
1283
.. opcode_params:: OP_INSTANCE_MIGRATE
1284
   :exclude: instance_name, live
1285

    
1286
Job result:
1287

    
1288
.. opcode_result:: OP_INSTANCE_MIGRATE
1289

    
1290

    
1291
``/2/instances/[instance_name]/failover``
1292
+++++++++++++++++++++++++++++++++++++++++
1293

    
1294
Does a failover of an instance.
1295

    
1296
Supports the following commands: ``PUT``.
1297

    
1298
``PUT``
1299
~~~~~~~
1300

    
1301
Returns a job ID.
1302

    
1303
Body parameters:
1304

    
1305
.. opcode_params:: OP_INSTANCE_FAILOVER
1306
   :exclude: instance_name
1307

    
1308
Job result:
1309

    
1310
.. opcode_result:: OP_INSTANCE_FAILOVER
1311

    
1312

    
1313
``/2/instances/[instance_name]/rename``
1314
++++++++++++++++++++++++++++++++++++++++
1315

    
1316
Renames an instance.
1317

    
1318
Supports the following commands: ``PUT``.
1319

    
1320
``PUT``
1321
~~~~~~~
1322

    
1323
Returns a job ID.
1324

    
1325
Body parameters:
1326

    
1327
.. opcode_params:: OP_INSTANCE_RENAME
1328
   :exclude: instance_name
1329

    
1330
Job result:
1331

    
1332
.. opcode_result:: OP_INSTANCE_RENAME
1333

    
1334

    
1335
``/2/instances/[instance_name]/modify``
1336
++++++++++++++++++++++++++++++++++++++++
1337

    
1338
Modifies an instance.
1339

    
1340
Supports the following commands: ``PUT``.
1341

    
1342
``PUT``
1343
~~~~~~~
1344

    
1345
Returns a job ID.
1346

    
1347
Body parameters:
1348

    
1349
.. opcode_params:: OP_INSTANCE_SET_PARAMS
1350
   :exclude: instance_name
1351

    
1352
Job result:
1353

    
1354
.. opcode_result:: OP_INSTANCE_SET_PARAMS
1355

    
1356

    
1357
``/2/instances/[instance_name]/console``
1358
++++++++++++++++++++++++++++++++++++++++
1359

    
1360
Request information for connecting to instance's console.
1361

    
1362
.. pyassert::
1363

    
1364
  not (hasattr(rlib2.R_2_instances_name_console, "PUT") or
1365
       hasattr(rlib2.R_2_instances_name_console, "POST") or
1366
       hasattr(rlib2.R_2_instances_name_console, "DELETE"))
1367

    
1368
Supports the following commands: ``GET``. Requires authentication with
1369
one of the following options:
1370
:pyeval:`utils.CommaJoin(rlib2.R_2_instances_name_console.GET_ACCESS)`.
1371

    
1372
``GET``
1373
~~~~~~~
1374

    
1375
Returns a dictionary containing information about the instance's
1376
console. Contained keys:
1377

    
1378
.. pyassert::
1379

    
1380
   constants.CONS_ALL == frozenset([
1381
     constants.CONS_MESSAGE,
1382
     constants.CONS_SSH,
1383
     constants.CONS_VNC,
1384
     constants.CONS_SPICE,
1385
     ])
1386

    
1387
``instance``
1388
  Instance name
1389
``kind``
1390
  Console type, one of :pyeval:`constants.CONS_SSH`,
1391
  :pyeval:`constants.CONS_VNC`, :pyeval:`constants.CONS_SPICE`
1392
  or :pyeval:`constants.CONS_MESSAGE`
1393
``message``
1394
  Message to display (:pyeval:`constants.CONS_MESSAGE` type only)
1395
``host``
1396
  Host to connect to (:pyeval:`constants.CONS_SSH`,
1397
  :pyeval:`constants.CONS_VNC` or :pyeval:`constants.CONS_SPICE` only)
1398
``port``
1399
  TCP port to connect to (:pyeval:`constants.CONS_VNC` or
1400
  :pyeval:`constants.CONS_SPICE` only)
1401
``user``
1402
  Username to use (:pyeval:`constants.CONS_SSH` only)
1403
``command``
1404
  Command to execute on machine (:pyeval:`constants.CONS_SSH` only)
1405
``display``
1406
  VNC display number (:pyeval:`constants.CONS_VNC` only)
1407

    
1408

    
1409
``/2/instances/[instance_name]/tags``
1410
+++++++++++++++++++++++++++++++++++++
1411

    
1412
Manages per-instance tags.
1413

    
1414
It supports the following commands: ``GET``, ``PUT``, ``DELETE``.
1415

    
1416
``GET``
1417
~~~~~~~
1418

    
1419
Returns a list of tags.
1420

    
1421
Example::
1422

    
1423
    ["tag1", "tag2", "tag3"]
1424

    
1425
``PUT``
1426
~~~~~~~
1427

    
1428
Add a set of tags.
1429

    
1430
The request as a list of strings should be ``PUT`` to this URI. The
1431
result will be a job id.
1432

    
1433
It supports the ``dry-run`` argument.
1434

    
1435

    
1436
``DELETE``
1437
~~~~~~~~~~
1438

    
1439
Delete a tag.
1440

    
1441
In order to delete a set of tags, the DELETE request should be addressed
1442
to URI like::
1443

    
1444
    /tags?tag=[tag]&tag=[tag]
1445

    
1446
It supports the ``dry-run`` argument.
1447

    
1448

    
1449
``/2/jobs``
1450
+++++++++++
1451

    
1452
The ``/2/jobs`` resource.
1453

    
1454
It supports the following commands: ``GET``.
1455

    
1456
``GET``
1457
~~~~~~~
1458

    
1459
Returns a dictionary of jobs.
1460

    
1461
Returns: a dictionary with jobs id and uri.
1462

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

    
1467
Returned fields for bulk requests (unlike other bulk requests, these
1468
fields are not the same as for per-job requests):
1469
:pyeval:`utils.CommaJoin(sorted(rlib2.J_FIELDS_BULK))`.
1470

    
1471
``/2/jobs/[job_id]``
1472
++++++++++++++++++++
1473

    
1474

    
1475
Individual job URI.
1476

    
1477
It supports the following commands: ``GET``, ``DELETE``.
1478

    
1479
``GET``
1480
~~~~~~~
1481

    
1482
Returns a dictionary with job parameters, containing the fields
1483
:pyeval:`utils.CommaJoin(sorted(rlib2.J_FIELDS))`.
1484

    
1485
The result includes:
1486

    
1487
- id: job ID as a number
1488
- status: current job status as a string
1489
- ops: involved OpCodes as a list of dictionaries for each opcodes in
1490
  the job
1491
- opstatus: OpCodes status as a list
1492
- opresult: OpCodes results as a list
1493

    
1494
For a successful opcode, the ``opresult`` field corresponding to it will
1495
contain the raw result from its :term:`LogicalUnit`. In case an opcode
1496
has failed, its element in the opresult list will be a list of two
1497
elements:
1498

    
1499
- first element the error type (the Ganeti internal error name)
1500
- second element a list of either one or two elements:
1501

    
1502
  - the first element is the textual error description
1503
  - the second element, if any, will hold an error classification
1504

    
1505
The error classification is most useful for the ``OpPrereqError``
1506
error type - these errors happen before the OpCode has started
1507
executing, so it's possible to retry the OpCode without side
1508
effects. But whether it make sense to retry depends on the error
1509
classification:
1510

    
1511
.. pyassert::
1512

    
1513
   errors.ECODE_ALL == set([errors.ECODE_RESOLVER, errors.ECODE_NORES,
1514
     errors.ECODE_INVAL, errors.ECODE_STATE, errors.ECODE_NOENT,
1515
     errors.ECODE_EXISTS, errors.ECODE_NOTUNIQUE, errors.ECODE_FAULT,
1516
     errors.ECODE_ENVIRON, errors.ECODE_TEMP_NORES])
1517

    
1518
:pyeval:`errors.ECODE_RESOLVER`
1519
  Resolver errors. This usually means that a name doesn't exist in DNS,
1520
  so if it's a case of slow DNS propagation the operation can be retried
1521
  later.
1522

    
1523
:pyeval:`errors.ECODE_NORES`
1524
  Not enough resources (iallocator failure, disk space, memory,
1525
  etc.). If the resources on the cluster increase, the operation might
1526
  succeed.
1527

    
1528
:pyeval:`errors.ECODE_TEMP_NORES`
1529
  Simliar to :pyeval:`errors.ECODE_NORES`, but indicating the operation
1530
  should be attempted again after some time.
1531

    
1532
:pyeval:`errors.ECODE_INVAL`
1533
  Wrong arguments (at syntax level). The operation will not ever be
1534
  accepted unless the arguments change.
1535

    
1536
:pyeval:`errors.ECODE_STATE`
1537
  Wrong entity state. For example, live migration has been requested for
1538
  a down instance, or instance creation on an offline node. The
1539
  operation can be retried once the resource has changed state.
1540

    
1541
:pyeval:`errors.ECODE_NOENT`
1542
  Entity not found. For example, information has been requested for an
1543
  unknown instance.
1544

    
1545
:pyeval:`errors.ECODE_EXISTS`
1546
  Entity already exists. For example, instance creation has been
1547
  requested for an already-existing instance.
1548

    
1549
:pyeval:`errors.ECODE_NOTUNIQUE`
1550
  Resource not unique (e.g. MAC or IP duplication).
1551

    
1552
:pyeval:`errors.ECODE_FAULT`
1553
  Internal cluster error. For example, a node is unreachable but not set
1554
  offline, or the ganeti node daemons are not working, etc. A
1555
  ``gnt-cluster verify`` should be run.
1556

    
1557
:pyeval:`errors.ECODE_ENVIRON`
1558
  Environment error (e.g. node disk error). A ``gnt-cluster verify``
1559
  should be run.
1560

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

    
1564

    
1565
``DELETE``
1566
~~~~~~~~~~
1567

    
1568
Cancel a not-yet-started job.
1569

    
1570

    
1571
``/2/jobs/[job_id]/wait``
1572
+++++++++++++++++++++++++
1573

    
1574
``GET``
1575
~~~~~~~
1576

    
1577
Waits for changes on a job. Takes the following body parameters in a
1578
dict:
1579

    
1580
``fields``
1581
  The job fields on which to watch for changes
1582

    
1583
``previous_job_info``
1584
  Previously received field values or None if not yet available
1585

    
1586
``previous_log_serial``
1587
  Highest log serial number received so far or None if not yet
1588
  available
1589

    
1590
Returns None if no changes have been detected and a dict with two keys,
1591
``job_info`` and ``log_entries`` otherwise.
1592

    
1593

    
1594
``/2/nodes``
1595
++++++++++++
1596

    
1597
Nodes resource.
1598

    
1599
It supports the following commands: ``GET``.
1600

    
1601
``GET``
1602
~~~~~~~
1603

    
1604
Returns a list of all nodes.
1605

    
1606
Example::
1607

    
1608
    [
1609
      {
1610
        "id": "node1.example.com",
1611
        "uri": "\/nodes\/node1.example.com"
1612
      },
1613
      {
1614
        "id": "node2.example.com",
1615
        "uri": "\/nodes\/node2.example.com"
1616
      }
1617
    ]
1618

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

    
1623
Returned fields: :pyeval:`utils.CommaJoin(sorted(rlib2.N_FIELDS))`.
1624

    
1625
Example::
1626

    
1627
    [
1628
      {
1629
        "pinst_cnt": 1,
1630
        "mfree": 31280,
1631
        "mtotal": 32763,
1632
        "name": "www.example.com",
1633
        "tags": [],
1634
        "mnode": 512,
1635
        "dtotal": 5246208,
1636
        "sinst_cnt": 2,
1637
        "dfree": 5171712,
1638
        "offline": false,
1639
1640
      },
1641
1642
    ]
1643

    
1644
``/2/nodes/[node_name]``
1645
+++++++++++++++++++++++++++++++++
1646

    
1647
Returns information about a node.
1648

    
1649
It supports the following commands: ``GET``.
1650

    
1651
Returned fields: :pyeval:`utils.CommaJoin(sorted(rlib2.N_FIELDS))`.
1652

    
1653
``/2/nodes/[node_name]/powercycle``
1654
+++++++++++++++++++++++++++++++++++
1655

    
1656
Powercycles a node. Supports the following commands: ``POST``.
1657

    
1658
``POST``
1659
~~~~~~~~
1660

    
1661
Returns a job ID.
1662

    
1663
Job result:
1664

    
1665
.. opcode_result:: OP_NODE_POWERCYCLE
1666

    
1667

    
1668
``/2/nodes/[node_name]/evacuate``
1669
+++++++++++++++++++++++++++++++++
1670

    
1671
Evacuates instances off a node.
1672

    
1673
It supports the following commands: ``POST``.
1674

    
1675
``POST``
1676
~~~~~~~~
1677

    
1678
Returns a job ID. The result of the job will contain the IDs of the
1679
individual jobs submitted to evacuate the node.
1680

    
1681
Body parameters:
1682

    
1683
.. opcode_params:: OP_NODE_EVACUATE
1684
   :exclude: nodes
1685

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

    
1690
Job result:
1691

    
1692
.. opcode_result:: OP_NODE_EVACUATE
1693

    
1694

    
1695
``/2/nodes/[node_name]/migrate``
1696
+++++++++++++++++++++++++++++++++
1697

    
1698
Migrates all primary instances from a node.
1699

    
1700
It supports the following commands: ``POST``.
1701

    
1702
``POST``
1703
~~~~~~~~
1704

    
1705
If no mode is explicitly specified, each instances' hypervisor default
1706
migration mode will be used. Body parameters:
1707

    
1708
.. opcode_params:: OP_NODE_MIGRATE
1709
   :exclude: node_name
1710

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

    
1715
Job result:
1716

    
1717
.. opcode_result:: OP_NODE_MIGRATE
1718

    
1719

    
1720
``/2/nodes/[node_name]/role``
1721
+++++++++++++++++++++++++++++
1722

    
1723
Manages node role.
1724

    
1725
It supports the following commands: ``GET``, ``PUT``.
1726

    
1727
The role is always one of the following:
1728

    
1729
  - drained
1730
  - master-candidate
1731
  - offline
1732
  - regular
1733

    
1734
Note that the 'master' role is a special, and currently it can't be
1735
modified via RAPI, only via the command line (``gnt-cluster
1736
master-failover``).
1737

    
1738
``GET``
1739
~~~~~~~
1740

    
1741
Returns the current node role.
1742

    
1743
Example::
1744

    
1745
    "master-candidate"
1746

    
1747
``PUT``
1748
~~~~~~~
1749

    
1750
Change the node role.
1751

    
1752
The request is a string which should be PUT to this URI. The result will
1753
be a job id.
1754

    
1755
It supports the bool ``force`` argument.
1756

    
1757
Job result:
1758

    
1759
.. opcode_result:: OP_NODE_SET_PARAMS
1760

    
1761

    
1762
``/2/nodes/[node_name]/modify``
1763
+++++++++++++++++++++++++++++++
1764

    
1765
Modifies the parameters of a node. Supports the following commands:
1766
``POST``.
1767

    
1768
``POST``
1769
~~~~~~~~
1770

    
1771
Returns a job ID.
1772

    
1773
Body parameters:
1774

    
1775
.. opcode_params:: OP_NODE_SET_PARAMS
1776
   :exclude: node_name
1777

    
1778
Job result:
1779

    
1780
.. opcode_result:: OP_NODE_SET_PARAMS
1781

    
1782

    
1783
``/2/nodes/[node_name]/storage``
1784
++++++++++++++++++++++++++++++++
1785

    
1786
Manages storage units on the node.
1787

    
1788
``GET``
1789
~~~~~~~
1790

    
1791
.. pyassert::
1792

    
1793
   constants.VALID_STORAGE_TYPES == set([constants.ST_FILE,
1794
                                         constants.ST_LVM_PV,
1795
                                         constants.ST_LVM_VG])
1796

    
1797
Requests a list of storage units on a node. Requires the parameters
1798
``storage_type`` (one of :pyeval:`constants.ST_FILE`,
1799
:pyeval:`constants.ST_LVM_PV` or :pyeval:`constants.ST_LVM_VG`) and
1800
``output_fields``. The result will be a job id, using which the result
1801
can be retrieved.
1802

    
1803
``/2/nodes/[node_name]/storage/modify``
1804
+++++++++++++++++++++++++++++++++++++++
1805

    
1806
Modifies storage units on the node.
1807

    
1808
``PUT``
1809
~~~~~~~
1810

    
1811
Modifies parameters of storage units on the node. Requires the
1812
parameters ``storage_type`` (one of :pyeval:`constants.ST_FILE`,
1813
:pyeval:`constants.ST_LVM_PV` or :pyeval:`constants.ST_LVM_VG`)
1814
and ``name`` (name of the storage unit).  Parameters can be passed
1815
additionally. Currently only :pyeval:`constants.SF_ALLOCATABLE` (bool)
1816
is supported. The result will be a job id.
1817

    
1818
Job result:
1819

    
1820
.. opcode_result:: OP_NODE_MODIFY_STORAGE
1821

    
1822

    
1823
``/2/nodes/[node_name]/storage/repair``
1824
+++++++++++++++++++++++++++++++++++++++
1825

    
1826
Repairs a storage unit on the node.
1827

    
1828
``PUT``
1829
~~~~~~~
1830

    
1831
.. pyassert::
1832

    
1833
   constants.VALID_STORAGE_OPERATIONS == {
1834
    constants.ST_LVM_VG: set([constants.SO_FIX_CONSISTENCY]),
1835
    }
1836

    
1837
Repairs a storage unit on the node. Requires the parameters
1838
``storage_type`` (currently only :pyeval:`constants.ST_LVM_VG` can be
1839
repaired) and ``name`` (name of the storage unit). The result will be a
1840
job id.
1841

    
1842
Job result:
1843

    
1844
.. opcode_result:: OP_REPAIR_NODE_STORAGE
1845

    
1846

    
1847
``/2/nodes/[node_name]/tags``
1848
+++++++++++++++++++++++++++++
1849

    
1850
Manages per-node tags.
1851

    
1852
It supports the following commands: ``GET``, ``PUT``, ``DELETE``.
1853

    
1854
``GET``
1855
~~~~~~~
1856

    
1857
Returns a list of tags.
1858

    
1859
Example::
1860

    
1861
    ["tag1", "tag2", "tag3"]
1862

    
1863
``PUT``
1864
~~~~~~~
1865

    
1866
Add a set of tags.
1867

    
1868
The request as a list of strings should be PUT to this URI. The result
1869
will be a job id.
1870

    
1871
It supports the ``dry-run`` argument.
1872

    
1873
``DELETE``
1874
~~~~~~~~~~
1875

    
1876
Deletes tags.
1877

    
1878
In order to delete a set of tags, the DELETE request should be addressed
1879
to URI like::
1880

    
1881
    /tags?tag=[tag]&tag=[tag]
1882

    
1883
It supports the ``dry-run`` argument.
1884

    
1885

    
1886
``/2/query/[resource]``
1887
+++++++++++++++++++++++
1888

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

    
1894
.. pyassert::
1895

    
1896
  (rlib2.R_2_query.GET_ACCESS == rlib2.R_2_query.PUT_ACCESS and
1897
   not (hasattr(rlib2.R_2_query, "POST") or
1898
        hasattr(rlib2.R_2_query, "DELETE")))
1899

    
1900
Supports the following commands: ``GET``, ``PUT``. Requires
1901
authentication with one of the following options:
1902
:pyeval:`utils.CommaJoin(rlib2.R_2_query.GET_ACCESS)`.
1903

    
1904
``GET``
1905
~~~~~~~
1906

    
1907
Returns list of included fields and actual data. Takes a query parameter
1908
named "fields", containing a comma-separated list of field names. Does
1909
not support filtering.
1910

    
1911
``PUT``
1912
~~~~~~~
1913

    
1914
Returns list of included fields and actual data. The list of requested
1915
fields can either be given as the query parameter "fields" or as a body
1916
parameter with the same name. The optional body parameter "filter" can
1917
be given and must be either ``null`` or a list containing filter
1918
operators.
1919

    
1920

    
1921
``/2/query/[resource]/fields``
1922
++++++++++++++++++++++++++++++
1923

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

    
1928
Supports the following commands: ``GET``.
1929

    
1930
``GET``
1931
~~~~~~~
1932

    
1933
Returns a list of field descriptions for available fields. Takes an
1934
optional query parameter named "fields", containing a comma-separated
1935
list of field names.
1936

    
1937

    
1938
``/2/os``
1939
+++++++++
1940

    
1941
OS resource.
1942

    
1943
It supports the following commands: ``GET``.
1944

    
1945
``GET``
1946
~~~~~~~
1947

    
1948
Return a list of all OSes.
1949

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

    
1953
Example::
1954

    
1955
    ["debian-etch"]
1956

    
1957
``/2/tags``
1958
+++++++++++
1959

    
1960
Manages cluster tags.
1961

    
1962
It supports the following commands: ``GET``, ``PUT``, ``DELETE``.
1963

    
1964
``GET``
1965
~~~~~~~
1966

    
1967
Returns the cluster tags.
1968

    
1969
Example::
1970

    
1971
    ["tag1", "tag2", "tag3"]
1972

    
1973
``PUT``
1974
~~~~~~~
1975

    
1976
Adds a set of tags.
1977

    
1978
The request as a list of strings should be PUT to this URI. The result
1979
will be a job id.
1980

    
1981
It supports the ``dry-run`` argument.
1982

    
1983

    
1984
``DELETE``
1985
~~~~~~~~~~
1986

    
1987
Deletes tags.
1988

    
1989
In order to delete a set of tags, the DELETE request should be addressed
1990
to URI like::
1991

    
1992
    /tags?tag=[tag]&tag=[tag]
1993

    
1994
It supports the ``dry-run`` argument.
1995

    
1996

    
1997
``/version``
1998
++++++++++++
1999

    
2000
The version resource.
2001

    
2002
This resource should be used to determine the remote API version and to
2003
adapt clients accordingly.
2004

    
2005
It supports the following commands: ``GET``.
2006

    
2007
``GET``
2008
~~~~~~~
2009

    
2010
Returns the remote API version. Ganeti 1.2 returned ``1`` and Ganeti 2.0
2011
returns ``2``.
2012

    
2013
.. vim: set textwidth=72 :
2014
.. Local Variables:
2015
.. mode: rst
2016
.. fill-column: 72
2017
.. End: