Compare commits

...

4 Commits
master ... ipv6

Author SHA1 Message Date
mirsal 70a193a0ce templates: Display IPv6 addresses on the capsul detail page 2021-08-16 09:30:00 +00:00
mirsal 7e4ebe75b4 cosmetics: Remove trailing whitespace 2021-08-16 09:30:00 +00:00
mirsal d289b55d27 Support dualstack ipv6 in the console controller
This commit updates the console controller logic and
a few bits in the model in order to support multiple
address families (ipv4 and ipv6)
2021-08-16 09:30:00 +00:00
mirsal 88f667f90f Retrieve IPv6 addresses from VMs
This commit allows the model to fetch IPv6 addresses
from running VMs and populate VirtualMachine objects
with the value if it was retrieved successfully
2021-08-16 09:30:00 +00:00
5 changed files with 52 additions and 33 deletions

View File

@ -27,12 +27,14 @@ def make_capsul_id():
letters_n_nummers = generate(alphabet="1234567890qwertyuiopasdfghjklzxcvbnm", size=10)
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:
result = current_app.config["HUB_MODEL"].get(id, get_ssh_host_keys)
if result != None and result.ipv4 != None and result.ipv4 != ipv4:
ipv4 = result.ipv4
get_model().update_vm_ip(email=session["account"], id=id, ipv4=result.ipv4)
get_model().update_vm_ipv4(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:
get_model().update_vm_ssh_host_keys(email=session["account"], id=id, ssh_host_keys=result.ssh_host_keys)
@ -59,37 +61,38 @@ def index():
# 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...
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:
vm["ipv4"] = result.ipv4
vm["ipv6"] = result.ipv6
vm["state"] = result.state
else:
vm["state"] = "unknown"
mappedVms = []
for vm in vms:
ip_display = vm['ipv4']
if not ip_display:
if vm["state"] == "running":
ip_display = "..booting.."
else:
ip_display = "unknown"
ip_display_class = "ok"
if not vm['ipv4']:
if vm["state"] == "running":
ip_display_class = "waiting-pulse"
else:
ip_display_class = "yellow"
ip_display = {}
ip_display_class = {}
for af in ['ipv4', 'ipv6']:
ip_display[af] = vm[af]
ip_display_class[af] = "ok"
if not ip_display[af]:
if vm["state"] == "running":
ip_display[af] = "..booting.."
ip_display_class[af] = "waiting-pulse"
else:
ip_display[af] = "unknown"
ip_display_class[af] = "yellow"
mappedVms.append(dict(
id=vm['id'],
size=vm['size'],
id=vm['id'],
size=vm['size'],
state=vm['state'],
ipv4=ip_display,
ipv4_status=ip_display_class,
os=vm['os'],
ipv4=ip_display['ipv4'],
ipv4_status=ip_display_class['ipv4'],
ipv6=ip_display['ipv6'],
ipv6_status=ip_display_class['ipv6'],
os=vm['os'],
created=vm['created'].strftime("%b %d %Y")
))
@ -169,10 +172,11 @@ def detail(id):
else:
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:
vm["ipv4"] = vm_from_virt_model.ipv4
vm["ipv6"] = vm_from_virt_model.ipv6
vm["state"] = vm_from_virt_model.state
if needs_ssh_host_keys:
vm["ssh_host_keys"] = vm_from_virt_model.ssh_host_keys

View File

@ -144,10 +144,14 @@ class DBModel:
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.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):
for key in ssh_host_keys:
self.cursor.execute("""

View File

@ -29,7 +29,8 @@ if virsh domuuid "$vmname" | grep -vqE '^[\t\s\n]*$'; then
esac
fi
# this gets the ipv4
# this gets the vm ip addresses
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"

View File

@ -114,24 +114,30 @@ class ShellScriptSpoke(VirtualizationInterface):
if len(fields) < 3:
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)
if get_ssh_host_keys:
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)
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:
mylog_warning(current_app, f"""
failed to ssh-keyscan {id} at {ipaddr}:
failed to ssh-keyscan {id} at {ip4addr}:
{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:
completedProcess = run([join(current_app.root_path, 'shell_scripts/list-ids.sh')], capture_output=True)

View File

@ -79,6 +79,10 @@
<label class="align" for="ipv4">IPv4 Address</label>
<span id="ipv4">{{ vm['ipv4'] }}</span>
</div>
<div class="row justify-start">
<label class="align" for="ipv6">IPv6 Address</label>
<span id="ipv6">{{ vm['ipv6'] }}</span>
</div>
<div class="row justify-start">
<label class="align" for="os_description">Operating System</label>
<span id="os_description">{{ vm['os_description'] }}</span>