forked from 3wordchant/capsul-flask
Compare commits
13 Commits
publicapi-
...
mock-hub-c
Author | SHA1 | Date | |
---|---|---|---|
6dbe2b5c86 | |||
f7461d5a28 | |||
9f23638959 | |||
8f2becb9ee | |||
f848eda931 | |||
46f49e8d8f | |||
36329796f0 | |||
28271ee852 | |||
7923f3a99f | |||
7ed847251f | |||
e3a4776a5d | |||
357d99cb91 | |||
b8279d7491 |
@ -31,7 +31,6 @@ load_dotenv(find_dotenv())
|
|||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
|
|
||||||
app.config.from_mapping(
|
app.config.from_mapping(
|
||||||
|
|
||||||
BASE_URL=os.environ.get("BASE_URL", default="http://localhost:5000"),
|
BASE_URL=os.environ.get("BASE_URL", default="http://localhost:5000"),
|
||||||
SECRET_KEY=os.environ.get("SECRET_KEY", default="dev"),
|
SECRET_KEY=os.environ.get("SECRET_KEY", default="dev"),
|
||||||
HUB_MODE_ENABLED=os.environ.get("HUB_MODE_ENABLED", default="True").lower() in ['true', '1', 't', 'y', 'yes'],
|
HUB_MODE_ENABLED=os.environ.get("HUB_MODE_ENABLED", default="True").lower() in ['true', '1', 't', 'y', 'yes'],
|
||||||
@ -72,7 +71,7 @@ app.config.from_mapping(
|
|||||||
#STRIPE_WEBHOOK_SECRET=os.environ.get("STRIPE_WEBHOOK_SECRET", default="")
|
#STRIPE_WEBHOOK_SECRET=os.environ.get("STRIPE_WEBHOOK_SECRET", default="")
|
||||||
|
|
||||||
BTCPAY_PRIVATE_KEY=os.environ.get("BTCPAY_PRIVATE_KEY", default="").replace("\\n", "\n"),
|
BTCPAY_PRIVATE_KEY=os.environ.get("BTCPAY_PRIVATE_KEY", default="").replace("\\n", "\n"),
|
||||||
BTCPAY_URL=os.environ.get("BTCPAY_URL", default="https://btcpay.cyberia.club")
|
BTCPAY_URL=os.environ.get("BTCPAY_URL", default="")
|
||||||
)
|
)
|
||||||
|
|
||||||
app.config['HUB_URL'] = os.environ.get("HUB_URL", default=app.config['BASE_URL'])
|
app.config['HUB_URL'] = os.environ.get("HUB_URL", default=app.config['BASE_URL'])
|
||||||
@ -140,10 +139,13 @@ else:
|
|||||||
|
|
||||||
app.config['HTTP_CLIENT'] = MyHTTPClient(timeout_seconds=int(app.config['INTERNAL_HTTP_TIMEOUT_SECONDS']))
|
app.config['HTTP_CLIENT'] = MyHTTPClient(timeout_seconds=int(app.config['INTERNAL_HTTP_TIMEOUT_SECONDS']))
|
||||||
|
|
||||||
try:
|
app.config['BTCPAY_ENABLED'] = False
|
||||||
app.config['BTCPAY_CLIENT'] = btcpay.Client(api_uri=app.config['BTCPAY_URL'], pem=app.config['BTCPAY_PRIVATE_KEY'])
|
if app.config['BTCPAY_URL'] != "":
|
||||||
except:
|
try:
|
||||||
app.logger.warning("unable to create btcpay client. Capsul will work fine except cryptocurrency payments will not work. The error was: " + my_exec_info_message(sys.exc_info()))
|
app.config['BTCPAY_CLIENT'] = btcpay.Client(api_uri=app.config['BTCPAY_URL'], pem=app.config['BTCPAY_PRIVATE_KEY'])
|
||||||
|
app.config['BTCPAY_ENABLED'] = True
|
||||||
|
except:
|
||||||
|
app.logger.warning("unable to create btcpay client. Capsul will work fine except cryptocurrency payments will not work. The error was: " + my_exec_info_message(sys.exc_info()))
|
||||||
|
|
||||||
# only start the scheduler and attempt to migrate the database if we are running the app.
|
# only start the scheduler and attempt to migrate the database if we are running the app.
|
||||||
# otherwise we are running a CLI command.
|
# otherwise we are running a CLI command.
|
||||||
@ -219,7 +221,6 @@ def override_url_for():
|
|||||||
return dict(url_for=url_for_with_cache_bust)
|
return dict(url_for=url_for_with_cache_bust)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def url_for_with_cache_bust(endpoint, **values):
|
def url_for_with_cache_bust(endpoint, **values):
|
||||||
"""
|
"""
|
||||||
Add a query parameter based on the hash of the file, this acts as a cache bust
|
Add a query parameter based on the hash of the file, this acts as a cache bust
|
||||||
@ -244,7 +245,3 @@ def url_for_with_cache_bust(endpoint, **values):
|
|||||||
values['q'] = current_app.config['STATIC_FILE_HASH_CACHE'][filename]
|
values['q'] = current_app.config['STATIC_FILE_HASH_CACHE'][filename]
|
||||||
|
|
||||||
return url_for(endpoint, **values)
|
return url_for(endpoint, **values)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -423,6 +423,7 @@ def account_balance():
|
|||||||
has_vms=len(vms_billed)>0,
|
has_vms=len(vms_billed)>0,
|
||||||
vms_billed=vms_billed,
|
vms_billed=vms_billed,
|
||||||
warning_text=warning_text,
|
warning_text=warning_text,
|
||||||
|
btcpay_enabled=current_app.config["BTCPAY_ENABLED"],
|
||||||
payments=list(map(
|
payments=list(map(
|
||||||
lambda x: dict(
|
lambda x: dict(
|
||||||
dollars=x["dollars"],
|
dollars=x["dollars"],
|
||||||
|
@ -17,6 +17,10 @@ from capsulflask.http_client import HTTPResult
|
|||||||
from capsulflask.shared import VirtualizationInterface, VirtualMachine, OnlineHost, validate_capsul_id, my_exec_info_message
|
from capsulflask.shared import VirtualizationInterface, VirtualMachine, OnlineHost, validate_capsul_id, my_exec_info_message
|
||||||
|
|
||||||
class MockHub(VirtualizationInterface):
|
class MockHub(VirtualizationInterface):
|
||||||
|
def __init__(self):
|
||||||
|
self.default_network = "public1"
|
||||||
|
self.default_ipv4 = "1.1.1.1"
|
||||||
|
|
||||||
def capacity_avaliable(self, additional_ram_bytes):
|
def capacity_avaliable(self, additional_ram_bytes):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@ -29,9 +33,9 @@ class MockHub(VirtualizationInterface):
|
|||||||
{"key_type":"RSA", "content":"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCvotgzgEP65JUQ8S8OoNKy1uEEPEAcFetSp7QpONe6hj4wPgyFNgVtdoWdNcU19dX3hpdse0G8OlaMUTnNVuRlbIZXuifXQ2jTtCFUA2mmJ5bF+XjGm3TXKMNGh9PN+wEPUeWd14vZL+QPUMev5LmA8cawPiU5+vVMLid93HRBj118aCJFQxLgrdP48VPfKHFRfCR6TIjg1ii3dH4acdJAvlmJ3GFB6ICT42EmBqskz2MPe0rIFxH8YohCBbAbrbWYcptHt4e48h4UdpZdYOhEdv89GrT8BF2C5cbQ5i9qVpI57bXKrj8hPZU5of48UHLSpXG8mbH0YDiOQOfKX/Mt", "sha256":"ghee6KzRnBJhND2kEUZSaouk7CD6o6z2aAc8GPkV+GQ"},
|
{"key_type":"RSA", "content":"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCvotgzgEP65JUQ8S8OoNKy1uEEPEAcFetSp7QpONe6hj4wPgyFNgVtdoWdNcU19dX3hpdse0G8OlaMUTnNVuRlbIZXuifXQ2jTtCFUA2mmJ5bF+XjGm3TXKMNGh9PN+wEPUeWd14vZL+QPUMev5LmA8cawPiU5+vVMLid93HRBj118aCJFQxLgrdP48VPfKHFRfCR6TIjg1ii3dH4acdJAvlmJ3GFB6ICT42EmBqskz2MPe0rIFxH8YohCBbAbrbWYcptHt4e48h4UdpZdYOhEdv89GrT8BF2C5cbQ5i9qVpI57bXKrj8hPZU5of48UHLSpXG8mbH0YDiOQOfKX/Mt", "sha256":"ghee6KzRnBJhND2kEUZSaouk7CD6o6z2aAc8GPkV+GQ"},
|
||||||
{"key_type":"ECDSA", "content":"ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBLLgOoATz9R4aS2kk7vWoxX+lshK63t9+5BIHdzZeFE1o+shlcf0Wji8cN/L1+m3bi0uSETZDOAWMP3rHLJj9Hk=", "sha256":"aCYG1aD8cv/TjzJL0bi9jdabMGksdkfa7R8dCGm1yYs"}
|
{"key_type":"ECDSA", "content":"ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBLLgOoATz9R4aS2kk7vWoxX+lshK63t9+5BIHdzZeFE1o+shlcf0Wji8cN/L1+m3bi0uSETZDOAWMP3rHLJj9Hk=", "sha256":"aCYG1aD8cv/TjzJL0bi9jdabMGksdkfa7R8dCGm1yYs"}
|
||||||
]""")
|
]""")
|
||||||
return VirtualMachine(id, current_app.config["SPOKE_HOST_ID"], ipv4="1.1.1.1", ssh_host_keys=ssh_host_keys)
|
return VirtualMachine(id, current_app.config["SPOKE_HOST_ID"], ipv4=self.default_ipv4, ssh_host_keys=ssh_host_keys)
|
||||||
|
|
||||||
return VirtualMachine(id, current_app.config["SPOKE_HOST_ID"], ipv4="1.1.1.1")
|
return VirtualMachine(id, current_app.config["SPOKE_HOST_ID"], ipv4=self.default_ipv4)
|
||||||
|
|
||||||
def list_ids(self) -> list:
|
def list_ids(self) -> list:
|
||||||
return get_model().all_non_deleted_vm_ids()
|
return get_model().all_non_deleted_vm_ids()
|
||||||
@ -40,6 +44,16 @@ class MockHub(VirtualizationInterface):
|
|||||||
validate_capsul_id(id)
|
validate_capsul_id(id)
|
||||||
current_app.logger.info(f"mock create: {id} for {email}")
|
current_app.logger.info(f"mock create: {id} for {email}")
|
||||||
sleep(1)
|
sleep(1)
|
||||||
|
get_model().create_vm(
|
||||||
|
email=email,
|
||||||
|
id=id,
|
||||||
|
size=size,
|
||||||
|
os=os,
|
||||||
|
host=current_app.config["SPOKE_HOST_ID"],
|
||||||
|
network_name=self.default_network,
|
||||||
|
public_ipv4=self.default_ipv4,
|
||||||
|
ssh_authorized_keys=list(map(lambda x: x["name"], ssh_authorized_keys)),
|
||||||
|
)
|
||||||
|
|
||||||
def destroy(self, email: str, id: str):
|
def destroy(self, email: str, id: str):
|
||||||
current_app.logger.info(f"mock destroy: {id} for {email}")
|
current_app.logger.info(f"mock destroy: {id} for {email}")
|
||||||
@ -49,7 +63,6 @@ class MockHub(VirtualizationInterface):
|
|||||||
|
|
||||||
|
|
||||||
class CapsulFlaskHub(VirtualizationInterface):
|
class CapsulFlaskHub(VirtualizationInterface):
|
||||||
|
|
||||||
def synchronous_operation(self, hosts: List[OnlineHost], email: str, payload: str) -> List[HTTPResult]:
|
def synchronous_operation(self, hosts: List[OnlineHost], email: str, payload: str) -> List[HTTPResult]:
|
||||||
return self.generic_operation(hosts, email, payload, True)[1]
|
return self.generic_operation(hosts, email, payload, True)[1]
|
||||||
|
|
||||||
@ -262,4 +275,3 @@ class CapsulFlaskHub(VirtualizationInterface):
|
|||||||
|
|
||||||
if not result_status == "success":
|
if not result_status == "success":
|
||||||
raise ValueError(f"""failed to {command} vm "{id}" on host "{host.id}" for {email}: {result_json_string}""")
|
raise ValueError(f"""failed to {command} vm "{id}" on host "{host.id}" for {email}: {result_json_string}""")
|
||||||
|
|
||||||
|
@ -12,9 +12,11 @@ def index():
|
|||||||
|
|
||||||
@bp.route("/pricing")
|
@bp.route("/pricing")
|
||||||
def pricing():
|
def pricing():
|
||||||
|
vm_sizes = get_model().vm_sizes_dict()
|
||||||
operating_systems = get_model().operating_systems_dict()
|
operating_systems = get_model().operating_systems_dict()
|
||||||
return render_template(
|
return render_template(
|
||||||
"pricing.html",
|
"pricing.html",
|
||||||
|
vm_sizes=vm_sizes,
|
||||||
operating_systems=operating_systems
|
operating_systems=operating_systems
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -48,6 +48,10 @@ def validate_dollars():
|
|||||||
def btcpay_payment():
|
def btcpay_payment():
|
||||||
errors = list()
|
errors = list()
|
||||||
|
|
||||||
|
if not current_app.config['BTCPAY_ENABLED']:
|
||||||
|
flash("BTCPay is not enabled on this server")
|
||||||
|
return redirect(url_for("console.account_balance"))
|
||||||
|
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
result = validate_dollars()
|
result = validate_dollars()
|
||||||
errors = result[0]
|
errors = result[0]
|
||||||
|
@ -241,7 +241,6 @@ thead {
|
|||||||
background: #bdc7b812;
|
background: #bdc7b812;
|
||||||
}
|
}
|
||||||
td, th {
|
td, th {
|
||||||
|
|
||||||
padding: 0.1em 1em;
|
padding: 0.1em 1em;
|
||||||
}
|
}
|
||||||
table.small td, table.small th {
|
table.small td, table.small th {
|
||||||
|
@ -46,7 +46,9 @@
|
|||||||
<a href="/payment/stripe">Add funds with Credit/Debit (stripe)</a>
|
<a href="/payment/stripe">Add funds with Credit/Debit (stripe)</a>
|
||||||
<ul><li>notice: stripe will load nonfree javascript </li></ul>
|
<ul><li>notice: stripe will load nonfree javascript </li></ul>
|
||||||
</li>
|
</li>
|
||||||
|
{% if btcpay_enabled %}
|
||||||
<li><a href="/payment/btcpay">Add funds with Bitcoin/Litecoin/Monero (btcpay)</a></li>
|
<li><a href="/payment/btcpay">Add funds with Bitcoin/Litecoin/Monero (btcpay)</a></li>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
<li>Cash: email <a href="mailto:treasurer@cyberia.club">treasurer@cyberia.club</a></li>
|
<li>Cash: email <a href="mailto:treasurer@cyberia.club">treasurer@cyberia.club</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
How do I log in?
|
How do I log in?
|
||||||
<p>ssh to the ip provided to you using the cyberian user.</p>
|
<p>ssh to the ip provided to you using the cyberian user.</p>
|
||||||
<pre class='code'>$ ssh cyberian@1.2.3.4</pre>
|
<pre class='code'>$ ssh cyberian@1.2.3.4</pre>
|
||||||
|
<p>For more information, see <a href="/about-ssh">Understanding the Secure Shell Protocol (SSH)</a>.</p>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
How do I change to the root user?
|
How do I change to the root user?
|
||||||
|
@ -6,22 +6,38 @@
|
|||||||
<div class="row third-margin">
|
<div class="row third-margin">
|
||||||
<h1>CAPSUL TYPES & PRICING</h1>
|
<h1>CAPSUL TYPES & PRICING</h1>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="row half-margin">
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>type</th>
|
||||||
|
<th>monthly*</th>
|
||||||
|
<th>cpus</th>
|
||||||
|
<th>mem</th>
|
||||||
|
<th>ssd</th>
|
||||||
|
<th>net</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for vm_size_key, vm_size in vm_sizes.items() %}
|
||||||
|
<tr>
|
||||||
|
<td>{{ vm_size_key }}</td>
|
||||||
|
<td>${{ vm_size['dollars_per_month'] }}</td>
|
||||||
|
<td>{{ vm_size['vcpus'] }}</td>
|
||||||
|
<td>{{ vm_size['memory_mb'] }}</td>
|
||||||
|
<td>25G</td>
|
||||||
|
<td>{{ vm_size['bandwidth_gb_per_month'] }}</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
<div class="row half-margin">
|
<div class="row half-margin">
|
||||||
<pre>
|
<pre>
|
||||||
type monthly* cpus mem ssd net*
|
|
||||||
----- ------- ---- --- --- ---
|
|
||||||
f1-xs $5.00 1 512M 25G .5TB
|
|
||||||
f1-s $7.50 1 1024M 25G 1TB
|
|
||||||
f1-m $12.50 1 2048M 25G 2TB
|
|
||||||
f1-l $20.00 2 3072M 25G 3TB
|
|
||||||
f1-x $27.50 3 4096M 25G 4TB
|
|
||||||
f1-xx $50.00 4 8192M 25G 5TB
|
|
||||||
|
|
||||||
* net is calculated as a per-month average
|
* net is calculated as a per-month average
|
||||||
* vms are billed for a minimum of 24 hours upon creation
|
* vms are billed for a minimum of 24 hours upon creation
|
||||||
* all VMs come standard with one public IPv4 address
|
* all VMs come standard with one public IPv4 address
|
||||||
|
|
||||||
|
|
||||||
SUPPORTED OPERATING SYSTEMS:
|
SUPPORTED OPERATING SYSTEMS:
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user