Support dualstack ipv6 in the controller layer #10
@ -29,12 +29,14 @@ def make_capsul_id():
|
|||||||
letters_n_nummers = generate(alphabet="1234567890qwertyuiopasdfghjklzxcvbnm", size=10)
|
letters_n_nummers = generate(alphabet="1234567890qwertyuiopasdfghjklzxcvbnm", size=10)
|
||||||
return f"capsul-{letters_n_nummers}"
|
return f"capsul-{letters_n_nummers}"
|
||||||
|
|
||||||
def double_check_capsul_address(id, ipv4, get_ssh_host_keys):
|
def double_check_capsul_address(id, ipv4, ipv6, get_ssh_host_keys):
|
||||||
try:
|
try:
|
||||||
result = current_app.config["HUB_MODEL"].get(id, get_ssh_host_keys)
|
result = current_app.config["HUB_MODEL"].get(id, get_ssh_host_keys)
|
||||||
if result != None and result.ipv4 != None and result.ipv4 != ipv4:
|
if result != None and result.ipv4 != None and result.ipv4 != ipv4:
|
||||||
ipv4 = result.ipv4
|
get_model().update_vm_ipv4(email=session["account"], id=id, ipv4=result.ipv4)
|
||||||
get_model().update_vm_ip(email=session["account"], id=id, ipv4=result.ipv4)
|
|
||||||
|
if result != None and result.ipv6 != None and result.ipv6 != ipv6:
|
||||||
|
get_model().update_vm_ipv6(email=session["account"], id=id, ipv6=result.ipv6)
|
||||||
|
|
||||||
if result != None and result.ssh_host_keys != None and get_ssh_host_keys:
|
if result != None and result.ssh_host_keys != None and get_ssh_host_keys:
|
||||||
get_model().update_vm_ssh_host_keys(email=session["account"], id=id, ssh_host_keys=result.ssh_host_keys)
|
get_model().update_vm_ssh_host_keys(email=session["account"], id=id, ssh_host_keys=result.ssh_host_keys)
|
||||||
@ -61,37 +63,38 @@ def index():
|
|||||||
# for now we are going to check the IP according to the virt model
|
# for now we are going to check the IP according to the virt model
|
||||||
# on every request. this could be done by a background job and cached later on...
|
# on every request. this could be done by a background job and cached later on...
|
||||||
for vm in vms:
|
for vm in vms:
|
||||||
result = double_check_capsul_address(vm["id"], vm["ipv4"], False)
|
result = double_check_capsul_address(vm["id"], vm["ipv4"], vm["ipv6"], False)
|
||||||
if result is not None:
|
if result is not None:
|
||||||
vm["ipv4"] = result.ipv4
|
vm["ipv4"] = result.ipv4
|
||||||
|
vm["ipv6"] = result.ipv6
|
||||||
vm["state"] = result.state
|
vm["state"] = result.state
|
||||||
else:
|
else:
|
||||||
vm["state"] = "unknown"
|
vm["state"] = "unknown"
|
||||||
|
|
||||||
|
|
||||||
mappedVms = []
|
mappedVms = []
|
||||||
for vm in vms:
|
for vm in vms:
|
||||||
ip_display = vm['ipv4']
|
ip_display = {}
|
||||||
if not ip_display:
|
ip_display_class = {}
|
||||||
if vm["state"] == "running":
|
for af in ['ipv4', 'ipv6']:
|
||||||
ip_display = "..booting.."
|
ip_display[af] = vm[af]
|
||||||
else:
|
ip_display_class[af] = "ok"
|
||||||
ip_display = "unknown"
|
if not ip_display[af]:
|
||||||
|
if vm["state"] == "running":
|
||||||
ip_display_class = "ok"
|
ip_display[af] = "..booting.."
|
||||||
if not vm['ipv4']:
|
ip_display_class[af] = "waiting-pulse"
|
||||||
if vm["state"] == "running":
|
else:
|
||||||
ip_display_class = "waiting-pulse"
|
ip_display[af] = "unknown"
|
||||||
else:
|
ip_display_class[af] = "yellow"
|
||||||
ip_display_class = "yellow"
|
|
||||||
|
|
||||||
mappedVms.append(dict(
|
mappedVms.append(dict(
|
||||||
id=vm['id'],
|
id=vm['id'],
|
||||||
size=vm['size'],
|
size=vm['size'],
|
||||||
state=vm['state'],
|
state=vm['state'],
|
||||||
ipv4=ip_display,
|
ipv4=ip_display['ipv4'],
|
||||||
ipv4_status=ip_display_class,
|
ipv4_status=ip_display_class['ipv4'],
|
||||||
os=vm['os'],
|
ipv6=ip_display['ipv6'],
|
||||||
|
ipv6_status=ip_display_class['ipv6'],
|
||||||
|
os=vm['os'],
|
||||||
created=vm['created'].strftime("%b %d %Y")
|
created=vm['created'].strftime("%b %d %Y")
|
||||||
))
|
))
|
||||||
|
|
||||||
@ -168,10 +171,11 @@ def detail(id):
|
|||||||
else:
|
else:
|
||||||
needs_ssh_host_keys = "ssh_host_keys" not in vm or len(vm["ssh_host_keys"]) == 0
|
needs_ssh_host_keys = "ssh_host_keys" not in vm or len(vm["ssh_host_keys"]) == 0
|
||||||
|
|
||||||
vm_from_virt_model = double_check_capsul_address(vm["id"], vm["ipv4"], needs_ssh_host_keys)
|
vm_from_virt_model = double_check_capsul_address(vm["id"], vm["ipv4"], vm['ipv6'], needs_ssh_host_keys)
|
||||||
|
|
||||||
if vm_from_virt_model is not None:
|
if vm_from_virt_model is not None:
|
||||||
vm["ipv4"] = vm_from_virt_model.ipv4
|
vm["ipv4"] = vm_from_virt_model.ipv4
|
||||||
|
vm["ipv6"] = vm_from_virt_model.ipv6
|
||||||
vm["state"] = vm_from_virt_model.state
|
vm["state"] = vm_from_virt_model.state
|
||||||
if needs_ssh_host_keys:
|
if needs_ssh_host_keys:
|
||||||
vm["ssh_host_keys"] = vm_from_virt_model.ssh_host_keys
|
vm["ssh_host_keys"] = vm_from_virt_model.ssh_host_keys
|
||||||
|
@ -179,10 +179,14 @@ class DBModel:
|
|||||||
self.cursor.fetchall()
|
self.cursor.fetchall()
|
||||||
))
|
))
|
||||||
|
|
||||||
def update_vm_ip(self, email, id, ipv4):
|
def update_vm_ipv4(self, email, id, ipv4):
|
||||||
self.cursor.execute("UPDATE vms SET public_ipv4 = %s WHERE email = %s AND id = %s", (ipv4, email, id))
|
self.cursor.execute("UPDATE vms SET public_ipv4 = %s WHERE email = %s AND id = %s", (ipv4, email, id))
|
||||||
self.connection.commit()
|
self.connection.commit()
|
||||||
|
|
||||||
|
def update_vm_ipv6(self, email, id, ipv6):
|
||||||
|
self.cursor.execute("UPDATE vms SET public_ipv6 = %s WHERE email = %s AND id = %s", (ipv6, email, id))
|
||||||
|
self.connection.commit()
|
||||||
|
|
||||||
def update_vm_ssh_host_keys(self, email, id, ssh_host_keys):
|
def update_vm_ssh_host_keys(self, email, id, ssh_host_keys):
|
||||||
for key in ssh_host_keys:
|
for key in ssh_host_keys:
|
||||||
self.cursor.execute("""
|
self.cursor.execute("""
|
||||||
|
@ -29,7 +29,8 @@ if virsh domuuid "$vmname" | grep -vqE '^[\t\s\n]*$'; then
|
|||||||
esac
|
esac
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# this gets the ipv4
|
# this gets the vm ip addresses
|
||||||
ipv4="$(virsh domifaddr "$vmname" | awk '/ipv4/ {print $4}' | cut -d'/' -f1)"
|
ipv4="$(virsh domifaddr "$vmname" | awk '/ipv4/ {print $4}' | cut -d'/' -f1)"
|
||||||
|
ipv6="$(virsh domifaddr "$vmname" | awk '/ipv6/ {print $4}' | cut -d'/' -f1)"
|
||||||
|
|
||||||
echo "$exists $state $ipv4"
|
echo "$exists $state $ipv4 $ipv6"
|
||||||
|
@ -114,24 +114,30 @@ class ShellScriptSpoke(VirtualizationInterface):
|
|||||||
if len(fields) < 3:
|
if len(fields) < 3:
|
||||||
return VirtualMachine(id, current_app.config["SPOKE_HOST_ID"], state=state)
|
return VirtualMachine(id, current_app.config["SPOKE_HOST_ID"], state=state)
|
||||||
|
|
||||||
ipaddr = fields[2]
|
ip4addr = fields[2]
|
||||||
|
|
||||||
if not re.match(r"^([0-9]{1,3}\.){3}[0-9]{1,3}$", ipaddr):
|
if not re.match(r"^([0-9]{1,3}\.){3}[0-9]{1,3}$", ip4addr):
|
||||||
return VirtualMachine(id, current_app.config["SPOKE_HOST_ID"], state=state)
|
return VirtualMachine(id, current_app.config["SPOKE_HOST_ID"], state=state)
|
||||||
|
|
||||||
if get_ssh_host_keys:
|
if get_ssh_host_keys:
|
||||||
try:
|
try:
|
||||||
completedProcess2 = run([join(current_app.root_path, 'shell_scripts/ssh-keyscan.sh'), ipaddr], capture_output=True)
|
completedProcess2 = run([join(current_app.root_path, 'shell_scripts/ssh-keyscan.sh'), ip4addr], capture_output=True)
|
||||||
self.validate_completed_process(completedProcess2)
|
self.validate_completed_process(completedProcess2)
|
||||||
ssh_host_keys = json.loads(completedProcess2.stdout.decode("utf-8"))
|
ssh_host_keys = json.loads(completedProcess2.stdout.decode("utf-8"))
|
||||||
return VirtualMachine(id, current_app.config["SPOKE_HOST_ID"], state=state, ipv4=ipaddr, ssh_host_keys=ssh_host_keys)
|
return VirtualMachine(id, current_app.config["SPOKE_HOST_ID"], state=state, ipv4=ip4addr, ssh_host_keys=ssh_host_keys)
|
||||||
except:
|
except:
|
||||||
current_app.logger.warning(f"""
|
current_app.logger.warning(f"""
|
||||||
failed to ssh-keyscan {id} at {ipaddr}:
|
failed to ssh-keyscan {id} at {ip4addr}:
|
||||||
{my_exec_info_message(sys.exc_info())}"""
|
{my_exec_info_message(sys.exc_info())}"""
|
||||||
)
|
)
|
||||||
|
|
||||||
return VirtualMachine(id, current_app.config["SPOKE_HOST_ID"], state=state, ipv4=ipaddr)
|
if len(fields) < 4:
|
||||||
|
return VirtualMachine(id, current_app.config["SPOKE_HOST_ID"], state=state, ipv4=ip4addr)
|
||||||
|
|
||||||
|
ip6addr = fields[3]
|
||||||
|
|
||||||
|
return VirtualMachine(id, current_app.config["SPOKE_HOST_ID"], state=state, ipv4=ip4addr, ipv6=ip6addr)
|
||||||
|
|
||||||
|
|
||||||
def list_ids(self) -> list:
|
def list_ids(self) -> list:
|
||||||
completedProcess = run([join(current_app.root_path, 'shell_scripts/list-ids.sh')], capture_output=True)
|
completedProcess = run([join(current_app.root_path, 'shell_scripts/list-ids.sh')], capture_output=True)
|
||||||
|
Loading…
Reference in New Issue
Block a user