import * as plugins from '../plugins.js'; import { Cloudly } from '../classes.cloudly.js'; import { Cluster } from '../manager.cluster/classes.cluster.js'; import { Server } from './classes.server.js'; import { CurlFresh } from './classes.curlfresh.js'; export class CloudlyServerManager { public cloudlyRef: Cloudly; public typedRouter = new plugins.typedrequest.TypedRouter(); public curlfreshInstance = new CurlFresh(this); public hetznerAccount: plugins.hetznercloud.HetznerAccount; public get db() { return this.cloudlyRef.mongodbConnector.smartdataDb; } public CServer = plugins.smartdata.setDefaultManagerForDoc(this, Server); constructor(cloudlyRefArg: Cloudly) { this.cloudlyRef = cloudlyRefArg; /** * is used be serverconfig module on the server to get the actual server config */ this.typedRouter.addTypedHandler( new plugins.typedrequest.TypedHandler( 'getServerConfig', async (requestData) => { const serverId = requestData.serverId; const server = await this.CServer.getInstance({ id: serverId, }) return { configData: await server.createSavableObject(), }; } ) ); } public async start() { this.hetznerAccount = new plugins.hetznercloud.HetznerAccount(this.cloudlyRef.config.data.hetznerToken); } public async stop() {} /** * creates the server infrastructure on hetzner * ensures that there are exactly the reources that are needed * no more, no less */ public async ensureServerInfrastructure() { // get all clusters const allClusters = await this.cloudlyRef.clusterManager.getAllClusters(); for (const cluster of allClusters) { // get existing servers const servers = await this.getServersByCluster(cluster); // if there is no server, create one if (servers.length === 0) { const server = await this.hetznerAccount.createServer({ name: plugins.smartunique.uniSimple('server'), location: 'nbg1', type: 'cpx41', labels: { clusterId: cluster.id, priority: '1', }, userData: await this.curlfreshInstance.getServerUserData() }); const newServer = await Server.createFromHetznerServer(server); console.log(`cluster created new server for cluster ${cluster.id}`); } else { console.log(`cluster ${cluster.id} already has servers. Making sure that they actually exist in the real world...`); // if there is a server, make sure that it exists for (const server of servers) { const hetznerServer = await this.hetznerAccount.getServersByLabel({ 'clusterId': cluster.id }); if (!hetznerServer) { console.log(`server ${server.id} does not exist in the real world. Creating it now...`); const hetznerServer = await this.hetznerAccount.createServer({ name: plugins.smartunique.uniSimple('server'), location: 'nbg1', type: 'cpx41', labels: { clusterId: cluster.id, priority: '1', } }); const newServer = await Server.createFromHetznerServer(hetznerServer); } } } } } public async getServersByCluster(clusterArg: Cluster) { const results = await this.CServer.getInstances({ data: { assignedClusterId: clusterArg.id, } }); return results; } }