Merge branch 'master' into multiple-hosts

Conflicts:
	capsulflask/console.py
	capsulflask/db.py
	capsulflask/shared.py
	capsulflask/virt_model.py
This commit is contained in:
2021-02-15 17:52:17 -06:00
23 changed files with 819 additions and 43 deletions

View File

@ -1,5 +1,6 @@
import re
import sys
import json
from datetime import datetime, timedelta
from flask import Blueprint
from flask import flash
@ -26,19 +27,22 @@ def makeCapsulId():
lettersAndNumbers = generate(alphabet="1234567890qwertyuiopasdfghjklzxcvbnm", size=10)
return f"capsul-{lettersAndNumbers}"
def double_check_capsul_address(id, ipv4):
def double_check_capsul_address(id, ipv4, get_ssh_host_keys):
try:
result = current_app.config["HUB_MODEL"].get(id)
result = current_app.config["HUB_MODEL"].get(id, get_ssh_host_keys)
if result.ipv4 != ipv4:
ipv4 = result.ipv4
get_model().update_vm_ip(email=session["account"], id=id, ipv4=result.ipv4)
if get_ssh_host_keys:
get_model().update_vm_ssh_host_keys(email=session["account"], id=id, ssh_host_keys=result.ssh_host_keys)
except:
current_app.logger.error(f"""
the virtualization model threw an error in double_check_capsul_address of {id}:
{my_exec_info_message(sys.exc_info())}"""
)
return None
return ipv4
return result
@bp.route("/")
@account_required
@ -54,7 +58,9 @@ 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:
vm["ipv4"] = double_check_capsul_address(vm["id"], vm["ipv4"])
result = double_check_capsul_address(vm["id"], vm["ipv4"], False)
if result is not None:
vm["ipv4"] = result.ipv4
vms = list(map(
lambda x: dict(
@ -105,9 +111,17 @@ def detail(id):
return render_template("capsul-detail.html", vm=vm, delete=True, deleted=True)
else:
vm["ipv4"] = double_check_capsul_address(vm["id"], vm["ipv4"])
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)
if vm_from_virt_model is not None:
vm["ipv4"] = vm_from_virt_model.ipv4
if needs_ssh_host_keys:
vm["ssh_host_keys"] = vm_from_virt_model.ssh_host_keys
vm["created"] = vm['created'].strftime("%b %d %Y %H:%M")
vm["ssh_public_keys"] = ", ".join(vm["ssh_public_keys"]) if len(vm["ssh_public_keys"]) > 0 else "<missing>"
vm["ssh_authorized_keys"] = ", ".join(vm["ssh_authorized_keys"]) if len(vm["ssh_authorized_keys"]) > 0 else "<missing>"
return render_template(
"capsul-detail.html",
@ -124,7 +138,7 @@ def detail(id):
def create():
vm_sizes = get_model().vm_sizes_dict()
operating_systems = get_model().operating_systems_dict()
ssh_public_keys = get_model().list_ssh_public_keys_for_account(session["account"])
public_keys_for_account = get_model().list_ssh_public_keys_for_account(session["account"])
account_balance = get_account_balance(get_vms(), get_payments(), datetime.utcnow())
capacity_avaliable = current_app.config["HUB_MODEL"].capacity_avaliable(512*1024*1024)
errors = list()
@ -155,7 +169,7 @@ def create():
if f"ssh_key_{i}" in request.form:
posted_name = request.form[f"ssh_key_{i}"]
key = None
for x in ssh_public_keys:
for x in public_keys_for_account:
if x['name'] == posted_name:
key = x
if key:
@ -180,7 +194,7 @@ def create():
id=id,
size=size,
os=os,
ssh_public_keys=list(map(lambda x: x["name"], posted_keys))
ssh_authorized_keys=list(map(lambda x: x["name"], posted_keys))
)
current_app.config["HUB_MODEL"].create(
email = session["account"],
@ -188,14 +202,17 @@ def create():
template_image_file_name=operating_systems[os]['template_image_file_name'],
vcpus=vm_sizes[size]['vcpus'],
memory_mb=vm_sizes[size]['memory_mb'],
ssh_public_keys=list(map(lambda x: x["content"], posted_keys))
ssh_authorized_keys=list(map(lambda x: x["content"], posted_keys))
)
return redirect(f"{url_for('console.index')}?created={id}")
affordable_vm_sizes = dict()
for key, vm_size in vm_sizes.items():
if vm_size["dollars_per_month"] <= account_balance:
# if a user deposits $7.50 and then creates an f1-s vm which costs 7.50 a month,
# then they have to delete the vm and re-create it, they will not be able to, they will have to pay again.
# so for UX it makes a lot of sense to give a small margin of 25 cents for usability sake
if vm_size["dollars_per_month"] <= account_balance+0.25:
affordable_vm_sizes[key] = vm_size
for error in errors:
@ -209,9 +226,9 @@ def create():
csrf_token = session["csrf-token"],
capacity_avaliable=capacity_avaliable,
account_balance=format(account_balance, '.2f'),
ssh_public_keys=ssh_public_keys,
ssh_public_key_count=len(ssh_public_keys),
no_ssh_public_keys=len(ssh_public_keys) == 0,
ssh_public_keys=public_keys_for_account,
ssh_public_key_count=len(public_keys_for_account),
no_ssh_public_keys=len(public_keys_for_account) == 0,
operating_systems=operating_systems,
cant_afford=len(affordable_vm_sizes) == 0,
vm_sizes=affordable_vm_sizes