import logging from flask import render_template, Blueprint, request, redirect, url_for, flash, session from flask_login import login_required, current_user from forms import FormVirtualMachine, UpdateVmInfo from db_manager import db, VirtualMachine, Actions, get_user_by_username, get_vm_by_vms from dotenv import load_dotenv from datetime import datetime from pyVim import connect from sqlalchemy import func import ssl import os vm_blueprint = Blueprint('vm', __name__) load_dotenv() hypervisors = { "5.9.87.101": {"user": os.getenv("HYPER1_USER"), "password": os.getenv("HYPER1_PASS"), "host": os.getenv("HYPER1_HOST")}, "135.181.138.180": {"user": os.getenv("HYPER2_USER"), "password": os.getenv("HYPER2_PASS"), "host": os.getenv("HYPER2_HOST")}, "136.243.43.245": {"user": os.getenv("HYPER3_USER"), "password": os.getenv("HYPER3_PASS"), "host": os.getenv("HYPER3_HOST")}, "65.108.193.220": {"user": os.getenv("HYPER4_USER"), "password": os.getenv("HYPER4_PASS"), "host": os.getenv("HYPER4_HOST")} } @vm_blueprint.route('/dashboard', methods=['GET', 'POST']) @login_required def dashboard(): virtual_machines = VirtualMachine.query.all() return render_template('dashboard.html', virtual_machines=virtual_machines) @vm_blueprint.route('/vms', methods=['GET', 'POST']) @login_required def vms(): virtual_machines = VirtualMachine.query.all() return render_template('vms.html', virtual_machines=virtual_machines) @vm_blueprint.route('/manage', methods=['GET', 'POST']) @login_required def manage(): virtual_machines = VirtualMachine.query.all() return render_template('manage.html', virtual_machines=virtual_machines) @vm_blueprint.route('/add', methods=['GET', 'POST']) @login_required def add_virtual_machine(): form = FormVirtualMachine(request.form) if request.method == 'POST': new_vm = VirtualMachine(hyper=form.hyper.data, id_vm=form.id_vm.data, name=form.name.data, os=form.os.data, memory=form.memory.data, cpu=form.cpu.data, technical=form.technical.data, status="Свободно") db.session.add(new_vm) db.session.commit() return redirect(url_for('vm.dashboard')) return render_template('add.html', form=form) @vm_blueprint.route('/delete/', methods=['GET', 'POST']) @login_required def delete_virtual_machine(id): vm_to_delete = VirtualMachine.query.get_or_404(id) new_action = Actions(user_id=get_user_by_username(current_user.username).id, action_type='del_vm', vm=get_vm_by_vms(vm_to_delete.hyper, vm_to_delete.name).id) db.session.add(new_action) db.session.commit() db.session.delete(vm_to_delete) db.session.commit() flash(f'Виртуальная машина {vm_to_delete.name} удалена!', 'success') return redirect(url_for('vm.vms')) @vm_blueprint.route('/edit/', methods=['GET', 'POST']) @login_required def edit_virtual_machine(id): vm_to_edit = VirtualMachine.query.get_or_404(id) if request.method == 'POST': vm_to_edit.hyper = request.form['hyper'] vm_to_edit.ip_addres = request.form['ip_addres'] vm_to_edit.name = request.form['name'] vm_to_edit.appointment = request.form['appointment'] vm_to_edit.os = request.form['os'] vm_to_edit.memory = request.form['memory'] vm_to_edit.cpu = request.form['cpu'] vm_to_edit.technical = request.form.get('technical', False) == 'on' new_action = Actions(user_id=get_user_by_username(current_user.username).id, action_type='edit_vm', vm=get_vm_by_vms(vm_to_edit.hyper, vm_to_edit.name).id) db.session.add(new_action) db.session.commit() flash(f'Виртуальная машина {vm_to_edit.name} отредактирована!', 'success') return redirect(url_for('vm.vms')) return render_template('edit.html', virtual_machine=vm_to_edit) @vm_blueprint.route('/occupy/', methods=['GET', 'POST']) @login_required def occupy_vm(id): vm = VirtualMachine.query.get_or_404(id) if request.method == 'POST': vm.status = 'Занято' vm.task = request.form['task'] vm.busy_date = datetime.now().strftime('%d.%m.%Y %H:%M') vm.who_borrowed = current_user.name vm.who_borrowed_username = current_user.username new_action = Actions(user_id=get_user_by_username(current_user.username).id, action_type='occupy_vm', vm=get_vm_by_vms(vm.hyper, vm.name).id) db.session.add(new_action) db.session.commit() return redirect(url_for('vm.dashboard')) return render_template('index.html', virtual_machines=VirtualMachine.query.all()) @vm_blueprint.route('/release/', methods=['GET', 'POST']) @login_required def release_vm(id): vm = VirtualMachine.query.get_or_404(id) if request.method == 'POST': vm.status = 'Свободно' vm.task = 'Свободно' vm.busy_date = 'Свободно' vm.who_borrowed = 'Свободно' vm.who_borrowed_username = 'Свободно' new_action = Actions(user_id=get_user_by_username(current_user.username).id, action_type='release_vm', vm=get_vm_by_vms(vm.hyper, vm.name).id) db.session.add(new_action) db.session.commit() return redirect(url_for('vm.dashboard')) return redirect(url_for('index')) def disable_ssl_verification(): ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS) ssl_context.verify_mode = ssl.CERT_NONE return ssl_context def find_vm_by_name(content, vm_name): vm = None for child in content.rootFolder.childEntity: if hasattr(child, 'vmFolder'): vm_folder = child.vmFolder vm_list = vm_folder.childEntity for vm_obj in vm_list: if vm_obj.name == vm_name: vm = vm_obj break if vm: break return vm def read_content(hyper): if hyper in hypervisors: user = hypervisors[hyper]["user"] password = hypervisors[hyper]["password"] host = hypervisors[hyper]["host"] else: flash(f'Узел {hyper} не найден', 'danger') return redirect(url_for('vm.manage')) service_instance = connect.SmartConnect( host=host, user=user, pwd=password, sslContext=disable_ssl_verification() ) content = service_instance.RetrieveContent() return content @vm_blueprint.route('/start//', methods=['GET', 'POST']) @login_required def start_virtual_machine(name, hyper): vm = find_vm_by_name(read_content(hyper), name) try: if vm: vm.PowerOnVM_Task() new_action = Actions(user_id=get_user_by_username(current_user.username).id, action_type='start_vm', vm=get_vm_by_vms(hyper, name).id) db.session.add(new_action) db.session.commit() flash(f'Запущена виртуальная машина: {name} на гипервизоре {hyper}.', 'success') return redirect(url_for('vm.manage')) else: flash(f'Ошибка запуска виртуальной машины: {name} на гипервизоре {hyper}.', 'danger') return redirect(url_for('vm.manage')) except Exception as e: flash(f'При выполнении операции запуска возникла ошибка {e}', 'danger') return redirect(url_for('vm.manage')) @vm_blueprint.route('/stop//', methods=['GET', 'POST']) @login_required def stop_virtual_machine(name, hyper): vm = find_vm_by_name(read_content(hyper), name) try: if vm: vm.PowerOffVM_Task() new_action = Actions(user_id=get_user_by_username(current_user.username).id, action_type='stop_vm', vm=get_vm_by_vms(hyper, name).id) db.session.add(new_action) db.session.commit() flash(f'Остановлена виртуальная машина: {name} на гипервизоре {hyper}.', 'success') return redirect(url_for('vm.manage')) else: flash(f'Ошибка остановки виртуальной машины: {name} на гипервизоре {hyper}.', 'danger') return redirect(url_for('vm.manage')) except Exception as e: flash(f'При выполнении операции остановки возникла ошибка {e}', 'danger') return redirect(url_for('vm.manage')) @vm_blueprint.route('/restart//', methods=['GET', 'POST']) @login_required def restart_virtual_machine(name, hyper): vm = find_vm_by_name(read_content(hyper), name) try: if vm: vm.ResetVM_Task() new_action = Actions(user_id=get_user_by_username(current_user.username).id, action_type='restart_vm', vm=get_vm_by_vms(hyper, name).id) db.session.add(new_action) db.session.commit() flash(f'Перезагружена виртуальная машина: {name} на гипервизоре {hyper}.', 'success') return redirect(url_for('vm.manage')) else: flash(f'Ошибка перезагрузки виртуальной машины: {name} на гипервизоре {hyper}.', 'danger') return redirect(url_for('vm.manage')) except Exception as e: flash(f'При выполнении операции перезагрузки возникла ошибка {e}', 'danger') return redirect(url_for('vm.manage')) @vm_blueprint.route('/vm_info//', methods=['GET', 'POST']) @login_required def vm_info(name, hyper): all_data_vm = VirtualMachine.query.filter_by(hyper=hyper, name=name).first() if not all_data_vm: flash('Виртуальная машина не найдена.', 'danger') return redirect(url_for('vm.dashboard')) form = UpdateVmInfo(request.form) if request.method == 'POST' and form.validate(): all_data_vm.information = form.information.data db.session.commit() flash('Комментарий к виртуальной машине успешно обновлена.', 'success') return redirect(url_for('vm.dashboard')) elif request.method == 'POST': flash('Ошибка при обновлении комментария к виртуальной машине.', 'danger') return render_template('vm_info.html', form=form, all_data_vm=all_data_vm, information=all_data_vm.information) @vm_blueprint.route('/statistics/', methods=['GET', 'POST']) @login_required def vm_statistics(): try: most_used_vm = db.session.query(Actions.vm, func.count(Actions.vm).label('vm_count')).group_by(Actions.vm).order_by( func.count(Actions.vm).desc()).first() action_counts = db.session.query(Actions.action_type, func.count(Actions.action_type).label('action_count')).group_by( Actions.action_type).order_by(func.count(Actions.action_type).desc()).all() data_vm = VirtualMachine.query.filter_by(id=most_used_vm[0]).first() return render_template('statistics.html', data_vm=data_vm, action_counts=action_counts) except Exception as e: logging.error(f"Ошибка отображения статистики {e}") return render_template('statistics.html', data_vm=None, action_counts=None)