:toc: right
:sectnums:
:sectanchors:

= Introduction

This document contains miscellaneous information about the oVirt REST
API.

== Features added in oVirt 4.0

=== Support for versions 3 and 4 of the API

Version 4 of the engine supports versions 3 and 4 of the API. Version 3
of the API will be identical to the API currently provided by version
3.6 of the engine. Version 4 will be different, as described in the
<<Backwards compatibility breaking changes in version 4 of the API, below>>.

Users of the API can select the version using the HTTP `Version` header.
The value of the header should be the version number. For example, to
retrieve the list of virtual machines requesting explicitly version 3 of
the API:

  GET /ovirt-engine/api/vms HTTP/1.1
  Version: 3
  ...

Alternatively, for users that can't modify their software to send the
`Version` header, it is also possible to add the `/v3` prefix to the
URL, as in most cases the URL will be a configuration parameter:

  GET /ovirt-engine/api/v3/vms HTTP/1.1
  ...

When neither the header nor the URL prefix are used the server will
automatically select a version. The default is version `4`, but this can
be changed using the `ENGINE_API_DEFAULT_VERSION` parameter:

  $ echo "ENGINE_API_DEFAULT_VERSION=3" > \
  /etc/ovirt-engine/engine.conf.d/99-set-default-version.conf
  $ systemctl restart ovirt-engine

NOTE: Take into account that changing this parameter affects all users
of the engine that don't specify the version explicitly.

The SDKs provided by the oVirt project have already been modified to
send the correct `Version` header, so users don't need to do anything if
they are using versions 3.6.3.0 or later.

=== Support change of allocation policy of disks imported

Adding support for changing the allocation policy of disks imported from
an export domain as part of importing a VM.  The caller can specify for
each disks the format and allocation policy. Note that
`collapse_snapshots` should be true.  The disk ids should be the ids of
the existing disks that the user is importing.

For example, to force one of the disks to be preallocated:

[source]
----
POST /storagedomains/{storagedomain:id}/vms/{vm:id}/import;collapse_snapshots=true
<action>
  <storage_domain>
    <name>mydata</name>
  </storage_domain>
  <cluster>
    <name>mycluster</name>
  </cluster>
  <vm>
    <disk_attachments>
      <disk_attachment>
        <disk id="792f8ca8-3932-429b-9660-006ba144bc72">
          <format>raw</format>
          <sparse>false</sparse>
        </disk>
      </disk_attachment>
    </disk_attachments>
  </vm>
</action>
----

=== Support skipping LUN status check

Adding support for skipping the LUN status check.
Checking the status of the LUN is an heavy weight operation
and this data is not always needed by the user.

The default is `true` for backward compatibility.
The parameter `report_status` is available both on getting the list of a host storages or a specific host storage:

[source]
----
GET /hosts/{host:id}/storage
GET /hosts/{host:id}/storage/{storage:id}
----

For example, to skip the LUN status check, set `report_status` to false:
(The `status` field of the LUN will not be present in the response)

[source]
----
GET /hosts/{host:id}/storage/{storage:id};report_status=false

<host_storage id="360014051136c20574f743bdbd28177fd">
  <logical_units>
    <logical_unit id="360014051136c20574f743bdbd28177fd">
      <lun_mapping>0</lun_mapping>
      <paths>1</paths>
      <product_id>lun0</product_id>
      <serial>SLIO-ORG_lun0_1136c205-74f7-43bd-bd28-177fd5ce6993</serial>
      <size>10737418240</size>
      <vendor_id>LIO-ORG</vendor_id>
      <volume_group_id>O9Du7I-RahN-ECe1-dZ1w-nh0b-64io-MNzIBZ</volume_group_id>
    </logical_unit>
  </logical_units>
  <type>iscsi</type>
  <host id="8bb5ade5-e988-4000-8b93-dbfc6717fe50"/>
</host_storage>

----


For example, to get the LUN status, set `report_status` to true:
(The `status` field of the LUN will be present in the response)

[source]
----
GET /hosts/{host:id}/storage/{storage:id};report_status=true

<host_storage id="360014051136c20574f743bdbd28177fd">
  <logical_units>
    <logical_unit id="360014051136c20574f743bdbd28177fd">
      <lun_mapping>0</lun_mapping>
      <paths>1</paths>
      <product_id>lun0</product_id>
      <serial>SLIO-ORG_lun0_1136c205-74f7-43bd-bd28-177fd5ce6993</serial>
      <size>10737418240</size>
      <status>used</status>
      <vendor_id>LIO-ORG</vendor_id>
      <volume_group_id>O9Du7I-RahN-ECe1-dZ1w-nh0b-64io-MNzIBZ</volume_group_id>
    </logical_unit>
  </logical_units>
  <type>iscsi</type>
  <host id="8bb5ade5-e988-4000-8b93-dbfc6717fe50"/>
</host_storage>

----

== Backwards compatibility breaking changes in version 3 of the API

This section enumerates the backwards compatibility breaking changes
that have been done in version 3 of the API.

== Backwards compatibility breaking changes in version 4 of the API

This section enumerates the backwards compatibility breaking changes
that have been done to version 4 of the API.

=== Removed YAML support

The support for YAML has been completely removed.

=== Renamed complex types

The following XML schema complex types have been renamed:

|===
| Version 3 | Version 4

| `API` | `Api`
| `CPU` | `Cpu`
| `CPUs` | `Cpus`
| `CdRom` | `Cdrom`
| `CdRoms` | `Cdroms`
| `DNS` | `Dns`
| `GuestNicConfiguration` | `NicConfiguration`
| `GuestNicsConfiguration` | `NicConfigurations`
| `HostNICStates` | `HostNicStates`
| `HostNIC` | `HostNic`
| `HostStorage` | `HostStorages`
| `IO` | `Io`
| `IP` | `Ip`
| `IPs` | `Ips`
| `KSM` | `Ksm`
| `MAC` | `Mac`
| `NIC` | `Nic`
| `PreviewVMs` | `PreviewVms`
| `QoS` | `Qos`
| `QoSs` | `Qoss`
| `RSDL` | `Rsdl`
| `SELinux` | `SeLinux`
| `SPM` | `Spm`
| `SSHPublicKey` | `SshPublicKey`
| `SSHPublicKeys` | `SshPublicKeys`
| `SSH` | `Ssh`
| `SkipIfSDActive` | `SkipIfSdActive`
| `Slaves` | `HostNics`
| `Storage` | `HostStorage`
| `SupportedVersions` | `Versions`
| `VCpuPin` | `VcpuPin`
| `VLAN` | `Vlan`
| `VM` | `Vm`
| `VMs` | `Vms`
| `VirtIO_SCSI` | `VirtioScsi`
| `WatchDog` | `Watchdog`
| `WatchDogs` | `Watchdogs`
|===

These renamings don't affect users of the API, unless they are using the
XML schema, either directly or indirectly via the Python or Java SDKs.

=== Replaced the `Status` type with enum types

Currently the status of different objects is reported using the `Status`
type, which contains a `state` string describing the status and another
`detail` string for additional details. For example, the status of a
virtual machine that is paused due to an IO error is currently reported
as follows:

[source]
----
<vm>
  ...
  <status>
    <state>paused</state>
    <detail>eio</detail>
  </status>
  ...
</vm>
----

In version 4 of the API this `Status` type has been removed and replaced
by enum types. When the additional `detail` string is needed it has been
replaced with an additional `status_detail` attribute. So, for example,
the status of the same virtual machine will now be reported as follows:

[source]
----
<vm>
  ...
  <status>paused</status>
  <status_detail>eio</status_detail>
  ...
</vm>
----

=== Remove the NIC `network` and `port_mirroring` properties

The NIC `network` and `port_mirroring` elements have been replaced by
the `vnic_profile` element, so when creating or updating a NIC instead
of specifying the network and port mirroring configuration, these are
previusly specified creating a VNIC profile:

[source]
----
POST /vnicprofiles
<vnic_profile>
  <name>myprofile</name>
  <network id="..."/>
  <port_mirroring>true</port_mirroring>
</vnic_profile>
----

And then the NIC is created or referencing the existing VNIC profile:

[source]
----
PUT /vms/{vm:id}/nics/{nic:id}
<nic>
  <vnic_profile id="/vnicprofiles/...">
</nic>
----

The old elements and their meaning were preserved for backwards
compatibility, but they have now been completely removed.

Note that the `network` element hasn't been removed from the XML schema
because it is still used by the `initialization` element, but it will be
completely ignored if provided when creating or updating a NIC.

=== Remove the NIC `active` property

The NIC `active` property was replaced by `plugged` some time ago. It
has been completely removed now.

=== Remove the disk `type` property

The `type` property of disks has been removed, but kept in the XML
schema and ignored. It has been completely removed now.

=== Remove the disk `size` property

The disk `size` property has been replaced by `provisioned_size` long
ago. It has been completely removed now.

=== Removed support for pinning a VM to a single host

Before version 3.6 the API had the possibility to pin a VM to a single
host, using the `placement_policy` element of the VM entity:

[source]
----
PUT /vms/{vm:id}
<vm>
  <placement_policy>
    <host id="{host:id}/">
  </placement_policy>
<vm>
----

In version 3.6 this capability was enhanced to support multiple
hosts, and to do so a new `hosts` element was added:

[source]
----
PUT /vms/{vm:id}
<vm>
  <placement_policy>
    <hosts>
      <host id="{host:id}"/>
      <host id="{host:id}"/>
      ...
    </hosts>
  </placement_policy>
<vm>
----

To preserve backwards compatibility the single `host` element was
preserved. In 4.0 this has been removed, so applications will need
to use the `hosts` element even if when pinning to a single host.

=== Removed the `capabilities.permits` element

The list of permits is potentiall different for each cluster level, and
it has been added to the `version` element long ago, but it has been
kept into the `capabilities` element as well, just for backwards
compatibility.

In 4.0 it the `capabilities` service has been completely removed, and
replaced by the new `clusterlevels` service. To find the permits
supported by cluster level 4.0 a request like this should be used:

[source]
----
GET /clusterlevels/4.0
----

The result will be a document containing the information specific to
that cluster level, in particular the set of supported permits:

[source,xml]
----
<cluster_level id="4.0" href="/clusterlevels/4.0">
  ...
  <permits>
    <permit id="1">
      <name>create_vm</name>
      <administrative>false</administrative>
    </permit>
    ...
  </permits>
</cluster_level>
----

=== Removed the `storage_manager` element

The `storage_manager` element was replaced by the `spm` element some
time ago. The old one was kept for backwards compatibility, but it has
been completely removed now.

=== Removed the data center `storage_type` element

Data centers used to be associated to a specific storage type (NFS,
Fiber Channel, iSCSI, etc) but they have been changed some time so that
there are only two types: with local storage and with shared storage. A
new `local` element was introduced to indicate this, and the old
`storage_type` was element was preserved for backwards compatibility.
This old element has now been completely removed.

=== Remove the `timezone` element

The VM resource used to contain a `timezone` element to represent the
time zone. This element only allowed a string:

[source]
----
<vm>
   <timezone>Europe/Madrid</timezone>
</vm>
----

This doesn't allow extension, and as a it was necessary to add the UTC
offset, it was replaced with a new structured `time_zone` element:

[source]
----
<vm>
  <time_zone>
    <name>Europe/Madrid</name>
    <utc_offset>GMT+1</utc_offset>
  </time_zone>
</vm>
----

The old `timezone` element was preserved, but it has been completely
removed now.

=== Removed the `guest_info` element

The `guest_info` element was used to hold information gathered by the
guest agent, like the IP addresses and the fully qualified host name.
This information is also available in other places. For example, the IP
addresses are available within VM resource:

[source]
----
GET /vms/{vm:id}
<vm>
  <guest_info>
    <ips>
      <ip address="192.168.122.30"/>
    </ips>
    <fqdn>whatever.example.com</fqdn>
  </guest_info>
</vm>
----

And also within the NIC resource, using the newer `reported_devices`
element:

[source]
----
GET /vms/{vm:id}/nics/{nic:id}
<nic>
  <reported_devices>
    <reported_device>
      <name>eth0</name>
      <mac address="00:1a:4a:b5:4c:94"/>
      <ips>
        <ip address="192.168.1.115" version="v4"/>
        <ip address="fe80::21a:4aff:feb5:4c94" version="v6"/>
        <ip address="::1:21a:4aff:feb5:4c94" version="v6"/>
      </ips>
    </reported_device>
  </reported_devices>
</nic>
----

In addition this newer `reported_devices` element provides more complete
information, like multiple IP addresses, MAC addresses, etc.

To remove this duplication the `guest_info` element has been removed.

To support the fully qualified domain name a new `fqdn` element has been
added to the VM resource:

[source]
----
GET /vms/{vm:id}
<vm>
  <fqdn>whatever.example.com</fqdn>
</vms>
----

This will contain the same information that `guest_info.fqdn` used to
contain.

=== Replaced CPU `id` attribute with `type` element

The `cpu` element used to have an `id` attribute that indicates the type
of CPU:

[source]
----
<cpu id="Intel Conroe Family">
  <architecture>X86_64</architecture>
  ...
</cpu>
----

This is in contradiction with the rest of the elements of the API
model, where the `id` attribute is used for opaque identifiers. This
`id` attribute has been replaced with a new `type` element:

[source]
----
<cpu>
  <type>Intel Conroe Family</type>
  <architecture>X86_64</architecture>
</cpu>
----

=== Use elements instead of attributes in CPU topology

In the past the CPU topology element used attributes for its properties:

[source]
----
<cpu>
  <topology sockets="1" cores="1" threads="1"/>
  ...
</cpu>
----

This is contrary to the common practice in the API. They have been
replaced by inner elements:

[source]
----
<cpu>
  <topology>
    <sockets>1<sockets>
    <cores>1<cores>
    <threads>1<threads>
  </topology>
  ...
</cpu>
----

=== Use elements instead of attributes in VCPU pin

In the past the VCPU pin element used attributes for its properties:

[source]
----
<cpu_tune>
  <vcpu_pin vcpu="0" cpu_set="0"/>
</cpu_tune>
----

This is contrary to the common practice in the API. They have been
replaced by inner elements:

[source]
----
<cpu_tune>
  <vcpu_pin>
    <vcpu>0</vcpu>
    <cpu_set>0</cpu_set>
  </vcpu_pin>
</cpu_tune>
----

=== Use elements instead of attributes in VCPU pin

In the past the `version` element used attributes for its properties:

[source]
----
<version major="3" minor="5" ../>
----

This is contrary to the common practice in the API. They have been
replaced by inner elements:

[source]
----
<version>
  <major>3</minor>
  <minor>5</minor>
  ...
</version>
----

=== Use elements instead of attributes in memory overcommit

In the past the `overcommit` element used attributes for its properties:

[source]
----
<memory_policy>
  <overcommit percent="100"/>
  ...
</memory_policy>
----

This is contrary to the common practice in the API. They have been
replaced by inner elements:

[source]
----
<memory_policy>
  <overcommit>
    <percent>100</percent>
  </overcommit>
  ...
</memory_policy>
----

=== Use elements instead of attributes in `console`

In the past the `console` element used attributes for its properties:

[source]
----
<console enabled="true"/>
----

This is contrary to the common practice in the API. They have been
replaced by inner elements:

[source]
----
<console>
  <enabled>true</enabled>
</console>
----

=== Use elements instead of attributes in VIRTIO SCSI

In the past the VIRTIO ISCSI element used attributes for its properties:

[source]
----
<virtio_scsi enabled="true"/>
----

This is contrary to the common practice in the API. They have been
replaced by inner elements:

[source]
----
<virtio_scsi>
  <enabled>true</enabled>
</virtio_scsi>
----

=== Use element instead of attribute for power management agent `type`

The power management `type` property was represented as an attribute:

[source]
----
<agent type="apc">
  <username>myuser</username>
  ...
</agent>
----

This is contrary to the common practice in the API. It has been
replaced with an inner element:

[source]
----
<agent>
  <type>apc</type>
  <username>myuser</username>
  ...
</agent>
----

=== Use elements instead of attributes in power management agent options

In the past the power management agent options element used attributes
for its properties:

[source]
----
<options>
  <option name="port" value="22"/>
  <option name="slot" value="5"/>
  ...
</options>
----

This is contrary to the common practice in the API. They have been
replaced with inner elements:

[source]
----
<options>
  <option>
    <name>port</name>
    <value>22</value>
  </option>
  <option>
    <name>slot</name>
    <value>5</value>
  </option>
  ...
</options>
----

=== Use elements instead of attributes in IP address:

In the past the IP address element used attributes for its properties:

[source]
----
<ip address="192.168.122.1" netmask="255.255.255.0"/>
----

This is contrary to the common practice in the API. They have been
replaced with inner elements:

[source]
----
<ip>
  <address>192.168.122.1</address>
  <netmask>255.255.255.0</netmask>
</ip>
----

=== Use elements instead of attributes in MAC address:

In the past the MAC address element used attributes for its properties:

[source]
----
<mac address="66:f2:c5:5f:bb:8d"/>
----

This is contrary to the common practice in the API. They have been
replaced by inner elements:

[source]
----
<mac>
  <address>66:f2:c5:5f:bb:8d</address>
</mac>
----

=== Use elements instead of attributes in boot device:

In the past the boot device element used attributes for its properties:

[source]
----
<boot dev="cdrom"/>
----

This is contrary to the common practice in the API. They have been
replaced by inner elements:

[source]
----
<boot>
  <dev>cdrom</dev>
</boot>
----

=== Use element instead of attribute for operating system `type`

The operating system `type` property was represented as an attribute:

[source]
----
<os type="other">
  ...
</os>
----

This is contrary to the common practice in the API. It has been
replaced with an inner element:

[source]
----
<os>
  <type>other</type>
  ...
</os>
----

=== Removed the `force` parameter from the request to retrieve a host

The request to retrieve a host used to support a `force` matrix
parameter to indicate that the data of the host should be refreshed
(calling VDSM to reload host capabilities and devices) before retrieving
it from the database:

[source]
----
GET /hosts/{host:id};force
----

This `force` parameter has been superseded by the host `refresh` action,
but kept for backwards compatibility. It has been completely removed
now. Applications that require this functionality should perform two
requests, first one to refresh the host:

[source]
----
POST /hosts/{host:id}/refresh
<action/>
----

And then one to retrieve it, without the `force` parameter:

[source]
----
ET /hosts/{host:id}
----

=== Removed deprecated host power management configuration

The host power management configuration used to be part of the host
resource, using embedded configuration elements:

[source]
----
<power_management type="apc">
  <enabled>true</enabled>
  <address>myaddress</address>
  <username>myaddress</username>
  <options>
    <option name="port" value="22/>
    </option name="slot" value="5/>
  </options>
  ...
</power_management>
----

This has been changed some time ago, in order to support multiple power
management agents, introducing a new
`/hosts/{host:id}fenceagents`collection.

The old `type` attribute, the old `address`, `username` and `password`
elements, and the inner `agents` element directly inside
`power_management` were preserved for backwards compatibility. All these
elements have been completely removed, so the only way to query or
modify the power management agents is now the
`/hosts/{host:id}/fenceagents` sub-collection.

=== Use multiple `boot.devices.device` instead of multiple `boot`

In the past the way to specify the boot sequence when starting a virtual
machine was to use multiple `boot` elements, each containing a `dev`
element. For example, to specify that the virtual machine should first
try to boot from CDROM and then from hard disk the following request was
used:

[source]
----
POST /vms/{vm:id}/start
<action>
  <vm>
    ...
    <boot>
      <dev>cdrom</dev>
    </boot>
    <boot>
      <dev>hd</dev>
    </boot>
  </vm>
</action>
----

The common practice in other parts of the API is to represent arrays
with a wrapper element. In that case that wrapper element could be named
`boots`, but that doesn't make much sense, as what can have multiple
values here is the boot device, not the boot sequence. To fix this
inconsistence this has been replaced with a single `boot` element that
can contain multiple devices:

[source]
----
POST /vms/{vm:id}/start
<action>
  <vm>
    ...
    <boot>
      <devices>
        <device>cdrom</device>
        <device>hd</device>
      </devices>
    </boot>
  </vm>
</action>
----

=== Removed the `disks.clone` and `disks.detach_only` elements

These elements aren't really part of the representation of disks, but
parameters of the operations to add and remove virtual machines.

The `disks.clone` element was used to indicate that the disks of a new
virtual machine have to be cloned:

[source]
----
POST /vms
<vm>
  ...
  <disks>
    <clone>true</clone>
  </disks>
<vm>
----

This has been now removed, and replaced by a new `clone` matrix
parameter:

[source]
----
POST /vms;clone=true
<vm>
  ...
</vm>
----

The `disks.detach_only` element was used to indicate that when removing
a virtual machine the disks don't have to be removed, but just detached
from the virtual machine:

[source]
----
DELETE /vms/{vm:id}
<action>
  <vm>
    <disks>
      <detach_only>true</detach_only>
    </disks>
  </vm>
</action>
----

This has been now removed, and replaced by a new `detach_only` matrix
parameter:

[source]
----
DELETE /vms/{vm:id};detach_only=true
----

=== Rename element `vmpool` to `vm_pool`

The names of the elements that represent pools of virtual machines used
to be `vmpool` and `vmpools`. They have been renamed to `vm_pool` and
`vm_pools` in order to have a consistent correspondence between names of
complex types (`VmPool` and `VmPools` in this case) and elements.

=== Use `logical_units` instead of multiple `logical_unit`

The logical units that are part of a volume group used to be reported as
an unbounded number of `logical_unit` elements. For example, when
reporting the details of a storage domain:

[source]
----
GET /storagedomains/{storagedomain:id}
<storage_domain>
  ...
  <storage>
    ...
    <volume_group>
      <logical_unit>
        <!-- First LU -->
      </logical_unit>
      <logical_unit>
        <!-- Second LU -->
      </logical_unit>
      ...
    </volume_group>
  </storage>
</storage_domain>
----

This is contrary to the usual practice in the API, as list of elements
are always wrapped with an element. This has been fixed now, so the list
of logical units will be wrapped with the `logical_units` element:

[source]
----
GET /storagedomains/{storagedomain:id}
<storage_domain>
  ...
  <storage>
    ...
    <volume_group>
      <logical_units>
        <logical_unit>
          <!-- First LU -->
        </logical_unit>
        <logical_unit>
          <!-- Second LU -->
        </logical_unit>
        ...
      </logical_units>
    </volume_group>
  </storage>
</storage_domain>
----

=== Removed the `snapshots.collapse_snapshots` element

This element isn't really part of the representation of snapshots, but
a parameter of the operation that imports a virtual machine from an
export storage domain:

[source]
----
POST /storagedomains/{sd:id}/vms/{vm:id}/import
<action>
  <vm>
    <snapshots>
      <collapse_snapshots>true</collapse_snapshots>
    </snapshots>
  </vm>
</action>
----

This has been now removed, and replaced by a new `collapse_snapshots`
matrix parameter:

[source]
----
POST /storagedomains/{sd:id}/vms/{vm:id}/import;collapse_snapshots
<action/>
----

=== Renamed `storage` and `host_storage` elements

The host storage collection used the `storage` and `host_storage`
elements and the `Storage` and `HostStorage` complex types to report the
storage associated to a host:

[source]
----
GET /hosts/{host:id}/storage
<host_storage>
  <storage>
    ...
  </storage>
  <storage>
    ...
  </storage>
  ...
</host_storage>
----

This doesn't follow the pattern used in the rest of the API, where the
outer element is a plural name and the inner element is the same name
but in singular. This has now been changed to use `host_storages` as the
outer element and `host_storage` as the inner element:

[source]
----
GET /hosts/{host:id}/storage
<host_storages>
  <host_storage>
    ...
  </host_storage>
  <host_storage>
    ...
  </host_storage>
  ...
</host_storage>
----

=== Removed the `permissions.clone` element

This element isn't really part of the representation of permissions, but
a parameter of the operations to create virtual machines or templates:

[source]
----
POST /vms
<vm>
  <template id="...">
    <permissions>
      <clone>true</clone>
    </permissions>
  </template>
</action>
----

[source]
----
POST /templates
<template>
  <vm id="...">
    <permissions>
      <clone>true</clone>
    </permissions>
  </vm>
</template>
----

This has been now removed, and replaced by a new `clone_permissions`
matrix parameter:

[source]
----
POST /vms;clone_permissions
<vm>
  <template id="..."/>
</vm>
----

[source]
----
POST /templates;clone_permissions
<template>
  <vm id="..."/>
</template>
----

=== Renamed the random number generator `source` elements

The random number generator sources used to be reported using a
collection of `source` elements wrapped by an element with a name
reflecting its use. For example, the required random number generator
sources of a cluster used to be reported as follows:

[source]
----
GET /clusters/{cluster:id}
<cluster>
  ...
  <required_rng_sources>
    <source>RANDOM</source>
  </required_rng_sources>
  ...
</cluster>
----

And the random number generator sources suported by a host used to be
reported as follows:

[source]
----
GET /hosts/{host:id}
<host>
  ...
  <hardware_information>
    <supported_rng_sources>
      <source>RANDOM</source>
    </supported_rng_sources>
  </hardware_information>
  ...
</host>
----

This isn't consistent with the rest of the API, where collections are
wrapped by a name in plural and elements by the same name in singular.
This has been now fixed. The required random number generator sources
will now be reported as follows:

[source]
----
GET /clusters/{cluster:id}
<cluster>
  <required_rng_sources>
    <required_rng_sourcesRANDOM</required_rng_source>
  </required_rng_sources>
  ...
</cluster>
----


And the random number generator sources supported by a host will be
reported as follows:

[source]
----
GET /hosts/{host:id}
<host>
  ...
  <hardware_information>
    <supported_rng_sources>
      <supported_rng_source>RANDOM</supported_rng_source>
    </supported_rng_sources>
  </hardware_information>
  ...
</host>
----

Note the use of `required_rng_source` and `supported_rng_source` instead
of just `source`.

=== Removed the intermediate `tag.parent` element

The relationship bettween a tag and it's parent tag used to be
represented using an intermedite `parent` tag, that in turn contains
another `tag` element:

[source]
----
<tag>
  <name>mytag</name>
  <parent>
    <tag id="..." href="..."/>
  </parent>
</tag>
----

This structure has been simplified so that only one `parent` element is
used now:

[source]
----
<tag>
  <name>mytag</name>
  <parent id="..." href="..."/>
</tag>
----

=== Remove scheduling built-in names and thresholds

In the past the specification of scheduling policies for clusters was
based in built-in names and thresholds. For example a cluster that used
the *evenly distributed* scheduling policy was represented as follows:

[source]
----
<cluster>
  <name>mycluster</name>
  <scheduling_policy>
    <policy>evenly_distributed</policy>
    <thresholds high="80" duration="120"/>
  </scheduling_policy>
  ...
</cluster>
----

This mechanism was replaced with a top level `/schedulingpolicies`
collection where scheduling policies can be defined with arbitrary names
and properties. For example, the same scheduling policy is represented
as follows in that top level collection:

[source]
----
<scheduling_policy>
  <name>evenly_distributed</name>
  <properties>
    <property>
      <name>CpuOverCommitDurationMinutes</name>
      <value>2</value>
    </property>
    <property>
      <name>HighUtilization</name>
      <value>80</value>
    </property>
  </properties>
</scheduling_policy>
----

The representation of the cluster references the scheduling policy with
its identifier:

[source]
----
<cluster>
  <name>mycluster</name>
  <scheduling_policy id="..."/>
  ...
</cluster>
----

To preserve backwards compatibility the old `policy` and `thresholds`
elements were preserved. The scheduling policy representation embedded
within the cluster was also preserved. All these things have been
completely removed now, so the only way to reference a scheduling policy
when retrieving, creating or updating a cluster is to reference an
existing one using its identifier. For example, when retrieving a
cluster only the `id` (and `href`) will be populated:

[source]
----
GET /clusters/{cluster:id}
<cluster>
  ...
  <scheduling_policy id="..." href="..."/>
  ...
</cluster>
----

When creating or updating a cluster only the `id` will be accepted.

=== Removed the `bricks.replica_count` and `bricks.stripe_count` elements

These elements aren't really part of the representation of a collection of
bricks, but parameters of the operations to add and remove bricks. They have
now been removed, and replaced by a new `replica_count` and `stripe_count`
matrix parameters:

[source]
----
POST .../bricks;replica_count=3;stripe_count=2
----

[source]
----
DELETE .../bricks;replica_count=3
----

=== Renamed the statistics `type` property to `kind`

The statistics used to be represented using a `type` element that
indicates the kind of statistic (gauge, counter, etc) and also a `type`
attribute that indicates the type of the values (integer, string, etc):

[source]
----
<statistic>
  <type>GAUGE</type>
  <values type="INTEGER">
    <value>...</value>
    <value>...</value>
    ...
  </values>
</statistic>
----

To avoid the use of the `type` concept for both things the first has
been replaced by `kind`, and both `kind` and `type` are now elements:

[source]
----
<statistic>
  <kind>GAUGE</kind>
  <type>INTEGER</type>
  <values>
    <value>...</value>
    <value>...</value>
    ...
  </values>
</statistic>
----

=== Use multiple `vcpu_pins.vcpu_pin` instead of multiple `vcpu_pin`

In the past the way to specify the virtual to physical CPU pinning of a
virtual machie was to use multiple `vcpu_pin` elements:

[source]
----
<vm>
  <cpu>
    <cpu_tune>
      <vcpu_pin>...</vcpu_pin>
      <vcpu_pin>...</vcpu_pin>
      ...
    </cpu_tune>
  </cpu>
</vm>
----

In order to conform to the common practice in other parts of the API
this has been changed to use a wrapper element, in this case
`vcpu_pins`:

[source]
----
<vm>
  <cpu>
    <cpu_tune>
      <vcpu_pins>
        <vcpu_pin>...</vcpu_pin>
        <vcpu_pin>...</vcpu_pin>
        ...
      </vcpu_pins>
    </cpu_tune>
  </cpu>
</vm>
----

=== Use `force` parameter to force remove a data center

The operation that removes a data center supports a `force` parameter.
In order to use it the `DELETE` operation used to support an optional
action parameter:

[source]
----
DELETE /datacenters/{datacenter:id}
<action>
  <force>true</force>
</action>
----

This optional action parameter has been replaced with an optional parameter:

[source]
----
DELETE /datacenters/{datacenter:id}?force=true
----

=== Use `force` matrix parameter to force remove a host

The operation that removes a host supports a `force` parameter. In
order to use it the `DELETE` operation used to support an optional
action parameter:

[source]
----
DELETE /host/{host:id}
<action>
  <force>true</force>
</action>
----

This optional action parameter has been replaced with an optional matrix
parameter:

[source]
----
DELETE /host/{host:id};force=true
----

=== Use matrix parameters for force remove storage domain

The operation that removes a storage domain supports the `force`,
`destroy` and `host` parameters. These parameters were passed to the
`DELETE` method using the representation of the storage domain as the
body:

[source]
----
DELETE /storagedomains/{storagedomain:id}
<storage_domain>
  <force>...</force>
  <destroy>...</destroy>
  <host id="...">
    <name>...</name>
  </host>
</storage_domain>
----

This was problematic, as the HTTP `DELETE` parameters shouldn't have a
body, and the representation of the storage domain shouldn't include
things that aren't attributes of the storage domain, rather parameters
of the operation.

The `force`, `delete` and `host` attributes have been replaced by
equivalent matrix parameters, and the operation doesn't now accept a
body. For example, now the correct way to delete a storage domain with
the `force` parameter is the following:

[source]
----
DELETE /storagedomain/{storagedomain:id};host=myhost;force=true
----

To delete with the `destroy` parameter:

[source]
----
DELETE /storagedomain/{storagedomain:id};host=myhost;destroy=true
----

=== Use `host` matrix parameter to remove storage server connection

The operation that removes a storage server connection supports a
`host` parameter. In order to use it the `DELETE` method used to
support an optional action parameter:

[source]
----
DELETE /storageconnections/{storageconnection:id}
<action>
  <host id="...">
    <name>...</name>
  </host>
</action>
----

This optional action parameter has been replaced with an optional matrix
parameter:

[source]
----
DELETE /storageconnections/{storageconnection:id};host=myhost
----

=== Use `force` and `storage_domain` matrix parameters to remove template disks

The operation that removes a template disk supports the `force` and
`storage_domain` parameters. In order to use it them the `DELETE` method
used to support an optional action parameter:

[source]
----
DELETE /templates/{template:id}/disks/{disk:id}
<action>
  <force>...</force>
  <storage_domain id="..."/>
</action>
----

In version 4 of the API this operation has been moved to the new
`diskattachments` collection, and the request body has been replaced
with the query parameters `force` and `storage_domain`:

[source]
----
DELETE /templates/{template:id}/disksattachments/{attachment:id}?force=true
----

[source]
----
DELETE /templates/{template:id}/disksattachments/{attachment:id}?storage_domain=123
----

=== Don't remove disks via the VM disk API

Removing an entity by deleting `/vms/{vm:id}/disks/{disk:id}` means
removing the relationship between the VM and the disk - i.e., this
operation should just detach the disk from the VM. This operation
is no longer able to remove disks completely from the system, which
was prone to user errors and had unreverseable consequences.
To remove a disk, instead use the `/disk/{disk:id}` API:

[source]
----
DELETE /disks/{disk:id}
----

=== Use `force` matrix parameter to force remove a virtual machine

The operation that removes a virtual machine supports a `force`
parameter. In order to use it the `DELETE` method used to support an
optional action parameter:

[source]
----
DELETE /vms/{vm:id}
<action>
  <force>true</force>
</action>
----

This optional action parameter has been replaced with an optional matrix
parameter:

[source]
----
DELETE /vms/{vm:id};force=true
----

=== Use `POST` instead of `DELETE` to remove multiple bricks

The operation that removes multiple Gluster bricks was implemented using
the `DELETE` method and passing the list of bricks as the body of the
request:

[source]
----
DELETE /clusters/{cluster:id}/glustervolumes/{volume:id}/bricks
<bricks>
  <bricks id="..."/>
  <bricks id="..."/>
  ...
</bricks>
----

This is problematic because the `DELETE` method shouldn't have a body,
so it has been replaced with a new `remove` action that uses the `POST`
method:

[source]
----
POST /clusters/{cluster:id}/glustervolumes/{volume:id}/bricks/remove
<bricks>
  <bricks id="..."/>
  <bricks id="..."/>
  ...
</bricks>
----

=== Removed the `scheduling_policy.policy` element

The element was kept for backward compatibility. Use
`scheduling_policy.name` instead.

[source]
----
POST /schedulingpolicies
<scheduling_policy>
  ...
  <name>policy_name</name>
  ...
</scheduling_policy>
----

[source]
----
PUT /schedulingpolicies/{schedulingpolicy:id}
<scheduling_policy>
  ...
  <name>policy_name</name>
  ...
</scheduling_policy>
----

=== Added `snapshot.snapshot_type`

Enums are being gradually introduces to the API. Some fields which
were string until now, are replaced with an appropriate enum. One
such field is vm.type. But this field is inherited by snapshot,
and snapshot type is different than vm type. So a new field has been
added to snapshot entity: `snapshot.snapshot_type`.

[source]
----
<snapshot>
  ...
  <snapshot_type>regular|active|stateless|preview</snapshot_type>
  ...
</snapshot>
----

=== Removed `move` action from `VM`

The deprecated `move` action of the `VM` entity has been removed.
Instead, you can move inidividual disks.

=== Moved `reported_configurations.in_sync` to `network_attachment`

In version 3 of the API the XML schema type `ReportedConfigurations` had
a `in_sync` property:

[source,xml]
----
<network_attachment>
  <reported_configurations>
    <in_sync>true</in_sync>
    <reported_configuration>
      ...
    </reported_configuration>
    ...
  </reported_configurations>
</network_attachment>
----

In the specification mechanism used by version 4 of the API this can't
be expressed, because list types (the list of reported configurations)
can't have attributes. To be able to represent it the attribute has been
moved to the enclosing `network_attachment`:

[source,xml]
----
<network_attachment>
  <in_sync>true</in_sync>
  <reported_configurations>
    <reported_configuration>
      ...
    </reported_configuration>
    ...
  </reported_configurations>
</network_attachment>
----

=== Replaced `capabilities` with `clusterlevels`

The top level `capabilities` collection has been replaced by the new
`clusterlevels` collection. This new collection will contain the
information that isn't available in the model, like the list of CPU
types available for each cluster level:

[source]
----
GET /clusterlevels
----

This will return a list of `ClusterLevel` objects containing the details
for all the cluster levels supported by the system:

[source,xml]
----
<cluster_levels>
  <cluster_level id="3.6" href="/clusterlevels/3.6">
    <cpu_types>
      <cpu_type>
        <name>Intel Conroe Family</name>
        <level>2</level>
        <architecture>x86_64</architecture>
      </cpu_type>
      ...
    </cpu_types>
    ...
  </cluster_level>
</cluster_levels>
----

Each specific cluster level has it's own subresource, identified by the
version itself:

[source]
----
GET /clusterlevels/3.6
----

This will return the details of that version:

[source,xml]
----
<cluster_level id="3.6" href="/clusterlevels/3.6">
  <cpu_types>
    <cpu_type>
      <name>Intel Conroe Family</name>
      <level>2</level>
      <architecture>x86_64</architecture>
    </cpu_type>
    ...
  </cpu_types>
  ...
</cluster_level>
----

=== Replaced `disks` with `diskattachments`

In version 3 of the API virtual machines and templates had a `disks`
collection containing all the information of the disks attached to them.
In version 4 of the API these `disks` collections have been removed and
replaced with a new `diskattachments` collection that will contain only
the references to the disk and the attributes that are specific of the
relationship between disks and the virtual machine or template that they
are attached to: `interface` and `bootable`.

To find what disks are attached to a virtual machine, for example, send
a request like this:

[source]
----
GET /vms/{vm:id}/diskattachments
----

That will return a response like this:

[source,xml]
----
<disk_attachments>
  <disk_attachment href="/vms/123/diskattachments/456" id="456">
    <bootable>false</bootable>
    <interface>virtio</interface>
    <disk href="/disks/456" id="456"/>
    <vm href="/vms/123" id="123"/>
  </disk_attachment>
  ...
<disk_attachments>
----

To find the rest of the details of the disk, follow the link provided.

Adding disks to a virtual machine or template uses the new
`disk_attachment` element as well:
request like this:

[source]
----
POST /vms/123/diskattachments
----

With the following body if the disk doesn't exist and you want to create
it:

[source,xml]
----
<disk_attachment>
  <bootable>false</bootable>
  <interface>virtio</interface>
  <disk>
    <description>My disk</description>
    <format>cow</format>
    <name>mydisk</name>
    <provisioned_size>1048576</provisioned_size>
    <storage_domains>
      <storage_domain>
        <name>mydata</name>
      </storage_domain>
    </storage_domains>
  </disk>
</disk_attachment>
----

Or with the following body if the disk already exists, and you just want
to attach it to the virtual machine:

[source,xml]
----
<disk_attachment>
  <bootable>false</bootable>
  <interface>virtio</interface>
  <disk id="456"/>
</disk_attachment>
----

Take into account that the `vm.disks` and `template.disks` attribtes
have `disk_attachments` for all usages. For example, when creating a
template the `vm.disks` element was used to indicate in which storage
domain to create the disks of the template. This usage has also been
replaced by `vm.disk_attachments`, so the request to creaate a template
with disks in specific storage domains will now look like this:

[source,xml]
----
<template>
  <name>mytemplate</name>
  <vm id="123">
    <disk_attachments>
      <disk_attachment>
        <disk id="456">
          <storage_domains>
            <storage_domain id="789"/>
          </storage_domains>
        </disk>
      </disk_attachment>
      ...
    </disk_attachments>
  </vm>
</template>
----

=== Use `iscsi_targets` element to discover unregistered storage

In version 3 of the API the operation to discover unregistered storage
domains used to receive a list of iSCSI targets, using multiple
`iscsi_target` elements:

[source]
----
POST /hosts/{host:id}/unregisteredstoragedomaindiscover
<action>
  <iscsi>
    <address>myiscsiserver</address>
  </iscsi>
  <iscsi_target>iqn.2016-07.com.example:mytarget1</iscsi_target>
  <iscsi_target>iqn.2016-07.com.example:mytarget2</iscsi_target>
</action>
----

In version 4 of the API all repeating elements, like `iscsi_target`
in this case, are wrapped with another element, `iscsi_targets` in
case. So the same request should now look like this:

[source]
----
POST /hosts/{host:id}/unregisteredstoragedomaindiscover
<action>
  <iscsi>
    <address>myiscsiserver</address>
  </iscsi>
  <iscsi_targets>
    <iscsi_target>iqn.2016-07.com.example:mytarget1</iscsi_target>
    <iscsi_target>iqn.2016-07.com.example:mytarget2</iscsi_target>
  </iscsi_targets>
</action>
----
