jcloude/press/api/selfhosted.py
2025-12-23 21:34:08 +08:00

170 lines
4.2 KiB
Python

import time
import jingrow
from dns.resolver import Resolver
from jingrow.utils import strip
from jcloude.api.server import plans
from jcloude.runner import Ansible
from jcloude.utils import get_current_team
from jcloude.utils.dns import NAMESERVERS
@jingrow.whitelist()
def new(server):
server_details = jingrow._dict(server)
team = get_current_team(get_pg=True)
validate_team(team)
proxy_server = get_proxy_server_for_cluster()
return create_self_hosted_server(server_details, team, proxy_server)
def create_self_hosted_server(server_details, team, proxy_server):
try:
self_hosted_server = jingrow.new_pg(
"Self Hosted Server",
**{
"ip": strip(server_details.get("app_public_ip", "")),
"private_ip": strip(server_details.get("app_private_ip", "")),
"mariadb_ip": strip(server_details.get("db_public_ip", "")),
"mariadb_private_ip": strip(server_details.get("db_private_ip", "")),
"title": server_details.title,
"proxy_server": proxy_server,
"proxy_created": True,
"different_database_server": True,
"team": team.name,
"plan": server_details.plan["name"],
"database_plan": server_details.plan["name"],
"new_server": True,
},
).insert()
except jingrow.DuplicateEntryError as e:
# Exception return tupple like ('Self Hosted Server', 'SHS-00018.cloud.pressonprem.com')
return e.args[1]
return self_hosted_server.name
def validate_team(team):
if not team:
jingrow.throw("You must be part of a team to create a new server")
if not team.enabled:
jingrow.throw("You cannot create a new server because your account is disabled")
if not team.self_hosted_servers_enabled:
jingrow.throw(
"You cannot create a new server because Hybrid Cloud is disabled for your account. Please contact support to enable it."
)
def get_proxy_server_for_cluster(cluster=None):
cluster = cluster if cluster else get_hybrid_cluster()
return jingrow.get_all("Proxy Server", {"cluster": cluster}, pluck="name")[0]
def get_hybrid_cluster():
return jingrow.db.get_value("Cluster", {"hybrid": 1}, "name")
@jingrow.whitelist()
def sshkey():
return jingrow.db.get_value("SSH Key", {"enabled": 1, "default": 1}, "public_key")
@jingrow.whitelist()
def verify(server):
server_pg = jingrow.get_pg("Self Hosted Server", server)
app_server_verified = verify_server("app", server_pg)
db_server_verified = verify_server("db", server_pg)
if app_server_verified and db_server_verified:
server_pg.check_minimum_specs()
server_pg.status = "Pending"
server_pg.save()
server_pg.reload()
server_pg.create_database_server()
server_pg.reload()
server_pg.create_application_server()
return True
return False
def verify_server(server_type, server_pg):
ping = Ansible(
playbook="ping.yml",
server=jingrow._dict(
{
"pagetype": "Self Hosted Server",
"name": server_pg.name,
"ssh_user": server_pg.ssh_user,
"ssh_port": server_pg.ssh_port,
"ip": server_pg.ip if server_type == "app" else server_pg.mariadb_ip,
}
),
)
result = ping.run()
if result.status == "Success":
server_pg.validate_private_ip(result.name, server_type=server_type)
server_pg.fetch_system_specifications(result.name, server_type=server_type)
server_pg.reload()
return True
return False
@jingrow.whitelist()
def setup(server):
server_pg = jingrow.get_pg("Self Hosted Server", server)
server_pg.start_setup = True
server_pg.save()
server_pg.setup_server()
time.sleep(1)
@jingrow.whitelist()
def get_plans():
return plans("Self Hosted Server")
@jingrow.whitelist()
def check_dns(domain, ip):
try:
resolver = Resolver(configure=False)
resolver.nameservers = NAMESERVERS
domain_ip = resolver.query(domain.strip(), "A")[0].to_text()
if domain_ip == ip:
return True
except Exception:
return False
return False
@jingrow.whitelist()
def options_for_new():
return {"plans": get_plans(), "ssh_key": sshkey()}
@jingrow.whitelist()
def create_and_verify_selfhosted(server):
self_hosted_server_name = new(server)
if verify(self_hosted_server_name):
setup(self_hosted_server_name)
return jingrow.get_value("Self Hosted Server", self_hosted_server_name, "server")
jingrow.throw("Server verification failed. Please check the server details and try again.")
return None