In this post, I will be sharing how I turned the server.destroy() and server.rebuild_now() pseudocode into actual Python.

server.destroy()

This function is triggered when a user cancels their subscription. It’s a very simple function, which consists of 5 “mini” functions:

_destroy_vps() — Destroys the VPS on Vultr

_destroy_snapshot() — Destroys the snapshot of the VPS on Vultr

_delete_cf_dns() — Deletes the A record from Cloudflare’s DNS

_get_cf_record_id() Helps _delete_cf_dns() figure out which record to delete

_delete_ovpn_file() — Deletes the OVPN file for this server from the GhostiFi webserver

Also, the server row is deleted from the database by the thread after server.destroy() finishes.

Output of server.py/server.destroy()

server.rebuild_now()

This function is triggered when someone clicks the “rebuild” button from the dashboard. The scheduled rebuilds will run on crons which I haven’t written yet, but will use this same code basically.

The server.rebuild_now() function consists of 5 “mini” functions. Notice that the _destroy_vps() function is actually reused from server.destroy().

_create_vps_from_snapshot() — Creates a new VPS on Vultr from the snapshot of the old VPS in whichever new location was specified in rebuild_now_location database column

_get_vps_status() — Checks status of VPS until it has completed installing

_update_cf_dns() — Updates the A record on Cloudflare after the VPS has finished installing, that way there is zero downtime caused by rebuilding

_update_bandwidth_this_month(old_vps_sub_id) — Copies the bandwidth used by the old VPS and adds it to the total bandwidth used this month, so that later bandwidth limitations can be enforced

_destroy_vps(old_vps_sub_id) — Destroys the old Vultr VPS

An error that occurs when a VPS is trying to rebuild but the original snapshot hasn’t finished yet
Rebuild being triggered without error
New VPN server being restored from snapshot beside the old one
The rest of the output of server.py/server.rebuild_now()

Updates made to openvpn-install.sh

One problem that I found during testing was that the openvpn-install.sh script was configuring the OVPN client file with an IP address instead of a hostname, so I changed that.

I also added “ping 3” and “ping-restart 10”, in order to force the client to failover to the new server faster. That translates to “ping the server every 3 seconds, and if you don’t get a reply after 10, then force a reconnect which will (hopefully) then resolve the server name to the new IP”

Server.py

https://gist.githubusercontent.com/reillychase/5a4879f544eefac806756a8e9a57b842/raw/afdb7df81c62bd80c978119f8f3b862d9534dd24/server.py

Closing thoughts

If you have any feedback on how I could improve this please let me know in the comments section!

I am also looking for feedback on the concept itself, as well as beta testers. Please sign up for the newsletter at https://ghostifi.net if you are interested.