コード例 #1
0
def restore_snapshot(module, vm_service, snapshots_service):
    changed = False
    snapshot_service = snapshots_service.snapshot_service(
        module.params['snapshot_id'])
    snapshot = get_entity(snapshot_service)
    if snapshot is None:
        raise Exception("Snapshot with id '%s' doesn't exist" %
                        module.params['snapshot_id'])

    if snapshot.snapshot_status != otypes.SnapshotStatus.IN_PREVIEW:
        if not module.check_mode:
            snapshot_service.restore(
                restore_memory=module.params.get('use_memory'), )
        changed = True
    else:
        if not module.check_mode:
            vm_service.commit_snapshot()
        changed = True

    if changed:
        wait(
            service=snapshot_service,
            condition=lambda snap: snap.snapshot_status == otypes.
            SnapshotStatus.OK,
            wait=module.params['wait'],
            timeout=module.params['timeout'],
        )
    return {
        'changed': changed,
        'id': snapshot.id if snapshot else None,
        'snapshot': get_dict_of_struct(snapshot),
    }
コード例 #2
0
def create_snapshot(module, vm_service, snapshots_service, connection):
    changed = False
    snapshot = get_entity(
        snapshots_service.snapshot_service(module.params['snapshot_id']))
    if snapshot is None:
        if not module.check_mode:
            disk_attachments_id = set(
                get_disk_attachment(
                    disk,
                    vm_service.disk_attachments_service().list(),
                    connection).id for disk in module.params.get(
                        'disks')) if module.params.get('disks') else None

            snapshot = snapshots_service.add(
                otypes.Snapshot(
                    description=module.params.get('description'),
                    persist_memorystate=module.params.get('use_memory'),
                    disk_attachments=[
                        otypes.DiskAttachment(disk=otypes.Disk(id=da_id))
                        for da_id in disk_attachments_id
                    ] if disk_attachments_id else None))
        changed = True
        wait(
            service=snapshots_service.snapshot_service(snapshot.id),
            condition=lambda snap: snap.snapshot_status == otypes.
            SnapshotStatus.OK,
            wait=module.params['wait'],
            timeout=module.params['timeout'],
        )
    return {
        'changed': changed,
        'id': snapshot.id,
        'snapshot': get_dict_of_struct(snapshot),
    }
コード例 #3
0
def control_state(host_module):
    host = host_module.search_entity()
    if host is None:
        return

    state = host_module._module.params['state']
    host_service = host_module._service.service(host.id)
    if failed_state(host):
        # In case host is in INSTALL_FAILED status, we can reinstall it:
        if hoststate.INSTALL_FAILED == host.status and state != 'reinstalled':
            raise Exception("Not possible to manage host '%s' in state '%s'." %
                            (host.name, host.status))
    elif host.status in [
            hoststate.REBOOT,
            hoststate.CONNECTING,
            hoststate.INITIALIZING,
            hoststate.INSTALLING,
            hoststate.INSTALLING_OS,
    ]:
        wait(
            service=host_service,
            condition=lambda host: host.status == hoststate.UP,
            fail_condition=failed_state,
        )
    elif host.status == hoststate.PREPARING_FOR_MAINTENANCE:
        wait(
            service=host_service,
            condition=lambda host: host.status == hoststate.MAINTENANCE,
            fail_condition=failed_state,
        )

    return host
コード例 #4
0
def main():
    argument_spec = ovirt_full_argument_spec(
        id=dict(default=None),
        state=dict(
            choices=['present', 'absent'],
            default='present',
        ),
        name=dict(required=True),
        template=dict(default=None),
        cluster=dict(default=None),
        description=dict(default=None),
        vm=dict(default=None, type='dict'),
        comment=dict(default=None),
        vm_per_user=dict(default=None, type='int'),
        prestarted=dict(default=None, type='int'),
        vm_count=dict(default=None, type='int'),
        type=dict(default=None, choices=['automatic', 'manual']),
    )
    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=True,
    )

    check_sdk(module)
    check_params(module)

    try:
        auth = module.params.pop('auth')
        connection = create_connection(auth)
        vm_pools_service = connection.system_service().vm_pools_service()
        vm_pools_module = VmPoolsModule(
            connection=connection,
            module=module,
            service=vm_pools_service,
        )

        state = module.params['state']
        if state == 'present':
            ret = vm_pools_module.create()

            # Wait for all VM pool VMs to be created:
            if module.params['wait']:
                vms_service = connection.system_service().vms_service()
                for vm in vms_service.list(search='pool=%s' %
                                           module.params['name']):
                    wait(
                        service=vms_service.service(vm.id),
                        condition=lambda vm: vm.status in
                        [otypes.VmStatus.DOWN, otypes.VmStatus.UP],
                        timeout=module.params['timeout'],
                    )

        elif state == 'absent':
            ret = vm_pools_module.remove()

        module.exit_json(**ret)
    except Exception as e:
        module.fail_json(msg=str(e), exception=traceback.format_exc())
    finally:
        connection.close(logout=auth.get('token') is None)
コード例 #5
0
def transfer(connection, module, direction, transfer_func):
    transfers_service = connection.system_service().image_transfers_service()
    transfer = transfers_service.add(
        otypes.ImageTransfer(
            image=otypes.Image(id=module.params['disk_id'], ),
            direction=direction,
        ))
    transfer_service = transfers_service.image_transfer_service(transfer.id)

    try:
        # After adding a new transfer for the disk, the transfer's status will be INITIALIZING.
        # Wait until the init phase is over. The actual transfer can start when its status is "Transferring".
        while transfer.phase == otypes.ImageTransferPhase.INITIALIZING:
            time.sleep(module.params['poll_interval'])
            transfer = transfer_service.get()

        proxy_url = urlparse(transfer.proxy_url)
        context = ssl.create_default_context()
        auth = module.params['auth']
        if auth.get('insecure'):
            context.check_hostname = False
            context.verify_mode = ssl.CERT_NONE
        elif auth.get('ca_file'):
            context.load_verify_locations(cafile=auth.get('ca_file'))

        proxy_connection = HTTPSConnection(
            proxy_url.hostname,
            proxy_url.port,
            context=context,
        )

        transfer_func(transfer_service, proxy_connection, proxy_url,
                      transfer.signed_ticket)
        return True
    finally:
        transfer_service.finalize()
        while transfer.phase in [
                otypes.ImageTransferPhase.TRANSFERRING,
                otypes.ImageTransferPhase.FINALIZING_SUCCESS,
        ]:
            time.sleep(module.params['poll_interval'])
            transfer = transfer_service.get()
        if transfer.phase in [
                otypes.ImageTransferPhase.UNKNOWN,
                otypes.ImageTransferPhase.FINISHED_FAILURE,
                otypes.ImageTransferPhase.FINALIZING_FAILURE,
                otypes.ImageTransferPhase.CANCELLED,
        ]:
            raise Exception(
                "Error occurred while uploading image. The transfer is in %s" %
                transfer.phase)
        if module.params.get('logical_unit'):
            disks_service = connection.system_service().disks_service()
            wait(
                service=disks_service.service(module.params['id']),
                condition=lambda d: d.status == otypes.DiskStatus.OK,
                wait=module.params['wait'],
                timeout=module.params['timeout'],
            )
コード例 #6
0
 def post_reinstall(self, host):
     wait(
         service=self._service.service(host.id),
         condition=lambda h: h.status != hoststate.MAINTENANCE,
         fail_condition=failed_state,
         wait=self.param('wait'),
         timeout=self.param('timeout'),
     )
コード例 #7
0
    def _maintenance(self, storage_domain):
        attached_sd_service = self._attached_sd_service(storage_domain)
        attached_sd = get_entity(attached_sd_service)

        if attached_sd and attached_sd.status != sdstate.MAINTENANCE:
            if not self._module.check_mode:
                attached_sd_service.deactivate()
            self.changed = True

            wait(
                service=attached_sd_service,
                condition=lambda sd: sd.status == sdstate.MAINTENANCE,
                wait=self.param('wait'),
                timeout=self.param('timeout'),
            )
コード例 #8
0
    def _unattach(self, storage_domain):
        attached_sd_service = self._attached_sd_service(storage_domain)
        attached_sd = get_entity(attached_sd_service)

        if attached_sd and attached_sd.status == sdstate.MAINTENANCE:
            if not self._module.check_mode:
                # Detach the storage domain:
                attached_sd_service.remove()
            self.changed = True
            # Wait until storage domain is detached:
            wait(
                service=attached_sd_service,
                condition=lambda sd: sd is None,
                wait=self.param('wait'),
                timeout=self.param('timeout'),
            )
コード例 #9
0
    def post_create_check(self, sd_id):
        storage_domain = self._service.service(sd_id).get()
        dc_name = self.param('data_center')
        if not dc_name:
            # Find the DC, where the storage resides:
            dc_name = self._find_attached_datacenter_name(storage_domain.name)
        self._service = self._attached_sds_service(dc_name)

        # If storage domain isn't attached, attach it:
        attached_sd_service = self._service.service(storage_domain.id)
        if get_entity(attached_sd_service) is None:
            self._service.add(otypes.StorageDomain(id=storage_domain.id, ), )
            self.changed = True
            # Wait until storage domain is in maintenance:
            wait(
                service=attached_sd_service,
                condition=lambda sd: sd.status == sdstate.ACTIVE,
                wait=self.param('wait'),
                timeout=self.param('timeout'),
            )
コード例 #10
0
def remove_snapshot(module, vm_service, snapshots_service, snapshot_id=None):
    changed = False
    if not snapshot_id:
        snapshot_id = module.params['snapshot_id']
    snapshot = get_entity(snapshots_service.snapshot_service(snapshot_id))

    if snapshot:
        snapshot_service = snapshots_service.snapshot_service(snapshot.id)
        if not module.check_mode:
            snapshot_service.remove()
        changed = True
        wait(
            service=snapshot_service,
            condition=lambda snapshot: snapshot is None,
            wait=module.params['wait'],
            timeout=module.params['timeout'],
        )

    return {
        'changed': changed,
        'id': snapshot.id if snapshot else None,
        'snapshot': get_dict_of_struct(snapshot),
    }
コード例 #11
0
def control_state(sd_module):
    sd = sd_module.search_entity()
    if sd is None:
        return

    sd_service = sd_module._service.service(sd.id)

    # In the case of no status returned, it's an attached storage domain.
    # Redetermine the corresponding service and entity:
    if sd.status is None:
        sd_service = sd_module._attached_sd_service(sd)
        sd = get_entity(sd_service)

    if sd.status == sdstate.LOCKED:
        wait(
            service=sd_service,
            condition=lambda sd: sd.status != sdstate.LOCKED,
            fail_condition=failed_state,
        )

    if failed_state(sd):
        raise Exception("Not possible to manage storage domain '%s'." %
                        sd.name)
    elif sd.status == sdstate.ACTIVATING:
        wait(
            service=sd_service,
            condition=lambda sd: sd.status == sdstate.ACTIVE,
            fail_condition=failed_state,
        )
    elif sd.status == sdstate.DETACHING:
        wait(
            service=sd_service,
            condition=lambda sd: sd.status == sdstate.UNATTACHED,
            fail_condition=failed_state,
        )
    elif sd.status == sdstate.PREPARING_FOR_MAINTENANCE:
        wait(
            service=sd_service,
            condition=lambda sd: sd.status == sdstate.MAINTENANCE,
            fail_condition=failed_state,
        )
コード例 #12
0
def main():
    argument_spec = ovirt_full_argument_spec(
        state=dict(choices=[
            'present', 'absent', 'attached', 'detached', 'exported', 'imported'
        ],
                   default='present'),
        id=dict(default=None),
        name=dict(default=None, aliases=['alias']),
        description=dict(default=None),
        vm_name=dict(default=None),
        vm_id=dict(default=None),
        size=dict(default=None),
        interface=dict(default=None, ),
        storage_domain=dict(default=None),
        storage_domains=dict(default=None, type='list'),
        profile=dict(default=None),
        quota_id=dict(default=None),
        format=dict(default='cow', choices=['raw', 'cow']),
        content_type=dict(default='data',
                          choices=[
                              'data', 'iso', 'hosted_engine',
                              'hosted_engine_sanlock',
                              'hosted_engine_metadata',
                              'hosted_engine_configuration'
                          ]),
        sparse=dict(default=None, type='bool'),
        bootable=dict(default=None, type='bool'),
        shareable=dict(default=None, type='bool'),
        logical_unit=dict(default=None, type='dict'),
        download_image_path=dict(default=None),
        upload_image_path=dict(default=None, aliases=['image_path']),
        force=dict(default=False, type='bool'),
        sparsify=dict(default=None, type='bool'),
        openstack_volume_type=dict(default=None),
        image_provider=dict(default=None),
        host=dict(default=None),
        wipe_after_delete=dict(type='bool', default=None),
        activate=dict(default=None, type='bool'),
    )
    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=True,
    )

    lun = module.params.get('logical_unit')
    host = module.params['host']
    # Fail when host is specified with the LUN id. Lun id is needed to identify
    # an existing disk if already available inthe environment.
    if (host and lun is None) or (host and lun.get("id") is None):
        module.fail_json(msg="Can not use parameter host ({0!s}) without "
                         "specifying the logical_unit id".format(host))

    check_sdk(module)
    check_params(module)

    try:
        disk = None
        state = module.params['state']
        auth = module.params.get('auth')
        connection = create_connection(auth)
        disks_service = connection.system_service().disks_service()
        disks_module = DisksModule(
            connection=connection,
            module=module,
            service=disks_service,
        )

        force_create = False
        vm_service = get_vm_service(connection, module)
        if lun:
            disk = _search_by_lun(disks_service, lun.get('id'))
        else:
            disk = disks_module.search_entity(
                search_params=searchable_attributes(module))
            if vm_service and disk:
                # If the VM don't exist in VMs disks, but still it's found it means it was found
                # for template with same name as VM, so we should force create the VM disk.
                force_create = disk.id not in [
                    a.disk.id
                    for a in vm_service.disk_attachments_service().list()
                    if a.disk
                ]

        ret = None
        # First take care of creating the VM, if needed:
        if state in ('present', 'detached', 'attached'):
            # Always activate disk when its being created
            if vm_service is not None and disk is None:
                module.params['activate'] = True
            ret = disks_module.create(
                entity=disk if not force_create else None,
                result_state=otypes.DiskStatus.OK if lun is None else None,
                fail_condition=lambda d: d.status == otypes.DiskStatus.ILLEGAL
                if lun is None else False,
                force_create=force_create,
                _wait=True if module.params['upload_image_path'] else
                module.params['wait'],
            )
            is_new_disk = ret['changed']
            ret['changed'] = ret[
                'changed'] or disks_module.update_storage_domains(ret['id'])
            # We need to pass ID to the module, so in case we want detach/attach disk
            # we have this ID specified to attach/detach method:
            module.params['id'] = ret['id']

            # Upload disk image in case it's new disk or force parameter is passed:
            if module.params['upload_image_path'] and (is_new_disk or
                                                       module.params['force']):
                if module.params['format'] == 'cow' and module.params[
                        'content_type'] == 'iso':
                    module.warn(
                        "To upload an ISO image 'format' parameter needs to be set to 'raw'."
                    )
                uploaded = upload_disk_image(connection, module)
                ret['changed'] = ret['changed'] or uploaded
            # Download disk image in case it's file don't exist or force parameter is passed:
            if (module.params['download_image_path'] and
                (not os.path.isfile(module.params['download_image_path'])
                 or module.params['force'])):
                downloaded = download_disk_image(connection, module)
                ret['changed'] = ret['changed'] or downloaded

            # Disk sparsify, only if disk is of image type:
            if not module.check_mode:
                disk = disks_service.disk_service(module.params['id']).get()
                if disk.storage_type == otypes.DiskStorageType.IMAGE:
                    ret = disks_module.action(
                        action='sparsify',
                        action_condition=lambda d: module.params['sparsify'],
                        wait_condition=lambda d: d.status == otypes.DiskStatus.
                        OK,
                    )

        # Export disk as image to glance domain
        elif state == 'exported':
            disk = disks_module.search_entity()
            if disk is None:
                module.fail_json(
                    msg="Can not export given disk '%s', it doesn't exist" %
                    module.params.get('name') or module.params.get('id'))
            if disk.storage_type == otypes.DiskStorageType.IMAGE:
                ret = disks_module.action(
                    action='export',
                    action_condition=lambda d: module.params['image_provider'],
                    wait_condition=lambda d: d.status == otypes.DiskStatus.OK,
                    storage_domain=otypes.StorageDomain(
                        name=module.params['image_provider']),
                )
        elif state == 'imported':
            glance_service = connection.system_service(
            ).openstack_image_providers_service()
            image_provider = search_by_name(glance_service,
                                            module.params['image_provider'])
            images_service = glance_service.service(
                image_provider.id).images_service()
            entity_id = get_id_by_name(images_service, module.params['name'])
            images_service.service(entity_id).import_(
                storage_domain=otypes.StorageDomain(
                    name=module.params['storage_domain'])
                if module.params['storage_domain'] else None,
                disk=otypes.Disk(name=module.params['name']),
                import_as_template=False,
            )
            # Wait for disk to appear in system:
            disk = disks_module.wait_for_import(
                condition=lambda t: t.status == otypes.DiskStatus.OK)
            ret = disks_module.create(result_state=otypes.DiskStatus.OK)
        elif state == 'absent':
            ret = disks_module.remove()

        # If VM was passed attach/detach disks to/from the VM:
        if vm_service:
            disk_attachments_service = vm_service.disk_attachments_service()
            disk_attachments_module = DiskAttachmentsModule(
                connection=connection,
                module=module,
                service=disk_attachments_service,
                changed=ret['changed'] if ret else False,
            )

            if state == 'present' or state == 'attached':
                ret = disk_attachments_module.create()
                if lun is None:
                    wait(
                        service=disk_attachments_service.service(ret['id']),
                        condition=lambda d: follow_link(connection, d.disk).
                        status == otypes.DiskStatus.OK,
                        wait=module.params['wait'],
                        timeout=module.params['timeout'],
                    )
            elif state == 'detached':
                ret = disk_attachments_module.remove()

        # When the host parameter is specified and the disk is not being
        # removed, refresh the information about the LUN.
        if state != 'absent' and host:
            hosts_service = connection.system_service().hosts_service()
            host_id = get_id_by_name(hosts_service, host)
            disks_service.disk_service(disk.id).refresh_lun(
                otypes.Host(id=host_id))

        module.exit_json(**ret)
    except Exception as e:
        module.fail_json(msg=str(e), exception=traceback.format_exc())
    finally:
        connection.close(logout=auth.get('token') is None)