jcloud/jcloud/api/selfhosted.py
2025-04-12 17:39:38 +08:00

174 lines
4.3 KiB
Python

import time
import jingrow
from dns.resolver import Resolver
from jingrow.utils import strip
from jcloud.api.server import plans
from jcloud.api.site import NAMESERVERS
from jcloud.runner import Ansible
from jcloud.utils import get_current_team
@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.jcloudonprem.com')
server_name = e.args[1]
return server_name
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 = get_hybrid_cluster() if not cluster else 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():
server_plan = plans("Self Hosted Server")
return server_plan
@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")
else:
jingrow.throw(
"Server verification failed. Please check the server details and try again."
)