-
Notifications
You must be signed in to change notification settings - Fork 12
/
resize.ts
159 lines (139 loc) · 4.56 KB
/
resize.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
import ora from 'ora';
import inquirer from 'inquirer';
import Command from '../../base.js';
import { Flags } from '@oclif/core';
import { createDebugLogger } from '../../utils/output.js';
import IGetDatabasesResponse from '../../types/get-dbs-response.js';
import spacing from '../../utils/spacing.js';
export default class Resize extends Command {
static description = 'resize a database';
static PATH = 'v1/databases/{database-id}/resize';
static flags = {
...Command.flags,
name: Flags.string({
char: 'n',
description: 'name of your database',
}),
plan: Flags.string({
description: 'new plan name',
}),
disk: Flags.string({
char: 'd',
description: 'extend disk size or not',
}),
};
async run(): Promise<void> {
this.spinner = ora();
const { flags } = await this.parse(Resize);
const debug = createDebugLogger(flags.debug);
await this.setGotConfig(flags);
const account = await this.getCurrentAccount();
((account && account.region === 'germany') || flags.region === 'germany') &&
this.error('We do not support germany any more.');
const hostname = flags.name || (await this.promptHostname());
const disk =
flags.disk === 'y'
? true
: flags.disk === 'n'
? false
: (await this.promptDisk()) === 'y'
? true
: false;
try {
const database = await this.getDatabaseByHostname(hostname);
if (database === undefined) {
this.log(`Database ${hostname} not found`);
return;
}
const planID = flags.plan || (await this.promptPlan(database.type));
const databaseID = database._id;
await this.got.post(Resize.PATH.replace('{database-id}', databaseID), {
json: { planID: planID, disk: disk },
});
this.log(`Database ${hostname} changed to plan ${planID}.`);
} catch (error) {
debug(error.message);
if (error.response && error.response.body) {
debug(JSON.stringify(error.response.body));
}
this.error(`Could not change the plan now. Please try again later.`);
}
}
async promptHostname() {
const { name } = (await inquirer.prompt({
name: 'name',
type: 'input',
message: 'Enter name:',
validate: (input) => input.length > 2,
})) as { name: string };
return name;
}
async getDatabaseByHostname(hostname: string) {
const { databases } = await this.got(
'v1/databases'
).json<IGetDatabasesResponse>();
if (!databases.length) {
this.error(`Not found any database.
Please open up https://console.liara.ir/databases and create the database, first.`);
}
const database = databases.find(
(database) => database.hostname === hostname
);
return database;
}
async promptPlan(databaseType: string) {
this.spinner.start('Loading...');
try {
const { plans } = await this.got('v1/me').json<{ plans: any }>();
this.spinner.stop();
const { plan } = (await inquirer.prompt({
name: 'plan',
type: 'list',
message: 'Please select new plan:',
choices: [
...Object.keys(plans.databases)
.filter((plan) => {
if (
plans.databases[plan].available &&
plans.databases[plan].supports.includes(databaseType)
) {
return true;
}
})
.map((plan) => {
const availablePlan = plans.databases[plan];
const ram = availablePlan.RAM.amount;
const cpu = availablePlan.CPU.amount;
const disk = availablePlan.volume;
const price = availablePlan.price * 720;
const storageClass = availablePlan.storageClass;
return {
value: plan,
name: `RAM: ${ram}${spacing(5, ram)}GB, CPU: ${cpu}${spacing(
5,
cpu
)}Core, Disk: ${disk}${spacing(3, disk) + 'GB'}${
storageClass || 'SSD'
}, Price: ${price.toLocaleString()}${
price ? spacing(7, price) + 'Tomans/Month' : ''
}`,
};
}),
],
})) as { plan: string };
return plan;
} catch (error) {
this.spinner.stop();
throw error;
}
}
async promptDisk() {
const { disk } = (await inquirer.prompt({
name: 'disk',
type: 'input',
message: 'extend disk size? (y/n):',
validate: (input) => input === 'y' || input === 'n',
})) as { disk: string };
return disk;
}
}