from flask import current_app from capsulflask.db import get_model # { # "capsul-123abc45": { # "id": "capsul-123abc45", # "public_ipv4": "123.123.123.123", # "public_ipv6": "::::", # "host": "baikal", # "network_name": "public1", # "virtual_bridge_name": "virbr1", # "state": "running" # }, # { ... }, # ... # } def get_all_vms_from_db() -> dict: db_hosts = get_model().list_hosts_with_networks(None) db_vms_by_host_and_network = get_model().non_deleted_vms_by_host_and_network(None) db_vms_by_id = dict() for kv in db_hosts.items(): host_id = kv[0] value = kv[1] for network in value['networks']: if host_id in db_vms_by_host_and_network and network['network_name'] in db_vms_by_host_and_network[host_id]: for vm in db_vms_by_host_and_network[host_id][network['network_name']]: vm['network_name'] = network['network_name'] vm['virtual_bridge_name'] = network['virtual_bridge_name'] vm['host'] = host_id db_vms_by_id[vm['id']] = vm # for vm in db_vms: # if vm["id"] not in db_vms_by_id: # # TODO # raise Exception("non_deleted_vms_by_host_and_network did not return a vm that was returned by all_vm_ids_with_desired_state") # else: # db_vms_by_id[vm["id"]]["state"] = vm["desired_state"] return db_vms_by_id def get_all_vms_from_hosts() -> dict: virt_vms = current_app.config["HUB_MODEL"].virsh_list() virt_networks = current_app.config["HUB_MODEL"].virsh_netlist() db_hosts = get_model().list_hosts_with_networks(None) virt_vms_by_id = dict() for kv in db_hosts.items(): host_id = kv[0] value = kv[1] for network in value['networks']: for vm in db_vms: if vm["id"] not in db_vms_by_id: # TODO raise Exception("non_deleted_vms_by_host_and_network did not return a vm that was returned by all_vm_ids_with_desired_state") else: db_vms_by_id[vm["id"]]["state"] = vm["desired_state"] virt_vms = current_app.config["HUB_MODEL"].get_vm_() def ensure_vms_and_db_are_synced(): # Now creating the capsuls running status ui # for vm in db_vms: db_ids_dict[vm['id']] = vm['desired_state'] for vm in virt_vms: virt_ids_dict[vm['id']] = vm['desired_state'] errors = list() for id in db_ids_dict: if id not in virt_ids_dict: errors.append(f"{id} is in the database but not in the virtualization model") elif db_ids_dict[id] != virt_ids_dict[id]: errors.append(f"{id} has the desired state {db_ids_dict[id]} in the database but current state {virt_ids_dict[id]} in the virtualization model") for id in virt_ids_dict: if id not in db_ids_dict: errors.append(f"{id} is in the virtualization model but not in the database") if len(errors) > 0: email_addresses_raw = current_app.config['ADMIN_EMAIL_ADDRESSES'].split(",") email_addresses = list(filter(lambda x: len(x) > 6, map(lambda x: x.strip(), email_addresses_raw ) )) current_app.logger.info(f"cron_task: sending inconsistency warning email to {','.join(email_addresses)}:") for error in errors: current_app.logger.info(f"cron_task: {error}.") current_app.config["FLASK_MAIL_INSTANCE"].send( Message( "Capsul Consistency Check Failed", sender=current_app.config["MAIL_DEFAULT_SENDER"], body="\n".join(errors), recipients=email_addresses ) )