capsul-flask/capsulflask/consistency.py
2021-12-05 16:50:55 -06:00

108 lines
3.4 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",
# "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"].get_all_by_host_and_network()
#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
)
)