Exemple #1
0
    def validate(self, attrs):
        target_hostname_or_uuid = attrs.get('target_hostname_or_uuid', None)
        target_disk_id = attrs.get('target_disk_id', None)

        if target_hostname_or_uuid and not target_disk_id:
            err_msg = _(
                'This field is required when target_hostname_or_uuid is specified.'
            )
            self._errors['target_disk_id'] = s.ErrorList([err_msg])
            return attrs
        elif not target_hostname_or_uuid and target_disk_id:
            err_msg = _(
                'This field is required when target_disk_id is specified.')
            self._errors['target_hostname_or_uuid'] = s.ErrorList([err_msg])
            return attrs
        elif target_hostname_or_uuid and target_disk_id:
            try:
                self.target_vm = get_vm(self.request,
                                        target_hostname_or_uuid,
                                        exists_ok=True,
                                        noexists_fail=True,
                                        check_node_status=None)
            except ObjectNotFound as exc:
                self._errors['target_hostname_or_uuid'] = s.ErrorList(
                    [exc.detail])
            else:
                try:
                    self.target_vm_disk_id, self.target_vm_real_disk_id, self.target_vm_disk_zfs_filesystem = \
                        get_disk_id(self.request, self.target_vm, disk_id=target_disk_id)
                except InvalidInput as exc:
                    self._errors['target_disk_id'] = s.ErrorList([exc.detail])

        return attrs
Exemple #2
0
    def validate_VMS_IMAGE_VM(self, attrs, source):
        try:
            value = attrs[source]
        except KeyError:
            pass
        else:
            if value:
                try:
                    vm = get_vm(self.request,
                                value,
                                exists_ok=True,
                                noexists_fail=True,
                                dc_bound=False)
                except ObjectNotFound as exc:
                    raise s.ValidationError(exc.detail)
                else:
                    if vm.status not in (Vm.RUNNING, Vm.STOPPED):
                        raise s.ValidationError(
                            _('Invalid VM status; VM must be running or stopped.'
                              ))

                    if vm.ostype != Vm.SUNOS_ZONE:
                        raise s.ValidationError(
                            _('Invalid OS type; VM must be a SunOS Zone.'))

                    attrs[source] = vm.uuid

        return attrs
Exemple #3
0
def vm_define_nic_list(request, hostname_or_uuid, data=None):
    """
    List (:http:get:`GET </vm/(hostname_or_uuid)/define/nic>`) VM NIC definitions.

    .. http:get:: /vm/(hostname_or_uuid)/define/nic

        :DC-bound?:
            * |dc-yes|
        :Permissions:
            * |VmOwner|
        :Asynchronous?:
            * |async-no|
        :arg hostname_or_uuid: **required** - Server hostname or uuid
        :type hostname_or_uuid: string
        :arg data.active: Display currently active VM NIC definitions on compute node (default: false)
        :type data.active: boolean
        :status 200: SUCCESS
        :status 403: Forbidden
        :status 404: VM not found
    """
    vm = get_vm(request,
                hostname_or_uuid,
                exists_ok=True,
                noexists_fail=True,
                check_node_status=None)

    return VmDefineNicView(request).get(vm, None, None, many=True)
Exemple #4
0
def vm_define_revert(request, hostname_or_uuid, data=None):
    """
    Revert (:http:put:`PUT </vm/(hostname_or_uuid)/define/revert>`)
    whole VM definition (including disks and nics) to currently active VM definition on compute node.

    .. http:put:: /vm/(hostname_or_uuid)/define/revert

        .. warning:: The DNS settings for server's hostname and IP addresses won't be reverted.

        :DC-bound?:
            * |dc-yes|
        :Permissions:
            * |VmOwner|
        :Asynchronous?:
            * |async-no|
        :arg hostname_or_uuid: **required** - Server hostname or uuid
        :type hostname_or_uuid: string
        :status 200: SUCCESS
        :status 403: Forbidden
        :status 404: VM not found
        :status 409: VM has pending tasks
        :status 417: VM definition unchanged
        :status 423: VM is not operational / VM is not created / VM is locked or has slave VMs
    """
    vm = get_vm(request,
                hostname_or_uuid,
                exists_ok=True,
                noexists_fail=True,
                sr=('node', 'owner', 'template', 'slavevm'),
                check_node_status=None)

    return VmDefineRevertView(request).put(vm, data)
Exemple #5
0
 def __init__(self, request, hostname_or_uuid, data):
     super(VmSnapshotList, self).__init__(request)
     self.data = data
     self.vm = get_vm(request,
                      hostname_or_uuid,
                      exists_ok=True,
                      noexists_fail=True)
Exemple #6
0
 def __init__(self, request, hostname_or_uuid, data):
     super(VmMonitoringView, self).__init__(request)
     self.vm = get_vm(request,
                      hostname_or_uuid,
                      sr=('dc', ),
                      exists_ok=True,
                      noexists_fail=True)
     self.data = data
Exemple #7
0
 def __init__(self, request, hostname_or_uuid, data):
     super(VmMigrate, self).__init__(request)
     self.hostname_or_uuid = hostname_or_uuid
     self.data = data
     self.vm = get_vm(request,
                      hostname_or_uuid,
                      exists_ok=True,
                      noexists_fail=True)
Exemple #8
0
    def __init__(self, request, hostname_or_uuid, bkpname, data):
        super(VmBackup, self).__init__(request)

        if request.method == 'POST':  # Got bkpdef instead of bkpname
            vm = get_vm(request, hostname_or_uuid, exists_ok=True, noexists_fail=True)
            disk_id, real_disk_id, zfs_filesystem = get_disk_id(request, vm, data)
            # TODO: check indexes
            define = get_object(request, BackupDefine, {'name': bkpname, 'vm': vm, 'disk_id': real_disk_id},
                                exists_ok=True, noexists_fail=True, sr=('vm', 'node'))
            bkpname = define.generate_backup_name()
            bkp_get = {'name': bkpname, 'vm_hostname': vm.hostname, 'vm_disk_id': disk_id - 1, 'vm': vm}

        else:
            try:
                if 'hostname' in data:  # Force original hostname
                    raise ObjectNotFound
                # Only target VM status and backup node status are important
                vm = get_vm(request, hostname_or_uuid, exists_ok=True, noexists_fail=True, check_node_status=None)
            except ObjectNotFound:
                vm = None
                bkp_get = {'name': bkpname, 'vm_hostname': hostname_or_uuid}
            else:
                bkp_get = {'vm': vm, 'name': bkpname}

            define = None
            real_disk_id = None
            zfs_filesystem = None
            bkp_get = filter_disk_id(None, bkp_get, data, default=1)  # vm_disk_id instead of disk_id

        bkp_get['dc'] = request.dc
        # Backup instance
        self.bkp = bkp = get_object(request, Backup, bkp_get, sr=('node', 'define', 'vm'))
        self.disk_id = bkp.array_disk_id
        self.hostname = bkp.vm_hostname_real
        self.define = define
        self.real_disk_id = real_disk_id
        self.zfs_filesystem = zfs_filesystem
        self.vm = vm
        self.data = data

        # Task type (a = automatic, e = manual)
        if getattr(request, 'define_id', None):
            self.tt = TT_AUTO
        else:
            self.tt = TT_EXEC
Exemple #9
0
 def __init__(self, request, hostname_or_uuid, yyyymm, data):
     super(VmSLAView, self).__init__(request)
     self.vm = get_vm(request,
                      hostname_or_uuid,
                      sr=(),
                      exists_ok=True,
                      noexists_fail=True)
     self.yyyymm = yyyymm
     self.data = data
Exemple #10
0
    def __init__(self, request, hostname_or_uuid, data):
        super(VmManage, self).__init__(request)
        self.hostname_or_uuid = hostname_or_uuid
        self.data = data

        if request.method == 'GET':  # get() uses different methods for getting vm(s) object(s)
            self.vm = None
        else:
            self.vm = get_vm(request, hostname_or_uuid, exists_ok=True, noexists_fail=True)
Exemple #11
0
 def __init__(self, request, hostname_or_uuid, graph_type, data):
     super(VmHistoryView, self).__init__(request)
     self.vm = get_vm(request,
                      hostname_or_uuid,
                      sr=('dc', ),
                      exists_ok=True,
                      noexists_fail=True)
     self.graph_type = graph_type
     self.data = data
Exemple #12
0
    def __init__(self, request, hostname_or_uuid, action, data):
        super(VmStatus, self).__init__(request)
        self.hostname_or_uuid = hostname_or_uuid
        self.action = action
        self.data = data

        if hostname_or_uuid:
            self.vm = get_vm(request, hostname_or_uuid, exists_ok=True, noexists_fail=True, sr=('node', 'owner'))
        else:
            self.vm = get_vms(request, sr=('node', 'owner'), order_by=self.order_by)
Exemple #13
0
    def get(self, many=False):
        request = self.request
        active = self.data.get('active', False)
        sr = ['owner', 'node']

        if self.extended:
            ser_class = ExtendedVmSerializer
            extra = {'select': ExtendedVmSerializer.extra_select}
            sr.append('slavevm')
        else:
            ser_class = VmSerializer
            extra = None

        def set_active(x):
            # Do not revert owner and template, because it could generate lots of queries otherwise
            x.revert_active(revert_owner=False, revert_template=False)
            return x

        if many:
            if self.full or self.extended:
                vms = get_vms(request, sr=sr, order_by=self.order_by)

                if self.extended:
                    # noinspection PyArgumentList
                    vms = vms.extra(**extra).prefetch_related('tags')

                if active:
                    vms = [set_active(vm) for vm in vms]

                if vms:
                    res = ser_class(request, vms, many=True).data
                else:
                    res = []
            else:
                res = list(
                    get_vms(request,
                            order_by=self.order_by).values_list('hostname',
                                                                flat=True))

        else:
            vm = get_vm(request,
                        self.hostname_or_uuid,
                        exists_ok=True,
                        noexists_fail=True,
                        sr=sr,
                        extra=extra)

            if active:
                set_active(vm)

            res = ser_class(request, vm).data

        return SuccessTaskResponse(self.request, res)
Exemple #14
0
def vm_define_user(request, hostname_or_uuid, data=None):
    """
    vm_define alternative used only for updating hostname and alias.
    Used by non-admin VM owners from GUI.
    """
    vm = get_vm(request, hostname_or_uuid, sr=('owner', 'node', 'template', 'slavevm'), check_node_status=None,
                exists_ok=True, noexists_fail=True)
    allowed = {'hostname', 'alias', 'installed'}

    for i in data.keys():  # A copy of keys, because dict can change during iteration
        if i not in allowed:
            del data[i]

    return VmDefineView(request).put(vm, data)
Exemple #15
0
def vm_define_backup_list(request, hostname_or_uuid, data=None):
    """
    List (:http:get:`GET </vm/(hostname_or_uuid)/define/backup>`) all VM backup definitions.

    .. http:get:: /vm/(hostname_or_uuid)/define/backup

        :DC-bound?:
            * |dc-yes|
        :Permissions:
            * |VmOwner|
        :Asynchronous?:
            * |async-no|
        :arg hostname_or_uuid: **required** - Server hostname or uuid
        :type hostname_or_uuid: string
        :arg data.full: Return list of objects with all backup definition details (default: false)
        :type data.full: boolean
        :arg data.disk_id: Filter by disk number/ID
        :type data.disk_id: integer
        :arg data.extended: Include total number of backups for each backup definition (default: false)
        :type data.extended: boolean
        :arg data.order_by: :ref:`Available fields for sorting <order_by>`: ``name``, ``disk_id``, ``created`` \
(default: ``-created``)
        :type data.order_by: string
        :status 200: SUCCESS
        :status 403: Forbidden
        :status 404: VM not found
        :status 412: Invalid disk_id
    """
    vm = get_vm(request,
                hostname_or_uuid,
                exists_ok=True,
                noexists_fail=True,
                sr=('node', 'owner'))

    query_filter = {'vm': vm}
    query_filter = filter_disk_id(vm, query_filter, data)

    extra = output_extended_backup_count(request, data)
    # TODO: check indexes
    bkp_define = BackupDefine.objects.select_related('vm', 'vm__dc', 'node', 'zpool', 'periodic_task',
                                                     'periodic_task__crontab')\
                                     .filter(**query_filter).order_by(*BackupDefineView.get_order_by(data))

    if extra:
        bkp_define = bkp_define.extra(extra)

    return BackupDefineView(request, data=data).get(vm,
                                                    bkp_define,
                                                    many=True,
                                                    extended=bool(extra))
Exemple #16
0
    def __init__(self, request, hostname_or_uuid, repname, data):
        super(VmReplicaBaseView, self).__init__(request)
        self.repname = repname
        self.data = data
        self._success = False
        self.vm = vm = get_vm(request, hostname_or_uuid, exists_ok=True, noexists_fail=True,
                              check_node_status=self._check_node_status)

        if repname is None:  # Exclude migration ghost VMs
            self.slave_vm = SlaveVm.objects.select_related('vm', 'master_vm', 'vm__node')\
                                           .filter(master_vm=vm).exclude(name=u'').order_by('name')
        else:
            self.slave_vm = get_object(request, SlaveVm, {'master_vm': vm, 'name': repname},
                                       sr=('vm', 'master_vm', 'vm__node'),
                                       create_attrs={'_master_vm': vm, 'name': repname})
Exemple #17
0
 def __init__(self, request, hostname_or_uuid, snapname, data):
     super(VmSnapshot, self).__init__(request)
     self.data = data
     self.vm = vm = get_vm(
         request,
         hostname_or_uuid,
         exists_ok=True,
         noexists_fail=True,
         check_node_status=('POST',
                            'DELETE'))  # custom node check inside put()
     self.disk_id, real_disk_id, self.zfs_filesystem = get_disk_id(
         request, vm, data)
     self.snap = get_object(request,
                            Snapshot, {
                                'name': snapname,
                                'vm': vm,
                                'disk_id': real_disk_id
                            },
                            sr=('define', ))
Exemple #18
0
    def _init_vm(self):
        request, data, hostname_or_uuid = self.request, self.data, self.hostname_or_uuid
        bkp_filter = {'dc': request.dc}

        try:
            if 'hostname' in data:  # Force original hostname
                raise ObjectNotFound
            # No need to check vm.node.status; only backup node status is important
            vm = get_vm(request,
                        hostname_or_uuid,
                        exists_ok=True,
                        noexists_fail=True,
                        check_node_status=None)
        except ObjectNotFound:
            vm = None
            bkp_filter['vm_hostname'] = hostname_or_uuid
        else:
            bkp_filter['vm'] = vm

        self.vm = vm
        self.bkp_filter = bkp_filter
Exemple #19
0
def vm_define(request, hostname_or_uuid, data=None):
    """
    Show (:http:get:`GET </vm/(hostname_or_uuid)/define>`),
    create (:http:post:`POST </vm/(hostname_or_uuid)/define>`),
    change (:http:put:`PUT </vm/(hostname_or_uuid)/define>`) or
    delete (:http:delete:`DELETE </vm/(hostname_or_uuid)/define>`)
    a VM definition.

    .. http:get:: /vm/(hostname_or_uuid)/define

        :DC-bound?:
            * |dc-yes|
        :Permissions:
            * |VmOwner|
        :Asynchronous?:
            * |async-no|
        :arg hostname_or_uuid: **required** - Server hostname or uuid
        :type hostname_or_uuid: string
        :arg data.full: Display full VM definition (including disk and nic lists) (default: false)
        :type data.full: boolean
        :arg data.active: Display currently active VM definition on compute node (default: false)
        :type data.active: boolean
        :arg data.diff: Display differences between active VM definition on compute node and current configuration \
(default: false)
        :type data.diff: boolean
        :status 200: SUCCESS
        :status 403: Forbidden
        :status 404: VM not found

    .. http:post:: /vm/(hostname_or_uuid)/define

        :DC-bound?:
            * |dc-yes|
        :Permissions:
            * |Admin|
        :Asynchronous?:
            * |async-no|
        :arg hostname_or_uuid: **required** - Server hostname
        :type hostname_or_uuid: string
        :arg data.alias: Short server name (default: ``hostname``)
        :type data.alias: string
        :arg data.template: VM template name (default: null)
        :type data.template: string
        :arg data.ostype: Operating system type (1 - Linux VM, 2 - SunOS VM, 3 - BSD VM, 4 - Windows VM, \
5 - SunOS Zone, 6 - Linux Zone) (default: 1)
        :type data.ostype: integer
        :arg data.vcpus: **required** - Number of virtual CPUs inside VM (1 - 64)
        :type data.vcpus: integer
        :arg data.ram: **required** - Size of RAM inside VM (32 - 524288 MB)
        :type data.ram: integer
        :arg data.note: Text note visible to every user with access to this VM (default: "")
        :type data.note: string
        :arg data.owner: User that owns the VM (default: logged in user)
        :type data.owner: string
        :arg data.node: Name of the host system \
(default: null => will be chosen automatically just before the VM is created)
        :type data.node: string
        :arg data.tags: Custom VM tags (default: [])
        :type data.tags: array
        :arg data.monitored: Enable VM synchronization with monitoring system (default: true)
        :type data.monitored: boolean
        :arg data.monitored_internal: Enable VM synchronization with internal monitoring system \
(requires |SuperAdmin| permission) (default: true)
        :type data.monitored: boolean
        :arg data.installed: Mark the server as installed (default: false)
        :type data.installed: boolean
        :arg data.snapshot_limit_manual: Maximum number of manual snapshots for this VM (default: null [unlimited])
        :type data.snapshot_limit_manual: integer
        :arg data.snapshot_size_limit: Maximum size of all snapshots for this VM (default: null [unlimited])
        :type data.snapshot_size_limit: integer
        :arg data.zpool: The zpool used for the VM zone (default: zones)
        :type data.zpool: string
        :arg data.cpu_shares: Number of VM's CPU shares relative to other VMs (requires |SuperAdmin| permission) \
(default: 100)
        :type data.cpu_shares: integer
        :arg data.zfs_io_priority: IO throttle priority relative to other VMs (requires |SuperAdmin| permission) \
(default: 100)
        :type data.zfs_io_priority: integer
        :arg data.cpu_type: **KVM only**; Type of the virtual CPU exposed to the VM. One of qemu64, host \
(default: qemu64; except for Windows ``ostype`` where the default is host)
        :type data.cpu_type: string
        :arg data.vga: **KVM only**; VGA emulation driver. One of std, cirrus, vmware (default: std)
        :type data.vga: string
        :arg data.routes: Key-value object that maps destinations to gateways. \
Items will be set as static routes in the OS (SunOS Zone only, default: {})
        :type data.routes: object
        :arg data.monitoring_hostgroups: Custom VM monitoring hostgroups (default: [])
        :type data.monitoring_hostgroups: array
        :arg data.monitoring_templates: Custom VM monitoring templates (default: [])
        :type data.monitoring_templates: array
        :arg data.mdata: Customer metadata accessible from within the VM (key=value string pairs) (default: {})
        :type data.mdata: object
        :status 201: SUCCESS
        :status 400: FAILURE
        :status 403: Forbidden
        :status 406: VM already exists

    .. http:put:: /vm/(hostname_or_uuid)/define

        :DC-bound?:
            * |dc-yes|
        :Permissions:
            * |Admin|
        :Asynchronous?:
            * |async-no|
        :arg hostname_or_uuid: **required** - Server hostname or uuid
        :type hostname_or_uuid: string
        :arg data.alias: Short server name
        :type data.alias: string
        :arg data.template: VM template name
        :type data.template: string
        :arg data.vcpus: Number of virtual CPUs inside VM (1 - 64)
        :type data.vcpus: integer
        :arg data.ram: Size of RAM inside VM (32 - 524288 MB)
        :type data.ram: integer
        :arg data.note: Text note visible to every user with access to this VM
        :type data.note: string
        :arg data.owner: User that owns the VM
        :type data.owner: string
        :arg data.node: Name of the host system
        :type data.node: string
        :arg data.tags: Custom VM tags
        :type data.tags: array
        :arg data.monitored: Enable VM synchronization with monitoring system
        :type data.monitored: boolean
        :arg data.monitored_internal: Enable VM synchronization with internal monitoring system \
(requires |SuperAdmin| permission)
        :type data.monitored: boolean
        :arg data.installed: Mark the server as installed
        :type data.installed: boolean
        :arg data.snapshot_limit_manual: Maximum number of manual snapshots for this VM
        :type data.snapshot_limit_manual: integer
        :arg data.snapshot_size_limit: Maximum size of all snapshots for this VM
        :type data.snapshot_size_limit: integer
        :arg data.zpool: The zpool used for the VM zone
        :type data.zpool: string
        :arg data.cpu_shares: Number of VM's CPU shares relative to other VMs (requires |SuperAdmin| permission)
        :type data.cpu_shares: integer
        :arg data.zfs_io_priority: IO throttle priority relative to other VMs (requires |SuperAdmin| permission)
        :type data.zfs_io_priority: integer
        :arg data.cpu_type: **KVM only**; Type of the virtual CPU exposed to the VM. One of qemu64, host
        :type data.cpu_type: string
        :arg data.vga: **KVM only**; VGA emulation driver. One of std, cirrus, vmware
        :type data.vga: string
        :arg data.routes: Key-value object that maps destinations to gateways. \
Items will be set as static routes in the OS (SunOS Zone only)
        :type data.routes: object
        :arg data.monitoring_hostgroups: Custom VM monitoring hostgroups
        :type data.monitoring_hostgroups: array
        :arg data.monitoring_templates: Custom VM monitoring templates
        :type data.monitoring_templates: array
        :arg data.mdata: Customer metadata accessible from within the VM (key=value string pairs)
        :type data.mdata: object
        :status 200: SUCCESS
        :status 400: FAILURE
        :status 403: Forbidden
        :status 404: VM not found
        :status 423: VM is not operational / VM is locked or has slave VMs

    .. http:delete:: /vm/(hostname_or_uuid)/define

        :DC-bound?:
            * |dc-yes|
        :Permissions:
            * |Admin|
        :Asynchronous?:
            * |async-no|
        :arg hostname_or_uuid: **required** - Server hostname or uuid
        :type hostname_or_uuid: string
        :status 200: SUCCESS
        :status 400: FAILURE
        :status 403: Forbidden
        :status 404: VM not found
        :status 423: VM is not operational / VM is not notcreated / VM is locked or has slave VMs
    """
    vm = get_vm(request,
                hostname_or_uuid,
                sr=('owner', 'node', 'template', 'slavevm'),
                check_node_status=None,
                noexists_fail=False,
                exists_ok=False)

    return VmDefineView(request).response(vm,
                                          data,
                                          hostname_or_uuid=hostname_or_uuid)
Exemple #20
0
def vm_define_nic(request, hostname_or_uuid, nic_id=None, data=None):
    """
    Show (:http:get:`GET </vm/(hostname_or_uuid)/define/nic/(nic_id)>`),
    create (:http:post:`POST </vm/(hostname_or_uuid)/define/nic/(nic_id)>`),
    change (:http:put:`PUT </vm/(hostname_or_uuid)/define/nic/(nic_id)>`) or
    delete (:http:delete:`DELETE </vm/(hostname_or_uuid)/define/nic/(nic_id)>`)
    a VM NIC definition.

    .. http:get:: /vm/(hostname_or_uuid)/define/nic/(nic_id)

        :DC-bound?:
            * |dc-yes|
        :Permissions:
            * |VmOwner|
        :Asynchronous?:
            * |async-no|
        :arg hostname_or_uuid: **required** - Server hostname or uuid
        :type hostname_or_uuid: string
        :arg nic_id: **required** - NIC number/ID (1 - 6)
        :type nic_id: integer
        :arg data.active: Display currently active VM NIC definition on compute node (default: false)
        :type data.active: boolean
        :arg data.diff: Display differences between active VM definition on compute node and current configuration \
(default: false)
        :type data.diff: boolean
        :status 200: SUCCESS
        :status 403: Forbidden
        :status 404: VM not found
        :status 406: VM NIC out of range

    .. http:post:: /vm/(hostname_or_uuid)/define/nic/(nic_id)

        :DC-bound?:
            * |dc-yes|
        :Permissions:
            * |Admin|
        :Asynchronous?:
            * |async-no|
        :arg hostname_or_uuid: **required** - Server hostname or uuid
        :type hostname_or_uuid: string
        :arg nic_id: **required** - NIC number/ID (1 - 6)
        :type nic_id: integer
        :arg data.net: **required** - Name of a virtual network
        :type data.net: string
        :arg data.ip: Virtual NIC IPv4 address. Must be part of net (default: auto select)
        :type data.ip: string
        :arg data.model: Virtual NIC Model. One of virtio, e1000, rtl8139 (default: virtio)
        :type data.model: string
        :arg data.dns: Create a DNS A record for VM's FQDN? (default: true for first NIC, otherwise false)
        :type data.dns: boolean
        :arg data.use_net_dns: Inherit DNS resolvers from network's resolvers setting (default: false)
        :type data.use_net_dns: boolean
        :arg data.mac: Virtual NIC MAC address (default: auto-generated)
        :type data.mac: string
        :arg data.primary: Use this NICs gateway as VM default gateway (default: true for first NIC, otherwise false)
        :type data.primary: boolean
        :arg data.allow_dhcp_spoofing: Allow packets required for DHCP server (requires |SuperAdmin| permission) \
(default: false)
        :type data.allow_dhcp_spoofing: boolean
        :arg data.allow_ip_spoofing: Allow sending and receiving packets for IP addresses other \
than specified in ``ip`` (requires |SuperAdmin| permission) (default: false)
        :type data.allow_ip_spoofing: boolean
        :arg data.allow_mac_spoofing: Allow sending packets with MAC addresses other than specified in ``mac`` \
(requires |SuperAdmin| permission) (default: false)
        :type data.allow_mac_spoofing: boolean
        :arg data.allow_restricted_traffic: Allow sending packets that are not IPv4, IPv6, or ARP \
(requires |SuperAdmin| permission) (default: false)
        :type data.allow_restricted_traffic: boolean
        :arg data.allow_unfiltered_promisc: Allow VM to have multiple MAC addresses. Use with caution! \
(requires |SuperAdmin| permission) (default: false)
        :type data.allow_unfiltered_promisc: boolean
        :arg data.allowed_ips: List of additional IP addresses that can be used by this VM's NIC and also by \
other VMs. Useful for floating/shared IPs (default: [])
        :type data.allowed_ips: array
        :arg data.monitoring: Use this NIC's IP address for external monitoring \
(default: true for first NIC, otherwise false)
        :type data.monitoring: boolean
        :arg data.set_gateway: Whether to set gateway from network (``data.net``) settings (default: true)
        :type data.set_gateway: boolean
        :status 201: SUCCESS
        :status 400: FAILURE
        :status 403: Forbidden
        :status 404: VM not found
        :status 406: VM NIC out of range / VM NIC already exists
        :status 423: VM is not operational / VM is locked or has slave VMs

    .. http:put:: /vm/(hostname_or_uuid)/define/nic/(nic_id)

        :DC-bound?:
            * |dc-yes|
        :Permissions:
            * |Admin|
        :Asynchronous?:
            * |async-no|
        :arg hostname_or_uuid: **required** - Server hostname or uuid
        :type hostname_or_uuid: string
        :arg nic_id: **required** - NIC number/ID (1 - 6)
        :type nic_id: integer
        :arg data.net: Name of a virtual network
        :type data.net: string
        :arg data.ip: Virtual NIC IPv4 address
        :type data.ip: string
        :arg data.model: Virtual NIC Model. One of virtio, e1000, rtl8139
        :type data.model: string
        :arg data.dns: Create a DNS A record for VM's FQDN?
        :type data.dns: boolean
        :arg data.use_net_dns: Inherit DNS resolvers from network's resolvers setting
        :type data.use_net_dns: boolean
        :arg data.mac: Virtual NIC MAC address
        :type data.mac: string
        :arg data.primary: Use this NICs gateway as VM default gateway
        :type data.primary: boolean
        :arg data.allow_dhcp_spoofing: Allow packets required for DHCP server \
(requires |SuperAdmin| permission)
        :type data.allow_dhcp_spoofing: boolean
        :arg data.allow_ip_spoofing: Allow sending and receiving packets for IP addresses other \
than specified in ``ip`` (requires |SuperAdmin| permission)
        :type data.allow_ip_spoofing: boolean
        :arg data.allow_mac_spoofing: Allow sending packets with MAC addresses other than specified in ``mac`` \
(requires |SuperAdmin| permission)
        :type data.allow_mac_spoofing: boolean
        :arg data.allow_restricted_traffic: Allow sending packets that are not IPv4, IPv6, or ARP \
(requires |SuperAdmin| permission)
        :type data.allow_restricted_traffic: boolean
        :arg data.allow_unfiltered_promisc: Allow VM to have multiple MAC addresses. Use with caution! \
(requires |SuperAdmin| permission)
        :type data.allow_unfiltered_promisc: boolean
        :arg data.allowed_ips: List of additional IP addresses that can be used by this VM's NIC and also by \
other VMs. Useful for floating/shared IPs
        :type data.allowed_ips: array
        :arg data.monitoring: Use this NIC's IP address for external monitoring
        :type data.monitoring: boolean
        :arg data.set_gateway: Whether to set gateway from network (``data.net``) settings
        :type data.set_gateway: boolean
        :status 200: SUCCESS
        :status 400: FAILURE
        :status 403: Forbidden
        :status 404: VM not found
        :status 406: VM NIC out of range
        :status 423: VM is not operational / VM is locked or has slave VMs

    .. http:delete:: /vm/(hostname_or_uuid)/define/nic/(nic_id)

        :DC-bound?:
            * |dc-yes|
        :Permissions:
            * |Admin|
        :Asynchronous?:
            * |async-no|
        :arg hostname_or_uuid: **required** - Server hostname or uuid
        :type hostname_or_uuid: string
        :arg nic_id: **required** - NIC number/ID (1 - 6)
        :type nic_id: integer
        :status 200: SUCCESS
        :status 400: FAILURE
        :status 403: Forbidden
        :status 404: VM not found
        :status 406: VM NIC out of range
        :status 423: VM is not operational / VM is locked or has slave VMs

    """
    vm = get_vm(request,
                hostname_or_uuid,
                exists_ok=True,
                noexists_fail=True,
                sr=('node', 'owner', 'template', 'slavevm'),
                check_node_status=None)

    try:
        nic_id = int(nic_id) - 1
    except ValueError:
        raise BadRequest

    return VmDefineNicView(request).response(vm, nic_id, data)
Exemple #21
0
def vm_define_disk(request, hostname_or_uuid, disk_id=None, data=None):
    """
    Show (:http:get:`GET </vm/(hostname_or_uuid)/define/disk/(disk_id)>`),
    create (:http:post:`POST </vm/(hostname_or_uuid)/define/disk/(disk_id)>`),
    change (:http:put:`PUT </vm/(hostname_or_uuid)/define/disk/(disk_id)>`) or
    delete (:http:delete:`DELETE </vm/(hostname_or_uuid)/define/disk/(disk_id)>`)
    a VM disk definition.

    .. http:get:: /vm/(hostname_or_uuid)/define/disk/(disk_id)

        :DC-bound?:
            * |dc-yes|
        :Permissions:
            * |VmOwner|
        :Asynchronous?:
            * |async-no|
        :arg hostname_or_uuid: **required** - Server hostname or uuid
        :type hostname_or_uuid: string
        :arg disk_id: **required** - Disk number/ID (1 - 2)
        :type disk_id: integer
        :arg data.active: Display currently active VM disk definition on compute node (default: false)
        :type data.active: boolean
        :arg data.diff: Display differences between active VM definition on compute node and current configuration \
(default: false)
        :type data.diff: boolean
        :status 200: SUCCESS
        :status 403: Forbidden
        :status 404: VM not found
        :status 406: VM disk out of range

    .. http:post:: /vm/(hostname_or_uuid)/define/disk/(disk_id)

        :DC-bound?:
            * |dc-yes|
        :Permissions:
            * |Admin|
        :Asynchronous?:
            * |async-no|
        :arg hostname_or_uuid: **required** - Server hostname or uuid
        :type hostname_or_uuid: string
        :arg disk_id: **required** - Disk number/ID (1 - 2)
        :type disk_id: integer
        :arg data.size: **required** (if not specified in image) - Disk size (1 - 268435456 MB)
        :type data.size: integer
        :arg data.image: **required** (if size is not specified) - Disk image name
        :type data.image: string
        :arg data.model: Disk driver. One of virtio, ide, scsi (default: virtio)
        :type data.model: string
        :arg data.block_size: Block size for this disk (default: depends on OS Type)
        :type data.block_size: integer
        :arg data.compression: Disk compression algorithm. One of off, lzjb, gzip, gzip-N, zle, lz4 (default: off)
        :type data.compression: string
        :arg data.zpool: The zpool in which to create the disk (default: ``vm.zpool`` [zones])
        :type data.zpool: string
        :arg data.boot: Whether this disk should be bootable (default: true for first disk, otherwise false)
        :type data.boot: boolean
        :arg data.refreservation: Minimum amount of space in MB reserved for this disk (KVM only, default: ``size``)
        :type data.refreservation: integer
        :arg data.image_tags_inherit: Whether to update VM tags from image tags (default: true)
        :type data.image_tags_inherit: boolean
        :status 201: SUCCESS
        :status 400: FAILURE
        :status 403: Forbidden
        :status 404: VM not found
        :status 406: VM disk out of range / VM disk already exists
        :status 423: VM is not operational / VM is locked or has slave VMs

    .. http:put:: /vm/(hostname_or_uuid)/define/disk/(disk_id)

        :DC-bound?:
            * |dc-yes|
        :Permissions:
            * |Admin|
        :Asynchronous?:
            * |async-no|
        :arg hostname_or_uuid: **required** - Server hostname or uuid
        :type hostname_or_uuid: string
        :arg disk_id: **required** - Disk number/ID (1 - 2)
        :type disk_id: integer
        :arg data.size: Disk size (1 - 268435456 MB)
        :type data.size: integer
        :arg data.model: Disk driver. One of virtio, ide, scsi
        :type data.model: string
        :arg data.block_size: Block size for this disk
        :type data.block_size: integer
        :arg data.compression: Disk compression algorithm. One of off, lzjb, gzip, gzip-N, zle, lz4
        :type data.compression: string
        :arg data.zpool: The zpool in which to create the disk
        :type data.zpool: string
        :arg data.boot: Whether this disk should be bootable
        :type data.boot: boolean
        :arg data.refreservation: Minimum amount of space in MB reserved for this disk (KVM only)
        :type data.refreservation: integer
        :arg data.image_tags_inherit: Whether to update VM tags from image tags (default: true)
        :type data.image_tags_inherit: boolean
        :status 200: SUCCESS
        :status 400: FAILURE
        :status 403: Forbidden
        :status 404: VM not found
        :status 406: VM disk out of range
        :status 423: VM is not operational / VM is locked or has slave VMs

    .. http:delete:: /vm/(hostname_or_uuid)/define/disk/(disk_id)

        :DC-bound?:
            * |dc-yes|
        :Permissions:
            * |Admin|
        :Asynchronous?:
            * |async-no|
        :arg hostname_or_uuid: **required** - Server hostname or uuid
        :type hostname_or_uuid: string
        :arg disk_id: **required** - Disk number/ID (1 - 2)
        :type disk_id: integer
        :arg data.image_tags_inherit: Whether to update VM tags from image tags (default: true)
        :type data.image_tags_inherit: boolean
        :status 200: SUCCESS
        :status 400: FAILURE
        :status 403: Forbidden
        :status 404: VM not found
        :status 406: VM disk out of range
        :status 423: VM is not operational / VM is locked or has slave VMs

    """
    vm = get_vm(request,
                hostname_or_uuid,
                exists_ok=True,
                noexists_fail=True,
                sr=('node', 'owner', 'template', 'slavevm'),
                check_node_status=None)

    try:
        disk_id = int(disk_id) - 1
    except ValueError:
        raise BadRequest

    return VmDefineDiskView(request).response(vm, disk_id, data)
Exemple #22
0
    def put(self):
        if 'note' in self.data:  # Changing backup note instead of restore (not logging!)
            return self.save_note()

        ser = BackupRestoreSerializer(data=self.data)
        if not ser.is_valid():
            return FailureTaskResponse(self.request, ser.errors)

        self._check_bkp()
        self._check_bkp_node()

        # Prepare vm for restore
        request, bkp = self.request, self.bkp

        vm = get_vm(request,
                    ser.data['target_hostname_or_uuid'],
                    exists_ok=True,
                    noexists_fail=True,
                    check_node_status=None)

        if vm.node.status not in vm.node.STATUS_OPERATIONAL:
            raise NodeIsNotOperational

        if vm.locked:
            raise VmIsLocked

        if not vm.has_compatible_brand(bkp.vm_brand):
            raise PreconditionRequired('VM brand mismatch')

        disk_id, real_disk_id, zfs_filesystem = get_disk_id(
            request, vm, self.data, key='target_disk_id', default=None)
        tgt_disk = vm.json_active_get_disks()[disk_id - 1]

        if tgt_disk['size'] != bkp.disk_size:
            raise PreconditionRequired('Disk size mismatch')

        target_ns = vm.get_node_storage(real_disk_id)
        # The backup is first restored to a temporary dataset, so it is required to have as much free space
        # as the backup size (which we don't have -> so we use the backup disk size [pessimism])
        if bkp.disk_size > target_ns.storage.size_free:
            raise PreconditionRequired(
                'Not enough free space on target storage')

        if not ser.data['force'] and Snapshot.objects.only('id').filter(
                vm=vm, disk_id=real_disk_id).exists():
            raise ExpectationFailed('VM has snapshots')

        if vm.status != vm.STOPPED:
            raise VmIsNotOperational(_('VM is not stopped'))

        if vm.tasks:
            raise VmHasPendingTasks

        self.msg = LOG_BKP_UPDATE
        self.obj = vm
        # Cache apiview and detail
        # noinspection PyUnusedLocal
        apiview = self.apiview  # noqa: F841
        # noinspection PyUnusedLocal
        detail = self.detail  # noqa: F841
        self._detail_ += ", target_hostname='%s', target_disk_id=%s" % (
            vm.hostname, disk_id)
        self._apiview_['target_hostname'] = vm.hostname
        self._apiview_['target_disk_id'] = disk_id
        self._apiview_['force'] = ser.data['force']

        if bkp.vm:
            self._apiview_['source_hostname'] = bkp.vm.hostname
        else:
            self._apiview_['source_hostname'] = ''

        vm.set_notready()

        if self.execute(get_backup_cmd('restore',
                                       bkp,
                                       zfs_filesystem=zfs_filesystem,
                                       vm=vm),
                        lock=self.LOCK % (vm.uuid, disk_id)):
            bkp.save_status(bkp.RESTORE)
            return self.task_response

        vm.revert_notready()
        return self.error_response
Exemple #23
0
def vm_define_snapshot(request, hostname_or_uuid, snapdef, data=None):
    """
    Show (:http:get:`GET </vm/(hostname_or_uuid)/define/snapshot/(snapdef)>`),
    create (:http:post:`POST </vm/(hostname_or_uuid)/define/snapshot/(snapdef)>`),
    remove (:http:delete:`DELETE </vm/(hostname_or_uuid)/define/snapshot/(snapdef)>`) or
    update (:http:put:`PUT </vm/(hostname_or_uuid)/define/snapshot/(snapdef)>`)
    a VM snapshot definition and schedule.

    .. http:get:: /vm/(hostname_or_uuid)/define/snapshot/(snapdef)

        :DC-bound?:
            * |dc-yes|
        :Permissions:
            * |VmOwner|
        :Asynchronous?:
            * |async-no|
        :arg hostname_or_uuid: **required** - Server hostname or uuid
        :type hostname_or_uuid: string
        :arg snapdef: **required** - Snapshot definition name
        :type snapdef: string
        :arg data.disk_id: **required** - Disk number/ID (default: 1)
        :type data.disk_id: integer
        :arg data.extended: Include total number of snapshots (default: false)
        :type data.extended: boolean
        :status 200: SUCCESS
        :status 403: Forbidden
        :status 404: VM not found / Snapshot definition not found
        :status 412: Invalid disk_id

    .. http:post:: /vm/(hostname_or_uuid)/define/snapshot/(snapdef)

        :DC-bound?:
            * |dc-yes|
        :Permissions:
            * |Admin|
        :Asynchronous?:
            * |async-no|
        :arg hostname_or_uuid: **required** - Server hostname or uuid
        :type hostname_or_uuid: string
        :arg snapdef: **required** - Snapshot definition name (predefined: hourly, daily, weekly, monthly)
        :type snapdef: string
        :arg data.disk_id: **required** - Disk number/ID (default: 1)
        :type data.disk_id: integer
        :arg data.schedule: **required** - Schedule in UTC CRON format (e.g. 30 4 * * 6)
        :type data.schedule: string
        :arg data.retention: **required** - Maximum number of snapshots to keep
        :type data.retention: integer
        :arg data.active: Enable or disable snapshot schedule (default: true)
        :type data.active: boolean
        :arg data.desc: Snapshot definition description
        :type data.desc: string
        :arg data.fsfreeze: Whether to send filesystem freeze command to QEMU agent socket before \
creating snapshot (requires QEMU Guest Agent) (default: false)
        :type data.fsfreeze: boolean
        :status 200: SUCCESS
        :status 400: FAILURE
        :status 403: Forbidden
        :status 404: VM not found
        :status 406: Snapshot definition already exists
        :status 412: Invalid disk_id
        :status 423: Node is not operational / VM is not operational

    .. http:put:: /vm/(hostname_or_uuid)/define/snapshot/(snapdef)

        :DC-bound?:
            * |dc-yes|
        :Permissions:
            * |Admin|
        :Asynchronous?:
            * |async-no|
        :arg hostname_or_uuid: **required** - Server hostname or uuid
        :type hostname_or_uuid: string
        :arg snapdef: **required** - Snapshot definition name
        :type snapdef: string
        :arg data.disk_id: **required** - Disk number/ID (default: 1)
        :type data.disk_id: integer
        :arg data.schedule: Schedule in UTC CRON format (e.g. 30 4 * * 6)
        :type data.schedule: string
        :arg data.retention: Maximum number of snapshots to keep
        :type data.retention: integer
        :arg data.active: Enable or disable snapshot schedule
        :type data.active: boolean
        :arg data.desc: Snapshot definition description
        :type data.desc: string
        :status 200: SUCCESS
        :status 400: FAILURE
        :status 403: Forbidden
        :status 404: VM not found / Snapshot definition not found
        :status 412: Invalid disk_id
        :status 423: Node is not operational / VM is not operational

    .. http:delete:: /vm/(hostname_or_uuid)/define/snapshot/(snapdef)

        :DC-bound?:
            * |dc-yes|
        :Permissions:
            * |Admin|
        :Asynchronous?:
            * |async-no|
        :arg hostname_or_uuid: **required** - Server hostname or uuid
        :type hostname_or_uuid: string
        :arg snapdef: **required** - Snapshot definition name
        :type snapdef: string
        :arg data.disk_id: **required** - Disk number/ID (default: 1)
        :type data.disk_id: integer
        :status 200: SUCCESS
        :status 400: FAILURE
        :status 403: Forbidden
        :status 404: VM not found / Snapshot definition not found
        :status 412: Invalid disk_id
        :status 423: Node is not operational / VM is not operational

    """
    vm = get_vm(request, hostname_or_uuid, exists_ok=True, noexists_fail=True)

    disk_id, real_disk_id, zfs_filesystem = get_disk_id(request, vm, data)

    extra = output_extended_snap_count(request, data)

    define = get_object(request,
                        SnapshotDefine, {
                            'name': snapdef,
                            'vm': vm,
                            'disk_id': real_disk_id
                        },
                        sr=('vm', 'periodic_task', 'periodic_task__crontab'),
                        extra={'select': extra})

    return SnapshotDefineView(request,
                              data=data).response(vm,
                                                  define,
                                                  extended=bool(extra))
Exemple #24
0
def vm_define_backup(request, hostname_or_uuid, bkpdef, data=None):
    """
    Show (:http:get:`GET </vm/(hostname_or_uuid)/define/backup/(bkpdef)>`),
    create (:http:post:`POST </vm/(hostname_or_uuid)/define/backup/(bkpdef)>`),
    remove (:http:delete:`DELETE </vm/(hostname_or_uuid)/define/backup/(bkpdef)>`) or
    update (:http:put:`PUT </vm/(hostname_or_uuid)/define/backup/(bkpdef)>`)
    a VM backup definition and schedule.

    .. http:get:: /vm/(hostname_or_uuid)/define/backup/(bkpdef)

        :DC-bound?:
            * |dc-yes|
        :Permissions:
            * |VmOwner|
        :Asynchronous?:
            * |async-no|
        :arg hostname_or_uuid: **required** - Server hostname or uuid
        :type hostname_or_uuid: string
        :arg bkpdef: **required** - Backup definition name
        :type bkpdef: string
        :arg data.disk_id: **required** - Disk number/ID (default: 1)
        :type data.disk_id: integer
        :arg data.extended: Include total number of backups (default: false)
        :type data.extended: boolean
        :status 200: SUCCESS
        :status 403: Forbidden
        :status 404: VM not found / Backup definition not found
        :status 412: Invalid disk_id

    .. http:post:: /vm/(hostname_or_uuid)/define/backup/(bkpdef)

        :DC-bound?:
            * |dc-yes|
        :Permissions:
            * |Admin|
        :Asynchronous?:
            * |async-no|
        :arg hostname_or_uuid: **required** - Server hostname or uuid
        :type hostname_or_uuid: string
        :arg bkpdef: **required** - Backup definition name (predefined: hourly, daily, weekly, monthly)
        :type bkpdef: string
        :arg data.disk_id: **required** - Disk number/ID (default: 1)
        :type data.disk_id: integer
        :arg data.type: **required** - Backup type (1 - dataset, 2 - file) (default: 1)
        :type: data.type: integer
        :arg data.node: **required** - Name of the backup node
        :type data.node: string
        :arg data.zpool: **required** - The zpool used on the backup node (default: zones)
        :type data.zpool: string
        :arg data.schedule: **required** - Schedule in UTC CRON format (e.g. 30 4 * * 6)
        :type data.schedule: string
        :arg data.retention: **required** - Maximum number of backups to keep
        :type data.retention: integer
        :arg data.active: Enable or disable backup schedule (default: true)
        :type data.active: boolean
        :arg data.compression: Backup file compression algorithm (0 - none, 1 - gzip, 2 - bzip2) (default: 0)
        :type data.compression: integer
        :arg data.bwlimit: Transfer rate limit in bytes (default: null => no limit)
        :type data.bwlimit: integer
        :arg data.desc: Backup definition description
        :type data.desc: string
        :arg data.fsfreeze: Whether to send filesystem freeze command to QEMU agent socket before \
creating backup snapshot (requires QEMU Guest Agent) (default: false)
        :type data.fsfreeze: boolean
        :status 200: SUCCESS
        :status 400: FAILURE
        :status 403: Forbidden
        :status 404: VM not found
        :status 406: Backup definition already exists
        :status 412: Invalid disk_id
        :status 423: Node is not operational / VM is not operational

    .. http:put:: /vm/(hostname_or_uuid)/define/backup/(bkpdef)

        :DC-bound?:
            * |dc-yes|
        :Permissions:
            * |Admin|
        :Asynchronous?:
            * |async-no|
        :arg hostname_or_uuid: **required** - Server hostname or uuid
        :type hostname_or_uuid: string
        :arg bkpdef: **required** - Backup definition name
        :type bkpdef: string
        :arg data.disk_id: **required** - Disk number/ID (default: 1)
        :type data.disk_id: integer
        :arg data.schedule: Schedule in UTC CRON format (e.g. 30 4 * * 6)
        :type data.schedule: string
        :arg data.retention: Maximum number of backups to keep
        :type data.retention: integer
        :arg data.active: Enable or disable backup schedule
        :type data.active: boolean
        :arg data.compression: Backup file compression algorithm (0 - none, 1 - gzip, 2 - bzip2)
        :type data.compression: integer
        :arg data.bwlimit: Transfer rate limit in bytes
        :type data.bwlimit: integer
        :arg data.desc: Backup definition description
        :type data.desc: string
        :status 200: SUCCESS
        :status 400: FAILURE
        :status 403: Forbidden
        :status 404: VM not found / Backup definition not found
        :status 412: Invalid disk_id
        :status 423: Node is not operational / VM is not operational

    .. http:delete:: /vm/(hostname_or_uuid)/define/backup/(bkpdef)

        :DC-bound?:
            * |dc-yes|
        :Permissions:
            * |Admin|
        :Asynchronous?:
            * |async-no|
        :arg hostname_or_uuid: **required** - Server hostname or uuid
        :type hostname_or_uuid: string
        :arg bkpdef: **required** - Backup definition name
        :type bkpdef: string
        :arg data.disk_id: **required** - Disk number/ID (default: 1)
        :type data.disk_id: integer
        :status 200: SUCCESS
        :status 400: FAILURE
        :status 403: Forbidden
        :status 404: VM not found / Backup definition not found
        :status 412: Invalid disk_id
        :status 423: Node is not operational / VM is not operational

    """
    vm = get_vm(request, hostname_or_uuid, exists_ok=True, noexists_fail=True)

    disk_id, real_disk_id, zfs_filesystem = get_disk_id(request, vm, data)

    extra = output_extended_backup_count(request, data)

    define = get_object(request,
                        BackupDefine, {
                            'name': bkpdef,
                            'vm': vm,
                            'disk_id': real_disk_id
                        },
                        sr=('vm', 'vm__dc', 'node', 'periodic_task',
                            'periodic_task__crontab'),
                        extra={'select': extra})

    return BackupDefineView(request, data=data).response(vm,
                                                         define,
                                                         extended=bool(extra))
Exemple #25
0
def image_snapshot(request, hostname_or_uuid, snapname, name, data=None):
    """
    Create (:http:post:`POST </vm/(hostname_or_uuid)/snapshot/(snapname)/image/(name)>`)
    a server disk image from a disk snapshot.

    .. note:: A global image server (:http:put:`VMS_IMAGE_VM </dc/(dc)/settings>`) must be configured in the system.

    .. http:post:: /vm/(hostname_or_uuid)/snapshot/(snapname)/image/(name)

        :DC-bound?:
            * |dc-yes|
        :Permissions:
            * |ImageAdmin|
        :Asynchronous?:
            * |async-yes|
        :arg name: **required** - Server disk image name
        :type name: string
        :arg hostname_or_uuid: **required** - Server hostname or uuid
        :type hostname_or_uuid: string
        :arg snapname: **required** - Snapshot name
        :type snapname: string
        :arg data.disk_id: **required** - Disk number/ID (default: 1)
        :type data.disk_id: integer
        :arg data.alias: Short image name (default: ``name``)
        :type data.alias: string
        :arg data.access: Access type (1 - Public, 3 - Private, 4 - Deleted) (default: 3)
        :type data.access: integer
        :arg data.owner: User that owns the image (default: logged in user)
        :type data.owner: string
        :arg data.desc: Image description
        :type data.desc: string
        :arg data.version: Image version (default: 1.0)
        :type data.version: string
        :arg data.resize: Whether the image is able to resize the disk during an initial start or deploy process \
(default: false)
        :type data.resize: boolean
        :arg data.deploy: Whether the image is able to shut down the server after an initial start (default: false)
        :type data.deploy: boolean
        :status 200: SUCCESS
        :status 201: PENDING
        :status 400: FAILURE
        :status 403: Forbidden
        :status 404: VM not found
        :status 406: Image already exists
        :status 412: Invalid disk_id
        :status 423: Node is not operational / VM is not operational
        :status 417: Image status is not OK / VM snapshot status is not OK
        :status 428: Image server is not available
    """
    from api.utils.db import get_object
    from api.vm.utils import get_vm
    from api.vm.snapshot.utils import get_disk_id
    from vms.models import Snapshot

    vm = get_vm(request, hostname_or_uuid, exists_ok=True, noexists_fail=True)
    disk_id, real_disk_id, zfs_filesystem = get_disk_id(request, vm, data)
    snap = get_object(request,
                      Snapshot, {
                          'name': snapname,
                          'vm': vm,
                          'disk_id': real_disk_id
                      },
                      exists_ok=True,
                      noexists_fail=True)

    assert zfs_filesystem == snap.zfs_filesystem

    return ImageView(request, name, data).create(vm, snap)
Exemple #26
0
def vm_define(request, hostname_or_uuid, data=None):
    """
    Show (:http:get:`GET </vm/(hostname_or_uuid)/define>`),
    create (:http:post:`POST </vm/(hostname_or_uuid)/define>`),
    change (:http:put:`PUT </vm/(hostname_or_uuid)/define>`) or
    delete (:http:delete:`DELETE </vm/(hostname_or_uuid)/define>`)
    a VM definition.

    .. http:get:: /vm/(hostname_or_uuid)/define

        :DC-bound?:
            * |dc-yes|
        :Permissions:
            * |VmOwner|
        :Asynchronous?:
            * |async-no|
        :arg hostname_or_uuid: **required** - Server hostname or uuid
        :type hostname_or_uuid: string
        :arg data.full: Display full VM definition (including disk and nic lists) (default: false)
        :type data.full: boolean
        :arg data.active: Display currently active VM definition on compute node (default: false)
        :type data.active: boolean
        :arg data.diff: Display differences between active VM definition on compute node and current configuration \
(default: false)
        :type data.diff: boolean
        :status 200: SUCCESS
        :status 403: Forbidden
        :status 404: VM not found

    .. http:post:: /vm/(hostname_or_uuid)/define

        :DC-bound?:
            * |dc-yes|
        :Permissions:
            * |Admin|
        :Asynchronous?:
            * |async-no|
        :arg hostname_or_uuid: **required** - Server hostname
        :type hostname_or_uuid: string
        :arg data.alias: Short server name (default: ``hostname``)
        :type data.alias: string
        :arg data.template: VM template name (default: null)
        :type data.template: string
        :arg data.ostype: Operating system type (1 - Linux VM, 2 - SunOS VM, 3 - BSD VM, 4 - Windows VM, \
5 - SunOS Zone, 6 - Linux Zone) (default: 1)
        :type data.ostype: integer
        :arg data.vcpus: **required** - Number of virtual CPUs inside VM (1 - 1024); \
This number is used to calculate an internal compute node CPU limit for the VM (cpu_cap). \
When the :http:put:`VMS_VM_CPU_CAP_REQUIRED </dc/(dc)/settings>` DC setting is disabled, \
then the vcpus value can be 0, which will remove the compute node CPU limit entirely (SunOS and LX Zone only)
        :type data.vcpus: integer
        :arg data.ram: **required** - Size of RAM inside VM (1 - 1048576 MB)
        :type data.ram: integer
        :arg data.note: Text note visible to every user with access to this VM (default: "")
        :type data.note: string
        :arg data.owner: User that owns the VM (default: logged in user)
        :type data.owner: string
        :arg data.node: Name of the host system \
(default: null => will be chosen automatically just before the VM is created)
        :type data.node: string
        :arg data.tags: Custom VM tags (default: [])
        :type data.tags: array
        :arg data.monitored: Enable VM synchronization with monitoring system (default: true)
        :type data.monitored: boolean
        :arg data.monitored_internal: Enable VM synchronization with internal monitoring system \
(requires |SuperAdmin| permission) (default: true)
        :type data.monitored: boolean
        :arg data.installed: Mark the server as installed (default: false)
        :type data.installed: boolean
        :arg data.snapshot_limit_manual: Maximum number of manual snapshots for this VM (default: null [unlimited])
        :type data.snapshot_limit_manual: integer
        :arg data.snapshot_size_percent_limit: Maximum size of all snapshots for this VM relative to size of all \
defined VM disks. Ignored if ``snapshot_size_limit`` is defined (default: null [unlimited])
        :type data.snapshot_size_percent_limit: integer
        :arg data.snapshot_size_limit: Maximum absolute size of all snapshots for this VM in megabytes \
(default: null [unlimited])
        :type data.snapshot_size_limit: integer
        :arg data.zpool: The zpool used for the VM (default: zones)
        :type data.zpool: string
        :arg data.cpu_shares: Number of VM's CPU shares relative to other VMs (requires |SuperAdmin| permission) \
(default: 100)
        :type data.cpu_shares: integer
        :arg data.zfs_io_priority: IO throttle priority relative to other VMs (requires |SuperAdmin| permission) \
(default: 100)
        :type data.zfs_io_priority: integer
        :arg data.cpu_type: **KVM only**; Type of the virtual CPU exposed to the VM. One of qemu64, host \
(default: qemu64; except for Windows ``ostype`` where the default is host)
        :type data.cpu_type: string
        :arg data.vga: **KVM only**; VGA emulation driver. One of std, cirrus, vmware (default: std)
        :type data.vga: string
        :arg data.bootrom: **BHYVE only**; Default VM boot firmware. One of bios, uefi (default: bios). \
Only uefi mode supports VNC.
        :type data.bootrom: string
        :arg data.dns_domain: Search domain set in /etc/hosts (SunOS Zone only, default: domain part of ``hostname``)
        :type data.dns_domain: string
        :arg data.routes: Key-value object that maps destinations to gateways. \
Items will be set as static routes in the OS (SunOS Zone only, default: {})
        :type data.routes: object
        :arg data.monitoring_hostgroups: Custom VM monitoring hostgroups (default: [])
        :type data.monitoring_hostgroups: array
        :arg data.monitoring_templates: Custom VM monitoring templates (default: [])
        :type data.monitoring_templates: array
        :arg data.mdata: Customer metadata accessible from within the VM (key=value string pairs) (default: {})
        :type data.mdata: object
        :status 201: SUCCESS
        :status 400: FAILURE
        :status 403: Forbidden
        :status 406: VM already exists

    .. note:: The **cpu_cap** defines a percentage of a single compute node CPU that can be used by the VM. \
It is calculated automatically based on this formula: \
``(vcpus * VMS_VM_CPU_BURST_RATIO * 100) + VMS_VM_CPU_BURST_DEFAULT``, where \
*VMS_VM_CPU_BURST_RATIO* is by default 1.0 and \
*VMS_VM_CPU_BURST_DEFAULT* is by default 100 when ``vcpus > 1`` and 50 when ``vcpus == 1``.

    .. http:put:: /vm/(hostname_or_uuid)/define

        :DC-bound?:
            * |dc-yes|
        :Permissions:
            * |Admin|
        :Asynchronous?:
            * |async-no|
        :arg hostname_or_uuid: **required** - Server hostname or uuid
        :type hostname_or_uuid: string
        :arg data.alias: Short server name
        :type data.alias: string
        :arg data.template: VM template name
        :type data.template: string
        :arg data.vcpus: Number of virtual CPUs inside VM (1 - 1024); \
This number is used to calculate an internal compute node CPU limit for the VM (cpu_cap). \
When the :http:put:`VMS_VM_CPU_CAP_REQUIRED </dc/(dc)/settings>` DC setting is disabled, \
then the vcpus value can be 0, which will remove the compute node CPU limit entirely (SunOS and LX Zone only)
        :type data.vcpus: integer
        :arg data.ram: Size of RAM inside VM (1 - 1048576 MB)
        :type data.ram: integer
        :arg data.note: Text note visible to every user with access to this VM
        :type data.note: string
        :arg data.owner: User that owns the VM
        :type data.owner: string
        :arg data.node: Name of the host system
        :type data.node: string
        :arg data.tags: Custom VM tags
        :type data.tags: array
        :arg data.monitored: Enable VM synchronization with monitoring system
        :type data.monitored: boolean
        :arg data.monitored_internal: Enable VM synchronization with internal monitoring system \
(requires |SuperAdmin| permission)
        :type data.monitored: boolean
        :arg data.installed: Mark the server as installed
        :type data.installed: boolean
        :arg data.snapshot_limit_manual: Maximum number of manual snapshots for this VM
        :type data.snapshot_limit_manual: integer
        :type data.snapshot_limit_manual: integer
        :arg data.snapshot_size_percent_limit: Maximum size of all snapshots for this VM relative to size of all \
defined VM disks. Ignored if ``snapshot_size_limit`` is defined
        :arg data.snapshot_size_limit: Maximum absolute size of all snapshots for this VM in megabytes
        :type data.snapshot_size_limit: integer
        :arg data.zpool: The zpool used for the VM zone
        :type data.zpool: string
        :arg data.cpu_shares: Number of VM's CPU shares relative to other VMs (requires |SuperAdmin| permission)
        :type data.cpu_shares: integer
        :arg data.zfs_io_priority: IO throttle priority relative to other VMs (requires |SuperAdmin| permission)
        :type data.zfs_io_priority: integer
        :arg data.cpu_type: **KVM only**; Type of the virtual CPU exposed to the VM. One of qemu64, host
        :type data.cpu_type: string
        :arg data.vga: **KVM only**; VGA emulation driver. One of std, cirrus, vmware
        :type data.vga: string
        :arg data.bootrom: **BHYVE only**; Default VM boot firmware. One of bios, uefi (default: bios). \
Only uefi mode supports VNC.
        :type data.bootrom: string
        :arg data.dns_domain: Search domain set in /etc/hosts (SunOS Zone only)
        :type data.dns_domain: string
        :arg data.routes: Key-value object that maps destinations to gateways. \
Items will be set as static routes in the OS (SunOS Zone only)
        :type data.routes: object
        :arg data.monitoring_hostgroups: Custom VM monitoring hostgroups
        :type data.monitoring_hostgroups: array
        :arg data.monitoring_templates: Custom VM monitoring templates
        :type data.monitoring_templates: array
        :arg data.mdata: Customer metadata accessible from within the VM (key=value string pairs)
        :type data.mdata: object
        :status 200: SUCCESS
        :status 400: FAILURE
        :status 403: Forbidden
        :status 404: VM not found
        :status 409: VM has pending tasks
        :status 423: VM is not operational / VM is locked or has slave VMs

    .. http:delete:: /vm/(hostname_or_uuid)/define

        :DC-bound?:
            * |dc-yes|
        :Permissions:
            * |Admin|
        :Asynchronous?:
            * |async-no|
        :arg hostname_or_uuid: **required** - Server hostname or uuid
        :type hostname_or_uuid: string
        :status 200: SUCCESS
        :status 400: FAILURE
        :status 403: Forbidden
        :status 404: VM not found
        :status 409: VM has pending tasks
        :status 423: VM is not operational / VM is not notcreated / VM is locked or has slave VMs
    """
    vm = get_vm(request, hostname_or_uuid, sr=('owner', 'node', 'template', 'slavevm'), check_node_status=None,
                noexists_fail=False, exists_ok=False)

    return VmDefineView(request).response(vm, data, hostname_or_uuid=hostname_or_uuid)