Statistics
| Branch: | Tag: | Revision:

root / doc / rapi.rst @ 681f4f7b

History | View | Annotate | Download (49.5 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_MIN,
230
                                     constants.ISPECS_MAX,
231
                                     constants.ISPECS_STD,
232
                                     constants.IPOLICY_DTS,
233
                                     constants.IPOLICY_VCPU_RATIO,
234
                                     constants.IPOLICY_SPINDLE_RATIO])
235

    
236

    
237
.. pyassert::
238

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

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

    
251

    
252
|ispec-min|, |ispec-max|, |ispec-std|
253
  A sub- `dict` with the following fields, which sets the limit and standard
254
  values of the instances:
255

    
256
  :pyeval:`constants.ISPEC_MEM_SIZE`
257
    The size in MiB of the memory used
258
  :pyeval:`constants.ISPEC_DISK_SIZE`
259
    The size in MiB of the disk used
260
  :pyeval:`constants.ISPEC_DISK_COUNT`
261
    The numbers of disks used
262
  :pyeval:`constants.ISPEC_CPU_COUNT`
263
    The numbers of cpus used
264
  :pyeval:`constants.ISPEC_NIC_COUNT`
265
    The numbers of nics used
266
  :pyeval:`constants.ISPEC_SPINDLE_USE`
267
    The numbers of virtual disk spindles used by this instance. They are
268
    not real in the sense of actual HDD spindles, but useful for
269
    accounting the spindle usage on the residing node
270
:pyeval:`constants.IPOLICY_DTS`
271
  A `list` of disk templates allowed for instances using this policy
272
:pyeval:`constants.IPOLICY_VCPU_RATIO`
273
  Maximum ratio of virtual to physical CPUs (`float`)
274
:pyeval:`constants.IPOLICY_SPINDLE_RATIO`
275
  Maximum ratio of instances to their node's ``spindle_count`` (`float`)
276

    
277
Usage examples
278
--------------
279

    
280
You can access the API using your favorite programming language as long
281
as it supports network connections.
282

    
283
Ganeti RAPI client
284
++++++++++++++++++
285

    
286
Ganeti includes a standalone RAPI client, ``lib/rapi/client.py``.
287

    
288
Shell
289
+++++
290

    
291
.. highlight:: shell-example
292

    
293
Using ``wget``::
294

    
295
   $ wget -q -O - https://%CLUSTERNAME%:5080/2/info
296

    
297
or ``curl``::
298

    
299
  $ curl https://%CLUSTERNAME%:5080/2/info
300

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

    
304
Python
305
++++++
306

    
307
.. highlight:: python
308

    
309
::
310

    
311
  import urllib2
312
  f = urllib2.urlopen('https://CLUSTERNAME:5080/2/info')
313
  print f.read()
314

    
315

    
316
JavaScript
317
++++++++++
318

    
319
.. warning:: While it's possible to use JavaScript, it poses several
320
   potential problems, including browser blocking request due to
321
   non-standard ports or different domain names. Fetching the data on
322
   the webserver is easier.
323

    
324
.. highlight:: javascript
325

    
326
::
327

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

    
344
Resources
345
---------
346

    
347
.. highlight:: javascript
348

    
349
``/``
350
+++++
351

    
352
The root resource. Has no function, but for legacy reasons the ``GET``
353
method is supported.
354

    
355
``/2``
356
++++++
357

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

    
360
.. _rapi-res-info:
361

    
362
``/2/info``
363
+++++++++++
364

    
365
Cluster information resource.
366

    
367
.. rapi_resource_details:: /2/info
368

    
369

    
370
.. _rapi-res-info+get:
371

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

    
375
Returns cluster information.
376

    
377
Example::
378

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

    
409

    
410
.. _rapi-res-redistribute-config:
411

    
412
``/2/redistribute-config``
413
++++++++++++++++++++++++++
414

    
415
Redistribute configuration to all nodes.
416

    
417
.. rapi_resource_details:: /2/redistribute-config
418

    
419

    
420
.. _rapi-res-redistribute-config+put:
421

    
422
``PUT``
423
~~~~~~~
424

    
425
Redistribute configuration to all nodes. The result will be a job id.
426

    
427
Job result:
428

    
429
.. opcode_result:: OP_CLUSTER_REDIST_CONF
430

    
431

    
432
.. _rapi-res-features:
433

    
434
``/2/features``
435
+++++++++++++++
436

    
437
.. rapi_resource_details:: /2/features
438

    
439

    
440
.. _rapi-res-features+get:
441

    
442
``GET``
443
~~~~~~~
444

    
445
Returns a list of features supported by the RAPI server. Available
446
features:
447

    
448
.. pyassert::
449

    
450
  rlib2.ALL_FEATURES == set([rlib2._INST_CREATE_REQV1,
451
                             rlib2._INST_REINSTALL_REQV1,
452
                             rlib2._NODE_MIGRATE_REQV1,
453
                             rlib2._NODE_EVAC_RES1])
454

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

    
466

    
467
.. _rapi-res-modify:
468

    
469
``/2/modify``
470
++++++++++++++++++++++++++++++++++++++++
471

    
472
Modifies cluster parameters.
473

    
474
.. rapi_resource_details:: /2/modify
475

    
476

    
477
.. _rapi-res-modify+put:
478

    
479
``PUT``
480
~~~~~~~
481

    
482
Returns a job ID.
483

    
484
Body parameters:
485

    
486
.. opcode_params:: OP_CLUSTER_SET_PARAMS
487

    
488
Job result:
489

    
490
.. opcode_result:: OP_CLUSTER_SET_PARAMS
491

    
492

    
493
.. _rapi-res-groups:
494

    
495
``/2/groups``
496
+++++++++++++
497

    
498
The groups resource.
499

    
500
.. rapi_resource_details:: /2/groups
501

    
502

    
503
.. _rapi-res-groups+get:
504

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

    
508
Returns a list of all existing node groups.
509

    
510
Example::
511

    
512
    [
513
      {
514
        "name": "group1",
515
        "uri": "\/2\/groups\/group1"
516
      },
517
      {
518
        "name": "group2",
519
        "uri": "\/2\/groups\/group2"
520
      }
521
    ]
522

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

    
527
Returned fields: :pyeval:`utils.CommaJoin(sorted(rlib2.G_FIELDS))`.
528

    
529
Example::
530

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

    
554

    
555
.. _rapi-res-groups+post:
556

    
557
``POST``
558
~~~~~~~~
559

    
560
Creates a node group.
561

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

    
565
Returns: a job ID that can be used later for polling.
566

    
567
Body parameters:
568

    
569
.. opcode_params:: OP_GROUP_ADD
570

    
571
Earlier versions used a parameter named ``name`` which, while still
572
supported, has been renamed to ``group_name``.
573

    
574
Job result:
575

    
576
.. opcode_result:: OP_GROUP_ADD
577

    
578

    
579
.. _rapi-res-groups-group_name:
580

    
581
``/2/groups/[group_name]``
582
++++++++++++++++++++++++++
583

    
584
Returns information about a node group.
585

    
586
.. rapi_resource_details:: /2/groups/[group_name]
587

    
588

    
589
.. _rapi-res-groups-group_name+get:
590

    
591
``GET``
592
~~~~~~~
593

    
594
Returns information about a node group, similar to the bulk output from
595
the node group list.
596

    
597
Returned fields: :pyeval:`utils.CommaJoin(sorted(rlib2.G_FIELDS))`.
598

    
599
.. _rapi-res-groups-group_name+delete:
600

    
601
``DELETE``
602
~~~~~~~~~~
603

    
604
Deletes a node group.
605

    
606
It supports the ``dry-run`` argument.
607

    
608
Job result:
609

    
610
.. opcode_result:: OP_GROUP_REMOVE
611

    
612

    
613
.. _rapi-res-groups-group_name-modify:
614

    
615
``/2/groups/[group_name]/modify``
616
+++++++++++++++++++++++++++++++++
617

    
618
Modifies the parameters of a node group.
619

    
620
.. rapi_resource_details:: /2/groups/[group_name]/modify
621

    
622

    
623
.. _rapi-res-groups-group_name-modify+put:
624

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

    
628
Returns a job ID.
629

    
630
Body parameters:
631

    
632
.. opcode_params:: OP_GROUP_SET_PARAMS
633
   :exclude: group_name
634

    
635
Job result:
636

    
637
.. opcode_result:: OP_GROUP_SET_PARAMS
638

    
639

    
640
.. _rapi-res-groups-group_name-rename:
641

    
642
``/2/groups/[group_name]/rename``
643
+++++++++++++++++++++++++++++++++
644

    
645
Renames a node group.
646

    
647
.. rapi_resource_details:: /2/groups/[group_name]/rename
648

    
649

    
650
.. _rapi-res-groups-group_name-rename+put:
651

    
652
``PUT``
653
~~~~~~~
654

    
655
Returns a job ID.
656

    
657
Body parameters:
658

    
659
.. opcode_params:: OP_GROUP_RENAME
660
   :exclude: group_name
661

    
662
Job result:
663

    
664
.. opcode_result:: OP_GROUP_RENAME
665

    
666

    
667
.. _rapi-res-groups-group_name-assign-nodes:
668

    
669
``/2/groups/[group_name]/assign-nodes``
670
+++++++++++++++++++++++++++++++++++++++
671

    
672
Assigns nodes to a group.
673

    
674
.. rapi_resource_details:: /2/groups/[group_name]/assign-nodes
675

    
676
.. _rapi-res-groups-group_name-assign-nodes+put:
677

    
678
``PUT``
679
~~~~~~~
680

    
681
Returns a job ID. It supports the ``dry-run`` and ``force`` arguments.
682

    
683
Body parameters:
684

    
685
.. opcode_params:: OP_GROUP_ASSIGN_NODES
686
   :exclude: group_name, force, dry_run
687

    
688
Job result:
689

    
690
.. opcode_result:: OP_GROUP_ASSIGN_NODES
691

    
692
.. _rapi-res-groups-group_name-tags:
693

    
694
``/2/groups/[group_name]/tags``
695
+++++++++++++++++++++++++++++++
696

    
697
Manages per-nodegroup tags.
698

    
699
.. rapi_resource_details:: /2/groups/[group_name]/tags
700

    
701

    
702
.. _rapi-res-groups-group_name-tags+get:
703

    
704
``GET``
705
~~~~~~~
706

    
707
Returns a list of tags.
708

    
709
Example::
710

    
711
    ["tag1", "tag2", "tag3"]
712

    
713
.. _rapi-res-groups-group_name-tags+put:
714

    
715
``PUT``
716
~~~~~~~
717

    
718
Add a set of tags.
719

    
720
The request as a list of strings should be ``PUT`` to this URI. The
721
result will be a job id.
722

    
723
It supports the ``dry-run`` argument.
724

    
725

    
726
.. _rapi-res-groups-group_name-tags+delete:
727

    
728
``DELETE``
729
~~~~~~~~~~
730

    
731
Delete a tag.
732

    
733
In order to delete a set of tags, the DELETE request should be addressed
734
to URI like::
735

    
736
    /tags?tag=[tag]&tag=[tag]
737

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

    
740

    
741
.. _rapi-res-networks:
742

    
743
``/2/networks``
744
+++++++++++++++
745

    
746
The networks resource.
747

    
748
.. rapi_resource_details:: /2/networks
749

    
750

    
751
.. _rapi-res-networks+get:
752

    
753
``GET``
754
~~~~~~~
755

    
756
Returns a list of all existing networks.
757

    
758
Example::
759

    
760
    [
761
      {
762
        "name": "network1",
763
        "uri": "\/2\/networks\/network1"
764
      },
765
      {
766
        "name": "network2",
767
        "uri": "\/2\/networks\/network2"
768
      }
769
    ]
770

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

    
775
Returned fields: :pyeval:`utils.CommaJoin(sorted(rlib2.NET_FIELDS))`.
776

    
777
Example::
778

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

    
799

    
800
.. _rapi-res-networks+post:
801

    
802
``POST``
803
~~~~~~~~
804

    
805
Creates a network.
806

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

    
810
Returns: a job ID that can be used later for polling.
811

    
812
Body parameters:
813

    
814
.. opcode_params:: OP_NETWORK_ADD
815

    
816
Job result:
817

    
818
.. opcode_result:: OP_NETWORK_ADD
819

    
820

    
821
.. _rapi-res-networks-network_name:
822

    
823
``/2/networks/[network_name]``
824
++++++++++++++++++++++++++++++
825

    
826
Returns information about a network.
827

    
828
.. rapi_resource_details:: /2/networks/[network_name]
829

    
830

    
831
.. _rapi-res-networks-network_name+get:
832

    
833
``GET``
834
~~~~~~~
835

    
836
Returns information about a network, similar to the bulk output from
837
the network list.
838

    
839
Returned fields: :pyeval:`utils.CommaJoin(sorted(rlib2.NET_FIELDS))`.
840

    
841

    
842
.. _rapi-res-networks-network_name+delete:
843

    
844
``DELETE``
845
~~~~~~~~~~
846

    
847
Deletes a network.
848

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

    
851
Job result:
852

    
853
.. opcode_result:: OP_NETWORK_REMOVE
854

    
855

    
856
.. _rapi-res-networks-network_name-modify:
857

    
858
``/2/networks/[network_name]/modify``
859
+++++++++++++++++++++++++++++++++++++
860

    
861
Modifies the parameters of a network.
862

    
863
.. rapi_resource_details:: /2/networks/[network_name]/modify
864

    
865

    
866
.. _rapi-res-networks-network_name-modify+put:
867

    
868
``PUT``
869
~~~~~~~
870

    
871
Returns a job ID.
872

    
873
Body parameters:
874

    
875
.. opcode_params:: OP_NETWORK_SET_PARAMS
876

    
877
Job result:
878

    
879
.. opcode_result:: OP_NETWORK_SET_PARAMS
880

    
881

    
882
.. _rapi-res-networks-network_name-connect:
883

    
884
``/2/networks/[network_name]/connect``
885
++++++++++++++++++++++++++++++++++++++
886

    
887
Connects a network to a nodegroup.
888

    
889
.. rapi_resource_details:: /2/networks/[network_name]/connect
890

    
891

    
892
.. _rapi-res-networks-network_name-connect+put:
893

    
894
``PUT``
895
~~~~~~~
896

    
897
Returns a job ID. It supports the ``dry-run`` arguments.
898

    
899
Body parameters:
900

    
901
.. opcode_params:: OP_NETWORK_CONNECT
902

    
903
Job result:
904

    
905
.. opcode_result:: OP_NETWORK_CONNECT
906

    
907

    
908
.. _rapi-res-networks-network_name-disconnect:
909

    
910
``/2/networks/[network_name]/disconnect``
911
+++++++++++++++++++++++++++++++++++++++++
912

    
913
Disonnects a network from a nodegroup.
914

    
915
.. rapi_resource_details:: /2/networks/[network_name]/disconnect
916

    
917

    
918
.. _rapi-res-networks-network_name-disconnect+put:
919

    
920
``PUT``
921
~~~~~~~
922

    
923
Returns a job ID. It supports the ``dry-run`` arguments.
924

    
925
Body parameters:
926

    
927
.. opcode_params:: OP_NETWORK_DISCONNECT
928

    
929
Job result:
930

    
931
.. opcode_result:: OP_NETWORK_DISCONNECT
932

    
933

    
934
.. _rapi-res-networks-network_name-tags:
935

    
936
``/2/networks/[network_name]/tags``
937
+++++++++++++++++++++++++++++++++++
938

    
939
Manages per-network tags.
940

    
941
.. rapi_resource_details:: /2/networks/[network_name]/tags
942

    
943

    
944
.. _rapi-res-networks-network_name-tags+get:
945

    
946
``GET``
947
~~~~~~~
948

    
949
Returns a list of tags.
950

    
951
Example::
952

    
953
    ["tag1", "tag2", "tag3"]
954

    
955

    
956
.. _rapi-res-networks-network_name-tags+put:
957

    
958
``PUT``
959
~~~~~~~
960

    
961
Add a set of tags.
962

    
963
The request as a list of strings should be ``PUT`` to this URI. The
964
result will be a job id.
965

    
966
It supports the ``dry-run`` argument.
967

    
968

    
969
.. _rapi-res-networks-network_name-tags+delete:
970

    
971
``DELETE``
972
~~~~~~~~~~
973

    
974
Delete a tag.
975

    
976
In order to delete a set of tags, the DELETE request should be addressed
977
to URI like::
978

    
979
    /tags?tag=[tag]&tag=[tag]
980

    
981
It supports the ``dry-run`` argument.
982

    
983

    
984
.. _rapi-res-instances-multi-alloc:
985

    
986
``/2/instances-multi-alloc``
987
++++++++++++++++++++++++++++
988

    
989
Tries to allocate multiple instances.
990

    
991
.. rapi_resource_details:: /2/instances-multi-alloc
992

    
993

    
994
.. _rapi-res-instances-multi-alloc+post:
995

    
996
``POST``
997
~~~~~~~~
998

    
999
The parameters:
1000

    
1001
.. opcode_params:: OP_INSTANCE_MULTI_ALLOC
1002

    
1003
Job result:
1004

    
1005
.. opcode_result:: OP_INSTANCE_MULTI_ALLOC
1006

    
1007

    
1008
.. _rapi-res-instances:
1009

    
1010
``/2/instances``
1011
++++++++++++++++
1012

    
1013
The instances resource.
1014

    
1015
.. rapi_resource_details:: /2/instances
1016

    
1017

    
1018
.. _rapi-res-instances+get:
1019

    
1020
``GET``
1021
~~~~~~~
1022

    
1023
Returns a list of all available instances.
1024

    
1025
Example::
1026

    
1027
    [
1028
      {
1029
        "name": "web.example.com",
1030
        "uri": "\/instances\/web.example.com"
1031
      },
1032
      {
1033
        "name": "mail.example.com",
1034
        "uri": "\/instances\/mail.example.com"
1035
      }
1036
    ]
1037

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

    
1042
Returned fields: :pyeval:`utils.CommaJoin(sorted(rlib2.I_FIELDS))`.
1043

    
1044
Example::
1045

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

    
1074

    
1075
.. _rapi-res-instances+post:
1076

    
1077
``POST``
1078
~~~~~~~~
1079

    
1080
Creates an instance.
1081

    
1082
If the optional bool *dry-run* argument is provided, the job will not be
1083
actually executed, only the pre-execution checks will be done. Query-ing
1084
the job result will return, in both dry-run and normal case, the list of
1085
nodes selected for the instance.
1086

    
1087
Returns: a job ID that can be used later for polling.
1088

    
1089
Body parameters:
1090

    
1091
``__version__`` (int, required)
1092
  Must be ``1`` (older Ganeti versions used a different format for
1093
  instance creation requests, version ``0``, but that format is no
1094
  longer supported)
1095

    
1096
.. opcode_params:: OP_INSTANCE_CREATE
1097

    
1098
Earlier versions used parameters named ``name`` and ``os``. These have
1099
been replaced by ``instance_name`` and ``os_type`` to match the
1100
underlying opcode. The old names can still be used.
1101

    
1102
Job result:
1103

    
1104
.. opcode_result:: OP_INSTANCE_CREATE
1105

    
1106

    
1107
.. _rapi-res-instances-instance_name:
1108

    
1109
``/2/instances/[instance_name]``
1110
++++++++++++++++++++++++++++++++
1111

    
1112
Instance-specific resource.
1113

    
1114
.. rapi_resource_details:: /2/instances/[instance_name]
1115

    
1116

    
1117
.. _rapi-res-instances-instance_name+get:
1118

    
1119
``GET``
1120
~~~~~~~
1121

    
1122
Returns information about an instance, similar to the bulk output from
1123
the instance list.
1124

    
1125
Returned fields: :pyeval:`utils.CommaJoin(sorted(rlib2.I_FIELDS))`.
1126

    
1127

    
1128
.. _rapi-res-instances-instance_name+delete:
1129

    
1130
``DELETE``
1131
~~~~~~~~~~
1132

    
1133
Deletes an instance.
1134

    
1135
It supports the ``dry-run`` argument.
1136

    
1137
Job result:
1138

    
1139
.. opcode_result:: OP_INSTANCE_REMOVE
1140

    
1141

    
1142
.. _rapi-res-instances-instance_name-info:
1143

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

    
1147
.. rapi_resource_details:: /2/instances/[instance_name]/info
1148

    
1149

    
1150
.. _rapi-res-instances-instance_name-info+get:
1151

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

    
1155
Requests detailed information about the instance. An optional parameter,
1156
``static`` (bool), can be set to return only static information from the
1157
configuration without querying the instance's nodes. The result will be
1158
a job id.
1159

    
1160
Job result:
1161

    
1162
.. opcode_result:: OP_INSTANCE_QUERY_DATA
1163

    
1164

    
1165
.. _rapi-res-instances-instance_name-reboot:
1166

    
1167
``/2/instances/[instance_name]/reboot``
1168
+++++++++++++++++++++++++++++++++++++++
1169

    
1170
Reboots URI for an instance.
1171

    
1172
.. rapi_resource_details:: /2/instances/[instance_name]/reboot
1173

    
1174

    
1175
.. _rapi-res-instances-instance_name-reboot+post:
1176

    
1177
``POST``
1178
~~~~~~~~
1179

    
1180
Reboots the instance.
1181

    
1182
The URI takes optional ``type=soft|hard|full`` and
1183
``ignore_secondaries=0|1`` parameters.
1184

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

    
1192
``ignore_secondaries`` is a bool argument indicating if we start the
1193
instance even if secondary disks are failing.
1194

    
1195
It supports the ``dry-run`` argument.
1196

    
1197
Job result:
1198

    
1199
.. opcode_result:: OP_INSTANCE_REBOOT
1200

    
1201

    
1202
.. _rapi-res-instances-instance_name-shutdown:
1203

    
1204
``/2/instances/[instance_name]/shutdown``
1205
+++++++++++++++++++++++++++++++++++++++++
1206

    
1207
Instance shutdown URI.
1208

    
1209
.. rapi_resource_details:: /2/instances/[instance_name]/shutdown
1210

    
1211

    
1212
.. _rapi-res-instances-instance_name-shutdown+put:
1213

    
1214
``PUT``
1215
~~~~~~~
1216

    
1217
Shutdowns an instance.
1218

    
1219
It supports the ``dry-run`` argument.
1220

    
1221
.. opcode_params:: OP_INSTANCE_SHUTDOWN
1222
   :exclude: instance_name, dry_run
1223

    
1224
Job result:
1225

    
1226
.. opcode_result:: OP_INSTANCE_SHUTDOWN
1227

    
1228

    
1229
.. _rapi-res-instances-instance_name-startup:
1230

    
1231
``/2/instances/[instance_name]/startup``
1232
++++++++++++++++++++++++++++++++++++++++
1233

    
1234
Instance startup URI.
1235

    
1236
.. rapi_resource_details:: /2/instances/[instance_name]/startup
1237

    
1238

    
1239
.. _rapi-res-instances-instance_name-startup+put:
1240

    
1241
``PUT``
1242
~~~~~~~
1243

    
1244
Startup an instance.
1245

    
1246
The URI takes an optional ``force=1|0`` parameter to start the
1247
instance even if secondary disks are failing.
1248

    
1249
It supports the ``dry-run`` argument.
1250

    
1251
Job result:
1252

    
1253
.. opcode_result:: OP_INSTANCE_STARTUP
1254

    
1255

    
1256
.. _rapi-res-instances-instance_name-reinstall:
1257

    
1258
``/2/instances/[instance_name]/reinstall``
1259
++++++++++++++++++++++++++++++++++++++++++++++
1260

    
1261
Installs the operating system again.
1262

    
1263
.. rapi_resource_details:: /2/instances/[instance_name]/reinstall
1264

    
1265

    
1266
.. _rapi-res-instances-instance_name-reinstall+post:
1267

    
1268
``POST``
1269
~~~~~~~~
1270

    
1271
Returns a job ID.
1272

    
1273
Body parameters:
1274

    
1275
``os`` (string, required)
1276
  Instance operating system.
1277
``start`` (bool, defaults to true)
1278
  Whether to start instance after reinstallation.
1279
``osparams`` (dict)
1280
  Dictionary with (temporary) OS parameters.
1281

    
1282
For backwards compatbility, this resource also takes the query
1283
parameters ``os`` (OS template name) and ``nostartup`` (bool). New
1284
clients should use the body parameters.
1285

    
1286

    
1287
.. _rapi-res-instances-instance_name-replace-disks:
1288

    
1289
``/2/instances/[instance_name]/replace-disks``
1290
++++++++++++++++++++++++++++++++++++++++++++++
1291

    
1292
Replaces disks on an instance.
1293

    
1294
.. rapi_resource_details:: /2/instances/[instance_name]/replace-disks
1295

    
1296

    
1297
.. _rapi-res-instances-instance_name-replace-disks+post:
1298

    
1299
``POST``
1300
~~~~~~~~
1301

    
1302
Returns a job ID.
1303

    
1304
Body parameters:
1305

    
1306
.. opcode_params:: OP_INSTANCE_REPLACE_DISKS
1307
   :exclude: instance_name
1308

    
1309
Ganeti 2.4 and below used query parameters. Those are deprecated and
1310
should no longer be used.
1311

    
1312
Job result:
1313

    
1314
.. opcode_result:: OP_INSTANCE_REPLACE_DISKS
1315

    
1316

    
1317
.. _rapi-res-instances-instance_name-activate-disks:
1318

    
1319
``/2/instances/[instance_name]/activate-disks``
1320
+++++++++++++++++++++++++++++++++++++++++++++++
1321

    
1322
Activate disks on an instance.
1323

    
1324
.. rapi_resource_details:: /2/instances/[instance_name]/activate-disks
1325

    
1326

    
1327
.. _rapi-res-instances-instance_name-activate-disks+put:
1328

    
1329
``PUT``
1330
~~~~~~~
1331

    
1332
Takes the bool parameter ``ignore_size``. When set ignore the recorded
1333
size (useful for forcing activation when recorded size is wrong).
1334

    
1335
Job result:
1336

    
1337
.. opcode_result:: OP_INSTANCE_ACTIVATE_DISKS
1338

    
1339

    
1340
.. _rapi-res-instances-instance_name-deactivate-disks:
1341

    
1342
``/2/instances/[instance_name]/deactivate-disks``
1343
+++++++++++++++++++++++++++++++++++++++++++++++++
1344

    
1345
Deactivate disks on an instance.
1346

    
1347
.. rapi_resource_details:: /2/instances/[instance_name]/deactivate-disks
1348

    
1349

    
1350
.. _rapi-res-instances-instance_name-deactivate-disks+put:
1351

    
1352
``PUT``
1353
~~~~~~~
1354

    
1355
Takes no parameters.
1356

    
1357
Job result:
1358

    
1359
.. opcode_result:: OP_INSTANCE_DEACTIVATE_DISKS
1360

    
1361

    
1362
.. _rapi-res-instances-instance_name-recreate-disks:
1363

    
1364
``/2/instances/[instance_name]/recreate-disks``
1365
+++++++++++++++++++++++++++++++++++++++++++++++++
1366

    
1367
Recreate disks of an instance.
1368

    
1369
.. rapi_resource_details:: /2/instances/[instance_name]/recreate-disks
1370

    
1371

    
1372
.. _rapi-res-instances-instance_name-recreate-disks+post:
1373

    
1374
``POST``
1375
~~~~~~~~
1376

    
1377
Returns a job ID.
1378

    
1379
Body parameters:
1380

    
1381
.. opcode_params:: OP_INSTANCE_RECREATE_DISKS
1382
   :exclude: instance_name
1383

    
1384
Job result:
1385

    
1386
.. opcode_result:: OP_INSTANCE_RECREATE_DISKS
1387

    
1388

    
1389
.. _rapi-res-instances-instance_name-disk-disk_index-grow:
1390

    
1391
``/2/instances/[instance_name]/disk/[disk_index]/grow``
1392
+++++++++++++++++++++++++++++++++++++++++++++++++++++++
1393

    
1394
Grows one disk of an instance.
1395

    
1396
.. rapi_resource_details:: /2/instances/[instance_name]/disk/[disk_index]/grow
1397

    
1398

    
1399
.. _rapi-res-instances-instance_name-disk-disk_index-grow+post:
1400

    
1401
``POST``
1402
~~~~~~~~
1403

    
1404
Returns a job ID.
1405

    
1406
Body parameters:
1407

    
1408
.. opcode_params:: OP_INSTANCE_GROW_DISK
1409
   :exclude: instance_name, disk
1410

    
1411
Job result:
1412

    
1413
.. opcode_result:: OP_INSTANCE_GROW_DISK
1414

    
1415

    
1416
.. _rapi-res-instances-instance_name-prepare-export:
1417

    
1418
``/2/instances/[instance_name]/prepare-export``
1419
+++++++++++++++++++++++++++++++++++++++++++++++++
1420

    
1421
Prepares an export of an instance.
1422

    
1423
.. rapi_resource_details:: /2/instances/[instance_name]/prepare-export
1424

    
1425

    
1426
.. _rapi-res-instances-instance_name-prepare-export+put:
1427

    
1428
``PUT``
1429
~~~~~~~
1430

    
1431
Takes one parameter, ``mode``, for the export mode. Returns a job ID.
1432

    
1433
Job result:
1434

    
1435
.. opcode_result:: OP_BACKUP_PREPARE
1436

    
1437

    
1438
.. _rapi-res-instances-instance_name-export:
1439

    
1440
``/2/instances/[instance_name]/export``
1441
+++++++++++++++++++++++++++++++++++++++++++++++++
1442

    
1443
Exports an instance.
1444

    
1445
.. rapi_resource_details:: /2/instances/[instance_name]/export
1446

    
1447

    
1448
.. _rapi-res-instances-instance_name-export+put:
1449

    
1450
``PUT``
1451
~~~~~~~
1452

    
1453
Returns a job ID.
1454

    
1455
Body parameters:
1456

    
1457
.. opcode_params:: OP_BACKUP_EXPORT
1458
   :exclude: instance_name
1459
   :alias: target_node=destination
1460

    
1461
Job result:
1462

    
1463
.. opcode_result:: OP_BACKUP_EXPORT
1464

    
1465

    
1466
.. _rapi-res-instances-instance_name-migrate:
1467

    
1468
``/2/instances/[instance_name]/migrate``
1469
++++++++++++++++++++++++++++++++++++++++
1470

    
1471
Migrates an instance.
1472

    
1473
.. rapi_resource_details:: /2/instances/[instance_name]/migrate
1474

    
1475

    
1476
.. _rapi-res-instances-instance_name-migrate+put:
1477

    
1478
``PUT``
1479
~~~~~~~
1480

    
1481
Returns a job ID.
1482

    
1483
Body parameters:
1484

    
1485
.. opcode_params:: OP_INSTANCE_MIGRATE
1486
   :exclude: instance_name, live
1487

    
1488
Job result:
1489

    
1490
.. opcode_result:: OP_INSTANCE_MIGRATE
1491

    
1492

    
1493
.. _rapi-res-instances-instance_name-failover:
1494

    
1495
``/2/instances/[instance_name]/failover``
1496
+++++++++++++++++++++++++++++++++++++++++
1497

    
1498
Does a failover of an instance.
1499

    
1500
.. rapi_resource_details:: /2/instances/[instance_name]/failover
1501

    
1502

    
1503
.. _rapi-res-instances-instance_name-failover+put:
1504

    
1505
``PUT``
1506
~~~~~~~
1507

    
1508
Returns a job ID.
1509

    
1510
Body parameters:
1511

    
1512
.. opcode_params:: OP_INSTANCE_FAILOVER
1513
   :exclude: instance_name
1514

    
1515
Job result:
1516

    
1517
.. opcode_result:: OP_INSTANCE_FAILOVER
1518

    
1519

    
1520
.. _rapi-res-instances-instance_name-rename:
1521

    
1522
``/2/instances/[instance_name]/rename``
1523
++++++++++++++++++++++++++++++++++++++++
1524

    
1525
Renames an instance.
1526

    
1527
.. rapi_resource_details:: /2/instances/[instance_name]/rename
1528

    
1529

    
1530
.. _rapi-res-instances-instance_name-rename+put:
1531

    
1532
``PUT``
1533
~~~~~~~
1534

    
1535
Returns a job ID.
1536

    
1537
Body parameters:
1538

    
1539
.. opcode_params:: OP_INSTANCE_RENAME
1540
   :exclude: instance_name
1541

    
1542
Job result:
1543

    
1544
.. opcode_result:: OP_INSTANCE_RENAME
1545

    
1546

    
1547
.. _rapi-res-instances-instance_name-modify:
1548

    
1549
``/2/instances/[instance_name]/modify``
1550
++++++++++++++++++++++++++++++++++++++++
1551

    
1552
Modifies an instance.
1553

    
1554
.. rapi_resource_details:: /2/instances/[instance_name]/modify
1555

    
1556

    
1557
.. _rapi-res-instances-instance_name-modify+put:
1558

    
1559
``PUT``
1560
~~~~~~~
1561

    
1562
Returns a job ID.
1563

    
1564
Body parameters:
1565

    
1566
.. opcode_params:: OP_INSTANCE_SET_PARAMS
1567
   :exclude: instance_name
1568

    
1569
Job result:
1570

    
1571
.. opcode_result:: OP_INSTANCE_SET_PARAMS
1572

    
1573

    
1574
.. _rapi-res-instances-instance_name-console:
1575

    
1576
``/2/instances/[instance_name]/console``
1577
++++++++++++++++++++++++++++++++++++++++
1578

    
1579
Request information for connecting to instance's console.
1580

    
1581
.. rapi_resource_details:: /2/instances/[instance_name]/console
1582

    
1583

    
1584
.. _rapi-res-instances-instance_name-console+get:
1585

    
1586
``GET``
1587
~~~~~~~
1588

    
1589
Returns a dictionary containing information about the instance's
1590
console. Contained keys:
1591

    
1592
.. pyassert::
1593

    
1594
   constants.CONS_ALL == frozenset([
1595
     constants.CONS_MESSAGE,
1596
     constants.CONS_SSH,
1597
     constants.CONS_VNC,
1598
     constants.CONS_SPICE,
1599
     ])
1600

    
1601
.. pyassert::
1602

    
1603
  frozenset(objects.InstanceConsole.GetAllSlots()) == frozenset([
1604
    "command",
1605
    "display",
1606
    "host",
1607
    "instance",
1608
    "kind",
1609
    "message",
1610
    "port",
1611
    "user",
1612
    ])
1613

    
1614

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

    
1636

    
1637
.. _rapi-res-instances-instance_name-tags:
1638

    
1639
``/2/instances/[instance_name]/tags``
1640
+++++++++++++++++++++++++++++++++++++
1641

    
1642
Manages per-instance tags.
1643

    
1644
.. rapi_resource_details:: /2/instances/[instance_name]/tags
1645

    
1646

    
1647
.. _rapi-res-instances-instance_name-tags+get:
1648

    
1649
``GET``
1650
~~~~~~~
1651

    
1652
Returns a list of tags.
1653

    
1654
Example::
1655

    
1656
    ["tag1", "tag2", "tag3"]
1657

    
1658

    
1659
.. _rapi-res-instances-instance_name-tags+put:
1660

    
1661
``PUT``
1662
~~~~~~~
1663

    
1664
Add a set of tags.
1665

    
1666
The request as a list of strings should be ``PUT`` to this URI. The
1667
result will be a job id.
1668

    
1669
It supports the ``dry-run`` argument.
1670

    
1671

    
1672
.. _rapi-res-instances-instance_name-tags+delete:
1673

    
1674
``DELETE``
1675
~~~~~~~~~~
1676

    
1677
Delete a tag.
1678

    
1679
In order to delete a set of tags, the DELETE request should be addressed
1680
to URI like::
1681

    
1682
    /tags?tag=[tag]&tag=[tag]
1683

    
1684
It supports the ``dry-run`` argument.
1685

    
1686

    
1687
.. _rapi-res-jobs:
1688

    
1689
``/2/jobs``
1690
+++++++++++
1691

    
1692
The ``/2/jobs`` resource.
1693

    
1694
.. rapi_resource_details:: /2/jobs
1695

    
1696

    
1697
.. _rapi-res-jobs+get:
1698

    
1699
``GET``
1700
~~~~~~~
1701

    
1702
Returns a dictionary of jobs.
1703

    
1704
Returns: a dictionary with jobs id and uri.
1705

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

    
1710
Returned fields for bulk requests (unlike other bulk requests, these
1711
fields are not the same as for per-job requests):
1712
:pyeval:`utils.CommaJoin(sorted(rlib2.J_FIELDS_BULK))`.
1713

    
1714

    
1715
.. _rapi-res-jobs-job_id:
1716

    
1717
``/2/jobs/[job_id]``
1718
++++++++++++++++++++
1719

    
1720
Individual job URI.
1721

    
1722
.. rapi_resource_details:: /2/jobs/[job_id]
1723

    
1724

    
1725
.. _rapi-res-jobs-job_id+get:
1726

    
1727
``GET``
1728
~~~~~~~
1729

    
1730
Returns a dictionary with job parameters, containing the fields
1731
:pyeval:`utils.CommaJoin(sorted(rlib2.J_FIELDS))`.
1732

    
1733
The result includes:
1734

    
1735
- id: job ID as a number
1736
- status: current job status as a string
1737
- ops: involved OpCodes as a list of dictionaries for each opcodes in
1738
  the job
1739
- opstatus: OpCodes status as a list
1740
- opresult: OpCodes results as a list
1741

    
1742
For a successful opcode, the ``opresult`` field corresponding to it will
1743
contain the raw result from its :term:`LogicalUnit`. In case an opcode
1744
has failed, its element in the opresult list will be a list of two
1745
elements:
1746

    
1747
- first element the error type (the Ganeti internal error name)
1748
- second element a list of either one or two elements:
1749

    
1750
  - the first element is the textual error description
1751
  - the second element, if any, will hold an error classification
1752

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

    
1759
.. pyassert::
1760

    
1761
   errors.ECODE_ALL == set([errors.ECODE_RESOLVER, errors.ECODE_NORES,
1762
     errors.ECODE_INVAL, errors.ECODE_STATE, errors.ECODE_NOENT,
1763
     errors.ECODE_EXISTS, errors.ECODE_NOTUNIQUE, errors.ECODE_FAULT,
1764
     errors.ECODE_ENVIRON, errors.ECODE_TEMP_NORES])
1765

    
1766
:pyeval:`errors.ECODE_RESOLVER`
1767
  Resolver errors. This usually means that a name doesn't exist in DNS,
1768
  so if it's a case of slow DNS propagation the operation can be retried
1769
  later.
1770

    
1771
:pyeval:`errors.ECODE_NORES`
1772
  Not enough resources (iallocator failure, disk space, memory,
1773
  etc.). If the resources on the cluster increase, the operation might
1774
  succeed.
1775

    
1776
:pyeval:`errors.ECODE_TEMP_NORES`
1777
  Simliar to :pyeval:`errors.ECODE_NORES`, but indicating the operation
1778
  should be attempted again after some time.
1779

    
1780
:pyeval:`errors.ECODE_INVAL`
1781
  Wrong arguments (at syntax level). The operation will not ever be
1782
  accepted unless the arguments change.
1783

    
1784
:pyeval:`errors.ECODE_STATE`
1785
  Wrong entity state. For example, live migration has been requested for
1786
  a down instance, or instance creation on an offline node. The
1787
  operation can be retried once the resource has changed state.
1788

    
1789
:pyeval:`errors.ECODE_NOENT`
1790
  Entity not found. For example, information has been requested for an
1791
  unknown instance.
1792

    
1793
:pyeval:`errors.ECODE_EXISTS`
1794
  Entity already exists. For example, instance creation has been
1795
  requested for an already-existing instance.
1796

    
1797
:pyeval:`errors.ECODE_NOTUNIQUE`
1798
  Resource not unique (e.g. MAC or IP duplication).
1799

    
1800
:pyeval:`errors.ECODE_FAULT`
1801
  Internal cluster error. For example, a node is unreachable but not set
1802
  offline, or the ganeti node daemons are not working, etc. A
1803
  ``gnt-cluster verify`` should be run.
1804

    
1805
:pyeval:`errors.ECODE_ENVIRON`
1806
  Environment error (e.g. node disk error). A ``gnt-cluster verify``
1807
  should be run.
1808

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

    
1812

    
1813
.. _rapi-res-jobs-job_id+delete:
1814

    
1815
``DELETE``
1816
~~~~~~~~~~
1817

    
1818
Cancel a not-yet-started job.
1819

    
1820

    
1821
.. _rapi-res-jobs-job_id-wait:
1822

    
1823
``/2/jobs/[job_id]/wait``
1824
+++++++++++++++++++++++++
1825

    
1826
.. rapi_resource_details:: /2/jobs/[job_id]/wait
1827

    
1828

    
1829
.. _rapi-res-jobs-job_id-wait+get:
1830

    
1831
``GET``
1832
~~~~~~~
1833

    
1834
Waits for changes on a job. Takes the following body parameters in a
1835
dict:
1836

    
1837
``fields``
1838
  The job fields on which to watch for changes
1839

    
1840
``previous_job_info``
1841
  Previously received field values or None if not yet available
1842

    
1843
``previous_log_serial``
1844
  Highest log serial number received so far or None if not yet
1845
  available
1846

    
1847
Returns None if no changes have been detected and a dict with two keys,
1848
``job_info`` and ``log_entries`` otherwise.
1849

    
1850

    
1851
.. _rapi-res-nodes:
1852

    
1853
``/2/nodes``
1854
++++++++++++
1855

    
1856
Nodes resource.
1857

    
1858
.. rapi_resource_details:: /2/nodes
1859

    
1860

    
1861
.. _rapi-res-nodes+get:
1862

    
1863
``GET``
1864
~~~~~~~
1865

    
1866
Returns a list of all nodes.
1867

    
1868
Example::
1869

    
1870
    [
1871
      {
1872
        "id": "node1.example.com",
1873
        "uri": "\/nodes\/node1.example.com"
1874
      },
1875
      {
1876
        "id": "node2.example.com",
1877
        "uri": "\/nodes\/node2.example.com"
1878
      }
1879
    ]
1880

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

    
1885
Returned fields: :pyeval:`utils.CommaJoin(sorted(rlib2.N_FIELDS))`.
1886

    
1887
Example::
1888

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

    
1906

    
1907
.. _rapi-res-nodes-node_name:
1908

    
1909
``/2/nodes/[node_name]``
1910
+++++++++++++++++++++++++++++++++
1911

    
1912
Returns information about a node.
1913

    
1914
.. rapi_resource_details:: /2/nodes/[node_name]
1915

    
1916

    
1917
.. _rapi-res-nodes-node_name+get:
1918

    
1919
``GET``
1920
~~~~~~~
1921

    
1922
Returned fields: :pyeval:`utils.CommaJoin(sorted(rlib2.N_FIELDS))`.
1923

    
1924

    
1925

    
1926
.. _rapi-res-nodes-node_name-powercycle:
1927

    
1928
``/2/nodes/[node_name]/powercycle``
1929
+++++++++++++++++++++++++++++++++++
1930

    
1931
Powercycles a node.
1932

    
1933
.. rapi_resource_details:: /2/nodes/[node_name]/powercycle
1934

    
1935

    
1936
.. _rapi-res-nodes-node_name-powercycle+post:
1937

    
1938
``POST``
1939
~~~~~~~~
1940

    
1941
Returns a job ID.
1942

    
1943
Job result:
1944

    
1945
.. opcode_result:: OP_NODE_POWERCYCLE
1946

    
1947

    
1948
.. _rapi-res-nodes-node_name-evacuate:
1949

    
1950
``/2/nodes/[node_name]/evacuate``
1951
+++++++++++++++++++++++++++++++++
1952

    
1953
Evacuates instances off a node.
1954

    
1955
.. rapi_resource_details:: /2/nodes/[node_name]/evacuate
1956

    
1957

    
1958
.. _rapi-res-nodes-node_name-evacuate+post:
1959

    
1960
``POST``
1961
~~~~~~~~
1962

    
1963
Returns a job ID. The result of the job will contain the IDs of the
1964
individual jobs submitted to evacuate the node.
1965

    
1966
Body parameters:
1967

    
1968
.. opcode_params:: OP_NODE_EVACUATE
1969
   :exclude: nodes
1970

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

    
1975
Job result:
1976

    
1977
.. opcode_result:: OP_NODE_EVACUATE
1978

    
1979

    
1980
.. _rapi-res-nodes-node_name-migrate:
1981

    
1982
``/2/nodes/[node_name]/migrate``
1983
+++++++++++++++++++++++++++++++++
1984

    
1985
Migrates all primary instances from a node.
1986

    
1987
.. rapi_resource_details:: /2/nodes/[node_name]/migrate
1988

    
1989

    
1990
.. _rapi-res-nodes-node_name-migrate+post:
1991

    
1992
``POST``
1993
~~~~~~~~
1994

    
1995
If no mode is explicitly specified, each instances' hypervisor default
1996
migration mode will be used. Body parameters:
1997

    
1998
.. opcode_params:: OP_NODE_MIGRATE
1999
   :exclude: node_name
2000

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

    
2005
Job result:
2006

    
2007
.. opcode_result:: OP_NODE_MIGRATE
2008

    
2009

    
2010
.. _rapi-res-nodes-node_name-role:
2011

    
2012
``/2/nodes/[node_name]/role``
2013
+++++++++++++++++++++++++++++
2014

    
2015
Manages node role.
2016

    
2017
.. rapi_resource_details:: /2/nodes/[node_name]/role
2018

    
2019
The role is always one of the following:
2020

    
2021
  - drained
2022
  - master-candidate
2023
  - offline
2024
  - regular
2025

    
2026
Note that the 'master' role is a special, and currently it can't be
2027
modified via RAPI, only via the command line (``gnt-cluster
2028
master-failover``).
2029

    
2030

    
2031
.. _rapi-res-nodes-node_name-role+get:
2032

    
2033
``GET``
2034
~~~~~~~
2035

    
2036
Returns the current node role.
2037

    
2038
Example::
2039

    
2040
    "master-candidate"
2041

    
2042

    
2043
.. _rapi-res-nodes-node_name-role+put:
2044

    
2045
``PUT``
2046
~~~~~~~
2047

    
2048
Change the node role.
2049

    
2050
The request is a string which should be PUT to this URI. The result will
2051
be a job id.
2052

    
2053
It supports the bool ``force`` argument.
2054

    
2055
Job result:
2056

    
2057
.. opcode_result:: OP_NODE_SET_PARAMS
2058

    
2059

    
2060
.. _rapi-res-nodes-node_name-modify:
2061

    
2062
``/2/nodes/[node_name]/modify``
2063
+++++++++++++++++++++++++++++++
2064

    
2065
Modifies the parameters of a node.
2066

    
2067
.. rapi_resource_details:: /2/nodes/[node_name]/modify
2068

    
2069

    
2070
.. _rapi-res-nodes-node_name-modify+post:
2071

    
2072
``POST``
2073
~~~~~~~~
2074

    
2075
Returns a job ID.
2076

    
2077
Body parameters:
2078

    
2079
.. opcode_params:: OP_NODE_SET_PARAMS
2080
   :exclude: node_name
2081

    
2082
Job result:
2083

    
2084
.. opcode_result:: OP_NODE_SET_PARAMS
2085

    
2086

    
2087
.. _rapi-res-nodes-node_name-storage:
2088

    
2089
``/2/nodes/[node_name]/storage``
2090
++++++++++++++++++++++++++++++++
2091

    
2092
Manages storage units on the node.
2093

    
2094
.. rapi_resource_details:: /2/nodes/[node_name]/storage
2095

    
2096

    
2097
.. _rapi-res-nodes-node_name-storage+get:
2098

    
2099
``GET``
2100
~~~~~~~
2101

    
2102
FIXME: enable ".. pyassert::" again when all storage types are
2103
implemented::
2104

    
2105
   constants.VALID_STORAGE_TYPES == set([constants.ST_FILE,
2106
                                         constants.ST_LVM_PV,
2107
                                         constants.ST_LVM_VG])
2108

    
2109
Requests a list of storage units on a node. Requires the parameters
2110
``storage_type`` (one of :pyeval:`constants.ST_FILE`,
2111
:pyeval:`constants.ST_LVM_PV` or :pyeval:`constants.ST_LVM_VG`) and
2112
``output_fields``. The result will be a job id, using which the result
2113
can be retrieved.
2114

    
2115

    
2116
.. _rapi-res-nodes-node_name-storage-modify:
2117

    
2118
``/2/nodes/[node_name]/storage/modify``
2119
+++++++++++++++++++++++++++++++++++++++
2120

    
2121
Modifies storage units on the node.
2122

    
2123
.. rapi_resource_details:: /2/nodes/[node_name]/storage/modify
2124

    
2125

    
2126
.. _rapi-res-nodes-node_name-storage-modify+put:
2127

    
2128
``PUT``
2129
~~~~~~~
2130

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

    
2138
Job result:
2139

    
2140
.. opcode_result:: OP_NODE_MODIFY_STORAGE
2141

    
2142

    
2143
.. _rapi-res-nodes-node_name-storage-repair:
2144

    
2145
``/2/nodes/[node_name]/storage/repair``
2146
+++++++++++++++++++++++++++++++++++++++
2147

    
2148
Repairs a storage unit on the node.
2149

    
2150
.. rapi_resource_details:: /2/nodes/[node_name]/storage/repair
2151

    
2152

    
2153
.. _rapi-res-nodes-node_name-storage-repair+put:
2154

    
2155
``PUT``
2156
~~~~~~~
2157

    
2158
.. pyassert::
2159

    
2160
   constants.VALID_STORAGE_OPERATIONS == {
2161
    constants.ST_LVM_VG: set([constants.SO_FIX_CONSISTENCY]),
2162
    }
2163

    
2164
Repairs a storage unit on the node. Requires the parameters
2165
``storage_type`` (currently only :pyeval:`constants.ST_LVM_VG` can be
2166
repaired) and ``name`` (name of the storage unit). The result will be a
2167
job id.
2168

    
2169
Job result:
2170

    
2171
.. opcode_result:: OP_REPAIR_NODE_STORAGE
2172

    
2173

    
2174
.. _rapi-res-nodes-node_name-tags:
2175

    
2176
``/2/nodes/[node_name]/tags``
2177
+++++++++++++++++++++++++++++
2178

    
2179
Manages per-node tags.
2180

    
2181
.. rapi_resource_details:: /2/nodes/[node_name]/tags
2182

    
2183

    
2184
.. _rapi-res-nodes-node_name-tags+get:
2185

    
2186
``GET``
2187
~~~~~~~
2188

    
2189
Returns a list of tags.
2190

    
2191
Example::
2192

    
2193
    ["tag1", "tag2", "tag3"]
2194

    
2195

    
2196
.. _rapi-res-nodes-node_name-tags+put:
2197

    
2198
``PUT``
2199
~~~~~~~
2200

    
2201
Add a set of tags.
2202

    
2203
The request as a list of strings should be PUT to this URI. The result
2204
will be a job id.
2205

    
2206
It supports the ``dry-run`` argument.
2207

    
2208

    
2209
.. _rapi-res-nodes-node_name-tags+delete:
2210

    
2211
``DELETE``
2212
~~~~~~~~~~
2213

    
2214
Deletes tags.
2215

    
2216
In order to delete a set of tags, the DELETE request should be addressed
2217
to URI like::
2218

    
2219
    /tags?tag=[tag]&tag=[tag]
2220

    
2221
It supports the ``dry-run`` argument.
2222

    
2223

    
2224
.. _rapi-res-query-resource:
2225

    
2226
``/2/query/[resource]``
2227
+++++++++++++++++++++++
2228

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

    
2234
.. rapi_resource_details:: /2/query/[resource]
2235

    
2236

    
2237
.. _rapi-res-query-resource+get:
2238

    
2239
``GET``
2240
~~~~~~~
2241

    
2242
Returns list of included fields and actual data. Takes a query parameter
2243
named "fields", containing a comma-separated list of field names. Does
2244
not support filtering.
2245

    
2246

    
2247
.. _rapi-res-query-resource+put:
2248

    
2249
``PUT``
2250
~~~~~~~
2251

    
2252
Returns list of included fields and actual data. The list of requested
2253
fields can either be given as the query parameter "fields" or as a body
2254
parameter with the same name. The optional body parameter "filter" can
2255
be given and must be either ``null`` or a list containing filter
2256
operators.
2257

    
2258

    
2259
.. _rapi-res-query-resource-fields:
2260

    
2261
``/2/query/[resource]/fields``
2262
++++++++++++++++++++++++++++++
2263

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

    
2268
.. rapi_resource_details:: /2/query/[resource]/fields
2269

    
2270

    
2271
.. _rapi-res-query-resource-fields+get:
2272

    
2273
``GET``
2274
~~~~~~~
2275

    
2276
Returns a list of field descriptions for available fields. Takes an
2277
optional query parameter named "fields", containing a comma-separated
2278
list of field names.
2279

    
2280

    
2281
.. _rapi-res-os:
2282

    
2283
``/2/os``
2284
+++++++++
2285

    
2286
OS resource.
2287

    
2288
.. rapi_resource_details:: /2/os
2289

    
2290

    
2291
.. _rapi-res-os+get:
2292

    
2293
``GET``
2294
~~~~~~~
2295

    
2296
Return a list of all OSes.
2297

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

    
2301
Example::
2302

    
2303
    ["debian-etch"]
2304

    
2305

    
2306
.. _rapi-res-tags:
2307

    
2308
``/2/tags``
2309
+++++++++++
2310

    
2311
Manages cluster tags.
2312

    
2313
.. rapi_resource_details:: /2/tags
2314

    
2315

    
2316
.. _rapi-res-tags+get:
2317

    
2318
``GET``
2319
~~~~~~~
2320

    
2321
Returns the cluster tags.
2322

    
2323
Example::
2324

    
2325
    ["tag1", "tag2", "tag3"]
2326

    
2327

    
2328
.. _rapi-res-tags+put:
2329

    
2330
``PUT``
2331
~~~~~~~
2332

    
2333
Adds a set of tags.
2334

    
2335
The request as a list of strings should be PUT to this URI. The result
2336
will be a job id.
2337

    
2338
It supports the ``dry-run`` argument.
2339

    
2340

    
2341
.. _rapi-res-tags+delete:
2342

    
2343
``DELETE``
2344
~~~~~~~~~~
2345

    
2346
Deletes tags.
2347

    
2348
In order to delete a set of tags, the DELETE request should be addressed
2349
to URI like::
2350

    
2351
    /tags?tag=[tag]&tag=[tag]
2352

    
2353
It supports the ``dry-run`` argument.
2354

    
2355

    
2356
.. _rapi-res-version:
2357

    
2358
``/version``
2359
++++++++++++
2360

    
2361
The version resource.
2362

    
2363
This resource should be used to determine the remote API version and to
2364
adapt clients accordingly.
2365

    
2366
.. rapi_resource_details:: /version
2367

    
2368

    
2369
.. _rapi-res-version+get:
2370

    
2371
``GET``
2372
~~~~~~~
2373

    
2374
Returns the remote API version. Ganeti 1.2 returned ``1`` and Ganeti 2.0
2375
returns ``2``.
2376

    
2377

    
2378
.. _rapi-access-permissions:
2379

    
2380
Access permissions
2381
------------------
2382

    
2383
The following list describes the access permissions required for each
2384
resource. See :ref:`rapi-users` for more details.
2385

    
2386
.. rapi_access_table::
2387

    
2388

    
2389
.. vim: set textwidth=72 :
2390
.. Local Variables:
2391
.. mode: rst
2392
.. fill-column: 72
2393
.. End: