Statistics
| Branch: | Tag: | Revision:

root / doc / rapi.rst @ 87c7621a

History | View | Annotate | Download (49.7 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).
33

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

    
42
Options control a user's access permissions. The section
43
:ref:`rapi-access-permissions` lists the permissions required for each
44
resource. If the ``--require-authentication`` command line option is
45
given to the ``ganeti-rapi`` daemon, all requests require
46
authentication. Available options:
47

    
48
.. pyassert::
49

    
50
  rapi.RAPI_ACCESS_ALL == set([
51
    rapi.RAPI_ACCESS_WRITE,
52
    rapi.RAPI_ACCESS_READ,
53
    ])
54

    
55
.. pyassert::
56

    
57
  rlib2.R_2_nodes_name_storage.GET_ACCESS == [rapi.RAPI_ACCESS_WRITE]
58

    
59
.. pyassert::
60

    
61
  rlib2.R_2_jobs_id_wait.GET_ACCESS == [rapi.RAPI_ACCESS_WRITE]
62

    
63
:pyeval:`rapi.RAPI_ACCESS_WRITE`
64
  Enables the user to execute operations modifying the cluster. Implies
65
  :pyeval:`rapi.RAPI_ACCESS_READ` access. Resources blocking other
66
  operations for read-only access, such as
67
  :ref:`/2/nodes/[node_name]/storage <rapi-res-nodes-node_name-storage+get>`
68
  or blocking server-side processes, such as
69
  :ref:`/2/jobs/[job_id]/wait <rapi-res-jobs-job_id-wait+get>`, use
70
  :pyeval:`rapi.RAPI_ACCESS_WRITE` to control access to their
71
  :pyeval:`http.HTTP_GET` method.
72
:pyeval:`rapi.RAPI_ACCESS_READ`
73
  Allow access to operations querying for information.
74

    
75
Example::
76

    
77
  # Give Jack and Fred read-only access
78
  jack abc123
79
  fred {cleartext}foo555
80

    
81
  # Give write access to an imaginary instance creation script
82
  autocreator xyz789 write
83

    
84
  # Hashed password for Jessica
85
  jessica {HA1}7046452df2cbb530877058712cf17bd4 write
86

    
87
  # Monitoring can query for values
88
  monitoring {HA1}ec018ffe72b8e75bb4d508ed5b6d079c read
89

    
90
  # A user who can read and write (the former is implied by granting
91
  # write access)
92
  superuser {HA1}ec018ffe72b8e75bb4d508ed5b6d079c read,write
93

    
94
When using the RAPI, username and password can be sent to the server
95
by using the standard HTTP basic access authentication. This means that
96
for accessing the protected URL ``https://cluster.example.com/resource``,
97
the address ``https://username:password@cluster.example.com/resource`` should
98
be used instead.
99

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

    
108

    
109
Protocol
110
--------
111

    
112
The protocol used is JSON_ over HTTP designed after the REST_ principle.
113
HTTP Basic authentication as per :rfc:`2617` is supported.
114

    
115
.. _JSON: http://www.json.org/
116
.. _REST: http://en.wikipedia.org/wiki/Representational_State_Transfer
117

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

    
122

    
123
A note on JSON as used by RAPI
124
++++++++++++++++++++++++++++++
125

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

    
133
.. highlight:: ruby
134

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

    
143
  require "json"
144

    
145
  # Insert code to get response here
146
  response = "\"1234\""
147

    
148
  decoded = JSON.parse("[#{response}]").first
149

    
150
Short of modifying the encoder to allow encoding to a less strict
151
format, requests will have to be formatted by hand. Newer RAPI requests
152
already use a dictionary as their input data and shouldn't cause any
153
problems.
154

    
155

    
156
PUT or POST?
157
------------
158

    
159
According to :rfc:`2616` the main difference between PUT and POST is
160
that POST can create new resources but PUT can only create the resource
161
the URI was pointing to on the PUT request.
162

    
163
Unfortunately, due to historic reasons, the Ganeti RAPI library is not
164
consistent with this usage, so just use the methods as documented below
165
for each resource.
166

    
167
For more details have a look in the source code at
168
``lib/rapi/rlib2.py``.
169

    
170

    
171
Generic parameter types
172
-----------------------
173

    
174
A few generic refered parameter types and the values they allow.
175

    
176
``bool``
177
++++++++
178

    
179
A boolean option will accept ``1`` or ``0`` as numbers but not
180
i.e. ``True`` or ``False``.
181

    
182
Generic parameters
183
------------------
184

    
185
A few parameter mean the same thing across all resources which implement
186
it.
187

    
188
``bulk``
189
++++++++
190

    
191
Bulk-mode means that for the resources which usually return just a list
192
of child resources (e.g. ``/2/instances`` which returns just instance
193
names), the output will instead contain detailed data for all these
194
subresources. This is more efficient than query-ing the sub-resources
195
themselves.
196

    
197
``dry-run``
198
+++++++++++
199

    
200
The boolean *dry-run* argument, if provided and set, signals to Ganeti
201
that the job should not be executed, only the pre-execution checks will
202
be done.
203

    
204
This is useful in trying to determine (without guarantees though, as in
205
the meantime the cluster state could have changed) if the operation is
206
likely to succeed or at least start executing.
207

    
208
``force``
209
+++++++++++
210

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

    
214
Parameter details
215
-----------------
216

    
217
Some parameters are not straight forward, so we describe them in details
218
here.
219

    
220
.. _rapi-ipolicy:
221

    
222
``ipolicy``
223
+++++++++++
224

    
225
The instance policy specification is a dict with the following fields:
226

    
227
.. pyassert::
228

    
229
  constants.IPOLICY_ALL_KEYS == set([constants.ISPECS_MINMAX,
230
                                     constants.ISPECS_STD,
231
                                     constants.IPOLICY_DTS,
232
                                     constants.IPOLICY_VCPU_RATIO,
233
                                     constants.IPOLICY_SPINDLE_RATIO])
234

    
235

    
236
.. pyassert::
237

    
238
  (set(constants.ISPECS_PARAMETER_TYPES.keys()) ==
239
   set([constants.ISPEC_MEM_SIZE,
240
        constants.ISPEC_DISK_SIZE,
241
        constants.ISPEC_DISK_COUNT,
242
        constants.ISPEC_CPU_COUNT,
243
        constants.ISPEC_NIC_COUNT,
244
        constants.ISPEC_SPINDLE_USE]))
245

    
246
.. |ispec-min| replace:: :pyeval:`constants.ISPECS_MIN`
247
.. |ispec-max| replace:: :pyeval:`constants.ISPECS_MAX`
248
.. |ispec-std| replace:: :pyeval:`constants.ISPECS_STD`
249

    
250

    
251
:pyeval:`constants.ISPECS_MINMAX`
252
  A dict with the following two fields:
253

    
254
  |ispec-min|, |ispec-max|
255
    A sub- `dict` with the following fields, which sets the limit of the
256
    instances:
257

    
258
    :pyeval:`constants.ISPEC_MEM_SIZE`
259
      The size in MiB of the memory used
260
    :pyeval:`constants.ISPEC_DISK_SIZE`
261
      The size in MiB of the disk used
262
    :pyeval:`constants.ISPEC_DISK_COUNT`
263
      The numbers of disks used
264
    :pyeval:`constants.ISPEC_CPU_COUNT`
265
      The numbers of cpus used
266
    :pyeval:`constants.ISPEC_NIC_COUNT`
267
      The numbers of nics used
268
    :pyeval:`constants.ISPEC_SPINDLE_USE`
269
      The numbers of virtual disk spindles used by this instance. They
270
      are not real in the sense of actual HDD spindles, but useful for
271
      accounting the spindle usage on the residing node
272
|ispec-std|
273
  A sub- `dict` with the same fields as |ispec-min| and |ispec-max| above,
274
  which sets the standard values of the instances.
275
:pyeval:`constants.IPOLICY_DTS`
276
  A `list` of disk templates allowed for instances using this policy
277
:pyeval:`constants.IPOLICY_VCPU_RATIO`
278
  Maximum ratio of virtual to physical CPUs (`float`)
279
:pyeval:`constants.IPOLICY_SPINDLE_RATIO`
280
  Maximum ratio of instances to their node's ``spindle_count`` (`float`)
281

    
282
Usage examples
283
--------------
284

    
285
You can access the API using your favorite programming language as long
286
as it supports network connections.
287

    
288
Ganeti RAPI client
289
++++++++++++++++++
290

    
291
Ganeti includes a standalone RAPI client, ``lib/rapi/client.py``.
292

    
293
Shell
294
+++++
295

    
296
.. highlight:: shell-example
297

    
298
Using ``wget``::
299

    
300
   $ wget -q -O - https://%CLUSTERNAME%:5080/2/info
301

    
302
or ``curl``::
303

    
304
  $ curl https://%CLUSTERNAME%:5080/2/info
305

    
306
Note: with ``curl``, the request method (GET, POST, PUT) can be specified
307
using the ``-X`` command line option.
308

    
309
Python
310
++++++
311

    
312
.. highlight:: python
313

    
314
::
315

    
316
  import urllib2
317
  f = urllib2.urlopen('https://CLUSTERNAME:5080/2/info')
318
  print f.read()
319

    
320

    
321
JavaScript
322
++++++++++
323

    
324
.. warning:: While it's possible to use JavaScript, it poses several
325
   potential problems, including browser blocking request due to
326
   non-standard ports or different domain names. Fetching the data on
327
   the webserver is easier.
328

    
329
.. highlight:: javascript
330

    
331
::
332

    
333
  var url = 'https://CLUSTERNAME:5080/2/info';
334
  var info;
335
  var xmlreq = new XMLHttpRequest();
336
  xmlreq.onreadystatechange = function () {
337
    if (xmlreq.readyState != 4) return;
338
    if (xmlreq.status == 200) {
339
      info = eval("(" + xmlreq.responseText + ")");
340
      alert(info);
341
    } else {
342
      alert('Error fetching cluster info');
343
    }
344
    xmlreq = null;
345
  };
346
  xmlreq.open('GET', url, true);
347
  xmlreq.send(null);
348

    
349
Resources
350
---------
351

    
352
.. highlight:: javascript
353

    
354
``/``
355
+++++
356

    
357
The root resource. Has no function, but for legacy reasons the ``GET``
358
method is supported.
359

    
360
``/2``
361
++++++
362

    
363
Has no function, but for legacy reasons the ``GET`` method is supported.
364

    
365
.. _rapi-res-info:
366

    
367
``/2/info``
368
+++++++++++
369

    
370
Cluster information resource.
371

    
372
.. rapi_resource_details:: /2/info
373

    
374

    
375
.. _rapi-res-info+get:
376

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

    
380
Returns cluster information.
381

    
382
Example::
383

    
384
  {
385
    "config_version": 2000000,
386
    "name": "cluster",
387
    "software_version": "2.0.0~beta2",
388
    "os_api_version": 10,
389
    "export_version": 0,
390
    "candidate_pool_size": 10,
391
    "enabled_hypervisors": [
392
      "fake"
393
    ],
394
    "hvparams": {
395
      "fake": {}
396
     },
397
    "default_hypervisor": "fake",
398
    "master": "node1.example.com",
399
    "architecture": [
400
      "64bit",
401
      "x86_64"
402
    ],
403
    "protocol_version": 20,
404
    "beparams": {
405
      "default": {
406
        "auto_balance": true,
407
        "vcpus": 1,
408
        "memory": 128
409
       }
410
      },
411
412
  }
413

    
414

    
415
.. _rapi-res-redistribute-config:
416

    
417
``/2/redistribute-config``
418
++++++++++++++++++++++++++
419

    
420
Redistribute configuration to all nodes.
421

    
422
.. rapi_resource_details:: /2/redistribute-config
423

    
424

    
425
.. _rapi-res-redistribute-config+put:
426

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

    
430
Redistribute configuration to all nodes. The result will be a job id.
431

    
432
Job result:
433

    
434
.. opcode_result:: OP_CLUSTER_REDIST_CONF
435

    
436

    
437
.. _rapi-res-features:
438

    
439
``/2/features``
440
+++++++++++++++
441

    
442
.. rapi_resource_details:: /2/features
443

    
444

    
445
.. _rapi-res-features+get:
446

    
447
``GET``
448
~~~~~~~
449

    
450
Returns a list of features supported by the RAPI server. Available
451
features:
452

    
453
.. pyassert::
454

    
455
  rlib2.ALL_FEATURES == set([rlib2._INST_CREATE_REQV1,
456
                             rlib2._INST_REINSTALL_REQV1,
457
                             rlib2._NODE_MIGRATE_REQV1,
458
                             rlib2._NODE_EVAC_RES1])
459

    
460
:pyeval:`rlib2._INST_CREATE_REQV1`
461
  Instance creation request data version 1 supported
462
:pyeval:`rlib2._INST_REINSTALL_REQV1`
463
  Instance reinstall supports body parameters
464
:pyeval:`rlib2._NODE_MIGRATE_REQV1`
465
  Whether migrating a node (``/2/nodes/[node_name]/migrate``) supports
466
  request body parameters
467
:pyeval:`rlib2._NODE_EVAC_RES1`
468
  Whether evacuating a node (``/2/nodes/[node_name]/evacuate``) returns
469
  a new-style result (see resource description)
470

    
471

    
472
.. _rapi-res-modify:
473

    
474
``/2/modify``
475
++++++++++++++++++++++++++++++++++++++++
476

    
477
Modifies cluster parameters.
478

    
479
.. rapi_resource_details:: /2/modify
480

    
481

    
482
.. _rapi-res-modify+put:
483

    
484
``PUT``
485
~~~~~~~
486

    
487
Returns a job ID.
488

    
489
Body parameters:
490

    
491
.. opcode_params:: OP_CLUSTER_SET_PARAMS
492

    
493
Job result:
494

    
495
.. opcode_result:: OP_CLUSTER_SET_PARAMS
496

    
497

    
498
.. _rapi-res-groups:
499

    
500
``/2/groups``
501
+++++++++++++
502

    
503
The groups resource.
504

    
505
.. rapi_resource_details:: /2/groups
506

    
507

    
508
.. _rapi-res-groups+get:
509

    
510
``GET``
511
~~~~~~~
512

    
513
Returns a list of all existing node groups.
514

    
515
Example::
516

    
517
    [
518
      {
519
        "name": "group1",
520
        "uri": "\/2\/groups\/group1"
521
      },
522
      {
523
        "name": "group2",
524
        "uri": "\/2\/groups\/group2"
525
      }
526
    ]
527

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

    
532
Returned fields: :pyeval:`utils.CommaJoin(sorted(rlib2.G_FIELDS))`.
533

    
534
Example::
535

    
536
    [
537
      {
538
        "name": "group1",
539
        "node_cnt": 2,
540
        "node_list": [
541
          "node1.example.com",
542
          "node2.example.com"
543
        ],
544
        "uuid": "0d7d407c-262e-49af-881a-6a430034bf43",
545
546
      },
547
      {
548
        "name": "group2",
549
        "node_cnt": 1,
550
        "node_list": [
551
          "node3.example.com"
552
        ],
553
        "uuid": "f5a277e7-68f9-44d3-a378-4b25ecb5df5c",
554
555
      },
556
557
    ]
558

    
559

    
560
.. _rapi-res-groups+post:
561

    
562
``POST``
563
~~~~~~~~
564

    
565
Creates a node group.
566

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

    
570
Returns: a job ID that can be used later for polling.
571

    
572
Body parameters:
573

    
574
.. opcode_params:: OP_GROUP_ADD
575

    
576
Earlier versions used a parameter named ``name`` which, while still
577
supported, has been renamed to ``group_name``.
578

    
579
Job result:
580

    
581
.. opcode_result:: OP_GROUP_ADD
582

    
583

    
584
.. _rapi-res-groups-group_name:
585

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

    
589
Returns information about a node group.
590

    
591
.. rapi_resource_details:: /2/groups/[group_name]
592

    
593

    
594
.. _rapi-res-groups-group_name+get:
595

    
596
``GET``
597
~~~~~~~
598

    
599
Returns information about a node group, similar to the bulk output from
600
the node group list.
601

    
602
Returned fields: :pyeval:`utils.CommaJoin(sorted(rlib2.G_FIELDS))`.
603

    
604
.. _rapi-res-groups-group_name+delete:
605

    
606
``DELETE``
607
~~~~~~~~~~
608

    
609
Deletes a node group.
610

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

    
613
Job result:
614

    
615
.. opcode_result:: OP_GROUP_REMOVE
616

    
617

    
618
.. _rapi-res-groups-group_name-modify:
619

    
620
``/2/groups/[group_name]/modify``
621
+++++++++++++++++++++++++++++++++
622

    
623
Modifies the parameters of a node group.
624

    
625
.. rapi_resource_details:: /2/groups/[group_name]/modify
626

    
627

    
628
.. _rapi-res-groups-group_name-modify+put:
629

    
630
``PUT``
631
~~~~~~~
632

    
633
Returns a job ID.
634

    
635
Body parameters:
636

    
637
.. opcode_params:: OP_GROUP_SET_PARAMS
638
   :exclude: group_name
639

    
640
Job result:
641

    
642
.. opcode_result:: OP_GROUP_SET_PARAMS
643

    
644

    
645
.. _rapi-res-groups-group_name-rename:
646

    
647
``/2/groups/[group_name]/rename``
648
+++++++++++++++++++++++++++++++++
649

    
650
Renames a node group.
651

    
652
.. rapi_resource_details:: /2/groups/[group_name]/rename
653

    
654

    
655
.. _rapi-res-groups-group_name-rename+put:
656

    
657
``PUT``
658
~~~~~~~
659

    
660
Returns a job ID.
661

    
662
Body parameters:
663

    
664
.. opcode_params:: OP_GROUP_RENAME
665
   :exclude: group_name
666

    
667
Job result:
668

    
669
.. opcode_result:: OP_GROUP_RENAME
670

    
671

    
672
.. _rapi-res-groups-group_name-assign-nodes:
673

    
674
``/2/groups/[group_name]/assign-nodes``
675
+++++++++++++++++++++++++++++++++++++++
676

    
677
Assigns nodes to a group.
678

    
679
.. rapi_resource_details:: /2/groups/[group_name]/assign-nodes
680

    
681
.. _rapi-res-groups-group_name-assign-nodes+put:
682

    
683
``PUT``
684
~~~~~~~
685

    
686
Returns a job ID. It supports the ``dry-run`` and ``force`` arguments.
687

    
688
Body parameters:
689

    
690
.. opcode_params:: OP_GROUP_ASSIGN_NODES
691
   :exclude: group_name, force, dry_run
692

    
693
Job result:
694

    
695
.. opcode_result:: OP_GROUP_ASSIGN_NODES
696

    
697
.. _rapi-res-groups-group_name-tags:
698

    
699
``/2/groups/[group_name]/tags``
700
+++++++++++++++++++++++++++++++
701

    
702
Manages per-nodegroup tags.
703

    
704
.. rapi_resource_details:: /2/groups/[group_name]/tags
705

    
706

    
707
.. _rapi-res-groups-group_name-tags+get:
708

    
709
``GET``
710
~~~~~~~
711

    
712
Returns a list of tags.
713

    
714
Example::
715

    
716
    ["tag1", "tag2", "tag3"]
717

    
718
.. _rapi-res-groups-group_name-tags+put:
719

    
720
``PUT``
721
~~~~~~~
722

    
723
Add a set of tags.
724

    
725
The request as a list of strings should be ``PUT`` to this URI. The
726
result will be a job id.
727

    
728
It supports the ``dry-run`` argument.
729

    
730

    
731
.. _rapi-res-groups-group_name-tags+delete:
732

    
733
``DELETE``
734
~~~~~~~~~~
735

    
736
Delete a tag.
737

    
738
In order to delete a set of tags, the DELETE request should be addressed
739
to URI like::
740

    
741
    /tags?tag=[tag]&tag=[tag]
742

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

    
745

    
746
.. _rapi-res-networks:
747

    
748
``/2/networks``
749
+++++++++++++++
750

    
751
The networks resource.
752

    
753
.. rapi_resource_details:: /2/networks
754

    
755

    
756
.. _rapi-res-networks+get:
757

    
758
``GET``
759
~~~~~~~
760

    
761
Returns a list of all existing networks.
762

    
763
Example::
764

    
765
    [
766
      {
767
        "name": "network1",
768
        "uri": "\/2\/networks\/network1"
769
      },
770
      {
771
        "name": "network2",
772
        "uri": "\/2\/networks\/network2"
773
      }
774
    ]
775

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

    
780
Returned fields: :pyeval:`utils.CommaJoin(sorted(rlib2.NET_FIELDS))`.
781

    
782
Example::
783

    
784
    [
785
      {
786
        'external_reservations': '10.0.0.0, 10.0.0.1, 10.0.0.15',
787
        'free_count': 13,
788
        'gateway': '10.0.0.1',
789
        'gateway6': None,
790
        'group_list': ['default(bridged, prv0)'],
791
        'inst_list': [],
792
        'mac_prefix': None,
793
        'map': 'XX.............X',
794
        'name': 'nat',
795
        'network': '10.0.0.0/28',
796
        'network6': None,
797
        'reserved_count': 3,
798
        'tags': ['nfdhcpd'],
799
800
      },
801
802
    ]
803

    
804

    
805
.. _rapi-res-networks+post:
806

    
807
``POST``
808
~~~~~~~~
809

    
810
Creates a network.
811

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

    
815
Returns: a job ID that can be used later for polling.
816

    
817
Body parameters:
818

    
819
.. opcode_params:: OP_NETWORK_ADD
820

    
821
Job result:
822

    
823
.. opcode_result:: OP_NETWORK_ADD
824

    
825

    
826
.. _rapi-res-networks-network_name:
827

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

    
831
Returns information about a network.
832

    
833
.. rapi_resource_details:: /2/networks/[network_name]
834

    
835

    
836
.. _rapi-res-networks-network_name+get:
837

    
838
``GET``
839
~~~~~~~
840

    
841
Returns information about a network, similar to the bulk output from
842
the network list.
843

    
844
Returned fields: :pyeval:`utils.CommaJoin(sorted(rlib2.NET_FIELDS))`.
845

    
846

    
847
.. _rapi-res-networks-network_name+delete:
848

    
849
``DELETE``
850
~~~~~~~~~~
851

    
852
Deletes a network.
853

    
854
It supports the ``dry-run`` argument.
855

    
856
Job result:
857

    
858
.. opcode_result:: OP_NETWORK_REMOVE
859

    
860

    
861
.. _rapi-res-networks-network_name-modify:
862

    
863
``/2/networks/[network_name]/modify``
864
+++++++++++++++++++++++++++++++++++++
865

    
866
Modifies the parameters of a network.
867

    
868
.. rapi_resource_details:: /2/networks/[network_name]/modify
869

    
870

    
871
.. _rapi-res-networks-network_name-modify+put:
872

    
873
``PUT``
874
~~~~~~~
875

    
876
Returns a job ID.
877

    
878
Body parameters:
879

    
880
.. opcode_params:: OP_NETWORK_SET_PARAMS
881

    
882
Job result:
883

    
884
.. opcode_result:: OP_NETWORK_SET_PARAMS
885

    
886

    
887
.. _rapi-res-networks-network_name-connect:
888

    
889
``/2/networks/[network_name]/connect``
890
++++++++++++++++++++++++++++++++++++++
891

    
892
Connects a network to a nodegroup.
893

    
894
.. rapi_resource_details:: /2/networks/[network_name]/connect
895

    
896

    
897
.. _rapi-res-networks-network_name-connect+put:
898

    
899
``PUT``
900
~~~~~~~
901

    
902
Returns a job ID. It supports the ``dry-run`` arguments.
903

    
904
Body parameters:
905

    
906
.. opcode_params:: OP_NETWORK_CONNECT
907

    
908
Job result:
909

    
910
.. opcode_result:: OP_NETWORK_CONNECT
911

    
912

    
913
.. _rapi-res-networks-network_name-disconnect:
914

    
915
``/2/networks/[network_name]/disconnect``
916
+++++++++++++++++++++++++++++++++++++++++
917

    
918
Disonnects a network from a nodegroup.
919

    
920
.. rapi_resource_details:: /2/networks/[network_name]/disconnect
921

    
922

    
923
.. _rapi-res-networks-network_name-disconnect+put:
924

    
925
``PUT``
926
~~~~~~~
927

    
928
Returns a job ID. It supports the ``dry-run`` arguments.
929

    
930
Body parameters:
931

    
932
.. opcode_params:: OP_NETWORK_DISCONNECT
933

    
934
Job result:
935

    
936
.. opcode_result:: OP_NETWORK_DISCONNECT
937

    
938

    
939
.. _rapi-res-networks-network_name-tags:
940

    
941
``/2/networks/[network_name]/tags``
942
+++++++++++++++++++++++++++++++++++
943

    
944
Manages per-network tags.
945

    
946
.. rapi_resource_details:: /2/networks/[network_name]/tags
947

    
948

    
949
.. _rapi-res-networks-network_name-tags+get:
950

    
951
``GET``
952
~~~~~~~
953

    
954
Returns a list of tags.
955

    
956
Example::
957

    
958
    ["tag1", "tag2", "tag3"]
959

    
960

    
961
.. _rapi-res-networks-network_name-tags+put:
962

    
963
``PUT``
964
~~~~~~~
965

    
966
Add a set of tags.
967

    
968
The request as a list of strings should be ``PUT`` to this URI. The
969
result will be a job id.
970

    
971
It supports the ``dry-run`` argument.
972

    
973

    
974
.. _rapi-res-networks-network_name-tags+delete:
975

    
976
``DELETE``
977
~~~~~~~~~~
978

    
979
Delete a tag.
980

    
981
In order to delete a set of tags, the DELETE request should be addressed
982
to URI like::
983

    
984
    /tags?tag=[tag]&tag=[tag]
985

    
986
It supports the ``dry-run`` argument.
987

    
988

    
989
.. _rapi-res-instances-multi-alloc:
990

    
991
``/2/instances-multi-alloc``
992
++++++++++++++++++++++++++++
993

    
994
Tries to allocate multiple instances.
995

    
996
.. rapi_resource_details:: /2/instances-multi-alloc
997

    
998

    
999
.. _rapi-res-instances-multi-alloc+post:
1000

    
1001
``POST``
1002
~~~~~~~~
1003

    
1004
The parameters:
1005

    
1006
.. opcode_params:: OP_INSTANCE_MULTI_ALLOC
1007

    
1008
Job result:
1009

    
1010
.. opcode_result:: OP_INSTANCE_MULTI_ALLOC
1011

    
1012

    
1013
.. _rapi-res-instances:
1014

    
1015
``/2/instances``
1016
++++++++++++++++
1017

    
1018
The instances resource.
1019

    
1020
.. rapi_resource_details:: /2/instances
1021

    
1022

    
1023
.. _rapi-res-instances+get:
1024

    
1025
``GET``
1026
~~~~~~~
1027

    
1028
Returns a list of all available instances.
1029

    
1030
Example::
1031

    
1032
    [
1033
      {
1034
        "name": "web.example.com",
1035
        "uri": "\/instances\/web.example.com"
1036
      },
1037
      {
1038
        "name": "mail.example.com",
1039
        "uri": "\/instances\/mail.example.com"
1040
      }
1041
    ]
1042

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

    
1047
Returned fields: :pyeval:`utils.CommaJoin(sorted(rlib2.I_FIELDS))`.
1048

    
1049
Example::
1050

    
1051
    [
1052
      {
1053
        "status": "running",
1054
        "disk_usage": 20480,
1055
        "nic.bridges": [
1056
          "xen-br0"
1057
        ],
1058
        "name": "web.example.com",
1059
        "tags": ["tag1", "tag2"],
1060
        "beparams": {
1061
          "vcpus": 2,
1062
          "memory": 512
1063
        },
1064
        "disk.sizes": [
1065
          20480
1066
        ],
1067
        "pnode": "node1.example.com",
1068
        "nic.macs": ["01:23:45:67:89:01"],
1069
        "snodes": ["node2.example.com"],
1070
        "disk_template": "drbd",
1071
        "admin_state": true,
1072
        "os": "debian-etch",
1073
        "oper_state": true,
1074
1075
      },
1076
1077
    ]
1078

    
1079

    
1080
.. _rapi-res-instances+post:
1081

    
1082
``POST``
1083
~~~~~~~~
1084

    
1085
Creates an instance.
1086

    
1087
If the optional bool *dry-run* argument is provided, the job will not be
1088
actually executed, only the pre-execution checks will be done. Query-ing
1089
the job result will return, in both dry-run and normal case, the list of
1090
nodes selected for the instance.
1091

    
1092
Returns: a job ID that can be used later for polling.
1093

    
1094
Body parameters:
1095

    
1096
``__version__`` (int, required)
1097
  Must be ``1`` (older Ganeti versions used a different format for
1098
  instance creation requests, version ``0``, but that format is no
1099
  longer supported)
1100

    
1101
.. opcode_params:: OP_INSTANCE_CREATE
1102

    
1103
Earlier versions used parameters named ``name`` and ``os``. These have
1104
been replaced by ``instance_name`` and ``os_type`` to match the
1105
underlying opcode. The old names can still be used.
1106

    
1107
Job result:
1108

    
1109
.. opcode_result:: OP_INSTANCE_CREATE
1110

    
1111

    
1112
.. _rapi-res-instances-instance_name:
1113

    
1114
``/2/instances/[instance_name]``
1115
++++++++++++++++++++++++++++++++
1116

    
1117
Instance-specific resource.
1118

    
1119
.. rapi_resource_details:: /2/instances/[instance_name]
1120

    
1121

    
1122
.. _rapi-res-instances-instance_name+get:
1123

    
1124
``GET``
1125
~~~~~~~
1126

    
1127
Returns information about an instance, similar to the bulk output from
1128
the instance list.
1129

    
1130
Returned fields: :pyeval:`utils.CommaJoin(sorted(rlib2.I_FIELDS))`.
1131

    
1132

    
1133
.. _rapi-res-instances-instance_name+delete:
1134

    
1135
``DELETE``
1136
~~~~~~~~~~
1137

    
1138
Deletes an instance.
1139

    
1140
It supports the ``dry-run`` argument.
1141

    
1142
Job result:
1143

    
1144
.. opcode_result:: OP_INSTANCE_REMOVE
1145

    
1146

    
1147
.. _rapi-res-instances-instance_name-info:
1148

    
1149
``/2/instances/[instance_name]/info``
1150
+++++++++++++++++++++++++++++++++++++++
1151

    
1152
.. rapi_resource_details:: /2/instances/[instance_name]/info
1153

    
1154

    
1155
.. _rapi-res-instances-instance_name-info+get:
1156

    
1157
``GET``
1158
~~~~~~~
1159

    
1160
Requests detailed information about the instance. An optional parameter,
1161
``static`` (bool), can be set to return only static information from the
1162
configuration without querying the instance's nodes. The result will be
1163
a job id.
1164

    
1165
Job result:
1166

    
1167
.. opcode_result:: OP_INSTANCE_QUERY_DATA
1168

    
1169

    
1170
.. _rapi-res-instances-instance_name-reboot:
1171

    
1172
``/2/instances/[instance_name]/reboot``
1173
+++++++++++++++++++++++++++++++++++++++
1174

    
1175
Reboots URI for an instance.
1176

    
1177
.. rapi_resource_details:: /2/instances/[instance_name]/reboot
1178

    
1179

    
1180
.. _rapi-res-instances-instance_name-reboot+post:
1181

    
1182
``POST``
1183
~~~~~~~~
1184

    
1185
Reboots the instance.
1186

    
1187
The URI takes optional ``type=soft|hard|full`` and
1188
``ignore_secondaries=0|1`` parameters.
1189

    
1190
``type`` defines the reboot type. ``soft`` is just a normal reboot,
1191
without terminating the hypervisor. ``hard`` means full shutdown
1192
(including terminating the hypervisor process) and startup again.
1193
``full`` is like ``hard`` but also recreates the configuration from
1194
ground up as if you would have done a ``gnt-instance shutdown`` and
1195
``gnt-instance start`` on it.
1196

    
1197
``ignore_secondaries`` is a bool argument indicating if we start the
1198
instance even if secondary disks are failing.
1199

    
1200
It supports the ``dry-run`` argument.
1201

    
1202
Job result:
1203

    
1204
.. opcode_result:: OP_INSTANCE_REBOOT
1205

    
1206

    
1207
.. _rapi-res-instances-instance_name-shutdown:
1208

    
1209
``/2/instances/[instance_name]/shutdown``
1210
+++++++++++++++++++++++++++++++++++++++++
1211

    
1212
Instance shutdown URI.
1213

    
1214
.. rapi_resource_details:: /2/instances/[instance_name]/shutdown
1215

    
1216

    
1217
.. _rapi-res-instances-instance_name-shutdown+put:
1218

    
1219
``PUT``
1220
~~~~~~~
1221

    
1222
Shutdowns an instance.
1223

    
1224
It supports the ``dry-run`` argument.
1225

    
1226
.. opcode_params:: OP_INSTANCE_SHUTDOWN
1227
   :exclude: instance_name, dry_run
1228

    
1229
Job result:
1230

    
1231
.. opcode_result:: OP_INSTANCE_SHUTDOWN
1232

    
1233

    
1234
.. _rapi-res-instances-instance_name-startup:
1235

    
1236
``/2/instances/[instance_name]/startup``
1237
++++++++++++++++++++++++++++++++++++++++
1238

    
1239
Instance startup URI.
1240

    
1241
.. rapi_resource_details:: /2/instances/[instance_name]/startup
1242

    
1243

    
1244
.. _rapi-res-instances-instance_name-startup+put:
1245

    
1246
``PUT``
1247
~~~~~~~
1248

    
1249
Startup an instance.
1250

    
1251
The URI takes an optional ``force=1|0`` parameter to start the
1252
instance even if secondary disks are failing.
1253

    
1254
It supports the ``dry-run`` argument.
1255

    
1256
Job result:
1257

    
1258
.. opcode_result:: OP_INSTANCE_STARTUP
1259

    
1260

    
1261
.. _rapi-res-instances-instance_name-reinstall:
1262

    
1263
``/2/instances/[instance_name]/reinstall``
1264
++++++++++++++++++++++++++++++++++++++++++++++
1265

    
1266
Installs the operating system again.
1267

    
1268
.. rapi_resource_details:: /2/instances/[instance_name]/reinstall
1269

    
1270

    
1271
.. _rapi-res-instances-instance_name-reinstall+post:
1272

    
1273
``POST``
1274
~~~~~~~~
1275

    
1276
Returns a job ID.
1277

    
1278
Body parameters:
1279

    
1280
``os`` (string, required)
1281
  Instance operating system.
1282
``start`` (bool, defaults to true)
1283
  Whether to start instance after reinstallation.
1284
``osparams`` (dict)
1285
  Dictionary with (temporary) OS parameters.
1286

    
1287
For backwards compatbility, this resource also takes the query
1288
parameters ``os`` (OS template name) and ``nostartup`` (bool). New
1289
clients should use the body parameters.
1290

    
1291

    
1292
.. _rapi-res-instances-instance_name-replace-disks:
1293

    
1294
``/2/instances/[instance_name]/replace-disks``
1295
++++++++++++++++++++++++++++++++++++++++++++++
1296

    
1297
Replaces disks on an instance.
1298

    
1299
.. rapi_resource_details:: /2/instances/[instance_name]/replace-disks
1300

    
1301

    
1302
.. _rapi-res-instances-instance_name-replace-disks+post:
1303

    
1304
``POST``
1305
~~~~~~~~
1306

    
1307
Returns a job ID.
1308

    
1309
Body parameters:
1310

    
1311
.. opcode_params:: OP_INSTANCE_REPLACE_DISKS
1312
   :exclude: instance_name
1313

    
1314
Ganeti 2.4 and below used query parameters. Those are deprecated and
1315
should no longer be used.
1316

    
1317
Job result:
1318

    
1319
.. opcode_result:: OP_INSTANCE_REPLACE_DISKS
1320

    
1321

    
1322
.. _rapi-res-instances-instance_name-activate-disks:
1323

    
1324
``/2/instances/[instance_name]/activate-disks``
1325
+++++++++++++++++++++++++++++++++++++++++++++++
1326

    
1327
Activate disks on an instance.
1328

    
1329
.. rapi_resource_details:: /2/instances/[instance_name]/activate-disks
1330

    
1331

    
1332
.. _rapi-res-instances-instance_name-activate-disks+put:
1333

    
1334
``PUT``
1335
~~~~~~~
1336

    
1337
Takes the bool parameter ``ignore_size``. When set ignore the recorded
1338
size (useful for forcing activation when recorded size is wrong).
1339

    
1340
Job result:
1341

    
1342
.. opcode_result:: OP_INSTANCE_ACTIVATE_DISKS
1343

    
1344

    
1345
.. _rapi-res-instances-instance_name-deactivate-disks:
1346

    
1347
``/2/instances/[instance_name]/deactivate-disks``
1348
+++++++++++++++++++++++++++++++++++++++++++++++++
1349

    
1350
Deactivate disks on an instance.
1351

    
1352
.. rapi_resource_details:: /2/instances/[instance_name]/deactivate-disks
1353

    
1354

    
1355
.. _rapi-res-instances-instance_name-deactivate-disks+put:
1356

    
1357
``PUT``
1358
~~~~~~~
1359

    
1360
Takes no parameters.
1361

    
1362
Job result:
1363

    
1364
.. opcode_result:: OP_INSTANCE_DEACTIVATE_DISKS
1365

    
1366

    
1367
.. _rapi-res-instances-instance_name-recreate-disks:
1368

    
1369
``/2/instances/[instance_name]/recreate-disks``
1370
+++++++++++++++++++++++++++++++++++++++++++++++++
1371

    
1372
Recreate disks of an instance.
1373

    
1374
.. rapi_resource_details:: /2/instances/[instance_name]/recreate-disks
1375

    
1376

    
1377
.. _rapi-res-instances-instance_name-recreate-disks+post:
1378

    
1379
``POST``
1380
~~~~~~~~
1381

    
1382
Returns a job ID.
1383

    
1384
Body parameters:
1385

    
1386
.. opcode_params:: OP_INSTANCE_RECREATE_DISKS
1387
   :exclude: instance_name
1388

    
1389
Job result:
1390

    
1391
.. opcode_result:: OP_INSTANCE_RECREATE_DISKS
1392

    
1393

    
1394
.. _rapi-res-instances-instance_name-disk-disk_index-grow:
1395

    
1396
``/2/instances/[instance_name]/disk/[disk_index]/grow``
1397
+++++++++++++++++++++++++++++++++++++++++++++++++++++++
1398

    
1399
Grows one disk of an instance.
1400

    
1401
.. rapi_resource_details:: /2/instances/[instance_name]/disk/[disk_index]/grow
1402

    
1403

    
1404
.. _rapi-res-instances-instance_name-disk-disk_index-grow+post:
1405

    
1406
``POST``
1407
~~~~~~~~
1408

    
1409
Returns a job ID.
1410

    
1411
Body parameters:
1412

    
1413
.. opcode_params:: OP_INSTANCE_GROW_DISK
1414
   :exclude: instance_name, disk
1415

    
1416
Job result:
1417

    
1418
.. opcode_result:: OP_INSTANCE_GROW_DISK
1419

    
1420

    
1421
.. _rapi-res-instances-instance_name-prepare-export:
1422

    
1423
``/2/instances/[instance_name]/prepare-export``
1424
+++++++++++++++++++++++++++++++++++++++++++++++++
1425

    
1426
Prepares an export of an instance.
1427

    
1428
.. rapi_resource_details:: /2/instances/[instance_name]/prepare-export
1429

    
1430

    
1431
.. _rapi-res-instances-instance_name-prepare-export+put:
1432

    
1433
``PUT``
1434
~~~~~~~
1435

    
1436
Takes one parameter, ``mode``, for the export mode. Returns a job ID.
1437

    
1438
Job result:
1439

    
1440
.. opcode_result:: OP_BACKUP_PREPARE
1441

    
1442

    
1443
.. _rapi-res-instances-instance_name-export:
1444

    
1445
``/2/instances/[instance_name]/export``
1446
+++++++++++++++++++++++++++++++++++++++++++++++++
1447

    
1448
Exports an instance.
1449

    
1450
.. rapi_resource_details:: /2/instances/[instance_name]/export
1451

    
1452

    
1453
.. _rapi-res-instances-instance_name-export+put:
1454

    
1455
``PUT``
1456
~~~~~~~
1457

    
1458
Returns a job ID.
1459

    
1460
Body parameters:
1461

    
1462
.. opcode_params:: OP_BACKUP_EXPORT
1463
   :exclude: instance_name
1464
   :alias: target_node=destination
1465

    
1466
Job result:
1467

    
1468
.. opcode_result:: OP_BACKUP_EXPORT
1469

    
1470

    
1471
.. _rapi-res-instances-instance_name-migrate:
1472

    
1473
``/2/instances/[instance_name]/migrate``
1474
++++++++++++++++++++++++++++++++++++++++
1475

    
1476
Migrates an instance.
1477

    
1478
.. rapi_resource_details:: /2/instances/[instance_name]/migrate
1479

    
1480

    
1481
.. _rapi-res-instances-instance_name-migrate+put:
1482

    
1483
``PUT``
1484
~~~~~~~
1485

    
1486
Returns a job ID.
1487

    
1488
Body parameters:
1489

    
1490
.. opcode_params:: OP_INSTANCE_MIGRATE
1491
   :exclude: instance_name, live
1492

    
1493
Job result:
1494

    
1495
.. opcode_result:: OP_INSTANCE_MIGRATE
1496

    
1497

    
1498
.. _rapi-res-instances-instance_name-failover:
1499

    
1500
``/2/instances/[instance_name]/failover``
1501
+++++++++++++++++++++++++++++++++++++++++
1502

    
1503
Does a failover of an instance.
1504

    
1505
.. rapi_resource_details:: /2/instances/[instance_name]/failover
1506

    
1507

    
1508
.. _rapi-res-instances-instance_name-failover+put:
1509

    
1510
``PUT``
1511
~~~~~~~
1512

    
1513
Returns a job ID.
1514

    
1515
Body parameters:
1516

    
1517
.. opcode_params:: OP_INSTANCE_FAILOVER
1518
   :exclude: instance_name
1519

    
1520
Job result:
1521

    
1522
.. opcode_result:: OP_INSTANCE_FAILOVER
1523

    
1524

    
1525
.. _rapi-res-instances-instance_name-rename:
1526

    
1527
``/2/instances/[instance_name]/rename``
1528
++++++++++++++++++++++++++++++++++++++++
1529

    
1530
Renames an instance.
1531

    
1532
.. rapi_resource_details:: /2/instances/[instance_name]/rename
1533

    
1534

    
1535
.. _rapi-res-instances-instance_name-rename+put:
1536

    
1537
``PUT``
1538
~~~~~~~
1539

    
1540
Returns a job ID.
1541

    
1542
Body parameters:
1543

    
1544
.. opcode_params:: OP_INSTANCE_RENAME
1545
   :exclude: instance_name
1546

    
1547
Job result:
1548

    
1549
.. opcode_result:: OP_INSTANCE_RENAME
1550

    
1551

    
1552
.. _rapi-res-instances-instance_name-modify:
1553

    
1554
``/2/instances/[instance_name]/modify``
1555
++++++++++++++++++++++++++++++++++++++++
1556

    
1557
Modifies an instance.
1558

    
1559
.. rapi_resource_details:: /2/instances/[instance_name]/modify
1560

    
1561

    
1562
.. _rapi-res-instances-instance_name-modify+put:
1563

    
1564
``PUT``
1565
~~~~~~~
1566

    
1567
Returns a job ID.
1568

    
1569
Body parameters:
1570

    
1571
.. opcode_params:: OP_INSTANCE_SET_PARAMS
1572
   :exclude: instance_name
1573

    
1574
Job result:
1575

    
1576
.. opcode_result:: OP_INSTANCE_SET_PARAMS
1577

    
1578

    
1579
.. _rapi-res-instances-instance_name-console:
1580

    
1581
``/2/instances/[instance_name]/console``
1582
++++++++++++++++++++++++++++++++++++++++
1583

    
1584
Request information for connecting to instance's console.
1585

    
1586
.. rapi_resource_details:: /2/instances/[instance_name]/console
1587

    
1588

    
1589
.. _rapi-res-instances-instance_name-console+get:
1590

    
1591
``GET``
1592
~~~~~~~
1593

    
1594
Returns a dictionary containing information about the instance's
1595
console. Contained keys:
1596

    
1597
.. pyassert::
1598

    
1599
   constants.CONS_ALL == frozenset([
1600
     constants.CONS_MESSAGE,
1601
     constants.CONS_SSH,
1602
     constants.CONS_VNC,
1603
     constants.CONS_SPICE,
1604
     ])
1605

    
1606
.. pyassert::
1607

    
1608
  frozenset(objects.InstanceConsole.GetAllSlots()) == frozenset([
1609
    "command",
1610
    "display",
1611
    "host",
1612
    "instance",
1613
    "kind",
1614
    "message",
1615
    "port",
1616
    "user",
1617
    ])
1618

    
1619

    
1620
``instance``
1621
  Instance name
1622
``kind``
1623
  Console type, one of :pyeval:`constants.CONS_SSH`,
1624
  :pyeval:`constants.CONS_VNC`, :pyeval:`constants.CONS_SPICE`
1625
  or :pyeval:`constants.CONS_MESSAGE`
1626
``message``
1627
  Message to display (:pyeval:`constants.CONS_MESSAGE` type only)
1628
``host``
1629
  Host to connect to (:pyeval:`constants.CONS_SSH`,
1630
  :pyeval:`constants.CONS_VNC` or :pyeval:`constants.CONS_SPICE` only)
1631
``port``
1632
  TCP port to connect to (:pyeval:`constants.CONS_VNC` or
1633
  :pyeval:`constants.CONS_SPICE` only)
1634
``user``
1635
  Username to use (:pyeval:`constants.CONS_SSH` only)
1636
``command``
1637
  Command to execute on machine (:pyeval:`constants.CONS_SSH` only)
1638
``display``
1639
  VNC display number (:pyeval:`constants.CONS_VNC` only)
1640

    
1641

    
1642
.. _rapi-res-instances-instance_name-tags:
1643

    
1644
``/2/instances/[instance_name]/tags``
1645
+++++++++++++++++++++++++++++++++++++
1646

    
1647
Manages per-instance tags.
1648

    
1649
.. rapi_resource_details:: /2/instances/[instance_name]/tags
1650

    
1651

    
1652
.. _rapi-res-instances-instance_name-tags+get:
1653

    
1654
``GET``
1655
~~~~~~~
1656

    
1657
Returns a list of tags.
1658

    
1659
Example::
1660

    
1661
    ["tag1", "tag2", "tag3"]
1662

    
1663

    
1664
.. _rapi-res-instances-instance_name-tags+put:
1665

    
1666
``PUT``
1667
~~~~~~~
1668

    
1669
Add a set of tags.
1670

    
1671
The request as a list of strings should be ``PUT`` to this URI. The
1672
result will be a job id.
1673

    
1674
It supports the ``dry-run`` argument.
1675

    
1676

    
1677
.. _rapi-res-instances-instance_name-tags+delete:
1678

    
1679
``DELETE``
1680
~~~~~~~~~~
1681

    
1682
Delete a tag.
1683

    
1684
In order to delete a set of tags, the DELETE request should be addressed
1685
to URI like::
1686

    
1687
    /tags?tag=[tag]&tag=[tag]
1688

    
1689
It supports the ``dry-run`` argument.
1690

    
1691

    
1692
.. _rapi-res-jobs:
1693

    
1694
``/2/jobs``
1695
+++++++++++
1696

    
1697
The ``/2/jobs`` resource.
1698

    
1699
.. rapi_resource_details:: /2/jobs
1700

    
1701

    
1702
.. _rapi-res-jobs+get:
1703

    
1704
``GET``
1705
~~~~~~~
1706

    
1707
Returns a dictionary of jobs.
1708

    
1709
Returns: a dictionary with jobs id and uri.
1710

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

    
1715
Returned fields for bulk requests (unlike other bulk requests, these
1716
fields are not the same as for per-job requests):
1717
:pyeval:`utils.CommaJoin(sorted(rlib2.J_FIELDS_BULK))`.
1718

    
1719

    
1720
.. _rapi-res-jobs-job_id:
1721

    
1722
``/2/jobs/[job_id]``
1723
++++++++++++++++++++
1724

    
1725
Individual job URI.
1726

    
1727
.. rapi_resource_details:: /2/jobs/[job_id]
1728

    
1729

    
1730
.. _rapi-res-jobs-job_id+get:
1731

    
1732
``GET``
1733
~~~~~~~
1734

    
1735
Returns a dictionary with job parameters, containing the fields
1736
:pyeval:`utils.CommaJoin(sorted(rlib2.J_FIELDS))`.
1737

    
1738
The result includes:
1739

    
1740
- id: job ID as a number
1741
- status: current job status as a string
1742
- ops: involved OpCodes as a list of dictionaries for each opcodes in
1743
  the job
1744
- opstatus: OpCodes status as a list
1745
- opresult: OpCodes results as a list
1746

    
1747
For a successful opcode, the ``opresult`` field corresponding to it will
1748
contain the raw result from its :term:`LogicalUnit`. In case an opcode
1749
has failed, its element in the opresult list will be a list of two
1750
elements:
1751

    
1752
- first element the error type (the Ganeti internal error name)
1753
- second element a list of either one or two elements:
1754

    
1755
  - the first element is the textual error description
1756
  - the second element, if any, will hold an error classification
1757

    
1758
The error classification is most useful for the ``OpPrereqError``
1759
error type - these errors happen before the OpCode has started
1760
executing, so it's possible to retry the OpCode without side
1761
effects. But whether it make sense to retry depends on the error
1762
classification:
1763

    
1764
.. pyassert::
1765

    
1766
   errors.ECODE_ALL == set([errors.ECODE_RESOLVER, errors.ECODE_NORES,
1767
     errors.ECODE_INVAL, errors.ECODE_STATE, errors.ECODE_NOENT,
1768
     errors.ECODE_EXISTS, errors.ECODE_NOTUNIQUE, errors.ECODE_FAULT,
1769
     errors.ECODE_ENVIRON, errors.ECODE_TEMP_NORES])
1770

    
1771
:pyeval:`errors.ECODE_RESOLVER`
1772
  Resolver errors. This usually means that a name doesn't exist in DNS,
1773
  so if it's a case of slow DNS propagation the operation can be retried
1774
  later.
1775

    
1776
:pyeval:`errors.ECODE_NORES`
1777
  Not enough resources (iallocator failure, disk space, memory,
1778
  etc.). If the resources on the cluster increase, the operation might
1779
  succeed.
1780

    
1781
:pyeval:`errors.ECODE_TEMP_NORES`
1782
  Simliar to :pyeval:`errors.ECODE_NORES`, but indicating the operation
1783
  should be attempted again after some time.
1784

    
1785
:pyeval:`errors.ECODE_INVAL`
1786
  Wrong arguments (at syntax level). The operation will not ever be
1787
  accepted unless the arguments change.
1788

    
1789
:pyeval:`errors.ECODE_STATE`
1790
  Wrong entity state. For example, live migration has been requested for
1791
  a down instance, or instance creation on an offline node. The
1792
  operation can be retried once the resource has changed state.
1793

    
1794
:pyeval:`errors.ECODE_NOENT`
1795
  Entity not found. For example, information has been requested for an
1796
  unknown instance.
1797

    
1798
:pyeval:`errors.ECODE_EXISTS`
1799
  Entity already exists. For example, instance creation has been
1800
  requested for an already-existing instance.
1801

    
1802
:pyeval:`errors.ECODE_NOTUNIQUE`
1803
  Resource not unique (e.g. MAC or IP duplication).
1804

    
1805
:pyeval:`errors.ECODE_FAULT`
1806
  Internal cluster error. For example, a node is unreachable but not set
1807
  offline, or the ganeti node daemons are not working, etc. A
1808
  ``gnt-cluster verify`` should be run.
1809

    
1810
:pyeval:`errors.ECODE_ENVIRON`
1811
  Environment error (e.g. node disk error). A ``gnt-cluster verify``
1812
  should be run.
1813

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

    
1817

    
1818
.. _rapi-res-jobs-job_id+delete:
1819

    
1820
``DELETE``
1821
~~~~~~~~~~
1822

    
1823
Cancel a not-yet-started job.
1824

    
1825

    
1826
.. _rapi-res-jobs-job_id-wait:
1827

    
1828
``/2/jobs/[job_id]/wait``
1829
+++++++++++++++++++++++++
1830

    
1831
.. rapi_resource_details:: /2/jobs/[job_id]/wait
1832

    
1833

    
1834
.. _rapi-res-jobs-job_id-wait+get:
1835

    
1836
``GET``
1837
~~~~~~~
1838

    
1839
Waits for changes on a job. Takes the following body parameters in a
1840
dict:
1841

    
1842
``fields``
1843
  The job fields on which to watch for changes
1844

    
1845
``previous_job_info``
1846
  Previously received field values or None if not yet available
1847

    
1848
``previous_log_serial``
1849
  Highest log serial number received so far or None if not yet
1850
  available
1851

    
1852
Returns None if no changes have been detected and a dict with two keys,
1853
``job_info`` and ``log_entries`` otherwise.
1854

    
1855

    
1856
.. _rapi-res-nodes:
1857

    
1858
``/2/nodes``
1859
++++++++++++
1860

    
1861
Nodes resource.
1862

    
1863
.. rapi_resource_details:: /2/nodes
1864

    
1865

    
1866
.. _rapi-res-nodes+get:
1867

    
1868
``GET``
1869
~~~~~~~
1870

    
1871
Returns a list of all nodes.
1872

    
1873
Example::
1874

    
1875
    [
1876
      {
1877
        "id": "node1.example.com",
1878
        "uri": "\/nodes\/node1.example.com"
1879
      },
1880
      {
1881
        "id": "node2.example.com",
1882
        "uri": "\/nodes\/node2.example.com"
1883
      }
1884
    ]
1885

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

    
1890
Returned fields: :pyeval:`utils.CommaJoin(sorted(rlib2.N_FIELDS))`.
1891

    
1892
Example::
1893

    
1894
    [
1895
      {
1896
        "pinst_cnt": 1,
1897
        "mfree": 31280,
1898
        "mtotal": 32763,
1899
        "name": "www.example.com",
1900
        "tags": [],
1901
        "mnode": 512,
1902
        "dtotal": 5246208,
1903
        "sinst_cnt": 2,
1904
        "dfree": 5171712,
1905
        "offline": false,
1906
1907
      },
1908
1909
    ]
1910

    
1911

    
1912
.. _rapi-res-nodes-node_name:
1913

    
1914
``/2/nodes/[node_name]``
1915
+++++++++++++++++++++++++++++++++
1916

    
1917
Returns information about a node.
1918

    
1919
.. rapi_resource_details:: /2/nodes/[node_name]
1920

    
1921

    
1922
.. _rapi-res-nodes-node_name+get:
1923

    
1924
``GET``
1925
~~~~~~~
1926

    
1927
Returned fields: :pyeval:`utils.CommaJoin(sorted(rlib2.N_FIELDS))`.
1928

    
1929

    
1930

    
1931
.. _rapi-res-nodes-node_name-powercycle:
1932

    
1933
``/2/nodes/[node_name]/powercycle``
1934
+++++++++++++++++++++++++++++++++++
1935

    
1936
Powercycles a node.
1937

    
1938
.. rapi_resource_details:: /2/nodes/[node_name]/powercycle
1939

    
1940

    
1941
.. _rapi-res-nodes-node_name-powercycle+post:
1942

    
1943
``POST``
1944
~~~~~~~~
1945

    
1946
Returns a job ID.
1947

    
1948
Job result:
1949

    
1950
.. opcode_result:: OP_NODE_POWERCYCLE
1951

    
1952

    
1953
.. _rapi-res-nodes-node_name-evacuate:
1954

    
1955
``/2/nodes/[node_name]/evacuate``
1956
+++++++++++++++++++++++++++++++++
1957

    
1958
Evacuates instances off a node.
1959

    
1960
.. rapi_resource_details:: /2/nodes/[node_name]/evacuate
1961

    
1962

    
1963
.. _rapi-res-nodes-node_name-evacuate+post:
1964

    
1965
``POST``
1966
~~~~~~~~
1967

    
1968
Returns a job ID. The result of the job will contain the IDs of the
1969
individual jobs submitted to evacuate the node.
1970

    
1971
Body parameters:
1972

    
1973
.. opcode_params:: OP_NODE_EVACUATE
1974
   :exclude: nodes
1975

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

    
1980
Job result:
1981

    
1982
.. opcode_result:: OP_NODE_EVACUATE
1983

    
1984

    
1985
.. _rapi-res-nodes-node_name-migrate:
1986

    
1987
``/2/nodes/[node_name]/migrate``
1988
+++++++++++++++++++++++++++++++++
1989

    
1990
Migrates all primary instances from a node.
1991

    
1992
.. rapi_resource_details:: /2/nodes/[node_name]/migrate
1993

    
1994

    
1995
.. _rapi-res-nodes-node_name-migrate+post:
1996

    
1997
``POST``
1998
~~~~~~~~
1999

    
2000
If no mode is explicitly specified, each instances' hypervisor default
2001
migration mode will be used. Body parameters:
2002

    
2003
.. opcode_params:: OP_NODE_MIGRATE
2004
   :exclude: node_name
2005

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

    
2010
Job result:
2011

    
2012
.. opcode_result:: OP_NODE_MIGRATE
2013

    
2014

    
2015
.. _rapi-res-nodes-node_name-role:
2016

    
2017
``/2/nodes/[node_name]/role``
2018
+++++++++++++++++++++++++++++
2019

    
2020
Manages node role.
2021

    
2022
.. rapi_resource_details:: /2/nodes/[node_name]/role
2023

    
2024
The role is always one of the following:
2025

    
2026
  - drained
2027
  - master-candidate
2028
  - offline
2029
  - regular
2030

    
2031
Note that the 'master' role is a special, and currently it can't be
2032
modified via RAPI, only via the command line (``gnt-cluster
2033
master-failover``).
2034

    
2035

    
2036
.. _rapi-res-nodes-node_name-role+get:
2037

    
2038
``GET``
2039
~~~~~~~
2040

    
2041
Returns the current node role.
2042

    
2043
Example::
2044

    
2045
    "master-candidate"
2046

    
2047

    
2048
.. _rapi-res-nodes-node_name-role+put:
2049

    
2050
``PUT``
2051
~~~~~~~
2052

    
2053
Change the node role.
2054

    
2055
The request is a string which should be PUT to this URI. The result will
2056
be a job id.
2057

    
2058
It supports the bool ``force`` argument.
2059

    
2060
Job result:
2061

    
2062
.. opcode_result:: OP_NODE_SET_PARAMS
2063

    
2064

    
2065
.. _rapi-res-nodes-node_name-modify:
2066

    
2067
``/2/nodes/[node_name]/modify``
2068
+++++++++++++++++++++++++++++++
2069

    
2070
Modifies the parameters of a node.
2071

    
2072
.. rapi_resource_details:: /2/nodes/[node_name]/modify
2073

    
2074

    
2075
.. _rapi-res-nodes-node_name-modify+post:
2076

    
2077
``POST``
2078
~~~~~~~~
2079

    
2080
Returns a job ID.
2081

    
2082
Body parameters:
2083

    
2084
.. opcode_params:: OP_NODE_SET_PARAMS
2085
   :exclude: node_name
2086

    
2087
Job result:
2088

    
2089
.. opcode_result:: OP_NODE_SET_PARAMS
2090

    
2091

    
2092
.. _rapi-res-nodes-node_name-storage:
2093

    
2094
``/2/nodes/[node_name]/storage``
2095
++++++++++++++++++++++++++++++++
2096

    
2097
Manages storage units on the node.
2098

    
2099
.. rapi_resource_details:: /2/nodes/[node_name]/storage
2100

    
2101

    
2102
.. _rapi-res-nodes-node_name-storage+get:
2103

    
2104
``GET``
2105
~~~~~~~
2106

    
2107
FIXME: enable ".. pyassert::" again when all storage types are
2108
implemented::
2109

    
2110
   constants.VALID_STORAGE_TYPES == set([constants.ST_FILE,
2111
                                         constants.ST_LVM_PV,
2112
                                         constants.ST_LVM_VG])
2113

    
2114
Requests a list of storage units on a node. Requires the parameters
2115
``storage_type`` (one of :pyeval:`constants.ST_FILE`,
2116
:pyeval:`constants.ST_LVM_PV` or :pyeval:`constants.ST_LVM_VG`) and
2117
``output_fields``. The result will be a job id, using which the result
2118
can be retrieved.
2119

    
2120

    
2121
.. _rapi-res-nodes-node_name-storage-modify:
2122

    
2123
``/2/nodes/[node_name]/storage/modify``
2124
+++++++++++++++++++++++++++++++++++++++
2125

    
2126
Modifies storage units on the node.
2127

    
2128
.. rapi_resource_details:: /2/nodes/[node_name]/storage/modify
2129

    
2130

    
2131
.. _rapi-res-nodes-node_name-storage-modify+put:
2132

    
2133
``PUT``
2134
~~~~~~~
2135

    
2136
Modifies parameters of storage units on the node. Requires the
2137
parameters ``storage_type`` (one of :pyeval:`constants.ST_FILE`,
2138
:pyeval:`constants.ST_LVM_PV` or :pyeval:`constants.ST_LVM_VG`)
2139
and ``name`` (name of the storage unit).  Parameters can be passed
2140
additionally. Currently only :pyeval:`constants.SF_ALLOCATABLE` (bool)
2141
is supported. The result will be a job id.
2142

    
2143
Job result:
2144

    
2145
.. opcode_result:: OP_NODE_MODIFY_STORAGE
2146

    
2147

    
2148
.. _rapi-res-nodes-node_name-storage-repair:
2149

    
2150
``/2/nodes/[node_name]/storage/repair``
2151
+++++++++++++++++++++++++++++++++++++++
2152

    
2153
Repairs a storage unit on the node.
2154

    
2155
.. rapi_resource_details:: /2/nodes/[node_name]/storage/repair
2156

    
2157

    
2158
.. _rapi-res-nodes-node_name-storage-repair+put:
2159

    
2160
``PUT``
2161
~~~~~~~
2162

    
2163
.. pyassert::
2164

    
2165
   constants.VALID_STORAGE_OPERATIONS == {
2166
    constants.ST_LVM_VG: set([constants.SO_FIX_CONSISTENCY]),
2167
    }
2168

    
2169
Repairs a storage unit on the node. Requires the parameters
2170
``storage_type`` (currently only :pyeval:`constants.ST_LVM_VG` can be
2171
repaired) and ``name`` (name of the storage unit). The result will be a
2172
job id.
2173

    
2174
Job result:
2175

    
2176
.. opcode_result:: OP_REPAIR_NODE_STORAGE
2177

    
2178

    
2179
.. _rapi-res-nodes-node_name-tags:
2180

    
2181
``/2/nodes/[node_name]/tags``
2182
+++++++++++++++++++++++++++++
2183

    
2184
Manages per-node tags.
2185

    
2186
.. rapi_resource_details:: /2/nodes/[node_name]/tags
2187

    
2188

    
2189
.. _rapi-res-nodes-node_name-tags+get:
2190

    
2191
``GET``
2192
~~~~~~~
2193

    
2194
Returns a list of tags.
2195

    
2196
Example::
2197

    
2198
    ["tag1", "tag2", "tag3"]
2199

    
2200

    
2201
.. _rapi-res-nodes-node_name-tags+put:
2202

    
2203
``PUT``
2204
~~~~~~~
2205

    
2206
Add a set of tags.
2207

    
2208
The request as a list of strings should be PUT to this URI. The result
2209
will be a job id.
2210

    
2211
It supports the ``dry-run`` argument.
2212

    
2213

    
2214
.. _rapi-res-nodes-node_name-tags+delete:
2215

    
2216
``DELETE``
2217
~~~~~~~~~~
2218

    
2219
Deletes tags.
2220

    
2221
In order to delete a set of tags, the DELETE request should be addressed
2222
to URI like::
2223

    
2224
    /tags?tag=[tag]&tag=[tag]
2225

    
2226
It supports the ``dry-run`` argument.
2227

    
2228

    
2229
.. _rapi-res-query-resource:
2230

    
2231
``/2/query/[resource]``
2232
+++++++++++++++++++++++
2233

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

    
2239
.. rapi_resource_details:: /2/query/[resource]
2240

    
2241

    
2242
.. _rapi-res-query-resource+get:
2243

    
2244
``GET``
2245
~~~~~~~
2246

    
2247
Returns list of included fields and actual data. Takes a query parameter
2248
named "fields", containing a comma-separated list of field names. Does
2249
not support filtering.
2250

    
2251

    
2252
.. _rapi-res-query-resource+put:
2253

    
2254
``PUT``
2255
~~~~~~~
2256

    
2257
Returns list of included fields and actual data. The list of requested
2258
fields can either be given as the query parameter "fields" or as a body
2259
parameter with the same name. The optional body parameter "filter" can
2260
be given and must be either ``null`` or a list containing filter
2261
operators.
2262

    
2263

    
2264
.. _rapi-res-query-resource-fields:
2265

    
2266
``/2/query/[resource]/fields``
2267
++++++++++++++++++++++++++++++
2268

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

    
2273
.. rapi_resource_details:: /2/query/[resource]/fields
2274

    
2275

    
2276
.. _rapi-res-query-resource-fields+get:
2277

    
2278
``GET``
2279
~~~~~~~
2280

    
2281
Returns a list of field descriptions for available fields. Takes an
2282
optional query parameter named "fields", containing a comma-separated
2283
list of field names.
2284

    
2285

    
2286
.. _rapi-res-os:
2287

    
2288
``/2/os``
2289
+++++++++
2290

    
2291
OS resource.
2292

    
2293
.. rapi_resource_details:: /2/os
2294

    
2295

    
2296
.. _rapi-res-os+get:
2297

    
2298
``GET``
2299
~~~~~~~
2300

    
2301
Return a list of all OSes.
2302

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

    
2306
Example::
2307

    
2308
    ["debian-etch"]
2309

    
2310

    
2311
.. _rapi-res-tags:
2312

    
2313
``/2/tags``
2314
+++++++++++
2315

    
2316
Manages cluster tags.
2317

    
2318
.. rapi_resource_details:: /2/tags
2319

    
2320

    
2321
.. _rapi-res-tags+get:
2322

    
2323
``GET``
2324
~~~~~~~
2325

    
2326
Returns the cluster tags.
2327

    
2328
Example::
2329

    
2330
    ["tag1", "tag2", "tag3"]
2331

    
2332

    
2333
.. _rapi-res-tags+put:
2334

    
2335
``PUT``
2336
~~~~~~~
2337

    
2338
Adds a set of tags.
2339

    
2340
The request as a list of strings should be PUT to this URI. The result
2341
will be a job id.
2342

    
2343
It supports the ``dry-run`` argument.
2344

    
2345

    
2346
.. _rapi-res-tags+delete:
2347

    
2348
``DELETE``
2349
~~~~~~~~~~
2350

    
2351
Deletes tags.
2352

    
2353
In order to delete a set of tags, the DELETE request should be addressed
2354
to URI like::
2355

    
2356
    /tags?tag=[tag]&tag=[tag]
2357

    
2358
It supports the ``dry-run`` argument.
2359

    
2360

    
2361
.. _rapi-res-version:
2362

    
2363
``/version``
2364
++++++++++++
2365

    
2366
The version resource.
2367

    
2368
This resource should be used to determine the remote API version and to
2369
adapt clients accordingly.
2370

    
2371
.. rapi_resource_details:: /version
2372

    
2373

    
2374
.. _rapi-res-version+get:
2375

    
2376
``GET``
2377
~~~~~~~
2378

    
2379
Returns the remote API version. Ganeti 1.2 returned ``1`` and Ganeti 2.0
2380
returns ``2``.
2381

    
2382

    
2383
.. _rapi-access-permissions:
2384

    
2385
Access permissions
2386
------------------
2387

    
2388
The following list describes the access permissions required for each
2389
resource. See :ref:`rapi-users` for more details.
2390

    
2391
.. rapi_access_table::
2392

    
2393

    
2394
.. vim: set textwidth=72 :
2395
.. Local Variables:
2396
.. mode: rst
2397
.. fill-column: 72
2398
.. End: