This commit is contained in:
2026-06-21 03:53:06 +03:00
commit f1dd557c5d
147 changed files with 34363 additions and 0 deletions
+139
View File
@@ -0,0 +1,139 @@
import config from "../config.ts";
import axios from "axios";
import { VMManager, type VM } from "./base.ts";
const DO_TOKEN = config.DO_TOKEN;
const region = "sfo3";
const gatewayHost = config.DO_GATEWAY;
const sshKeys = config.DO_SSH_KEYS.split(",");
export class DigitalOcean extends VMManager {
size = "s-2vcpu-2gb"; // s-1vcpu-1gb, s-1vcpu-2gb, s-2vcpu-2gb, s-2vcpu-4gb, c-2, s-4vcpu-8gb
largeSize = "s-4vcpu-8gb";
minRetries = 5;
reuseVMs = true;
id = "DO";
imageId = config.DO_IMAGE;
startVM = async (name: string) => {
const response = await axios({
method: "POST",
url: `https://api.digitalocean.com/v2/droplets`,
headers: {
Authorization: "Bearer " + DO_TOKEN,
"Content-Type": "application/json",
},
data: {
name: name,
region: region,
size: this.isLarge ? this.largeSize : this.size,
image: Number(this.imageId),
ssh_keys: sshKeys,
private_networking: true,
// user_data: cloudInit(),
tags: [this.getTag()],
},
});
const id = response.data.droplet.id;
return id;
};
terminateVM = async (id: string) => {
const response = await axios({
method: "DELETE",
url: `https://api.digitalocean.com/v2/droplets/${id}`,
headers: {
Authorization: "Bearer " + DO_TOKEN,
"Content-Type": "application/json",
},
});
};
rebootVM = async (id: string) => {
// Reboot the VM
const response2 = await axios({
method: "POST",
url: `https://api.digitalocean.com/v2/droplets/${id}/actions`,
headers: {
Authorization: "Bearer " + DO_TOKEN,
"Content-Type": "application/json",
},
data: {
type: "reboot",
},
});
return;
};
reimageVM = async (id: string) => {
// Rebuild the VM
const response2 = await axios({
method: "POST",
url: `https://api.digitalocean.com/v2/droplets/${id}/actions`,
headers: {
Authorization: "Bearer " + DO_TOKEN,
"Content-Type": "application/json",
},
data: {
type: "rebuild",
image: Number(this.imageId),
},
});
return;
};
getVM = async (id: string) => {
const response = await axios({
method: "GET",
url: `https://api.digitalocean.com/v2/droplets/${id}`,
headers: {
Authorization: "Bearer " + DO_TOKEN,
"Content-Type": "application/json",
},
});
let server = this.mapServerObject(response.data.droplet);
return server;
};
listVMs = async (filter: string) => {
// console.log(filter, tags);
const response = await axios({
method: "GET",
url: `https://api.digitalocean.com/v2/droplets`,
headers: {
Authorization: "Bearer " + DO_TOKEN,
"Content-Type": "application/json",
},
params: {
// TODO need to update if over 100 results
per_page: 100,
tag_name: filter,
},
});
return response.data.droplets.map(this.mapServerObject);
};
powerOn = async (_id: string) => {};
attachToNetwork = async (_id: string) => {};
updateSnapshot = async () => {
return "";
};
mapServerObject = (server: any): VM => {
// const ip = server.networks.v4.find(
// (network: any) => network.type === 'private',
// )?.ip_address;
const ip = server.networks.v4.find(
(network: any) => network.type === "public",
)?.ip_address;
return {
id: server.id?.toString(),
// The gateway handles SSL termination and proxies to the private IP
host: ip ? `${gatewayHost}/?ip=${ip}` : "",
provider: this.id,
large: this.isLarge,
region: this.region,
};
};
}