capsul-flask/capsulflask/consistency.py

111 lines
3.8 KiB
Python

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",
# "desired_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
# this returns the same shape of object as get_all_vms_from_db except it has 'state' instead of 'desired_state'
def get_all_vms_from_hosts(db_vms_by_id: dict) -> dict:
virt_vms_by_id = current_app.config["HUB_MODEL"].get_all_by_id()
db_hosts = get_model().list_hosts_with_networks(None)
for vm_id, virt_vm in virt_vms_by_id.items():
if vm_id in db_vms_by_id:
if 'host' not in virt_vm:
virt_vm['host'] = db_vms_by_id[vm_id]['host']
if 'network_name' not in virt_vm:
virt_vm['network_name'] = db_vms_by_id[vm_id]['network_name']
else:
if 'host' not in virt_vm:
virt_vm['host'] = "unknown"
if 'network_name' not in virt_vm:
virt_vm['network_name'] = "unknown"
if virt_vm['host'] in db_hosts and virt_vm['network_name'] in db_hosts[virt_vm['host']]:
virt_vm['virtual_bridge_name'] = db_hosts[virt_vm['host']][virt_vm['network_name']]['virtual_bridge_name']
else:
virt_vm['virtual_bridge_name'] = "unknown"
return virt_vms_by_id
def ensure_vms_and_db_are_synced():
pass
# # 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
# )
# )