push wip get_all_by_host_and_network

This commit is contained in:
forest 2021-12-08 12:57:22 -06:00
parent a93a97c66c
commit e134184ab7
6 changed files with 81 additions and 18 deletions

View File

@ -42,6 +42,9 @@ app.config.from_mapping(
SPOKE_HOST_ID=os.environ.get("SPOKE_HOST_ID", default="baikal"),
SPOKE_HOST_TOKEN=os.environ.get("SPOKE_HOST_TOKEN", default="changeme"),
HUB_TOKEN=os.environ.get("HUB_TOKEN", default="changeme"),
LIBVIRT_DNSMASQ_PATH=os.environ.get("LIBVIRT_DNSMASQ_PATH", default="/var/lib/libvirt/dnsmasq").rstrip("/"),
# https://www.postgresql.org/docs/9.1/libpq-ssl.html#LIBPQ-SSL-SSLMODE-STATEMENTS
# https://stackoverflow.com/questions/56332906/where-to-put-ssl-certificates-when-trying-to-connect-to-a-remote-database-using

View File

@ -175,10 +175,11 @@ class CapsulFlaskHub(VirtualizationInterface):
try:
result_body = json.loads(result.body)
has_host = isinstance(result_body, dict) and host.id in result_body and isinstance(result_body[host.id], dict)
has_networks = has_host and 'networks' in result_body[host.id] and isinstance(result_body[host.id]['networks'], dict)
if has_host and has_networks:
to_return[host.id] = result_body[host.id]['networks']
has_hosts = isinstance(result_body, dict) and "hosts" in result_body and isinstance(result_body["hosts"], dict)
has_current_host = has_hosts and isinstance(result_body["hosts"], dict) and host.id in result_body["hosts"] and isinstance(result_body["hosts"][host.id], dict)
has_networks = has_current_host and 'networks' in result_body["hosts"][host.id] and isinstance(result_body["hosts"][host.id]['networks'], dict)
if has_networks:
to_return[host.id] = result_body["hosts"][host.id]['networks']
else:
# result_json_string = json.dumps({"error_message": "invalid response, missing 'networks' list"})
current_app.logger.error(f"""missing 'networks' list for get_all_by_host_and_network operation, host {host.id}""")

View File

@ -2,12 +2,10 @@
printf '['
delimiter=""
virsh list --all | while read -r line; do
if echo "$line" | grep -qE '(running)|(shut off)'; then
capsul_id="$(echo "$line" | awk '{ print $2 }')"
capsul_state="$(echo "$line" | sed -E 's/.*((running)|(shut off))\w*/\1/')"
printf '%s\n {"id":"%s", "state":"%s"}' "$delimiter" "$capsul_id" "$capsul_state"
delimiter=","
fi
virsh list --all | tail -n +3 | while read -r line; do
capsul_id="$(echo "$line" | awk '{ print $2 }')"
capsul_state="$(echo "$line" | sed -E 's/^ *[0-9-]+ +[^ ]+ +//')"
printf '%s\n {"id":"%s", "state":"%s"}' "$delimiter" "$capsul_id" "$capsul_state"
delimiter=","
done
printf '\n]\n'

View File

@ -1,3 +1,13 @@
#!/bin/sh
virsh net-list --all | tail -n +3 | awk '{ print $1 }'
printf '['
delimiter=""
virsh net-list --all | tail -n +3 | awk '{ print $1 }' | while read -r network_name; do
virtual_bridge_name="$(virsh net-info "$network_name" | grep -E '^Bridge:' | awk '{ print $2 }')"
capsul_state="$(echo "$line" | sed -E 's/^ *[0-9-]+ +[^ ]+ +//')"
printf '%s\n {"name":"%s", "virtual_bridge_name":"%s"}' "$delimiter" "$network_name" "$virtual_bridge_name"
delimiter=","
done
printf '\n]\n'

View File

@ -96,7 +96,7 @@ def handle_get(operation_id, request_body):
return jsonify(dict(assignment_status="assigned", id=vm.id, host=vm.host, state=vm.state, ipv4=vm.ipv4, ipv6=vm.ipv6, ssh_host_keys=vm.ssh_host_keys))
def handle_get_all_by_host_and_network(operation_id, request_body):
def handle_get_all_by_host_and_network(operation_id, request_body) -> dict:
return jsonify(dict(assignment_status="assigned", ids=current_app.config['SPOKE_MODEL'].get_all_by_host_and_network()))
def handle_create(operation_id, request_body):

View File

@ -133,11 +133,62 @@ class ShellScriptSpoke(VirtualizationInterface):
return VirtualMachine(id, current_app.config["SPOKE_HOST_ID"], state=state, ipv4=ipaddr)
def get_all_by_host_and_network(self) -> list:
# TODO implement this
completedProcess = run([join(current_app.root_path, 'shell_scripts/virsh-list.sh')], capture_output=True)
self.validate_completed_process(completedProcess)
return json.loads(completedProcess.stdout.decode("utf-8"))
def get_all_by_host_and_network(self) -> dict:
vm_list_process = run([join(current_app.root_path, 'shell_scripts/virsh-list.sh')], capture_output=True)
self.validate_completed_process(vm_list_process)
list_of_vms = json.loads(vm_list_process.stdout.decode("utf-8"))
vm_state_by_id = dict()
for vm in list_of_vms:
vm_state_by_id[vm['id']] = vm['state']
net_list_process = run([join(current_app.root_path, 'shell_scripts/virsh-net-list.sh')], capture_output=True)
self.validate_completed_process(net_list_process)
list_of_networks = json.loads(net_list_process.stdout.decode("utf-8"))
networks = dict()
vms_by_id = dict()
vm_id_by_mac = dict()
for network in list_of_networks:
with open(f"{current_app.config['LIBVIRT_DNSMASQ_PATH']}/{network['virtual_bridge_name']}.macs", mode='r') as macs_json_file:
vms_with_macs = json.load(macs_json_file)
for vm in vms_with_macs:
for mac in vm['macs']:
if mac not in vm_id_by_mac:
vm_id_by_mac[mac] = vm['domain']
else:
raise Exception(f"the mac address '{mac}' is used by both '{vm_id_by_mac[mac]}' and '{vm['domain']}'")
if vm['domain'] not in vms_by_id:
vm_state = 'shut off'
if vm['domain'] in vm_state_by_id:
vm_state = vm_state_by_id[vm['domain']]
else:
current_app.logger.info(f"get_all_by_host_and_network: '{vm['domain']}' not in vm_state_by_id, defaulting to 'shut off'")
vms_by_id[vm['domain']] = dict(macs=dict(), state=vm_state)
vms_by_id[vm['domain']]['macs'][mac] = True
with open(f"{current_app.config['LIBVIRT_DNSMASQ_PATH']}/{network['virtual_bridge_name']}.status", mode='r') as status_json_file:
statuses = json.load(status_json_file)
for status in statuses:
if status['mac-address'] in vm_id_by_mac:
vm_id = vm_id_by_mac[status['mac-address']]
vms_by_id[vm_id]['ipv4'] = status['ip-address']
else:
current_app.logger.info(f"get_all_by_host_and_network: {status['mac-address']} not in vm_id_by_mac")
networks[network['name']] = vms_by_id
to_return = dict()
to_return[current_app.config['SPOKE_HOST_ID']] = networks
return to_return
def create(self, email: str, id: str, template_image_file_name: str, vcpus: int, memory_mb: int, ssh_authorized_keys: list, network_name: str, public_ipv4: str):
validate_capsul_id(id)