hetzner-robot-cli 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +440 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +934 -0
- package/dist/client.d.ts +256 -0
- package/dist/client.js +656 -0
- package/dist/config.d.ts +41 -0
- package/dist/config.js +109 -0
- package/dist/formatter.d.ts +85 -0
- package/dist/formatter.js +617 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +9 -0
- package/dist/types.d.ts +352 -0
- package/dist/types.js +5 -0
- package/package.json +89 -0
package/dist/client.js
ADDED
|
@@ -0,0 +1,656 @@
|
|
|
1
|
+
// ============================================================================
|
|
2
|
+
// Hetzner Robot API Client
|
|
3
|
+
// Base URL: https://robot-ws.your-server.de
|
|
4
|
+
// Auth: HTTP Basic Authentication
|
|
5
|
+
// ============================================================================
|
|
6
|
+
const BASE_URL = 'https://robot-ws.your-server.de';
|
|
7
|
+
export class HetznerRobotClient {
|
|
8
|
+
auth;
|
|
9
|
+
constructor(username, password) {
|
|
10
|
+
this.auth = Buffer.from(`${username}:${password}`).toString('base64');
|
|
11
|
+
}
|
|
12
|
+
async request(endpoint, options = {}) {
|
|
13
|
+
const url = `${BASE_URL}${endpoint}`;
|
|
14
|
+
const headers = {
|
|
15
|
+
Authorization: `Basic ${this.auth}`,
|
|
16
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
17
|
+
Accept: 'application/json',
|
|
18
|
+
...options.headers,
|
|
19
|
+
};
|
|
20
|
+
const response = await fetch(url, {
|
|
21
|
+
...options,
|
|
22
|
+
headers,
|
|
23
|
+
});
|
|
24
|
+
if (!response.ok) {
|
|
25
|
+
let errorMessage = `HTTP ${response.status}: ${response.statusText}`;
|
|
26
|
+
try {
|
|
27
|
+
const errorBody = await response.json();
|
|
28
|
+
if (errorBody.error) {
|
|
29
|
+
errorMessage = `${errorBody.error.code ?? 'ERROR'}: ${errorBody.error.message ?? 'Unknown error'}`;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
// Use default error message
|
|
34
|
+
}
|
|
35
|
+
throw new Error(errorMessage);
|
|
36
|
+
}
|
|
37
|
+
// Handle 204 No Content
|
|
38
|
+
if (response.status === 204) {
|
|
39
|
+
return {};
|
|
40
|
+
}
|
|
41
|
+
return response.json();
|
|
42
|
+
}
|
|
43
|
+
encodeParams(params) {
|
|
44
|
+
const parts = [];
|
|
45
|
+
for (const [key, value] of Object.entries(params)) {
|
|
46
|
+
if (value === undefined)
|
|
47
|
+
continue;
|
|
48
|
+
if (Array.isArray(value)) {
|
|
49
|
+
for (const v of value) {
|
|
50
|
+
parts.push(`${encodeURIComponent(key)}[]=${encodeURIComponent(v)}`);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
parts.push(`${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return parts.join('&');
|
|
58
|
+
}
|
|
59
|
+
buildTrafficParams(trafficWarnings, trafficHourly, trafficDaily, trafficMonthly) {
|
|
60
|
+
return {
|
|
61
|
+
traffic_warnings: trafficWarnings,
|
|
62
|
+
traffic_hourly: trafficHourly,
|
|
63
|
+
traffic_daily: trafficDaily,
|
|
64
|
+
traffic_monthly: trafficMonthly,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
// =========================================================================
|
|
68
|
+
// Server Management
|
|
69
|
+
// =========================================================================
|
|
70
|
+
async listServers() {
|
|
71
|
+
return this.request('/server');
|
|
72
|
+
}
|
|
73
|
+
async getServer(serverIpOrNumber) {
|
|
74
|
+
return this.request(`/server/${serverIpOrNumber}`);
|
|
75
|
+
}
|
|
76
|
+
async updateServerName(serverIpOrNumber, name) {
|
|
77
|
+
return this.request(`/server/${serverIpOrNumber}`, {
|
|
78
|
+
method: 'POST',
|
|
79
|
+
body: this.encodeParams({ server_name: name }),
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
// =========================================================================
|
|
83
|
+
// Cancellation
|
|
84
|
+
// =========================================================================
|
|
85
|
+
async getCancellation(serverIpOrNumber) {
|
|
86
|
+
return this.request(`/server/${serverIpOrNumber}/cancellation`);
|
|
87
|
+
}
|
|
88
|
+
async cancelServer(serverIpOrNumber, cancellationDate, cancellationReason) {
|
|
89
|
+
const params = {};
|
|
90
|
+
if (cancellationDate)
|
|
91
|
+
params.cancellation_date = cancellationDate;
|
|
92
|
+
if (cancellationReason)
|
|
93
|
+
params.cancellation_reason = cancellationReason;
|
|
94
|
+
return this.request(`/server/${serverIpOrNumber}/cancellation`, {
|
|
95
|
+
method: 'POST',
|
|
96
|
+
body: this.encodeParams(params),
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
async revokeCancellation(serverIpOrNumber) {
|
|
100
|
+
await this.request(`/server/${serverIpOrNumber}/cancellation`, {
|
|
101
|
+
method: 'DELETE',
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
// =========================================================================
|
|
105
|
+
// Reset
|
|
106
|
+
// =========================================================================
|
|
107
|
+
async listResetOptions() {
|
|
108
|
+
return this.request('/reset');
|
|
109
|
+
}
|
|
110
|
+
async getResetOptions(serverIpOrNumber) {
|
|
111
|
+
return this.request(`/reset/${serverIpOrNumber}`);
|
|
112
|
+
}
|
|
113
|
+
async resetServer(serverIpOrNumber, type = 'sw') {
|
|
114
|
+
return this.request(`/reset/${serverIpOrNumber}`, {
|
|
115
|
+
method: 'POST',
|
|
116
|
+
body: this.encodeParams({ type }),
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
// =========================================================================
|
|
120
|
+
// Boot Configuration
|
|
121
|
+
// =========================================================================
|
|
122
|
+
async getBootConfig(serverIpOrNumber) {
|
|
123
|
+
return this.request(`/boot/${serverIpOrNumber}`);
|
|
124
|
+
}
|
|
125
|
+
// Rescue System
|
|
126
|
+
async getRescue(serverIpOrNumber) {
|
|
127
|
+
return this.request(`/boot/${serverIpOrNumber}/rescue`);
|
|
128
|
+
}
|
|
129
|
+
async activateRescue(serverIpOrNumber, os, arch, authorizedKeys) {
|
|
130
|
+
const params = { os };
|
|
131
|
+
if (arch)
|
|
132
|
+
params.arch = arch;
|
|
133
|
+
if (authorizedKeys)
|
|
134
|
+
params.authorized_key = authorizedKeys;
|
|
135
|
+
return this.request(`/boot/${serverIpOrNumber}/rescue`, {
|
|
136
|
+
method: 'POST',
|
|
137
|
+
body: this.encodeParams(params),
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
async deactivateRescue(serverIpOrNumber) {
|
|
141
|
+
return this.request(`/boot/${serverIpOrNumber}/rescue`, {
|
|
142
|
+
method: 'DELETE',
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
async getLastRescue(serverIpOrNumber) {
|
|
146
|
+
return this.request(`/boot/${serverIpOrNumber}/rescue/last`);
|
|
147
|
+
}
|
|
148
|
+
// Linux Install
|
|
149
|
+
async getLinux(serverIpOrNumber) {
|
|
150
|
+
return this.request(`/boot/${serverIpOrNumber}/linux`);
|
|
151
|
+
}
|
|
152
|
+
async activateLinux(serverIpOrNumber, dist, arch, lang, authorizedKeys) {
|
|
153
|
+
const params = { dist };
|
|
154
|
+
if (arch)
|
|
155
|
+
params.arch = arch;
|
|
156
|
+
if (lang)
|
|
157
|
+
params.lang = lang;
|
|
158
|
+
if (authorizedKeys)
|
|
159
|
+
params.authorized_key = authorizedKeys;
|
|
160
|
+
return this.request(`/boot/${serverIpOrNumber}/linux`, {
|
|
161
|
+
method: 'POST',
|
|
162
|
+
body: this.encodeParams(params),
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
async deactivateLinux(serverIpOrNumber) {
|
|
166
|
+
return this.request(`/boot/${serverIpOrNumber}/linux`, {
|
|
167
|
+
method: 'DELETE',
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
async getLastLinux(serverIpOrNumber) {
|
|
171
|
+
return this.request(`/boot/${serverIpOrNumber}/linux/last`);
|
|
172
|
+
}
|
|
173
|
+
// VNC Install
|
|
174
|
+
async getVnc(serverIpOrNumber) {
|
|
175
|
+
return this.request(`/boot/${serverIpOrNumber}/vnc`);
|
|
176
|
+
}
|
|
177
|
+
async activateVnc(serverIpOrNumber, dist, arch, lang) {
|
|
178
|
+
const params = { dist };
|
|
179
|
+
if (arch)
|
|
180
|
+
params.arch = arch;
|
|
181
|
+
if (lang)
|
|
182
|
+
params.lang = lang;
|
|
183
|
+
return this.request(`/boot/${serverIpOrNumber}/vnc`, {
|
|
184
|
+
method: 'POST',
|
|
185
|
+
body: this.encodeParams(params),
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
async deactivateVnc(serverIpOrNumber) {
|
|
189
|
+
return this.request(`/boot/${serverIpOrNumber}/vnc`, {
|
|
190
|
+
method: 'DELETE',
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
// Windows Install
|
|
194
|
+
async getWindows(serverIpOrNumber) {
|
|
195
|
+
return this.request(`/boot/${serverIpOrNumber}/windows`);
|
|
196
|
+
}
|
|
197
|
+
async activateWindows(serverIpOrNumber, dist, lang) {
|
|
198
|
+
const params = { dist };
|
|
199
|
+
if (lang)
|
|
200
|
+
params.lang = lang;
|
|
201
|
+
return this.request(`/boot/${serverIpOrNumber}/windows`, {
|
|
202
|
+
method: 'POST',
|
|
203
|
+
body: this.encodeParams(params),
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
async deactivateWindows(serverIpOrNumber) {
|
|
207
|
+
return this.request(`/boot/${serverIpOrNumber}/windows`, {
|
|
208
|
+
method: 'DELETE',
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
// =========================================================================
|
|
212
|
+
// IP Management
|
|
213
|
+
// =========================================================================
|
|
214
|
+
async listIps() {
|
|
215
|
+
return this.request('/ip');
|
|
216
|
+
}
|
|
217
|
+
async getIp(ip) {
|
|
218
|
+
return this.request(`/ip/${ip}`);
|
|
219
|
+
}
|
|
220
|
+
async updateIp(ip, trafficWarnings, trafficHourly, trafficDaily, trafficMonthly) {
|
|
221
|
+
return this.request(`/ip/${ip}`, {
|
|
222
|
+
method: 'POST',
|
|
223
|
+
body: this.encodeParams(this.buildTrafficParams(trafficWarnings, trafficHourly, trafficDaily, trafficMonthly)),
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
async getIpMac(ip) {
|
|
227
|
+
return this.request(`/ip/${ip}/mac`);
|
|
228
|
+
}
|
|
229
|
+
async generateIpMac(ip) {
|
|
230
|
+
return this.request(`/ip/${ip}/mac`, {
|
|
231
|
+
method: 'PUT',
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
async deleteIpMac(ip) {
|
|
235
|
+
await this.request(`/ip/${ip}/mac`, {
|
|
236
|
+
method: 'DELETE',
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
// =========================================================================
|
|
240
|
+
// Subnet Management
|
|
241
|
+
// =========================================================================
|
|
242
|
+
async listSubnets() {
|
|
243
|
+
return this.request('/subnet');
|
|
244
|
+
}
|
|
245
|
+
async getSubnet(netIp) {
|
|
246
|
+
return this.request(`/subnet/${netIp}`);
|
|
247
|
+
}
|
|
248
|
+
async updateSubnet(netIp, trafficWarnings, trafficHourly, trafficDaily, trafficMonthly) {
|
|
249
|
+
return this.request(`/subnet/${netIp}`, {
|
|
250
|
+
method: 'POST',
|
|
251
|
+
body: this.encodeParams(this.buildTrafficParams(trafficWarnings, trafficHourly, trafficDaily, trafficMonthly)),
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
async getSubnetMac(netIp) {
|
|
255
|
+
return this.request(`/subnet/${netIp}/mac`);
|
|
256
|
+
}
|
|
257
|
+
async generateSubnetMac(netIp) {
|
|
258
|
+
return this.request(`/subnet/${netIp}/mac`, {
|
|
259
|
+
method: 'PUT',
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
async deleteSubnetMac(netIp) {
|
|
263
|
+
await this.request(`/subnet/${netIp}/mac`, {
|
|
264
|
+
method: 'DELETE',
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
// =========================================================================
|
|
268
|
+
// Failover
|
|
269
|
+
// =========================================================================
|
|
270
|
+
async listFailovers() {
|
|
271
|
+
return this.request('/failover');
|
|
272
|
+
}
|
|
273
|
+
async getFailover(failoverIp) {
|
|
274
|
+
return this.request(`/failover/${failoverIp}`);
|
|
275
|
+
}
|
|
276
|
+
async switchFailover(failoverIp, activeServerIp) {
|
|
277
|
+
return this.request(`/failover/${failoverIp}`, {
|
|
278
|
+
method: 'POST',
|
|
279
|
+
body: this.encodeParams({ active_server_ip: activeServerIp }),
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
async deleteFailoverRouting(failoverIp) {
|
|
283
|
+
await this.request(`/failover/${failoverIp}`, {
|
|
284
|
+
method: 'DELETE',
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
// =========================================================================
|
|
288
|
+
// Reverse DNS
|
|
289
|
+
// =========================================================================
|
|
290
|
+
async listRdns() {
|
|
291
|
+
return this.request('/rdns');
|
|
292
|
+
}
|
|
293
|
+
async getRdns(ip) {
|
|
294
|
+
return this.request(`/rdns/${ip}`);
|
|
295
|
+
}
|
|
296
|
+
async createRdns(ip, ptr) {
|
|
297
|
+
return this.request(`/rdns/${ip}`, {
|
|
298
|
+
method: 'PUT',
|
|
299
|
+
body: this.encodeParams({ ptr }),
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
async updateRdns(ip, ptr) {
|
|
303
|
+
return this.request(`/rdns/${ip}`, {
|
|
304
|
+
method: 'POST',
|
|
305
|
+
body: this.encodeParams({ ptr }),
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
async deleteRdns(ip) {
|
|
309
|
+
await this.request(`/rdns/${ip}`, {
|
|
310
|
+
method: 'DELETE',
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
// =========================================================================
|
|
314
|
+
// SSH Keys
|
|
315
|
+
// =========================================================================
|
|
316
|
+
async listSshKeys() {
|
|
317
|
+
return this.request('/key');
|
|
318
|
+
}
|
|
319
|
+
async getSshKey(fingerprint) {
|
|
320
|
+
return this.request(`/key/${fingerprint}`);
|
|
321
|
+
}
|
|
322
|
+
async createSshKey(name, data) {
|
|
323
|
+
return this.request('/key', {
|
|
324
|
+
method: 'POST',
|
|
325
|
+
body: this.encodeParams({ name, data }),
|
|
326
|
+
});
|
|
327
|
+
}
|
|
328
|
+
async updateSshKey(fingerprint, name) {
|
|
329
|
+
return this.request(`/key/${fingerprint}`, {
|
|
330
|
+
method: 'POST',
|
|
331
|
+
body: this.encodeParams({ name }),
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
async deleteSshKey(fingerprint) {
|
|
335
|
+
await this.request(`/key/${fingerprint}`, {
|
|
336
|
+
method: 'DELETE',
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
// =========================================================================
|
|
340
|
+
// Firewall
|
|
341
|
+
// =========================================================================
|
|
342
|
+
async getFirewall(serverIpOrNumber) {
|
|
343
|
+
return this.request(`/firewall/${serverIpOrNumber}`);
|
|
344
|
+
}
|
|
345
|
+
async updateFirewall(serverIpOrNumber, status, rules) {
|
|
346
|
+
const params = { status };
|
|
347
|
+
if (rules) {
|
|
348
|
+
params['rules[input]'] = JSON.stringify(rules.input);
|
|
349
|
+
}
|
|
350
|
+
return this.request(`/firewall/${serverIpOrNumber}`, {
|
|
351
|
+
method: 'POST',
|
|
352
|
+
body: this.encodeParams(params),
|
|
353
|
+
});
|
|
354
|
+
}
|
|
355
|
+
async deleteFirewall(serverIpOrNumber) {
|
|
356
|
+
await this.request(`/firewall/${serverIpOrNumber}`, {
|
|
357
|
+
method: 'DELETE',
|
|
358
|
+
});
|
|
359
|
+
}
|
|
360
|
+
// Firewall Templates
|
|
361
|
+
async listFirewallTemplates() {
|
|
362
|
+
return this.request('/firewall/template');
|
|
363
|
+
}
|
|
364
|
+
async getFirewallTemplate(templateId) {
|
|
365
|
+
return this.request(`/firewall/template/${templateId}`);
|
|
366
|
+
}
|
|
367
|
+
async createFirewallTemplate(name, filterIpv6, whitelistHos, isDefault, rules) {
|
|
368
|
+
const params = { name };
|
|
369
|
+
if (filterIpv6 !== undefined)
|
|
370
|
+
params.filter_ipv6 = filterIpv6;
|
|
371
|
+
if (whitelistHos !== undefined)
|
|
372
|
+
params.whitelist_hos = whitelistHos;
|
|
373
|
+
if (isDefault !== undefined)
|
|
374
|
+
params.is_default = isDefault;
|
|
375
|
+
if (rules)
|
|
376
|
+
params['rules[input]'] = JSON.stringify(rules.input);
|
|
377
|
+
return this.request('/firewall/template', {
|
|
378
|
+
method: 'POST',
|
|
379
|
+
body: this.encodeParams(params),
|
|
380
|
+
});
|
|
381
|
+
}
|
|
382
|
+
async updateFirewallTemplate(templateId, name, filterIpv6, whitelistHos, isDefault, rules) {
|
|
383
|
+
const params = {};
|
|
384
|
+
if (name)
|
|
385
|
+
params.name = name;
|
|
386
|
+
if (filterIpv6 !== undefined)
|
|
387
|
+
params.filter_ipv6 = filterIpv6;
|
|
388
|
+
if (whitelistHos !== undefined)
|
|
389
|
+
params.whitelist_hos = whitelistHos;
|
|
390
|
+
if (isDefault !== undefined)
|
|
391
|
+
params.is_default = isDefault;
|
|
392
|
+
if (rules)
|
|
393
|
+
params['rules[input]'] = JSON.stringify(rules.input);
|
|
394
|
+
return this.request(`/firewall/template/${templateId}`, {
|
|
395
|
+
method: 'POST',
|
|
396
|
+
body: this.encodeParams(params),
|
|
397
|
+
});
|
|
398
|
+
}
|
|
399
|
+
async deleteFirewallTemplate(templateId) {
|
|
400
|
+
await this.request(`/firewall/template/${templateId}`, {
|
|
401
|
+
method: 'DELETE',
|
|
402
|
+
});
|
|
403
|
+
}
|
|
404
|
+
// =========================================================================
|
|
405
|
+
// vSwitch
|
|
406
|
+
// =========================================================================
|
|
407
|
+
async listVSwitches() {
|
|
408
|
+
return this.request('/vswitch');
|
|
409
|
+
}
|
|
410
|
+
async getVSwitch(id) {
|
|
411
|
+
return this.request(`/vswitch/${id}`);
|
|
412
|
+
}
|
|
413
|
+
async createVSwitch(name, vlan) {
|
|
414
|
+
return this.request('/vswitch', {
|
|
415
|
+
method: 'POST',
|
|
416
|
+
body: this.encodeParams({ name, vlan }),
|
|
417
|
+
});
|
|
418
|
+
}
|
|
419
|
+
async updateVSwitch(id, name, vlan) {
|
|
420
|
+
const params = {};
|
|
421
|
+
if (name)
|
|
422
|
+
params.name = name;
|
|
423
|
+
if (vlan !== undefined)
|
|
424
|
+
params.vlan = vlan;
|
|
425
|
+
return this.request(`/vswitch/${id}`, {
|
|
426
|
+
method: 'POST',
|
|
427
|
+
body: this.encodeParams(params),
|
|
428
|
+
});
|
|
429
|
+
}
|
|
430
|
+
async deleteVSwitch(id, cancellationDate) {
|
|
431
|
+
const params = {};
|
|
432
|
+
if (cancellationDate)
|
|
433
|
+
params.cancellation_date = cancellationDate;
|
|
434
|
+
await this.request(`/vswitch/${id}`, {
|
|
435
|
+
method: 'DELETE',
|
|
436
|
+
body: this.encodeParams(params),
|
|
437
|
+
});
|
|
438
|
+
}
|
|
439
|
+
async addServerToVSwitch(vswitchId, serverIpOrNumber) {
|
|
440
|
+
return this.request(`/vswitch/${vswitchId}/server`, {
|
|
441
|
+
method: 'POST',
|
|
442
|
+
body: this.encodeParams({ server: String(serverIpOrNumber) }),
|
|
443
|
+
});
|
|
444
|
+
}
|
|
445
|
+
async removeServerFromVSwitch(vswitchId, serverIpOrNumber) {
|
|
446
|
+
await this.request(`/vswitch/${vswitchId}/server`, {
|
|
447
|
+
method: 'DELETE',
|
|
448
|
+
body: this.encodeParams({ server: String(serverIpOrNumber) }),
|
|
449
|
+
});
|
|
450
|
+
}
|
|
451
|
+
// =========================================================================
|
|
452
|
+
// Storage Box
|
|
453
|
+
// =========================================================================
|
|
454
|
+
async listStorageBoxes() {
|
|
455
|
+
return this.request('/storagebox');
|
|
456
|
+
}
|
|
457
|
+
async getStorageBox(id) {
|
|
458
|
+
return this.request(`/storagebox/${id}`);
|
|
459
|
+
}
|
|
460
|
+
async updateStorageBox(id, name, webdav, samba, ssh, externalReachability, zfs) {
|
|
461
|
+
const params = {};
|
|
462
|
+
if (name)
|
|
463
|
+
params.storagebox_name = name;
|
|
464
|
+
if (webdav !== undefined)
|
|
465
|
+
params.webdav = webdav;
|
|
466
|
+
if (samba !== undefined)
|
|
467
|
+
params.samba = samba;
|
|
468
|
+
if (ssh !== undefined)
|
|
469
|
+
params.ssh = ssh;
|
|
470
|
+
if (externalReachability !== undefined)
|
|
471
|
+
params.external_reachability = externalReachability;
|
|
472
|
+
if (zfs !== undefined)
|
|
473
|
+
params.zfs = zfs;
|
|
474
|
+
return this.request(`/storagebox/${id}`, {
|
|
475
|
+
method: 'POST',
|
|
476
|
+
body: this.encodeParams(params),
|
|
477
|
+
});
|
|
478
|
+
}
|
|
479
|
+
async resetStorageBoxPassword(id) {
|
|
480
|
+
return this.request(`/storagebox/${id}/password`, {
|
|
481
|
+
method: 'POST',
|
|
482
|
+
});
|
|
483
|
+
}
|
|
484
|
+
// Snapshots
|
|
485
|
+
async listStorageBoxSnapshots(id) {
|
|
486
|
+
return this.request(`/storagebox/${id}/snapshot`);
|
|
487
|
+
}
|
|
488
|
+
async createStorageBoxSnapshot(id) {
|
|
489
|
+
return this.request(`/storagebox/${id}/snapshot`, {
|
|
490
|
+
method: 'POST',
|
|
491
|
+
});
|
|
492
|
+
}
|
|
493
|
+
async deleteStorageBoxSnapshot(id, snapshotName) {
|
|
494
|
+
await this.request(`/storagebox/${id}/snapshot/${snapshotName}`, {
|
|
495
|
+
method: 'DELETE',
|
|
496
|
+
});
|
|
497
|
+
}
|
|
498
|
+
async revertStorageBoxSnapshot(id, snapshotName) {
|
|
499
|
+
await this.request(`/storagebox/${id}/snapshot/${snapshotName}/revert`, {
|
|
500
|
+
method: 'POST',
|
|
501
|
+
});
|
|
502
|
+
}
|
|
503
|
+
// Snapshot Plan
|
|
504
|
+
async getStorageBoxSnapshotPlan(id) {
|
|
505
|
+
return this.request(`/storagebox/${id}/snapshotplan`);
|
|
506
|
+
}
|
|
507
|
+
async updateStorageBoxSnapshotPlan(id, status, minute, hour, dayOfWeek, dayOfMonth, maxSnapshots) {
|
|
508
|
+
const params = { status };
|
|
509
|
+
if (minute !== undefined)
|
|
510
|
+
params.minute = minute;
|
|
511
|
+
if (hour !== undefined)
|
|
512
|
+
params.hour = hour;
|
|
513
|
+
if (dayOfWeek !== undefined)
|
|
514
|
+
params.day_of_week = dayOfWeek;
|
|
515
|
+
if (dayOfMonth !== undefined)
|
|
516
|
+
params.day_of_month = dayOfMonth;
|
|
517
|
+
if (maxSnapshots !== undefined)
|
|
518
|
+
params.max_snapshots = maxSnapshots;
|
|
519
|
+
return this.request(`/storagebox/${id}/snapshotplan`, {
|
|
520
|
+
method: 'POST',
|
|
521
|
+
body: this.encodeParams(params),
|
|
522
|
+
});
|
|
523
|
+
}
|
|
524
|
+
// Subaccounts
|
|
525
|
+
async listStorageBoxSubaccounts(id) {
|
|
526
|
+
return this.request(`/storagebox/${id}/subaccount`);
|
|
527
|
+
}
|
|
528
|
+
async createStorageBoxSubaccount(id, homedirectory, samba, ssh, externalReachability, webdav, readonly, comment) {
|
|
529
|
+
const params = { homedirectory };
|
|
530
|
+
if (samba !== undefined)
|
|
531
|
+
params.samba = samba;
|
|
532
|
+
if (ssh !== undefined)
|
|
533
|
+
params.ssh = ssh;
|
|
534
|
+
if (externalReachability !== undefined)
|
|
535
|
+
params.external_reachability = externalReachability;
|
|
536
|
+
if (webdav !== undefined)
|
|
537
|
+
params.webdav = webdav;
|
|
538
|
+
if (readonly !== undefined)
|
|
539
|
+
params.readonly = readonly;
|
|
540
|
+
if (comment)
|
|
541
|
+
params.comment = comment;
|
|
542
|
+
return this.request(`/storagebox/${id}/subaccount`, {
|
|
543
|
+
method: 'POST',
|
|
544
|
+
body: this.encodeParams(params),
|
|
545
|
+
});
|
|
546
|
+
}
|
|
547
|
+
async updateStorageBoxSubaccount(id, username, samba, ssh, externalReachability, webdav, readonly, comment) {
|
|
548
|
+
const params = {};
|
|
549
|
+
if (samba !== undefined)
|
|
550
|
+
params.samba = samba;
|
|
551
|
+
if (ssh !== undefined)
|
|
552
|
+
params.ssh = ssh;
|
|
553
|
+
if (externalReachability !== undefined)
|
|
554
|
+
params.external_reachability = externalReachability;
|
|
555
|
+
if (webdav !== undefined)
|
|
556
|
+
params.webdav = webdav;
|
|
557
|
+
if (readonly !== undefined)
|
|
558
|
+
params.readonly = readonly;
|
|
559
|
+
if (comment !== undefined)
|
|
560
|
+
params.comment = comment;
|
|
561
|
+
return this.request(`/storagebox/${id}/subaccount/${username}`, {
|
|
562
|
+
method: 'PUT',
|
|
563
|
+
body: this.encodeParams(params),
|
|
564
|
+
});
|
|
565
|
+
}
|
|
566
|
+
async deleteStorageBoxSubaccount(id, username) {
|
|
567
|
+
await this.request(`/storagebox/${id}/subaccount/${username}`, {
|
|
568
|
+
method: 'DELETE',
|
|
569
|
+
});
|
|
570
|
+
}
|
|
571
|
+
async resetStorageBoxSubaccountPassword(id, username) {
|
|
572
|
+
return this.request(`/storagebox/${id}/subaccount/${username}/password`, {
|
|
573
|
+
method: 'POST',
|
|
574
|
+
});
|
|
575
|
+
}
|
|
576
|
+
// =========================================================================
|
|
577
|
+
// Traffic
|
|
578
|
+
// =========================================================================
|
|
579
|
+
async getTraffic(ips, subnets, from, to, type = 'month') {
|
|
580
|
+
const params = {
|
|
581
|
+
type,
|
|
582
|
+
from,
|
|
583
|
+
to,
|
|
584
|
+
};
|
|
585
|
+
if (ips.length > 0)
|
|
586
|
+
params.ip = ips;
|
|
587
|
+
if (subnets.length > 0)
|
|
588
|
+
params.subnet = subnets;
|
|
589
|
+
return this.request('/traffic', {
|
|
590
|
+
method: 'POST',
|
|
591
|
+
body: this.encodeParams(params),
|
|
592
|
+
});
|
|
593
|
+
}
|
|
594
|
+
// =========================================================================
|
|
595
|
+
// Wake on LAN
|
|
596
|
+
// =========================================================================
|
|
597
|
+
async getWol(serverIpOrNumber) {
|
|
598
|
+
return this.request(`/wol/${serverIpOrNumber}`);
|
|
599
|
+
}
|
|
600
|
+
async sendWol(serverIpOrNumber) {
|
|
601
|
+
return this.request(`/wol/${serverIpOrNumber}`, {
|
|
602
|
+
method: 'POST',
|
|
603
|
+
});
|
|
604
|
+
}
|
|
605
|
+
// =========================================================================
|
|
606
|
+
// Server Ordering
|
|
607
|
+
// =========================================================================
|
|
608
|
+
async listServerProducts() {
|
|
609
|
+
return this.request('/order/server/product');
|
|
610
|
+
}
|
|
611
|
+
async listServerMarketProducts() {
|
|
612
|
+
return this.request('/order/server_market/product');
|
|
613
|
+
}
|
|
614
|
+
async listServerTransactions() {
|
|
615
|
+
return this.request('/order/server/transaction');
|
|
616
|
+
}
|
|
617
|
+
async getServerTransaction(transactionId) {
|
|
618
|
+
return this.request(`/order/server/transaction/${transactionId}`);
|
|
619
|
+
}
|
|
620
|
+
async orderServer(productId, authorizedKeys, password, dist, arch, lang, location, addons, test) {
|
|
621
|
+
const params = this.buildOrderParams(productId, authorizedKeys, password, dist, arch, lang, addons, test);
|
|
622
|
+
if (location)
|
|
623
|
+
params.location = location;
|
|
624
|
+
return this.request('/order/server/transaction', {
|
|
625
|
+
method: 'POST',
|
|
626
|
+
body: this.encodeParams(params),
|
|
627
|
+
});
|
|
628
|
+
}
|
|
629
|
+
async orderServerMarket(productId, authorizedKeys, password, dist, arch, lang, addons, test) {
|
|
630
|
+
const params = this.buildOrderParams(productId, authorizedKeys, password, dist, arch, lang, addons, test);
|
|
631
|
+
return this.request('/order/server_market/transaction', {
|
|
632
|
+
method: 'POST',
|
|
633
|
+
body: this.encodeParams(params),
|
|
634
|
+
});
|
|
635
|
+
}
|
|
636
|
+
buildOrderParams(productId, authorizedKeys, password, dist, arch, lang, addons, test) {
|
|
637
|
+
const params = {
|
|
638
|
+
product_id: productId,
|
|
639
|
+
};
|
|
640
|
+
if (authorizedKeys)
|
|
641
|
+
params.authorized_key = authorizedKeys;
|
|
642
|
+
if (password)
|
|
643
|
+
params.password = password;
|
|
644
|
+
if (dist)
|
|
645
|
+
params.dist = dist;
|
|
646
|
+
if (arch)
|
|
647
|
+
params.arch = arch;
|
|
648
|
+
if (lang)
|
|
649
|
+
params.lang = lang;
|
|
650
|
+
if (addons)
|
|
651
|
+
params.addon = addons;
|
|
652
|
+
if (test !== undefined)
|
|
653
|
+
params.test = test;
|
|
654
|
+
return params;
|
|
655
|
+
}
|
|
656
|
+
}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export interface Config {
|
|
2
|
+
user?: string;
|
|
3
|
+
password?: string;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Load configuration from file
|
|
7
|
+
*/
|
|
8
|
+
export declare function loadConfig(): Config;
|
|
9
|
+
/**
|
|
10
|
+
* Save configuration to file
|
|
11
|
+
*/
|
|
12
|
+
export declare function saveConfig(cfg: Config): void;
|
|
13
|
+
/**
|
|
14
|
+
* Clear saved configuration
|
|
15
|
+
*/
|
|
16
|
+
export declare function clearConfig(): void;
|
|
17
|
+
/**
|
|
18
|
+
* Get credentials from environment variables, config file, or prompt
|
|
19
|
+
*/
|
|
20
|
+
export declare function getCredentials(): {
|
|
21
|
+
user: string;
|
|
22
|
+
password: string;
|
|
23
|
+
} | null;
|
|
24
|
+
/**
|
|
25
|
+
* Check if credentials are configured
|
|
26
|
+
*/
|
|
27
|
+
export declare function hasCredentials(): boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Interactive login prompt
|
|
30
|
+
*/
|
|
31
|
+
export declare function promptLogin(): Promise<{
|
|
32
|
+
user: string;
|
|
33
|
+
password: string;
|
|
34
|
+
}>;
|
|
35
|
+
/**
|
|
36
|
+
* Get credentials, prompting if necessary
|
|
37
|
+
*/
|
|
38
|
+
export declare function requireCredentials(): Promise<{
|
|
39
|
+
user: string;
|
|
40
|
+
password: string;
|
|
41
|
+
}>;
|