108 lines
3.4 KiB
Python
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
|
|
)
|
|
) |