Example #1
0
def stopWebsockify(cu):
    logger.info('Acabando la conexión de WebSockify')
    pid = request.json['pid']
    kill_process(pid)
    global startedWebsockify
    startedWebsockify = False
    return json_response()
Example #2
0
def get_all_domains(cu):
    logger.info('Obteniendo dominios')
    try:
        conn = libvirt.open(app.config['LOCAL_QEMU_URI'])
        domains = conn.listAllDomains()
        domains_list = list()
        for dom in domains:
            is_active = True if dom.isActive() == 1 else False
            uuid = dom.UUIDString()
            name = dom.name()
            os_type = dom.OSType()
            total_memory = round(dom.info()[1] / 1024, 2)  # KB to MB
            used_memory = "-" if not is_active else round(
                dom.info()[2] / 1024, 2)  # KB to MB
            memory = dict(total=total_memory, used=used_memory)
            vcpus = dom.info()[3]
            state = dom.info()[0]
            vnc_port = get_vnc_port(dom)

            domains_list.append(
                dict(uuid=uuid,
                     name=name,
                     is_active=is_active,
                     os_type=os_type,
                     memory=memory,
                     vcpus=vcpus,
                     state=state,
                     vnc_port=vnc_port))
        conn.close()
        return json_response(data=domains_list)
    except Exception as e:
        logger.error('No se pudo obtener los dominios: %s', str(e))
        return json_response(status=500)
Example #3
0
def get_hosts(cu):
    logger.info('Obteniendo los hosts')
    try:
        hosts = Host.get()
        return json_response(data=[h.to_dict() for h in hosts])
    except Exception as e:
        logger.error('No se han podido obtener los hosts: %s', str(e))
        return json_response(status=500)
Example #4
0
def get_settings(cu):
    logger.info("Obteniendo parámetros")
    try:
        parameters = models.Config.get()
        return json_response(parameters)
    except Exception as e:
        logger.error('Error obteniendo la configuración: %s', e)
        return json_response(status=500)
def get_templates(cu):
    logger.info('Obteniendo plantillas')
    try:
        templates = Template.get()
        data = [t.to_dict() for t in templates]
        return json_response(data=data)
    except Exception as e:
        logger.error('No se pudo obtener las plantillas: %s', str(e))
        return json_response(status=500)
Example #6
0
def add_host(cu):
    logger.info('Añadiendo host')
    try:
        host = Host(request.json)
        host.save()
        return json_response()
    except Exception as e:
        logger.error('No se ha podido añadir el host: %s', str(e))
        return json_response(status=500)
Example #7
0
def get_labs(cu):
    logger.info('Obteniendo laboratorios')
    try:
        labs = Lab.get()
        data = [l.to_dict() for l in labs]
        return json_response(data=data)
    except Exception as e:
        logger.error('No se pudo obtener los laboratorios: %s', str(e))
        return json_response(status=500)
Example #8
0
def get_hosts(cu, lab_uuid):
    logger.info('Obteniendo los hosts del laboratorio %s', lab_uuid)
    try:
        lab = Lab.get(lab_uuid)
        hosts = lab.hosts
        return json_response(data=[h.to_dict() for h in hosts])
    except Exception as e:
        logger.error('No se han podido obtener los hosts: %s', str(e))
        return json_response(status=500)
Example #9
0
def delete_host(cu, host_uuid):
    logger.info('Eliminando host %s', host_uuid)
    try:
        host = Host.get(host_uuid)
        Host.delete(host)
        return json_response()
    except Exception as e:
        logger.error('No se ha podido eliminar el host %s: %s', host_uuid,
                     str(e))
def clone_template(cu, template_uuid):
    logger.info('Desplegando plantilla')
    try:
        template = Template.get(template_uuid).to_dict()
        domain_name = request.json['domain_name']
        lab_uuid = request.json['lab_uuid']

        lab = Lab.get(lab_uuid)
        hosts = lab.hosts

        if hosts.__len__() == 0:
            logger.error('El laboratorio no tiene ningún host asociado')
            return json_response(status=500)

        cmd = [
            'virt-clone', '--connect', app.config['LOCAL_QEMU_URI'],
            '--original-xml', template['xml_path'], '--name', domain_name
        ]

        for count in range(template['images_path'].__len__()):
            cmd.append('--file')
            cmd.append(app.config['DOMAIN_IMAGES_DIR'] + domain_name +
                       '-disk' + str(count) + '.qcow2')

        ssh = paramiko.SSHClient()
        # Surrounds 'known_hosts' error
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        errors = list()
        for h in hosts:
            host = h.ip_address
            username = h.conn_user
            try:
                # NO PASSWORD!! Server SSH key is previously distributed among lab PCs
                ssh.connect(hostname=host.compressed,
                            username=username,
                            timeout=4)
                ssh_stdin, ssh_stdout, ssh_stderr = ssh.exec_command(
                    ' '.join(cmd))
                errors = [b.rstrip() for b in ssh_stderr.readlines()]
                if len(errors) > 0:
                    logger.error(
                        'No se pudo desplegar la plantilla en el host %s (%s)',
                        h.code, h.ip_address.compressed)
                    logger.error(e for e in errors)
            except Exception as e:
                logger.error(
                    'No se pudo desplegar la plantilla en el host %s (%s): %s',
                    h.code, h.ip_address.compressed, str(e))
                errors = True
            finally:
                ssh.close()
        if errors or len(errors) > 0:
            return json_response(status=500)
        return json_response()
    except Exception as e:
        logger.error('No se pudo desplegar la plantilla: %s', str(e))
        return json_response(status=500)
Example #11
0
def clear_logs(cu):
    logger.info('Limpiando el fichero de logs')
    try:
        logs_file = open('dvls.log', 'w')
        logs_file.truncate()
        logs_file.close()
        return json_response()
    except Exception as e:
        logger.error('No se ha podido limpiar el fichero de logs: %s', str(e))
        return json_response(status=500)
Example #12
0
def delete_lab(cu, lab_uuid):
    logger.info('Eliminando laboratorio')
    try:
        lab = Lab.get(lab_uuid)
        Lab.delete(lab)
        return json_response()
    except Exception as e:
        logger.error('No se pudo eliminar el laboratorio seleccionado: %s',
                     str(e))
        return json_response(status=500)
Example #13
0
def update_lab(cu, lab_uuid):
    logger.info('Actualizando laboratorio %s', lab_uuid)
    try:
        lab = Lab.get(lab_uuid)
        lab.update(request.json)
        return json_response()
    except Exception as e:
        logger.error('No se pudo actualizar el laboratorio %s: %s', lab_uuid,
                     e)
        return json_response(status=500)
Example #14
0
def get_dashboard():
    logger.info('Cargando dashboard')
    try:
        conn = libvirt.open(app.config['LOCAL_QEMU_URI'])
        host_info = get_host_details(conn)
        host_info['templates'] = len(Template.get())
        host_info['labs'] = len(Lab.get())
        conn.close()
        return json_response(data=host_info)
    except Exception as e:
        logger.error('No se pudo obtener el dashboard: %s', libvirt.virGetLastErrorMessage())
        return json_response(status=500)
def delete_template(cu, template_uuid):
    logger.info('Eliminando plantilla')
    try:
        template = Template.get(template_uuid)
        for image_path in pickle.loads(template.images_path):
            subprocess.check_call(['rm', '-f', image_path])
        subprocess.check_call(['rm', '-f', template.xml_path])
        Template.delete(template)
        return json_response()
    except Exception as e:
        logger.error('No se pudo eliminar la plantilla: %s', str(e))
        return json_response(status=500)
Example #16
0
def reboot_domain(cu, domain_uuid):
    logger.info('Reiniciando dominio %s', domain_uuid)
    try:
        conn = libvirt.open(app.config['LOCAL_QEMU_URI'])
        domain = conn.lookupByUUIDString(domain_uuid)
        domain.reboot(libvirt.VIR_DOMAIN_REBOOT_DEFAULT)
        time.sleep(3)
        conn.close()
        return json_response()
    except Exception as e:
        logger.error('No se ha podido reiniciar el dominio %s: %s',
                     domain_uuid, str(e))
        return json_response(status=500)
Example #17
0
def get_all_domains(cu):
    logger.info('Obteniendo dominios')
    try:
        conn = libvirt.open(app.config['LOCAL_QEMU_URI'])
        domains = conn.listAllDomains()
        domains_list = list()
        for dom in domains:
            is_active = True if dom.isActive() == 1 else False
            uuid = dom.UUIDString()
            name = dom.name()
            os_type = dom.OSType()
            total_memory = round(dom.info()[1] / 1024, 2)  # KB to MB
            used_memory = "-" if not is_active else round(
                dom.info()[2] / 1024, 2)  # KB to MB
            memory = dict(total=total_memory, used=used_memory)
            vcpus = dom.info()[3]
            state = dom.info()[0]
            vnc_port = get_vnc_port(dom)

            # ADDED SUPPORT FOR DISKS
            xml = ET.fromstring(dom.XMLDesc())
            devices = xml.findall('devices/disk')

            disk = {}

            for d in devices:
                if d.get('device') == 'disk':
                    file_path = d.find('source').get('file')
                    disk_info = dom.blockInfo(file_path)
                    disk['capacity'] = round(disk_info[0] / 1024 / 1024 / 1024,
                                             2)
                    disk['allocation'] = round(
                        disk_info[1] / 1024 / 1024 / 1024, 2)
                    disk['physical'] = round(disk_info[2] / 1024 / 1024 / 1024,
                                             2)

            domains_list.append(
                dict(uuid=uuid,
                     name=name,
                     is_active=is_active,
                     os_type=os_type,
                     memory=memory,
                     vcpus=vcpus,
                     state=state,
                     disk=disk,
                     vnc_port=vnc_port))
        conn.close()
        return json_response(data=domains_list)
    except Exception as e:
        logger.error('No se pudo obtener los dominios: %s', str(e))
        return json_response(status=500)
Example #18
0
def update_domain(cu, domain_uuid):
    logger.info('Actualizando el dominio %s', domain_uuid)
    data = request.json
    try:
        conn = libvirt.open(app.config['LOCAL_QEMU_URI'])
        dom = conn.lookupByUUIDString(domain_uuid)
        dom.setMaxMemory(int(data['memory']) * 1024)
        dom.setVcpusFlags(
            int(data['vcpus']),
            libvirt.VIR_DOMAIN_AFFECT_CONFIG | libvirt.VIR_DOMAIN_VCPU_MAXIMUM)
        dom.setVcpusFlags(int(data['vcpus']))
    except Exception as e:
        logger.error("No se ha podido actualizar el dominio %s: %s",
                     domain_uuid, str(e))
    return json_response(status=200)
Example #19
0
def create_lab(cu):
    logger.info('Añadiendo laboratorio')
    try:
        lab = Lab(request.json)
        ip_range = ip_range_to_list(lab.start_ip_range, lab.end_ip_range)
        for ip in ip_range:
            data = dict(code=lab.code + '_' + str(ip_range.index(ip)),
                        ip_address=ip,
                        conn_user='******',
                        lab_uuid=lab.uuid)
            lab.add_host(Host(data))
        lab.save()
        return json_response()
    except Exception as e:
        logger.error('No se pudo añadir el laboratorio: %s', str(e))
        return json_response(status=500)
Example #20
0
def start_domain(cu, domain_uuid):
    logger.info('Encendiendo dominio %s', domain_uuid)
    try:
        conn = libvirt.open(app.config['LOCAL_QEMU_URI'])
        domain = conn.lookupByUUIDString(domain_uuid)
        domain.create()
        time.sleep(3)
        domain = conn.lookupByUUIDString(domain_uuid)
        if domain.info()[0] != libvirt.VIR_DOMAIN_RUNNING:
            logger.error('No se pudo encender el dominio %s', domain_uuid)
            conn.close()
            return json_response(status=500)
        conn.close()
        return json_response()
    except Exception as e:
        logger.error('No se pudo encender el dominio %s: %s', domain_uuid,
                     str(e))
        return json_response(status=500)
Example #21
0
    def after_request(request, response):

        # 获取响应数据
        try:
            response_data = json.loads(response.body.decode('utf-8'))
        except Exception:
            response_data = response.body

        log_info = {
            "response_body": str(response_data)[:5000]
            or "UnKnown Response Data",
            'response_header': dict(response.headers),
            "url": request.url,
            "path": request.path,
            "method": request.method,
            'http_state': response.status,
        }
        logger.info(log_info)
Example #22
0
def startWebsockify(cu):
    logger.info('Iniciando conexión de WebSockify')
    global startedWebsockify
    global websockifyPid
    port = request.json['port']
    conn_str = 'localhost:' + str(port)
    if (startedWebsockify):
        kill_process(websockifyPid)
        startedWebsockify = False

    proc = subprocess.Popen([
        './app/api/tools/websockify/run', 'localhost:6080', conn_str, '--cert',
        '/etc/nginx/ssl/nginx.crt', '--key', '/etc/nginx/ssl/nginx.key'
    ])
    websockifyPid = proc.pid
    time.sleep(2)
    startedWebsockify = True
    return json_response(data=proc.pid)
Example #23
0
def shutdown_domain(cu, domain_uuid):
    logger.info('Apagando el dominio %s', domain_uuid)
    try:
        conn = libvirt.open(app.config['LOCAL_QEMU_URI'])
        domain = conn.lookupByUUIDString(domain_uuid)
        domain.destroy()
        time.sleep(3)
        domain = conn.lookupByUUIDString(domain_uuid)
        if domain.info()[0] != libvirt.VIR_DOMAIN_SHUTOFF:
            logger.error('No se pudo apagar el dominio %s', domain_uuid)
            conn.close()
            return json_response(status=500)
        conn.close()
        return json_response()
    except Exception as e:
        logger.error('No se ha podido apagar el dominio %s: %s', domain_uuid,
                     str(e))
        return json_response(status=500)
Example #24
0
def create_domain(cu):
    logger.info('Creando dominio')

    data = request.json
    cmd = [
        'virt-install', '--connect', app.config['LOCAL_QEMU_URI'], '--name',
        data['name'], '--memory',
        str(data['memory']), '--vcpus',
        str(data['vcpus']), '--os-variant', data['os_variant'],
        '--noautoconsole'
    ]
    if data['graphics']['vnc']:
        cmd.append('--graphics')
        cmd.append('vnc,listen=' + data['graphics']['listen'] + ',password='******'graphics']['password'])
    if data['installation_type'] == "iso":
        cmd.append('--disk')
        cmd.append('size=' + str(data['disk']['size']))
        cmd.append('--cdrom')
        cmd.append(data['cdrom'])
    elif data['installation_type'] == "image":
        cmd.append('--disk')
        cmd.append(data['disk']['path'])
        cmd.append('--import')
    elif data['installation_type'] == "network":
        cmd.append('--disk')
        cmd.append('size=' + str(data['disk']['size']))
        cmd.append('--location')
        cmd.append(data['location'])
    elif data['installation_type'] == "pxe":
        cmd.append('--disk')
        cmd.append('size=' + str(data['disk']['size']))
        cmd.append('--network')
        cmd.append(data['network'])
        cmd.append('--pxe')
    else:
        logger.warn('El método de instalación no es correcto')
        return json_response(status=400)
    try:
        subprocess.check_call(cmd)
        return json_response()
    except Exception as e:
        logger.error('No se ha podido crear el dominio: %s', str(e))
        return json_response(status=500)
Example #25
0
    def before_request(request):
        # 获取请求参数
        request_params = request.args
        if request.method == "POST":
            request_params = request.form
        if not request_params:
            try:
                request_params = request.json
            except Exception:
                request_params = {}

        log_info = {
            'request_params': request_params,
            'request_header': dict(request.headers),
            "url": request.url,
            "ip": request.ip,
            "method": request.method,
        }
        logger.info(log_info)
Example #26
0
def delete_domain(cu, domain_uuid):
    logger.info('Eliminando dominio %s', domain_uuid)
    try:
        conn = libvirt.open(app.config['LOCAL_QEMU_URI'])
        domain = conn.lookupByUUIDString(domain_uuid)
        xml = ET.fromstring(domain.XMLDesc())
        devices = xml.findall('devices/disk')
        for d in devices:
            if d.get('device') == 'disk':
                file_path = d.find('source').get('file')
                disk = conn.storageVolLookupByPath(file_path)
                disk.delete(libvirt.VIR_STORAGE_VOL_DELETE_NORMAL)
        domain.undefine()
        conn.close()
        return json_response()
    except Exception as e:
        logger.error('No se pudo eliminar el dominio %s: %s', domain_uuid,
                     str(e))
        return json_response(status=500)
Example #27
0
# -*- coding: utf-8 -*-
"""
(C) Guangcai Ren blueprint_api
All rights reserved
create time '2019/9/16 10:21'

Module usage:

"""

from app import create_app
from app.core import logger

app = create_app()
workers = app.config.get('WORKERS')
app.debug = app.config.get('DEBUG')

if __name__ == '__main__':
    logger.info("""
       _____             _         _____ _             _     _ 
      / ____|           (_)       / ____| |           | |   | |
     | (___   __ _ _ __  _  ___  | (___ | |_ __ _ _ __| |_  | |
      \___ \ / _` | '_ \| |/ __|  \___ \| __/ _` | '__| __| | |
      ____) | (_| | | | | | (__   ____) | || (_| | |  | |_  |_|
     |_____/ \__,_|_| |_|_|\___| |_____/ \__\__,_|_|   \__| (_)
    """)
    app.run(host="0.0.0.0", port=5000, workers=workers, auto_reload=False)
Example #28
0
def clone_template(self, template_uuid, data):
    logger.info("Desplegando nueva plantilla")
    socketio = SocketIO(message_queue=app.config['CELERY_BROKER_URL'])
    try:
        template = Template.get(template_uuid).to_dict()
        domain_name = data['domain_name']
        lab_uuid = data['lab_uuid']

        lab = Lab.get(lab_uuid)
        hosts = lab.hosts

        if hosts.__len__() == 0:
            logger.error('El laboratorio no tiene ningún host asociado')
            socketio.emit('task-finished', {
                'task_type': 'clone-template',
                'task_id': self.request.id.__str__(),
                'status': -1
            })
            return -1

        cmd = ['virt-clone',
               '--connect', app.config['LOCAL_QEMU_URI'],
               '--original-xml', template['xml_path'],
               '--name', domain_name]

        for count in range(template['images_path'].__len__()):
            cmd.append('--file')
            cmd.append(app.config['DOMAIN_IMAGES_DIR'] + domain_name + '-disk' + str(count) + '.qcow2')

        ssh = paramiko.SSHClient()
        # Surrounds 'known_hosts' error
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        k = paramiko.RSAKey.from_private_key_file("/home/dvls/.ssh/id_rsa")
        errors = list()
        for h in hosts:
            host = h.ip_address
            username = h.conn_user
            logger.debug('Desplegando en el host %s, IP: %s', h.code, h.ip_address)
            try:
                # NO PASSWORD!! Server SSH key is previously distributed among lab PCs
                logger.debug('Conectando al equipo')
                ssh.connect(hostname=host.compressed, username=username, timeout=4, pkey=k)
                ssh_stdin, ssh_stdout, ssh_stderr = ssh.exec_command(' '.join(cmd))
                errors = [b.rstrip() for b in ssh_stderr.readlines()]
                if len(errors) > 0:
                    logger.error('No se pudo desplegar la plantilla en el host %s (%s)', h.code, h.ip_address.compressed)
                    logger.error(cmd)
                    logger.error(errors)
            except Exception as e:
                logger.error('No se pudo desplegar la plantilla en el host %s (%s): %s', h.code, h.ip_address.compressed, str(e))
                errors = True
            finally:
                logger.debug('Desplegado en el equipo %s', h.code)
                ssh.close()
        if errors or len(errors) > 0:
            socketio.emit('task-finished', {
                'task_type': 'clone-template',
                'task_id': self.request.id.__str__(),
                'status': -1
            })
            return -1

        socketio.emit('task-finished', {
            'task_type': 'clone-template',
            'task_id': self.request.id.__str__(),
            'status': 0
        })
        logger.info("Plantilla desplegada correctamente")
        return 0
    except Exception as e:
        logger.error('No se pudo desplegar la plantilla: %s', str(e))
        socketio.emit('task-finished', {
            'task_type': 'clone-template',
            'task_id': self.request.id.__str__(),
            'status': -1
        })
        return -1
Example #29
0
def create_template(self, data):
    socketio = SocketIO(message_queue=app.config['CELERY_BROKER_URL'])
    try:
        domain_uuid = data['domain_uuid']
        template_name = data['template_name']
        template_description = data['template_description']
        do_sysprep = data['do_sysprep']

        # Check domain state
        conn = libvirt.open(app.config['LOCAL_QEMU_URI'])
        domain = conn.lookupByUUIDString(domain_uuid)
        if domain.isActive():
            logger.error('No se pudo crear la plantilla: el dominio debe estar apagado')
            socketio.emit('task-finished', {
                'task_type': 'create-template',
                'task_id': self.request.id.__str__(),
                'status': -1
            })
            return -1

        # Domain cloning (get disks paths and some hardware stuff)
        info = domain.info()
        memory = info[2]
        vcpus = info[3]

        xml = ET.fromstring(domain.XMLDesc())
        devices = xml.findall('devices/disk')
        disks = list()
        for d in devices:
            if d.get('device') == 'disk':
                file_path = d.find('source').get('file')
                disks.append(file_path)

        cmd = ['virt-clone',
               '--connect', app.config['LOCAL_QEMU_URI'],
               '--original', domain.name(),
               '--name', template_name]
        template_images_path = list()
        for count in range(disks.__len__()):
            template_image_path = app.config['TEMPLATE_IMAGES_DIR'] + template_name + '-disk' + str(count) + '.qcow2'
            template_images_path.append(template_image_path)
            cmd.append('--file')
            cmd.append(template_image_path)
        subprocess.check_call(cmd)

        if do_sysprep:
            # Decontextualize the template and dumps XML --> USING POLICYKIT WITH 'virt-sysprep'
            subprocess.check_call(['pkexec', '/usr/bin/virt-sysprep',
                                   '--connect', app.config['LOCAL_QEMU_URI'],
                                   '--domain', template_name])
        template_xml = str(app.config['TEMPLATE_DEFINITIONS_DIR'] + template_name + '.xml')
        proc = subprocess.Popen(['virsh', '--connect', app.config['LOCAL_QEMU_URI'], 'dumpxml', template_name],
                                stdout=subprocess.PIPE)
        out = proc.stdout.read().decode('utf-8')
        # print(out)

        file = open(str(template_xml), 'w')
        file.write(out)
        file.close()

        # Undefine template
        template = conn.lookupByName(template_name)
        template.undefine()

        # Add template to database

        data = dict(name=template_name,
                    description=template_description,
                    vcpus=vcpus,
                    memory=memory,
                    xml_path=template_xml,
                    images_path=template_images_path)
        template = Template(data)
        template.save()
        logger.info("Plantilla creada")
        socketio.emit('task-finished', {
            'task_type': 'create-template',
            'task_id': self.request.id.__str__(),
            'status': 0
        })
        return 0
    except Exception as e:
        # TODO - Delete template on fs if Exception is instance of sqlite3.OperationalError
        logger.error('No se pudo crear la plantilla: %s', str(e))
        socketio.emit('task-finished', {
            'task_type': 'create-template',
            'task_id': self.request.id.__str__(),
            'status': -1
        })
        return -1
Example #30
0
def create_domain(cu):
    logger.info('Creando dominio')
    data = request.json
    task = domains.create_domain.delay(data)
    return json_response(data=task.task_id)