import {Injectable, Model, Field, FieldType} from '@extollo/lib' import {IpAddress, Subnet} from '../types' import {Host, SSHHost} from '../support/hosts' import * as ssh2 from 'ssh2' import * as sshpk from 'sshpk' import {Setting} from './Setting.model' import {PCTHost} from '../support/hosts/PCTHost' /** * Node Model * ----------------------------------- * Represents a single LXC container running a K8s worker node. */ @Injectable() export class Node extends Model { protected static table = 'p5x_nodes' protected static key = 'node_id' @Field(FieldType.serial) public id?: number @Field(FieldType.varchar, 'pve_id') public pveId!: number @Field(FieldType.varchar) public hostname!: string @Field(FieldType.varchar, 'assigned_ip') public assignedIp!: IpAddress @Field(FieldType.int, 'assigned_subnet') public assignedSubnet!: Subnet @Field(FieldType.bool, 'is_permanent') public isPermanent: boolean = false @Field(FieldType.bool, 'is_master') public isMaster: boolean = false public async getHost(): Promise { // Try to make a direct SSH connection to the container const privKey = await Setting.loadOneRequired('sshPrivateKey') const formattedPrivKey = sshpk.parsePrivateKey(privKey, 'pem', {passphrase: ''}).toString('ssh') const directHost = this.container().makeNew(SSHHost, { host: this.assignedIp, username: 'root', privateKey: formattedPrivKey, } as ssh2.ConnectConfig) if ( await directHost.isAlive() ) { return directHost } // Otherwise, fall back to the PCTHost proxy return this.container().makeNew(PCTHost, { host: await Setting.loadOneRequired('pveApiHost'), username: 'root', password: await Setting.loadOneRequired('pveRootPassword'), }, this.pveId) } }