diff --git a/capsulflask/cli.py b/capsulflask/cli.py index fbade05..d0dc28c 100644 --- a/capsulflask/cli.py +++ b/capsulflask/cli.py @@ -161,6 +161,7 @@ def cron_task(): index_to_send = i if index_to_send > -1: + print(f"cron_task: sending {warnings[index_to_send]['id']} warning email to {account['email']}.") current_app.config["FLASK_MAIL_INSTANCE"].send( Message( warnings[index_to_send]['subject'], @@ -170,7 +171,10 @@ def cron_task(): ) get_model().set_account_balance_warning(account['email'], warnings[index_to_send]['id']) if index_to_send == len(warnings)-1: - print('TODO: delete capsuls') + for vm in vms: + print(f"cron_task: deleting {vm['id']} ( {account['email']} ) due to negative account balance.") + current_app.config["VIRTUALIZATION_MODEL"].destroy(email=account["email"], id=vm['id']) + get_model().delete_vm(email=account["email"], id=vm['id']) diff --git a/capsulflask/console.py b/capsulflask/console.py index 92717f5..567a143 100644 --- a/capsulflask/console.py +++ b/capsulflask/console.py @@ -27,7 +27,7 @@ def double_check_capsul_address(id, ipv4): result = current_app.config["VIRTUALIZATION_MODEL"].get(id) if result.ipv4 != ipv4: ipv4 = result.ipv4 - get_model().updateVm(email=session["account"], id=id, ipv4=result.ipv4) + get_model().update_vm_ip(email=session["account"], id=id, ipv4=result.ipv4) except: print(f""" the virtualization model threw an error in double_check_capsul_address of {id}: @@ -55,12 +55,12 @@ def index(): os=x['os'], created=x['created'].strftime("%b %d %Y") ), - vms + list(filter(lambda x: not x['deleted'], vms)) )) return render_template("capsuls.html", vms=vms, has_vms=len(vms) > 0) -@bp.route("/") +@bp.route("/", methods=("GET", "POST")) @account_required def detail(id): @@ -73,16 +73,31 @@ def detail(id): if vm is None: return abort(404, f"{id} doesn't exist.") - vm["ipv4"] = double_check_capsul_address(vm["id"], vm["ipv4"]) - 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 "" + if vm['deleted']: + return render_template("capsul-detail.html", vm=vm, delete=True, are_you_sure=True) - return render_template( - "capsul-detail.html", - vm=vm, - durations=list(map(lambda x: x.strip("_"), metric_durations.keys())), - duration=duration - ) + if request.method == "POST": + if 'are_you_sure' not in request.form or not request.form['are_you_sure']: + + return render_template("capsul-detail.html", vm=vm, delete=True, are_you_sure=False) + else: + print(f"deleting {vm['id']} per user request ({session['account']})") + current_app.config["VIRTUALIZATION_MODEL"].destroy(email=session['account'], id=id) + get_model().delete_vm(email=session['account'], id=id) + + return render_template("capsul-detail.html", vm=vm, delete=True, are_you_sure=True) + + else: + vm["ipv4"] = double_check_capsul_address(vm["id"], vm["ipv4"]) + 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 "" + + return render_template( + "capsul-detail.html", + vm=vm, delete=False, + durations=list(map(lambda x: x.strip("_"), metric_durations.keys())), + duration=duration + ) @bp.route("/create", methods=("GET", "POST")) diff --git a/capsulflask/db_model.py b/capsulflask/db_model.py index 533c3be..1706133 100644 --- a/capsulflask/db_model.py +++ b/capsulflask/db_model.py @@ -90,7 +90,7 @@ class DBModel: self.cursor.fetchall() )) - def updateVm(self, email, id, ipv4): + def update_vm_ip(self, email, id, ipv4): self.cursor.execute("UPDATE vms SET last_seen_ipv4 = %s WHERE email = %s AND id = %s", (ipv4, email, id)) self.connection.commit() @@ -111,9 +111,9 @@ class DBModel: ) self.connection.commit() - # def vm_exists(self, email, id): - # self.cursor.execute("SELECT id FROM vms WHERE email = %s AND id = %s ", (email, id)) - # return len(self.cursor.fetchall()) > 0 + def delete_vm(self, email, id): + self.cursor.execute("UPDATE vms SET deleted = now() WHERE email = %s AND id = %s", ( email, id)) + self.connection.commit() def get_vm_detail(self, email, id): self.cursor.execute(""" diff --git a/capsulflask/static/style.css b/capsulflask/static/style.css index df7c84c..9122197 100644 --- a/capsulflask/static/style.css +++ b/capsulflask/static/style.css @@ -23,21 +23,15 @@ a { text-shadow: 1px 1px 0px #000c; } +a.no-shadow { + text-shadow: initial; +} + a:hover, a:active, a:visited { color: #b5bd68; } -.nav-row { - display: flex; - justify-content: space-between; -} -.nav-row a { - white-space: nowrap; -} -.nav-row:last-child { - justify-content: center; -} -.nav-row:last-child a { +.nav-links a { margin: 0 1em; } @@ -88,6 +82,9 @@ main { justify-content: space-around; width: 100%; } +.center { + align-items: center; +} .wrap { flex-wrap: wrap; } @@ -104,10 +101,19 @@ main { justify-content: flex-end; } +.justify-space-between { + justify-content: space-between; +} +.justify-center { + justify-content: center; +} + + form { display: flex; flex-direction: column; align-items: flex-start; + margin: 0; } label.align { @@ -170,6 +176,14 @@ input[type=submit], select { cursor: pointer; } +input[type=submit].form-submit-link { + border: none; + background-color: initial; + color: #6CF; + padding: 0; + margin: 0; +} + input::-webkit-outer-spin-button, input::-webkit-inner-spin-button { -webkit-appearance: none; diff --git a/capsulflask/templates/base.html b/capsulflask/templates/base.html index bbdba33..68408ba 100644 --- a/capsulflask/templates/base.html +++ b/capsulflask/templates/base.html @@ -10,11 +10,12 @@