160 lines
4.5 KiB
TypeScript
160 lines
4.5 KiB
TypeScript
import config from "../config.ts";
|
|
import axios from "axios";
|
|
import { VMManager, type VM } from "./base.ts";
|
|
|
|
const SCW_SECRET_KEY = config.SCW_SECRET_KEY;
|
|
const SCW_ORGANIZATION_ID = config.SCW_ORGANIZATION_ID;
|
|
const region = "nl-ams-1"; //fr-par-1
|
|
const gatewayHost = config.SCW_GATEWAY;
|
|
|
|
export class Scaleway extends VMManager {
|
|
size = "DEV1-S"; // DEV1-S, DEV1-M, DEV1-L, GP1-XS
|
|
largeSize = "DEV1-M";
|
|
minRetries = 5;
|
|
reuseVMs = true;
|
|
id = "Scaleway";
|
|
imageId = config.SCW_IMAGE;
|
|
startVM = async (name: string) => {
|
|
const response = await axios({
|
|
method: "POST",
|
|
url: `https://api.scaleway.com/instance/v1/zones/${region}/servers`,
|
|
headers: {
|
|
"X-Auth-Token": SCW_SECRET_KEY,
|
|
"Content-Type": "application/json",
|
|
},
|
|
data: {
|
|
name: name,
|
|
dynamic_ip_required: true,
|
|
commercial_type: this.isLarge ? this.largeSize : this.size,
|
|
image: this.imageId,
|
|
volumes: {},
|
|
organization: SCW_ORGANIZATION_ID,
|
|
tags: [this.getTag()],
|
|
},
|
|
});
|
|
// console.log(response.data);
|
|
const id = response.data.server.id;
|
|
const response2 = await axios({
|
|
method: "PATCH",
|
|
url: `https://api.scaleway.com/instance/v1/zones/${region}/servers/${id}/user_data/cloud-init`,
|
|
headers: {
|
|
"X-Auth-Token": SCW_SECRET_KEY,
|
|
"Content-Type": "text/plain",
|
|
},
|
|
// set userdata for boot action
|
|
//data: cloudInit(),
|
|
});
|
|
// console.log(response2.data);
|
|
// boot the instance
|
|
const response3 = await axios({
|
|
method: "POST",
|
|
url: `https://api.scaleway.com/instance/v1/zones/${region}/servers/${id}/action`,
|
|
headers: {
|
|
"X-Auth-Token": SCW_SECRET_KEY,
|
|
"Content-Type": "application/json",
|
|
},
|
|
data: {
|
|
action: "poweron",
|
|
},
|
|
});
|
|
// console.log(response3.data);
|
|
return id;
|
|
};
|
|
|
|
terminateVM = async (id: string) => {
|
|
const response = await axios({
|
|
method: "POST",
|
|
url: `https://api.scaleway.com/instance/v1/zones/${region}/servers/${id}/action`,
|
|
headers: {
|
|
"X-Auth-Token": SCW_SECRET_KEY,
|
|
"Content-Type": "application/json",
|
|
},
|
|
data: {
|
|
action: "terminate",
|
|
},
|
|
});
|
|
};
|
|
|
|
rebootVM = async (id: string) => {
|
|
// Reboot the VM (also destroys the Docker container since it has --rm flag)
|
|
const response2 = await axios({
|
|
method: "POST",
|
|
url: `https://api.scaleway.com/instance/v1/zones/${region}/servers/${id}/action`,
|
|
headers: {
|
|
"X-Auth-Token": SCW_SECRET_KEY,
|
|
"Content-Type": "application/json",
|
|
},
|
|
data: {
|
|
action: "reboot",
|
|
},
|
|
});
|
|
return;
|
|
};
|
|
|
|
reimageVM = async (id: string) => {
|
|
// Scaleway doesn't have a reimage/rebuild command. Delete the VM
|
|
await this.terminateVMWrapper(id);
|
|
};
|
|
|
|
getVM = async (id: string) => {
|
|
const response = await axios({
|
|
method: "GET",
|
|
url: `https://api.scaleway.com/instance/v1/zones/${region}/servers/${id}`,
|
|
headers: {
|
|
"X-Auth-Token": SCW_SECRET_KEY,
|
|
"Content-Type": "application/json",
|
|
},
|
|
});
|
|
let server = this.mapServerObject(response.data.server);
|
|
return server;
|
|
};
|
|
|
|
listVMs = async (filter: string) => {
|
|
const limit = this.getLimitSize();
|
|
const pageCount = Math.ceil((limit || 1) / 100);
|
|
const pages = Array.from(Array(pageCount).keys()).map((i) => i + 1);
|
|
const responses: any[] = await Promise.all(
|
|
pages.map((page) =>
|
|
axios({
|
|
method: "GET",
|
|
url: `https://api.scaleway.com/instance/v1/zones/${region}/servers`,
|
|
headers: {
|
|
"X-Auth-Token": SCW_SECRET_KEY,
|
|
"Content-Type": "application/json",
|
|
},
|
|
params: {
|
|
page,
|
|
per_page: 100,
|
|
tags: filter,
|
|
},
|
|
}),
|
|
),
|
|
);
|
|
const responsesMapped = responses.map((response) =>
|
|
response.data.servers.map(this.mapServerObject),
|
|
);
|
|
return responsesMapped.flat();
|
|
};
|
|
|
|
powerOn = async (_id: string) => {};
|
|
|
|
attachToNetwork = async (_id: string) => {};
|
|
|
|
updateSnapshot = async () => {
|
|
return "";
|
|
};
|
|
|
|
mapServerObject = (server: any): VM => {
|
|
// const ip = server.private_ip;
|
|
const ip = server.public_ip?.address;
|
|
return {
|
|
id: server.id,
|
|
// 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,
|
|
};
|
|
};
|
|
}
|