@ebowwa/hetzner 0.3.2 → 0.3.3
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/dist/actions.js +782 -0
- package/dist/bootstrap/index.js +1 -0
- package/dist/client.js +1867 -0
- package/dist/errors.js +236 -0
- package/dist/index.js +40 -38
- package/dist/onboarding/index.js +2 -2
- package/dist/pricing.js +587 -0
- package/dist/schemas.js +475 -0
- package/dist/servers.js +688 -0
- package/dist/ssh-keys.js +474 -0
- package/dist/types.js +101 -0
- package/dist/volumes.js +119 -0
- package/package.json +51 -1
- package/dist/actions.d.ts +0 -355
- package/dist/auth.d.ts +0 -6
- package/dist/bootstrap/cloud-init.d.ts +0 -78
- package/dist/bootstrap/firewall.d.ts +0 -118
- package/dist/bootstrap/genesis.d.ts +0 -82
- package/dist/bootstrap/index.d.ts +0 -29
- package/dist/bootstrap/kernel-hardening.d.ts +0 -69
- package/dist/bootstrap/security-audit.d.ts +0 -45
- package/dist/bootstrap/ssh-hardening.d.ts +0 -67
- package/dist/client.d.ts +0 -62
- package/dist/config.d.ts +0 -4
- package/dist/cpufeatures-mvwrkyaq.node +0 -0
- package/dist/errors.d.ts +0 -170
- package/dist/index.d.ts +0 -21
- package/dist/onboarding/claude.d.ts +0 -37
- package/dist/onboarding/cpufeatures-mvwrkyaq.node +0 -0
- package/dist/onboarding/doppler.d.ts +0 -37
- package/dist/onboarding/git.d.ts +0 -38
- package/dist/onboarding/index.d.ts +0 -19
- package/dist/onboarding/onboarding.d.ts +0 -41
- package/dist/onboarding/sshcrypto-6mayxj08.node +0 -0
- package/dist/onboarding/tailscale.d.ts +0 -38
- package/dist/onboarding/types.d.ts +0 -111
- package/dist/pricing.d.ts +0 -330
- package/dist/schemas.d.ts +0 -6629
- package/dist/server-status.d.ts +0 -25
- package/dist/servers.d.ts +0 -164
- package/dist/ssh-keys.d.ts +0 -35
- package/dist/ssh-setup.d.ts +0 -47
- package/dist/sshcrypto-6mayxj08.node +0 -0
- package/dist/types.d.ts +0 -303
- package/dist/volumes.d.ts +0 -105
package/dist/servers.js
ADDED
|
@@ -0,0 +1,688 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __toESM = (mod, isNodeMode, target) => {
|
|
8
|
+
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
9
|
+
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
10
|
+
for (let key of __getOwnPropNames(mod))
|
|
11
|
+
if (!__hasOwnProp.call(to, key))
|
|
12
|
+
__defProp(to, key, {
|
|
13
|
+
get: () => mod[key],
|
|
14
|
+
enumerable: true
|
|
15
|
+
});
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __require = import.meta.require;
|
|
19
|
+
|
|
20
|
+
// src/schemas.ts
|
|
21
|
+
import { z } from "zod";
|
|
22
|
+
import {
|
|
23
|
+
EnvironmentStatus,
|
|
24
|
+
ActionStatus,
|
|
25
|
+
VolumeStatus
|
|
26
|
+
} from "@ebowwa/codespaces-types/compile";
|
|
27
|
+
var ipv4Regex = /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
|
|
28
|
+
var ipv6Regex = /^[0-9a-fA-F:]+(?:\/\d{1,3})?$/;
|
|
29
|
+
var ipRegex = /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$|^(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$/;
|
|
30
|
+
var HetznerErrorSchema = z.object({
|
|
31
|
+
code: z.string(),
|
|
32
|
+
message: z.string(),
|
|
33
|
+
details: z.any().optional()
|
|
34
|
+
});
|
|
35
|
+
var HetznerPaginationSchema = z.object({
|
|
36
|
+
page: z.number(),
|
|
37
|
+
per_page: z.number(),
|
|
38
|
+
previous_page: z.number().nullable(),
|
|
39
|
+
next_page: z.number().nullable(),
|
|
40
|
+
last_page: z.number(),
|
|
41
|
+
total_entries: z.number()
|
|
42
|
+
});
|
|
43
|
+
var HetznerMetaSchema = z.object({
|
|
44
|
+
pagination: HetznerPaginationSchema.optional()
|
|
45
|
+
});
|
|
46
|
+
var HetznerActionResourceSchema = z.object({
|
|
47
|
+
id: z.number(),
|
|
48
|
+
type: z.enum([
|
|
49
|
+
"server",
|
|
50
|
+
"volume",
|
|
51
|
+
"network",
|
|
52
|
+
"floating_ip",
|
|
53
|
+
"load_balancer",
|
|
54
|
+
"certificate",
|
|
55
|
+
"firewall",
|
|
56
|
+
"image"
|
|
57
|
+
])
|
|
58
|
+
});
|
|
59
|
+
var HetznerActionErrorSchema = z.object({
|
|
60
|
+
code: z.string(),
|
|
61
|
+
message: z.string()
|
|
62
|
+
});
|
|
63
|
+
var HetznerActionSchema = z.object({
|
|
64
|
+
id: z.number(),
|
|
65
|
+
command: z.string(),
|
|
66
|
+
status: z.nativeEnum(ActionStatus),
|
|
67
|
+
started: z.string(),
|
|
68
|
+
finished: z.string().nullable(),
|
|
69
|
+
progress: z.number().min(0).max(100),
|
|
70
|
+
resources: z.array(HetznerActionResourceSchema),
|
|
71
|
+
error: HetznerActionErrorSchema.nullable()
|
|
72
|
+
});
|
|
73
|
+
var HetznerActionResponseSchema = z.object({
|
|
74
|
+
action: HetznerActionSchema
|
|
75
|
+
});
|
|
76
|
+
var HetznerActionsResponseSchema = z.object({
|
|
77
|
+
actions: z.array(HetznerActionSchema),
|
|
78
|
+
meta: HetznerMetaSchema
|
|
79
|
+
});
|
|
80
|
+
var HetznerServerImageSchema = z.object({
|
|
81
|
+
id: z.number(),
|
|
82
|
+
name: z.string(),
|
|
83
|
+
description: z.string(),
|
|
84
|
+
type: z.enum(["snapshot", "backup", "system"])
|
|
85
|
+
});
|
|
86
|
+
var HetznerIPv4Schema = z.object({
|
|
87
|
+
ip: z.string().regex(ipv4Regex),
|
|
88
|
+
blocked: z.boolean()
|
|
89
|
+
});
|
|
90
|
+
var HetznerIPv6Schema = z.object({
|
|
91
|
+
ip: z.string().regex(ipv6Regex),
|
|
92
|
+
blocked: z.boolean()
|
|
93
|
+
});
|
|
94
|
+
var HetznerFloatingIpRefSchema = z.object({
|
|
95
|
+
id: z.number(),
|
|
96
|
+
ip: z.string()
|
|
97
|
+
});
|
|
98
|
+
var HetznerFirewallRefSchema = z.object({
|
|
99
|
+
id: z.number(),
|
|
100
|
+
name: z.string(),
|
|
101
|
+
status: z.enum(["applied", "pending"])
|
|
102
|
+
});
|
|
103
|
+
var HetznerPublicNetSchema = z.object({
|
|
104
|
+
ipv4: HetznerIPv4Schema,
|
|
105
|
+
ipv6: HetznerIPv6Schema.optional(),
|
|
106
|
+
floating_ips: z.array(HetznerFloatingIpRefSchema),
|
|
107
|
+
firewalls: z.array(HetznerFirewallRefSchema)
|
|
108
|
+
});
|
|
109
|
+
var HetznerServerTypeSchema = z.object({
|
|
110
|
+
id: z.number(),
|
|
111
|
+
name: z.string(),
|
|
112
|
+
description: z.string(),
|
|
113
|
+
cores: z.number(),
|
|
114
|
+
memory: z.number(),
|
|
115
|
+
disk: z.number()
|
|
116
|
+
});
|
|
117
|
+
var HetznerLocationSchema = z.object({
|
|
118
|
+
id: z.number(),
|
|
119
|
+
name: z.string(),
|
|
120
|
+
description: z.string(),
|
|
121
|
+
country: z.string(),
|
|
122
|
+
city: z.string(),
|
|
123
|
+
latitude: z.number(),
|
|
124
|
+
longitude: z.number(),
|
|
125
|
+
network_zone: z.string()
|
|
126
|
+
});
|
|
127
|
+
var HetznerDatacenterSchema = z.object({
|
|
128
|
+
id: z.number(),
|
|
129
|
+
name: z.string(),
|
|
130
|
+
description: z.string(),
|
|
131
|
+
location: HetznerLocationSchema,
|
|
132
|
+
supported_server_types: z.array(z.object({
|
|
133
|
+
id: z.number(),
|
|
134
|
+
name: z.string()
|
|
135
|
+
})).optional().nullable()
|
|
136
|
+
});
|
|
137
|
+
var HetznerVolumeRefSchema = z.object({
|
|
138
|
+
id: z.number(),
|
|
139
|
+
name: z.string(),
|
|
140
|
+
size: z.number().positive(),
|
|
141
|
+
linux_device: z.string()
|
|
142
|
+
});
|
|
143
|
+
var HetznerServerProtectionSchema = z.object({
|
|
144
|
+
delete: z.boolean(),
|
|
145
|
+
rebuild: z.boolean()
|
|
146
|
+
});
|
|
147
|
+
var HetznerServerSchema = z.object({
|
|
148
|
+
id: z.number().positive(),
|
|
149
|
+
name: z.string().min(1),
|
|
150
|
+
status: z.nativeEnum(EnvironmentStatus),
|
|
151
|
+
image: HetznerServerImageSchema.nullable().optional(),
|
|
152
|
+
public_net: HetznerPublicNetSchema,
|
|
153
|
+
server_type: HetznerServerTypeSchema,
|
|
154
|
+
datacenter: HetznerDatacenterSchema,
|
|
155
|
+
labels: z.record(z.string(), z.any()),
|
|
156
|
+
created: z.string().datetime(),
|
|
157
|
+
protection: HetznerServerProtectionSchema,
|
|
158
|
+
volumes: z.array(HetznerVolumeRefSchema)
|
|
159
|
+
});
|
|
160
|
+
var HetznerListServersResponseSchema = z.object({
|
|
161
|
+
servers: z.array(HetznerServerSchema),
|
|
162
|
+
meta: HetznerMetaSchema
|
|
163
|
+
});
|
|
164
|
+
var HetznerGetServerResponseSchema = z.object({
|
|
165
|
+
server: HetznerServerSchema
|
|
166
|
+
});
|
|
167
|
+
var HetznerCreateServerRequestSchema = z.object({
|
|
168
|
+
name: z.string().min(1).max(64).regex(/^[a-zA-Z0-9][a-zA-Z0-9-]*$/, "Name must start with letter/number and contain only letters, numbers, and hyphens"),
|
|
169
|
+
server_type: z.string().min(1),
|
|
170
|
+
image: z.string().min(1),
|
|
171
|
+
location: z.string().min(1).optional(),
|
|
172
|
+
datacenter: z.string().min(1).optional(),
|
|
173
|
+
ssh_keys: z.array(z.union([z.string(), z.number()])).optional(),
|
|
174
|
+
volumes: z.array(z.number().positive()).optional(),
|
|
175
|
+
labels: z.record(z.string(), z.any()).optional(),
|
|
176
|
+
start_after_create: z.boolean().optional()
|
|
177
|
+
}).refine((data) => !(data.location && data.datacenter), "Cannot specify both location and datacenter");
|
|
178
|
+
var HetznerCreateServerResponseSchema = z.object({
|
|
179
|
+
server: HetznerServerSchema,
|
|
180
|
+
action: HetznerActionSchema,
|
|
181
|
+
next_actions: z.array(HetznerActionSchema),
|
|
182
|
+
root_password: z.string().nullable()
|
|
183
|
+
});
|
|
184
|
+
var HetznerUpdateServerRequestSchema = z.object({
|
|
185
|
+
name: z.string().min(1).max(64).optional(),
|
|
186
|
+
labels: z.record(z.string(), z.any()).optional()
|
|
187
|
+
});
|
|
188
|
+
var HetznerUpdateServerResponseSchema = z.object({
|
|
189
|
+
server: HetznerServerSchema
|
|
190
|
+
});
|
|
191
|
+
var HetznerVolumeLocationSchema = z.object({
|
|
192
|
+
id: z.number(),
|
|
193
|
+
name: z.string(),
|
|
194
|
+
description: z.string(),
|
|
195
|
+
country: z.string(),
|
|
196
|
+
city: z.string(),
|
|
197
|
+
latitude: z.number(),
|
|
198
|
+
longitude: z.number()
|
|
199
|
+
});
|
|
200
|
+
var HetznerVolumeProtectionSchema = z.object({
|
|
201
|
+
delete: z.boolean()
|
|
202
|
+
});
|
|
203
|
+
var HetznerVolumeSchema = z.object({
|
|
204
|
+
id: z.number().positive(),
|
|
205
|
+
name: z.string().min(1),
|
|
206
|
+
status: z.nativeEnum(VolumeStatus),
|
|
207
|
+
server: z.number().positive().nullable().optional(),
|
|
208
|
+
size: z.number().positive(),
|
|
209
|
+
linux_device: z.string().nullable().optional(),
|
|
210
|
+
format: z.string().nullable().optional(),
|
|
211
|
+
location: HetznerVolumeLocationSchema.nullable().optional(),
|
|
212
|
+
labels: z.record(z.string(), z.any()),
|
|
213
|
+
created: z.string().datetime(),
|
|
214
|
+
protection: HetznerVolumeProtectionSchema
|
|
215
|
+
});
|
|
216
|
+
var HetznerListVolumesResponseSchema = z.object({
|
|
217
|
+
volumes: z.array(HetznerVolumeSchema),
|
|
218
|
+
meta: HetznerMetaSchema
|
|
219
|
+
});
|
|
220
|
+
var HetznerGetVolumeResponseSchema = z.object({
|
|
221
|
+
volume: HetznerVolumeSchema
|
|
222
|
+
});
|
|
223
|
+
var HetznerCreateVolumeRequestSchema = z.object({
|
|
224
|
+
name: z.string().min(1).max(64),
|
|
225
|
+
size: z.number().positive().multipleOf(1),
|
|
226
|
+
server: z.number().positive().optional(),
|
|
227
|
+
location: z.string().min(1).optional(),
|
|
228
|
+
automount: z.boolean().optional(),
|
|
229
|
+
format: z.string().optional(),
|
|
230
|
+
labels: z.record(z.string(), z.any()).optional()
|
|
231
|
+
}).refine((data) => {
|
|
232
|
+
return Number.isInteger(data.size);
|
|
233
|
+
}, "Volume size must be a whole number in GB");
|
|
234
|
+
var HetznerCreateVolumeResponseSchema = z.object({
|
|
235
|
+
volume: HetznerVolumeSchema,
|
|
236
|
+
action: HetznerActionSchema,
|
|
237
|
+
next_actions: z.array(HetznerActionSchema)
|
|
238
|
+
});
|
|
239
|
+
var HetznerSubnetSchema = z.object({
|
|
240
|
+
type: z.enum(["server", "cloud", "vswitch"]),
|
|
241
|
+
ip_range: z.string().regex(ipRegex),
|
|
242
|
+
network_zone: z.string(),
|
|
243
|
+
gateway: z.string().regex(ipRegex)
|
|
244
|
+
});
|
|
245
|
+
var HetznerRouteSchema = z.object({
|
|
246
|
+
destination: z.string().regex(ipRegex),
|
|
247
|
+
gateway: z.string().regex(ipRegex)
|
|
248
|
+
});
|
|
249
|
+
var HetznerNetworkProtectionSchema = z.object({
|
|
250
|
+
delete: z.boolean()
|
|
251
|
+
});
|
|
252
|
+
var HetznerNetworkSchema = z.object({
|
|
253
|
+
id: z.number().positive(),
|
|
254
|
+
name: z.string().min(1).max(64),
|
|
255
|
+
ip_range: z.string().regex(ipRegex),
|
|
256
|
+
subnets: z.array(HetznerSubnetSchema),
|
|
257
|
+
routes: z.array(HetznerRouteSchema),
|
|
258
|
+
servers: z.array(z.number().positive()),
|
|
259
|
+
protection: HetznerNetworkProtectionSchema,
|
|
260
|
+
labels: z.record(z.string(), z.any()),
|
|
261
|
+
created: z.string().datetime()
|
|
262
|
+
});
|
|
263
|
+
var HetznerListNetworksResponseSchema = z.object({
|
|
264
|
+
networks: z.array(HetznerNetworkSchema),
|
|
265
|
+
meta: HetznerMetaSchema
|
|
266
|
+
});
|
|
267
|
+
var HetznerGetNetworkResponseSchema = z.object({
|
|
268
|
+
network: HetznerNetworkSchema
|
|
269
|
+
});
|
|
270
|
+
var HetznerSSHKeySchema = z.object({
|
|
271
|
+
id: z.number().positive(),
|
|
272
|
+
name: z.string().min(1).max(64),
|
|
273
|
+
fingerprint: z.string(),
|
|
274
|
+
public_key: z.string(),
|
|
275
|
+
labels: z.record(z.string(), z.any()),
|
|
276
|
+
created: z.string().datetime()
|
|
277
|
+
});
|
|
278
|
+
var HetznerListSSHKeysResponseSchema = z.object({
|
|
279
|
+
ssh_keys: z.array(HetznerSSHKeySchema),
|
|
280
|
+
meta: HetznerMetaSchema
|
|
281
|
+
});
|
|
282
|
+
var HetznerGetSSHKeyResponseSchema = z.object({
|
|
283
|
+
ssh_key: HetznerSSHKeySchema
|
|
284
|
+
});
|
|
285
|
+
var HetznerCreateSSHKeyRequestSchema = z.object({
|
|
286
|
+
name: z.string().min(1).max(64).regex(/^[a-zA-Z0-9][a-zA-Z0-9-]*$/, "Name must start with letter/number and contain only letters, numbers, and hyphens"),
|
|
287
|
+
public_key: z.string().min(1),
|
|
288
|
+
labels: z.record(z.string(), z.any()).optional()
|
|
289
|
+
});
|
|
290
|
+
var HetznerCreateSSHKeyResponseSchema = z.object({
|
|
291
|
+
ssh_key: HetznerSSHKeySchema
|
|
292
|
+
});
|
|
293
|
+
var HetznerFloatingIpSchema = z.object({
|
|
294
|
+
id: z.number().positive(),
|
|
295
|
+
name: z.string().min(1).max(64),
|
|
296
|
+
description: z.string().optional(),
|
|
297
|
+
type: z.enum(["ipv4", "ipv6"]),
|
|
298
|
+
ip: z.string().regex(ipRegex),
|
|
299
|
+
server: z.number().positive().nullable(),
|
|
300
|
+
dns_ptr: z.array(z.object({
|
|
301
|
+
ip: z.string(),
|
|
302
|
+
dns_ptr: z.string()
|
|
303
|
+
})),
|
|
304
|
+
home_location: HetznerLocationSchema,
|
|
305
|
+
blocked: z.boolean(),
|
|
306
|
+
protection: z.object({
|
|
307
|
+
delete: z.boolean()
|
|
308
|
+
}),
|
|
309
|
+
labels: z.record(z.string(), z.any()),
|
|
310
|
+
created: z.string().datetime()
|
|
311
|
+
});
|
|
312
|
+
var HetznerListFloatingIpsResponseSchema = z.object({
|
|
313
|
+
floating_ips: z.array(HetznerFloatingIpSchema),
|
|
314
|
+
meta: HetznerMetaSchema
|
|
315
|
+
});
|
|
316
|
+
var HetznerFirewallRuleSchema = z.object({
|
|
317
|
+
direction: z.enum(["in", "out"]),
|
|
318
|
+
source_ips: z.array(z.string().regex(ipRegex)).optional(),
|
|
319
|
+
destination_ips: z.array(z.string().regex(ipRegex)).optional(),
|
|
320
|
+
source_port: z.string().optional(),
|
|
321
|
+
destination_port: z.string().optional(),
|
|
322
|
+
protocol: z.enum(["tcp", "udp", "icmp", "esp", "gre"])
|
|
323
|
+
});
|
|
324
|
+
var HetznerFirewallResourceSchema = z.object({
|
|
325
|
+
type: z.enum(["server", "label_selector"]),
|
|
326
|
+
server: z.object({
|
|
327
|
+
id: z.number().positive()
|
|
328
|
+
}).optional(),
|
|
329
|
+
label_selector: z.object({
|
|
330
|
+
selector: z.string()
|
|
331
|
+
}).optional()
|
|
332
|
+
});
|
|
333
|
+
var HetznerFirewallSchema = z.object({
|
|
334
|
+
id: z.number().positive(),
|
|
335
|
+
name: z.string().min(1).max(64),
|
|
336
|
+
rules: z.array(HetznerFirewallRuleSchema),
|
|
337
|
+
apply_to: z.array(HetznerFirewallResourceSchema),
|
|
338
|
+
labels: z.record(z.string(), z.any()),
|
|
339
|
+
created: z.string().datetime()
|
|
340
|
+
});
|
|
341
|
+
var HetznerListFirewallsResponseSchema = z.object({
|
|
342
|
+
firewalls: z.array(HetznerFirewallSchema),
|
|
343
|
+
meta: HetznerMetaSchema
|
|
344
|
+
});
|
|
345
|
+
var HetznerIsoSchema = z.object({
|
|
346
|
+
id: z.number().positive(),
|
|
347
|
+
name: z.string(),
|
|
348
|
+
description: z.string(),
|
|
349
|
+
type: z.enum(["public", "private"]),
|
|
350
|
+
deprecated: z.date().nullable().optional(),
|
|
351
|
+
architecture: z.array(z.enum(["x86", "arm"])).optional()
|
|
352
|
+
});
|
|
353
|
+
var HetznerListIsosResponseSchema = z.object({
|
|
354
|
+
isos: z.array(HetznerIsoSchema),
|
|
355
|
+
meta: HetznerMetaSchema
|
|
356
|
+
});
|
|
357
|
+
var HetznerListLocationsResponseSchema = z.object({
|
|
358
|
+
locations: z.array(HetznerLocationSchema)
|
|
359
|
+
});
|
|
360
|
+
var HetznerListDatacentersResponseSchema = z.object({
|
|
361
|
+
datacenters: z.array(HetznerDatacenterSchema)
|
|
362
|
+
});
|
|
363
|
+
var HetznerServerTypePricingSchema = z.object({
|
|
364
|
+
location: z.string().nullable().optional(),
|
|
365
|
+
price_hourly: z.object({
|
|
366
|
+
net: z.string(),
|
|
367
|
+
gross: z.string()
|
|
368
|
+
}),
|
|
369
|
+
price_monthly: z.object({
|
|
370
|
+
net: z.string(),
|
|
371
|
+
gross: z.string()
|
|
372
|
+
})
|
|
373
|
+
});
|
|
374
|
+
var HetznerServerTypeExtendedSchema = HetznerServerTypeSchema.extend({
|
|
375
|
+
deprecated: z.boolean().optional(),
|
|
376
|
+
prices: z.array(HetznerServerTypePricingSchema),
|
|
377
|
+
storage_type: z.enum(["local", "network"]),
|
|
378
|
+
cpu_type: z.enum(["shared", "dedicated"])
|
|
379
|
+
});
|
|
380
|
+
var HetznerListServerTypesResponseSchema = z.object({
|
|
381
|
+
server_types: z.array(HetznerServerTypeExtendedSchema)
|
|
382
|
+
});
|
|
383
|
+
var HetznerCertificateSchema = z.object({
|
|
384
|
+
id: z.number().positive(),
|
|
385
|
+
name: z.string().min(1).max(64),
|
|
386
|
+
labels: z.record(z.string(), z.any()),
|
|
387
|
+
certificate: z.string(),
|
|
388
|
+
not_valid_before: z.string().datetime(),
|
|
389
|
+
not_valid_after: z.string().datetime(),
|
|
390
|
+
domain_names: z.array(z.string().url()),
|
|
391
|
+
fingerprint: z.string(),
|
|
392
|
+
created: z.string().datetime(),
|
|
393
|
+
status: z.enum(["pending", "issued", "failed", "revoked"]),
|
|
394
|
+
failed: z.boolean().optional(),
|
|
395
|
+
type: z.enum(["uploaded", "managed"]),
|
|
396
|
+
usage: z.array(z.enum(["dual_stack", "server", "load_balancer", "dns"])).optional()
|
|
397
|
+
});
|
|
398
|
+
var HetznerListCertificatesResponseSchema = z.object({
|
|
399
|
+
certificates: z.array(HetznerCertificateSchema),
|
|
400
|
+
meta: HetznerMetaSchema
|
|
401
|
+
});
|
|
402
|
+
function createPaginatedResponseSchema(itemSchema, itemName) {
|
|
403
|
+
return z.object({
|
|
404
|
+
[itemName]: z.array(itemSchema),
|
|
405
|
+
meta: HetznerMetaSchema
|
|
406
|
+
});
|
|
407
|
+
}
|
|
408
|
+
function createItemResponseSchema(itemSchema, itemName) {
|
|
409
|
+
return z.object({
|
|
410
|
+
[itemName]: itemSchema
|
|
411
|
+
});
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
// src/servers.ts
|
|
415
|
+
import { z as z2 } from "zod";
|
|
416
|
+
class ServerOperations {
|
|
417
|
+
client;
|
|
418
|
+
constructor(client) {
|
|
419
|
+
this.client = client;
|
|
420
|
+
}
|
|
421
|
+
async list() {
|
|
422
|
+
const response = await this.client.request("/servers");
|
|
423
|
+
const validated = HetznerListServersResponseSchema.safeParse(response);
|
|
424
|
+
if (!validated.success) {
|
|
425
|
+
console.warn("Hetzner list servers validation warning:", validated.error.issues);
|
|
426
|
+
return response.servers;
|
|
427
|
+
}
|
|
428
|
+
return validated.data.servers;
|
|
429
|
+
}
|
|
430
|
+
async get(id) {
|
|
431
|
+
const response = await this.client.request(`/servers/${id}`);
|
|
432
|
+
const validated = HetznerGetServerResponseSchema.safeParse(response);
|
|
433
|
+
if (!validated.success) {
|
|
434
|
+
console.warn("Hetzner get server validation warning:", validated.error.issues);
|
|
435
|
+
return response.server;
|
|
436
|
+
}
|
|
437
|
+
return validated.data.server;
|
|
438
|
+
}
|
|
439
|
+
async create(options) {
|
|
440
|
+
const createServerOptionsSchema = z2.object({
|
|
441
|
+
name: z2.string().min(1),
|
|
442
|
+
server_type: z2.string().min(1).default("cpx11"),
|
|
443
|
+
image: z2.string().min(1).default("ubuntu-24.04"),
|
|
444
|
+
location: z2.string().min(1).optional(),
|
|
445
|
+
datacenter: z2.string().min(1).optional(),
|
|
446
|
+
ssh_keys: z2.array(z2.union([z2.string(), z2.number()])).default([]),
|
|
447
|
+
volumes: z2.array(z2.number()).default([]),
|
|
448
|
+
labels: z2.record(z2.string(), z2.any()).optional(),
|
|
449
|
+
start_after_create: z2.boolean().default(true),
|
|
450
|
+
user_data: z2.string().optional()
|
|
451
|
+
});
|
|
452
|
+
const validatedOptions = createServerOptionsSchema.safeParse(options);
|
|
453
|
+
if (!validatedOptions.success) {
|
|
454
|
+
throw new Error(`Invalid server options: ${validatedOptions.error.issues.map((i) => i.message).join(", ")}`);
|
|
455
|
+
}
|
|
456
|
+
if (validatedOptions.data.location && validatedOptions.data.datacenter) {
|
|
457
|
+
throw new Error("Cannot specify both location and datacenter");
|
|
458
|
+
}
|
|
459
|
+
const body = {
|
|
460
|
+
name: validatedOptions.data.name,
|
|
461
|
+
server_type: validatedOptions.data.server_type,
|
|
462
|
+
image: validatedOptions.data.image,
|
|
463
|
+
...validatedOptions.data.location && { location: validatedOptions.data.location },
|
|
464
|
+
...validatedOptions.data.datacenter && { datacenter: { id: validatedOptions.data.datacenter } },
|
|
465
|
+
ssh_keys: validatedOptions.data.ssh_keys,
|
|
466
|
+
volumes: validatedOptions.data.volumes,
|
|
467
|
+
...validatedOptions.data.labels && { labels: validatedOptions.data.labels },
|
|
468
|
+
start_after_create: validatedOptions.data.start_after_create,
|
|
469
|
+
...validatedOptions.data.user_data && { user_data: validatedOptions.data.user_data }
|
|
470
|
+
};
|
|
471
|
+
console.log("[Hetzner] Creating server with body:", JSON.stringify(body, null, 2));
|
|
472
|
+
const response = await this.client.request("/servers", {
|
|
473
|
+
method: "POST",
|
|
474
|
+
body: JSON.stringify(body)
|
|
475
|
+
});
|
|
476
|
+
const validatedResponse = HetznerCreateServerResponseSchema.safeParse(response);
|
|
477
|
+
if (!validatedResponse.success) {
|
|
478
|
+
console.warn("Hetzner create server validation warning:", validatedResponse.error.issues);
|
|
479
|
+
return response;
|
|
480
|
+
}
|
|
481
|
+
return validatedResponse.data;
|
|
482
|
+
}
|
|
483
|
+
async createAndWait(options, onProgress) {
|
|
484
|
+
const response = await this.create(options);
|
|
485
|
+
const waitOptions = onProgress !== undefined ? { onProgress } : {};
|
|
486
|
+
if (response.action.status === "running") {
|
|
487
|
+
await this.client.actions.waitFor(response.action.id, waitOptions);
|
|
488
|
+
}
|
|
489
|
+
if (response.next_actions.length > 0) {
|
|
490
|
+
for (const action of response.next_actions) {
|
|
491
|
+
await this.client.actions.waitFor(action.id, waitOptions);
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
const server = await this.get(response.server.id);
|
|
495
|
+
return server;
|
|
496
|
+
}
|
|
497
|
+
async delete(id) {
|
|
498
|
+
const serverIdSchema = z2.number().int().positive();
|
|
499
|
+
const validatedId = serverIdSchema.safeParse(id);
|
|
500
|
+
if (!validatedId.success) {
|
|
501
|
+
throw new Error(`Invalid server ID: ${validatedId.error.issues.map((i) => i.message).join(", ")}`);
|
|
502
|
+
}
|
|
503
|
+
const response = await this.client.request(`/servers/${validatedId.data}`, { method: "DELETE" });
|
|
504
|
+
const validated = HetznerActionSchema.safeParse(response.action);
|
|
505
|
+
if (!validated.success) {
|
|
506
|
+
console.warn("Hetzner delete server validation warning:", validated.error.issues);
|
|
507
|
+
return response.action;
|
|
508
|
+
}
|
|
509
|
+
return validated.data;
|
|
510
|
+
}
|
|
511
|
+
async deleteAndWait(id, onProgress) {
|
|
512
|
+
const action = await this.delete(id);
|
|
513
|
+
await this.client.actions.waitFor(action.id, { onProgress });
|
|
514
|
+
}
|
|
515
|
+
async powerOn(id) {
|
|
516
|
+
const serverIdSchema = z2.number().int().positive();
|
|
517
|
+
const validatedId = serverIdSchema.safeParse(id);
|
|
518
|
+
if (!validatedId.success) {
|
|
519
|
+
throw new Error(`Invalid server ID: ${validatedId.error.issues.map((i) => i.message).join(", ")}`);
|
|
520
|
+
}
|
|
521
|
+
const response = await this.client.request(`/servers/${validatedId.data}/actions/poweron`, { method: "POST" });
|
|
522
|
+
const validated = HetznerActionSchema.safeParse(response.action);
|
|
523
|
+
if (!validated.success) {
|
|
524
|
+
console.warn("Hetzner power on validation warning:", validated.error.issues);
|
|
525
|
+
return response.action;
|
|
526
|
+
}
|
|
527
|
+
return validated.data;
|
|
528
|
+
}
|
|
529
|
+
async powerOnAndWait(id, onProgress) {
|
|
530
|
+
const action = await this.powerOn(id);
|
|
531
|
+
return await this.client.actions.waitFor(action.id, { onProgress });
|
|
532
|
+
}
|
|
533
|
+
async powerOff(id) {
|
|
534
|
+
const serverIdSchema = z2.number().int().positive();
|
|
535
|
+
const validatedId = serverIdSchema.safeParse(id);
|
|
536
|
+
if (!validatedId.success) {
|
|
537
|
+
throw new Error(`Invalid server ID: ${validatedId.error.issues.map((i) => i.message).join(", ")}`);
|
|
538
|
+
}
|
|
539
|
+
const response = await this.client.request(`/servers/${validatedId.data}/actions/poweroff`, { method: "POST" });
|
|
540
|
+
const validated = HetznerActionSchema.safeParse(response.action);
|
|
541
|
+
if (!validated.success) {
|
|
542
|
+
console.warn("Hetzner power off validation warning:", validated.error.issues);
|
|
543
|
+
return response.action;
|
|
544
|
+
}
|
|
545
|
+
return validated.data;
|
|
546
|
+
}
|
|
547
|
+
async powerOffAndWait(id, onProgress) {
|
|
548
|
+
const action = await this.powerOff(id);
|
|
549
|
+
return await this.client.actions.waitFor(action.id, { onProgress });
|
|
550
|
+
}
|
|
551
|
+
async reboot(id) {
|
|
552
|
+
const serverIdSchema = z2.number().int().positive();
|
|
553
|
+
const validatedId = serverIdSchema.safeParse(id);
|
|
554
|
+
if (!validatedId.success) {
|
|
555
|
+
throw new Error(`Invalid server ID: ${validatedId.error.issues.map((i) => i.message).join(", ")}`);
|
|
556
|
+
}
|
|
557
|
+
const response = await this.client.request(`/servers/${validatedId.data}/actions/reboot`, { method: "POST" });
|
|
558
|
+
const validated = HetznerActionSchema.safeParse(response.action);
|
|
559
|
+
if (!validated.success) {
|
|
560
|
+
console.warn("Hetzner reboot validation warning:", validated.error.issues);
|
|
561
|
+
return response.action;
|
|
562
|
+
}
|
|
563
|
+
return validated.data;
|
|
564
|
+
}
|
|
565
|
+
async rebootAndWait(id, onProgress) {
|
|
566
|
+
const action = await this.reboot(id);
|
|
567
|
+
return await this.client.actions.waitFor(action.id, { onProgress });
|
|
568
|
+
}
|
|
569
|
+
async shutdown(id) {
|
|
570
|
+
const serverIdSchema = z2.number().int().positive();
|
|
571
|
+
const validatedId = serverIdSchema.safeParse(id);
|
|
572
|
+
if (!validatedId.success) {
|
|
573
|
+
throw new Error(`Invalid server ID: ${validatedId.error.issues.map((i) => i.message).join(", ")}`);
|
|
574
|
+
}
|
|
575
|
+
const response = await this.client.request(`/servers/${validatedId.data}/actions/shutdown`, { method: "POST" });
|
|
576
|
+
const validated = HetznerActionSchema.safeParse(response.action);
|
|
577
|
+
if (!validated.success) {
|
|
578
|
+
console.warn("Hetzner shutdown validation warning:", validated.error.issues);
|
|
579
|
+
return response.action;
|
|
580
|
+
}
|
|
581
|
+
return validated.data;
|
|
582
|
+
}
|
|
583
|
+
async shutdownAndWait(id, onProgress) {
|
|
584
|
+
const action = await this.shutdown(id);
|
|
585
|
+
return await this.client.actions.waitFor(action.id, { onProgress });
|
|
586
|
+
}
|
|
587
|
+
async reset(id) {
|
|
588
|
+
const serverIdSchema = z2.number().int().positive();
|
|
589
|
+
const validatedId = serverIdSchema.safeParse(id);
|
|
590
|
+
if (!validatedId.success) {
|
|
591
|
+
throw new Error(`Invalid server ID: ${validatedId.error.issues.map((i) => i.message).join(", ")}`);
|
|
592
|
+
}
|
|
593
|
+
const response = await this.client.request(`/servers/${validatedId.data}/actions/reset`, { method: "POST" });
|
|
594
|
+
const validated = HetznerActionSchema.safeParse(response.action);
|
|
595
|
+
if (!validated.success) {
|
|
596
|
+
console.warn("Hetzner reset validation warning:", validated.error.issues);
|
|
597
|
+
return response.action;
|
|
598
|
+
}
|
|
599
|
+
return validated.data;
|
|
600
|
+
}
|
|
601
|
+
async resetAndWait(id, onProgress) {
|
|
602
|
+
const action = await this.reset(id);
|
|
603
|
+
return await this.client.actions.waitFor(action.id, { onProgress });
|
|
604
|
+
}
|
|
605
|
+
async rebuild(id, image) {
|
|
606
|
+
const serverIdSchema = z2.number().int().positive();
|
|
607
|
+
const validatedId = serverIdSchema.safeParse(id);
|
|
608
|
+
if (!validatedId.success) {
|
|
609
|
+
throw new Error(`Invalid server ID: ${validatedId.error.issues.map((i) => i.message).join(", ")}`);
|
|
610
|
+
}
|
|
611
|
+
const response = await this.client.request(`/servers/${validatedId.data}/actions/rebuild`, {
|
|
612
|
+
method: "POST",
|
|
613
|
+
body: JSON.stringify({ image })
|
|
614
|
+
});
|
|
615
|
+
const validated = HetznerActionSchema.safeParse(response.action);
|
|
616
|
+
if (!validated.success) {
|
|
617
|
+
console.warn("Hetzner rebuild validation warning:", validated.error.issues);
|
|
618
|
+
return response.action;
|
|
619
|
+
}
|
|
620
|
+
return validated.data;
|
|
621
|
+
}
|
|
622
|
+
async enableRescue(id, options) {
|
|
623
|
+
const serverIdSchema = z2.number().int().positive();
|
|
624
|
+
const validatedId = serverIdSchema.safeParse(id);
|
|
625
|
+
if (!validatedId.success) {
|
|
626
|
+
throw new Error(`Invalid server ID: ${validatedId.error.issues.map((i) => i.message).join(", ")}`);
|
|
627
|
+
}
|
|
628
|
+
const response = await this.client.request(`/servers/${validatedId.data}/actions/enable_rescue`, {
|
|
629
|
+
method: "POST",
|
|
630
|
+
body: JSON.stringify(options || {})
|
|
631
|
+
});
|
|
632
|
+
const validated = HetznerActionSchema.safeParse(response.action);
|
|
633
|
+
if (!validated.success) {
|
|
634
|
+
console.warn("Hetzner enable rescue validation warning:", validated.error.issues);
|
|
635
|
+
return response.action;
|
|
636
|
+
}
|
|
637
|
+
return validated.data;
|
|
638
|
+
}
|
|
639
|
+
async disableRescue(id) {
|
|
640
|
+
const serverIdSchema = z2.number().int().positive();
|
|
641
|
+
const validatedId = serverIdSchema.safeParse(id);
|
|
642
|
+
if (!validatedId.success) {
|
|
643
|
+
throw new Error(`Invalid server ID: ${validatedId.error.issues.map((i) => i.message).join(", ")}`);
|
|
644
|
+
}
|
|
645
|
+
const response = await this.client.request(`/servers/${validatedId.data}/actions/disable_rescue`, { method: "POST" });
|
|
646
|
+
const validated = HetznerActionSchema.safeParse(response.action);
|
|
647
|
+
if (!validated.success) {
|
|
648
|
+
console.warn("Hetzner disable rescue validation warning:", validated.error.issues);
|
|
649
|
+
return response.action;
|
|
650
|
+
}
|
|
651
|
+
return validated.data;
|
|
652
|
+
}
|
|
653
|
+
async changeType(id, serverType, upgradeDisk = false) {
|
|
654
|
+
const serverIdSchema = z2.number().int().positive();
|
|
655
|
+
const validatedId = serverIdSchema.safeParse(id);
|
|
656
|
+
if (!validatedId.success) {
|
|
657
|
+
throw new Error(`Invalid server ID: ${validatedId.error.issues.map((i) => i.message).join(", ")}`);
|
|
658
|
+
}
|
|
659
|
+
const response = await this.client.request(`/servers/${validatedId.data}/actions/change_type`, {
|
|
660
|
+
method: "POST",
|
|
661
|
+
body: JSON.stringify({ server_type: serverType, upgrade_disk: upgradeDisk })
|
|
662
|
+
});
|
|
663
|
+
const validated = HetznerActionSchema.safeParse(response.action);
|
|
664
|
+
if (!validated.success) {
|
|
665
|
+
console.warn("Hetzner change type validation warning:", validated.error.issues);
|
|
666
|
+
return response.action;
|
|
667
|
+
}
|
|
668
|
+
return validated.data;
|
|
669
|
+
}
|
|
670
|
+
async getActions(id, options) {
|
|
671
|
+
const serverIdSchema = z2.number().int().positive();
|
|
672
|
+
const validatedId = serverIdSchema.safeParse(id);
|
|
673
|
+
if (!validatedId.success) {
|
|
674
|
+
throw new Error(`Invalid server ID: ${validatedId.error.issues.map((i) => i.message).join(", ")}`);
|
|
675
|
+
}
|
|
676
|
+
const params = new URLSearchParams;
|
|
677
|
+
if (options?.status)
|
|
678
|
+
params.append("status", options.status);
|
|
679
|
+
if (options?.sort)
|
|
680
|
+
params.append("sort", options.sort);
|
|
681
|
+
const query = params.toString();
|
|
682
|
+
const response = await this.client.request(`/servers/${validatedId.data}/actions${query ? `?${query}` : ""}`);
|
|
683
|
+
return response.actions;
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
export {
|
|
687
|
+
ServerOperations
|
|
688
|
+
};
|