projects/guix·blob javascript-team · refs

673 lines · 25.8 KiB

1;;; GNU Guix --- Functional package management for GNU
2;;; Copyright © 2024 Roman Scherer <[email protected]>
3;;; Copyright © 2026 Ludovic Courtès <[email protected]>
4;;;
5;;; This file is part of GNU Guix.
6;;;
7;;; GNU Guix is free software; you can redistribute it and/or modify it
8;;; under the terms of the GNU General Public License as published by
9;;; the Free Software Foundation; either version 3 of the License, or (at
10;;; your option) any later version.
11;;;
12;;; GNU Guix is distributed in the hope that it will be useful, but
13;;; WITHOUT ANY WARRANTY; without even the implied warranty of
14;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15;;; GNU General Public License for more details.
16;;;
17;;; You should have received a copy of the GNU General Public License
18;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
19
20(define-module (tests machine hetzner http)
21 #:use-module (gnu machine hetzner http)
22 #:use-module (guix build utils)
23 #:use-module (guix tests)
24 #:use-module (srfi srfi-1)
25 #:use-module (srfi srfi-34)
26 #:use-module (srfi srfi-64)
27 #:use-module (ssh key)
28 #:use-module (ice-9 match))
29
30;; Unit and integration tests the (gnu machine hetzner http) module.
31
32;; Integration tests require the GUIX_HETZNER_API_TOKEN environment variable.
33;; https://docs.hetzner.com/cloud/api/getting-started/generating-api-token
34
35;; The integration tests sometimes fail due to the Hetzner API not being able
36;; to allocate a resource. Switching to a different location might help.
37
38(define %labels
39 '(("guix.gnu.org/test" . "true")))
40
41(define %server-name
42 "guix-hetzner-api-test-server")
43
44(define %ssh-key-name
45 "guix-hetzner-api-test-key")
46
47(define %ssh-key-file
48 (string-append "/tmp/" %ssh-key-name))
49
50(unless (file-exists? %ssh-key-file)
51 (private-key-to-file (make-keypair 'rsa 2048) %ssh-key-file))
52
53(define %ssh-key
54 (hetzner-ssh-key-read-file %ssh-key-file))
55
56(define %when-no-token
57 (if (hetzner-api-token (hetzner-api)) 0 1))
58
59(define action-create-server
60 (make-hetzner-action
61 "create_server" #f *unspecified* 1896091819 0
62 (list (make-hetzner-resource 59570198 "server"))
63 #(0 17 11 2 1 125 0 32 -1 0 #f) "running"))
64
65(define action-create-server-alist
66 '(("command" . "create_server")
67 ("error" . null)
68 ("finished" . null)
69 ("id" . 1896091819)
70 ("progress" . 0)
71 ("resources" . #((("type" . "server") ("id" . 59570198))))
72 ("started" . "2025-02-02T11:17:00+00:00")
73 ("status" . "running")))
74
75(define action-delete-server
76 (make-hetzner-action
77 "delete_server" #f *unspecified* 1896091928 0
78 (list (make-hetzner-resource 59570198 "server"))
79 #(10 17 11 2 1 125 0 32 -1 0 #f) "running"))
80
81(define action-delete-server-alist
82 '(("command" . "delete_server")
83 ("error" . null)
84 ("finished" . null)
85 ("id" . 1896091928)
86 ("progress" . 0)
87 ("resources" . #((("type" . "server") ("id" . 59570198))))
88 ("started" . "2025-02-02T11:17:10+00:00")
89 ("status" . "running")))
90
91(define action-enable-rescue
92 (make-hetzner-action
93 "enable_rescue" #f *unspecified* 1896091721 0
94 (list (make-hetzner-resource 59570198 "server"))
95 #(10 17 11 2 1 125 0 32 -1 0 #f) "success"))
96
97(define action-enable-rescue-alist
98 '(("command" . "enable_rescue")
99 ("error" . null)
100 ("finished" . null)
101 ("id" . 1896091721)
102 ("progress" . 0)
103 ("resources" . #((("type" . "server") ("id" . 59570198))))
104 ("started" . "2025-02-02T11:17:10+00:00")
105 ("status" . "running")))
106
107(define action-power-off
108 (make-hetzner-action
109 "stop_server" #f *unspecified* 1896091721 0
110 (list (make-hetzner-resource 59570198 "server"))
111 #(10 17 11 2 1 125 0 32 -1 0 #f) "success"))
112
113(define action-power-off-alist
114 '(("command" . "stop_server")
115 ("error" . null)
116 ("finished" . null)
117 ("id" . 1896091721)
118 ("progress" . 0)
119 ("resources" . #((("type" . "server") ("id" . 59570198))))
120 ("started" . "2025-02-02T11:17:10+00:00")
121 ("status" . "running")))
122
123(define action-power-on
124 (make-hetzner-action
125 "start_server" #f *unspecified* 1896091721 0
126 (list (make-hetzner-resource 59570198 "server"))
127 #(10 17 11 2 1 125 0 32 -1 0 #f) "success"))
128
129(define action-power-on-alist
130 '(("command" . "start_server")
131 ("error" . null)
132 ("finished" . null)
133 ("id" . 1896091721)
134 ("progress" . 0)
135 ("resources" . #((("type" . "server") ("id" . 59570198))))
136 ("started" . "2025-02-02T11:17:10+00:00")
137 ("status" . "running")))
138
139(define action-reboot
140 (make-hetzner-action
141 "reboot_server" #f *unspecified* 1896091721 0
142 (list (make-hetzner-resource 59570198 "server"))
143 #(10 17 11 2 1 125 0 32 -1 0 #f) "success"))
144
145(define action-reboot-alist
146 '(("command" . "reboot_server")
147 ("error" . null)
148 ("finished" . null)
149 ("id" . 1896091721)
150 ("progress" . 0)
151 ("resources" . #((("type" . "server") ("id" . 59570198))))
152 ("started" . "2025-02-02T11:17:10+00:00")
153 ("status" . "running")))
154
155(define meta-page-alist
156 '("pagination"
157 ("last_page" . 1)
158 ("next_page" . null)
159 ("page" . 1)
160 ("per_page" . 25)
161 ("previous_page" . null)
162 ("total_entries" . 1)))
163
164(define location-falkenstein
165 (make-hetzner-location
166 "Falkenstein" "DE" "Falkenstein DC Park 1"
167 1 50.47612 12.370071 "fsn1" "eu-central"))
168
169(define location-falkenstein-alist
170 `(("city" . "Falkenstein")
171 ("country" . "DE")
172 ("description" . "Falkenstein DC Park 1")
173 ("id" . 1)
174 ("latitude" . 50.47612)
175 ("longitude" . 12.370071)
176 ("name" . "fsn1")
177 ("network_zone" . "eu-central")))
178
179(define server-type-cpx-11
180 (make-hetzner-server-type
181 "x86" 2 "shared" #f *unspecified*
182 "CPX 11" 40 22 2 "cpx11" "local"))
183
184(define server-type-cpx-11-alist
185 `(("architecture" . "x86")
186 ("cores" . 2)
187 ("cpu_type" . "shared")
188 ("deprecated" . #f)
189 ("deprecation" . null)
190 ("description" . "CPX 11")
191 ("disk" . 40)
192 ("id" . 22)
193 ("memory" . 2)
194 ("name" . "cpx11")
195 ("storage_type" . "local")))
196
197(define server-x86
198 (make-hetzner-server
199 "2024-12-30T16:38:11+00:00"
200 59570198
201 '()
202 "guix-x86"
203 (make-hetzner-public-net
204 (make-hetzner-ipv4 #f "static.218.128.13.49.clients.your-server.de" 78014457 "49.13.128.218")
205 (make-hetzner-ipv6 #f '() 78014458 "2a01:4f8:c17:293e::/64"))
206 #f
207 server-type-cpx-11))
208
209(define server-x86-alist
210 `(("backup_window" . null)
211 ("created" . "2024-12-30T16:38:11+00:00")
212 ("id" . 59570198)
213 ("included_traffic" . 21990232555520)
214 ("ingoing_traffic" . 124530000)
215 ("iso" . null)
216 ("labels")
217 ("load_balancers" . #())
218 ("locked" . #f)
219 ("name" . "guix-x86")
220 ("outgoing_traffic" . 1391250000)
221 ("placement_group" . null)
222 ("primary_disk_size" . 320)
223 ("private_net" . #())
224 ("protection" ("rebuild" . #f) ("delete" . #f))
225 ("public_net"
226 ("firewalls" . #())
227 ("floating_ips" . #())
228 ("ipv6"
229 ("id" . 78014458)
230 ("dns_ptr" . #())
231 ("blocked" . #f)
232 ("ip" . "2a01:4f8:c17:293e::/64"))
233 ("ipv4"
234 ("id" . 78014457)
235 ("dns_ptr" . "static.218.128.13.49.clients.your-server.de")
236 ("blocked" . #f)
237 ("ip" . "49.13.128.218")))
238 ("rescue_enabled" . #f)
239 ("server_type" ,@server-type-cpx-11-alist)
240 ("status" . "running")
241 ("volumes" . #())))
242
243(define primary-ip
244 (make-hetzner-primary-ip
245 #(55 2 19 28 9 123 6 300 -1 0 #f)
246 42
247 "131.232.99.1"
248 '()
249 "static-ip"
250 "ipv4"))
251
252(define primary-ip-alist
253 `(("created" . "2023-10-28T19:02:55+00:00")
254 ("id" . 42)
255 ("labels")
256 ("name" . "static-ip")
257 ("blocked" . #f)
258 ("ip" . "131.232.99.1")
259 ("datacenter")
260 ("dns_ptr")
261 ("protection" . (("delete" . #f)))
262 ("type" . "ipv4")
263 ("auto_delete" . #t)
264 ("assignee_type" . "server")
265 ("assignee_id" . 17)))
266
267(define ssh-key-root
268 (make-hetzner-ssh-key
269 #(55 2 19 28 9 123 6 300 -1 0 #f)
270 "8c:25:09:8f:37:0f:d8:f0:99:4e:ab:c7:5c:1b:c6:53"
271 16510983 '() "[email protected]"
272 "ssh-ed25519 ABCAC3NzaC1lZDI1NTE5AAAAIBT3lLYPfOZV9NNrNk0jGCufWmXbFSz+ORxowJdHoSIM"))
273
274(define ssh-key-root-alist
275 `(("created" . "2023-10-28T19:02:55+00:00")
276 ("fingerprint" . "8c:25:09:8f:37:0f:d8:f0:99:4e:ab:c7:5c:1b:c6:53")
277 ("id" . 16510983)
278 ("labels")
279 ("name" . "[email protected]")
280 ("public_key" . "ssh-ed25519 ABCAC3NzaC1lZDI1NTE5AAAAIBT3lLYPfOZV9NNrNk0jGCufWmXbFSz+ORxowJdHoSIM")))
281
282(define* (create-ssh-key api ssh-key #:key (labels %labels))
283 (hetzner-api-ssh-key-create
284 api
285 (hetzner-ssh-key-name ssh-key)
286 (hetzner-ssh-key-public-key ssh-key)
287 #:labels labels))
288
289(define* (create-server api ssh-key #:key (labels %labels))
290 (hetzner-api-server-create api %server-name
291 #:ssh-keys (list ssh-key)
292 #:labels labels
293 #:server-type "cpx31"))
294
295(define (cleanup api)
296 (for-each (lambda (server)
297 (hetzner-api-server-delete api server))
298 (hetzner-api-servers
299 api #:params `(("label_selector" . "guix.gnu.org/test=true"))))
300 (for-each (lambda (ssh-key)
301 (hetzner-api-ssh-key-delete api ssh-key))
302 (hetzner-api-ssh-keys
303 api #:params `(("label_selector" . "guix.gnu.org/test=true"))))
304 api)
305
306(define-syntax-rule (with-cleanup-api (api-sym api-init) body ...)
307 (let ((api-sym (cleanup api-init)))
308 (dynamic-wind
309 (const #t)
310 (lambda ()
311 body ...)
312 (lambda ()
313 (cleanup api-sym)))))
314
315(test-begin "machine-hetzner-api")
316
317;; Unit Tests
318
319(test-equal "hetzner-api-actions-unit"
320 (list action-create-server action-delete-server)
321 (let ((actions (list action-create-server-alist action-delete-server-alist)))
322 (mock ((gnu machine hetzner http) hetzner-api-request-send
323 (lambda* (request #:key expected)
324 (match (list (hetzner-api-request-method request)
325 (hetzner-api-request-url request))
326 (('GET "https://api.hetzner.cloud/v1/actions")
327 (and (unspecified? (hetzner-api-request-body request))
328 (equal? `(("page" . 1)
329 ("id" . ,(string-join
330 (map (lambda (action)
331 (number->string (assoc-ref action "id")))
332 actions)
333 ",")))
334 (hetzner-api-request-params request))
335 (hetzner-api-response
336 (body `(("meta" . ,meta-page-alist)
337 ("actions" . #(,action-create-server-alist
338 ,action-delete-server-alist))))))))))
339 (hetzner-api-actions (hetzner-api)
340 (map (lambda (action)
341 (assoc-ref action "id"))
342 actions)))))
343
344(test-equal "hetzner-api-locations-unit"
345 (list location-falkenstein)
346 (mock ((gnu machine hetzner http) hetzner-api-request-send
347 (lambda* (request #:key expected)
348 (match (list (hetzner-api-request-method request)
349 (hetzner-api-request-url request))
350 (('GET "https://api.hetzner.cloud/v1/locations")
351 (and (unspecified? (hetzner-api-request-body request))
352 (equal? '(("page" . 1))
353 (hetzner-api-request-params request))
354 (hetzner-api-response
355 (body `(("meta" . ,meta-page-alist)
356 ("locations" . #(,location-falkenstein-alist))))))))))
357 (hetzner-api-locations (hetzner-api))))
358
359(test-equal "hetzner-api-server-types-unit"
360 (list server-type-cpx-11)
361 (mock ((gnu machine hetzner http) hetzner-api-request-send
362 (lambda* (request #:key expected)
363 (match (list (hetzner-api-request-method request)
364 (hetzner-api-request-url request))
365 (('GET "https://api.hetzner.cloud/v1/server_types")
366 (and (unspecified? (hetzner-api-request-body request))
367 (equal? '(("page" . 1))
368 (hetzner-api-request-params request))
369 (hetzner-api-response
370 (body `(("meta" . ,meta-page-alist)
371 ("server_types" . #(,server-type-cpx-11-alist))))))))))
372 (hetzner-api-server-types (hetzner-api))))
373
374(test-equal "hetzner-api-server-create-unit"
375 server-x86
376 (mock ((gnu machine hetzner http) hetzner-api-request-send
377 (lambda* (request #:key expected)
378 (match (list (hetzner-api-request-method request)
379 (hetzner-api-request-url request))
380 (('GET "https://api.hetzner.cloud/v1/images")
381 (hetzner-api-response
382 (body `(("images"
383 . #((("id" . 123)
384 ("created_from" . null)
385 ("protection" . (("delete" . #t)))
386 ("os_flavor" . "debian"))))))))
387 (('POST "https://api.hetzner.cloud/v1/servers")
388 (hetzner-api-response
389 (body `(("action" . ,action-create-server-alist)
390 ("server" . ,server-x86-alist)))))
391 (('GET "https://api.hetzner.cloud/v1/actions")
392 (hetzner-api-response
393 (body `(("actions" . ,(vector (cons `("status" . "success")
394 action-create-server-alist)))
395 ("meta" . ,meta-page-alist))))))))
396 (hetzner-api-server-create (hetzner-api) %server-name
397 #:ssh-keys (list ssh-key-root))))
398
399(test-equal "hetzner-api-server-delete-unit"
400 (make-hetzner-action
401 "delete_server" #f *unspecified* 1896091928 0
402 (list (make-hetzner-resource 59570198 "server"))
403 #(10 17 11 2 1 125 0 32 -1 0 #f) "success")
404 (mock ((gnu machine hetzner http) hetzner-api-request-send
405 (lambda* (request #:key expected)
406 (match (list (hetzner-api-request-method request)
407 (hetzner-api-request-url request))
408 (('DELETE "https://api.hetzner.cloud/v1/servers/59570198")
409 (hetzner-api-response
410 (body `(("action" . ,action-delete-server-alist)))))
411 (('GET "https://api.hetzner.cloud/v1/actions")
412 (hetzner-api-response
413 (body `(("actions" . ,(vector (cons `("status" . "success")
414 action-delete-server-alist)))
415 ("meta" . ,meta-page-alist))))))))
416 (hetzner-api-server-delete (hetzner-api) server-x86)))
417
418(test-equal "hetzner-api-server-enable-rescue-system-unit"
419 action-enable-rescue
420 (mock ((gnu machine hetzner http) hetzner-api-request-send
421 (lambda* (request #:key expected)
422 (match (list (hetzner-api-request-method request)
423 (hetzner-api-request-url request))
424 (('POST
425 "https://api.hetzner.cloud/v1/servers/59570198/actions/enable_rescue")
426 (hetzner-api-response
427 (body `(("action" . ,action-enable-rescue-alist)))))
428 (('GET "https://api.hetzner.cloud/v1/actions")
429 (hetzner-api-response
430 (body `(("actions" . ,(vector (cons `("status" . "success")
431 action-enable-rescue-alist)))
432 ("meta" . ,meta-page-alist))))))))
433 (hetzner-api-server-enable-rescue-system
434 (hetzner-api) server-x86 #:ssh-keys (list ssh-key-root))))
435
436(test-equal "hetzner-api-server-power-on-unit"
437 action-power-on
438 (mock ((gnu machine hetzner http) hetzner-api-request-send
439 (lambda* (request #:key expected)
440 (match (list (hetzner-api-request-method request)
441 (hetzner-api-request-url request))
442 (('POST
443 "https://api.hetzner.cloud/v1/servers/59570198/actions/poweron")
444 (hetzner-api-response
445 (body `(("action" . ,action-power-on-alist)))))
446 (('GET "https://api.hetzner.cloud/v1/actions")
447 (hetzner-api-response
448 (body `(("actions" . ,(vector (cons `("status" . "success")
449 action-power-on-alist)))
450 ("meta" . ,meta-page-alist))))))))
451 (hetzner-api-server-power-on (hetzner-api) server-x86)))
452
453(test-equal "hetzner-api-server-power-off-unit"
454 action-power-off
455 (mock ((gnu machine hetzner http) hetzner-api-request-send
456 (lambda* (request #:key expected)
457 (match (list (hetzner-api-request-method request)
458 (hetzner-api-request-url request))
459 (('POST
460 "https://api.hetzner.cloud/v1/servers/59570198/actions/poweroff")
461 (hetzner-api-response
462 (body `(("action" . ,action-power-off-alist)))))
463 (('GET "https://api.hetzner.cloud/v1/actions")
464 (hetzner-api-response
465 (body `(("actions" . ,(vector (cons `("status" . "success")
466 action-power-off-alist)))
467 ("meta" . ,meta-page-alist))))))))
468 (hetzner-api-server-power-off (hetzner-api) server-x86)))
469
470(test-equal "hetzner-api-server-reboot-unit"
471 action-reboot
472 (mock ((gnu machine hetzner http) hetzner-api-request-send
473 (lambda* (request #:key expected)
474 (match (list (hetzner-api-request-method request)
475 (hetzner-api-request-url request))
476 (('POST
477 "https://api.hetzner.cloud/v1/servers/59570198/actions/reboot")
478 (hetzner-api-response
479 (body `(("action" . ,action-reboot-alist)))))
480 (('GET "https://api.hetzner.cloud/v1/actions")
481 (hetzner-api-response
482 (body `(("actions" . ,(vector (cons `("status" . "success")
483 action-reboot-alist)))
484 ("meta" . ,meta-page-alist))))))))
485 (hetzner-api-server-reboot (hetzner-api) server-x86)))
486
487(test-equal "hetzner-api-servers-unit"
488 (list server-x86)
489 (mock ((gnu machine hetzner http) hetzner-api-request-send
490 (lambda* (request #:key expected)
491 (hetzner-api-response
492 (body `(("meta" . ,meta-page-alist)
493 ("servers" . #(,server-x86-alist)))))))
494 (hetzner-api-servers (hetzner-api))))
495
496(test-equal "hetzner-api-ssh-key-create-unit"
497 ssh-key-root
498 (mock ((gnu machine hetzner http) hetzner-api-request-send
499 (lambda* (request #:key expected)
500 (match (list (hetzner-api-request-method request)
501 (hetzner-api-request-url request))
502 (('POST "https://api.hetzner.cloud/v1/ssh_keys")
503 (and (equal? `(("name" . "guix-hetzner-api-test-key")
504 ("public_key" . "ssh-ed25519 ABCAC3NzaC1lZDI1NTE5AAAAIBT3lLYPfOZV9NNrNk0jGCufWmXbFSz+ORxowJdHoSIM")
505 ("labels" . (("a" . "1"))))
506 (hetzner-api-request-body request))
507 (null? (hetzner-api-request-params request))
508 (hetzner-api-response
509 (body `(("ssh_key" . ,ssh-key-root-alist)))))))))
510 (hetzner-api-ssh-key-create
511 (hetzner-api)
512 "guix-hetzner-api-test-key"
513 "ssh-ed25519 ABCAC3NzaC1lZDI1NTE5AAAAIBT3lLYPfOZV9NNrNk0jGCufWmXbFSz+ORxowJdHoSIM"
514 #:labels '(("a" . "1")))))
515
516(test-assert "hetzner-api-ssh-key-delete-unit"
517 (mock ((gnu machine hetzner http) hetzner-api-request-send
518 (lambda* (request #:key expected)
519 (match (list (hetzner-api-request-method request)
520 (hetzner-api-request-url request))
521 (('DELETE "https://api.hetzner.cloud/v1/ssh_keys/16510983")
522 (hetzner-api-response)))))
523 (hetzner-api-ssh-key-delete (hetzner-api) ssh-key-root)))
524
525(test-equal "hetzner-api-ssh-keys-unit"
526 (list ssh-key-root)
527 (mock ((gnu machine hetzner http) hetzner-api-request-send
528 (lambda* (request #:key expected)
529 (match (list (hetzner-api-request-method request)
530 (hetzner-api-request-url request))
531 (('GET "https://api.hetzner.cloud/v1/ssh_keys")
532 (and (unspecified? (hetzner-api-request-body request))
533 (equal? '(("page" . 1))
534 (hetzner-api-request-params request))
535 (hetzner-api-response
536 (body `(("meta" . ,meta-page-alist)
537 ("ssh_keys" . #(,ssh-key-root-alist))))))))))
538 (hetzner-api-ssh-keys (hetzner-api))))
539
540(test-equal "hetzner-api-primary-ips-unit"
541 (list primary-ip)
542 (mock ((gnu machine hetzner http) hetzner-api-request-send
543 (lambda* (request #:key expected)
544 (match (list (hetzner-api-request-method request)
545 (hetzner-api-request-url request))
546 (('GET "https://api.hetzner.cloud/v1/primary_ips")
547 (and (unspecified? (hetzner-api-request-body request))
548 (equal? '(("page" . 1))
549 (hetzner-api-request-params request))
550 (hetzner-api-response
551 (body `(("meta" . ,meta-page-alist)
552 ("primary_ips" . #(,primary-ip-alist))))))))))
553 (hetzner-api-primary-ips (hetzner-api))))
554
555;; Integration tests
556
557(test-skip %when-no-token)
558(test-assert "hetzner-api-actions-integration"
559 (with-cleanup-api (api (hetzner-api))
560 (let* ((ssh-key (create-ssh-key api %ssh-key))
561 (server (create-server api ssh-key))
562 (action (hetzner-api-server-enable-rescue-system
563 api server #:ssh-keys (list ssh-key))))
564 (member action (hetzner-api-actions api (list (hetzner-action-id action)))))))
565
566(test-skip %when-no-token)
567(test-assert "hetzner-api-locations-integration"
568 (let ((locations (hetzner-api-locations (hetzner-api))))
569 (and (> (length locations) 0)
570 (every hetzner-location? locations))))
571
572(test-skip %when-no-token)
573(test-assert "hetzner-api-server-types-integration"
574 (let ((server-types (hetzner-api-server-types (hetzner-api))))
575 (and (> (length server-types) 0)
576 (every hetzner-server-type? server-types))))
577
578(test-skip %when-no-token)
579(test-assert "hetzner-api-server-create-integration"
580 (with-cleanup-api (api (hetzner-api))
581 (let* ((ssh-key (create-ssh-key api %ssh-key))
582 (server (create-server api ssh-key)))
583 (and (hetzner-server? server)
584 (equal? %server-name (hetzner-server-name server))))))
585
586(test-skip %when-no-token)
587(test-assert "hetzner-api-server-delete-integration"
588 (with-cleanup-api (api (hetzner-api))
589 (let* ((ssh-key (create-ssh-key api %ssh-key))
590 (server (create-server api ssh-key))
591 (action (hetzner-api-server-delete api server)))
592 (and (hetzner-action? action)
593 (equal? "delete_server"
594 (hetzner-action-command action))))))
595
596(test-skip %when-no-token)
597(test-assert "hetzner-api-server-enable-rescue-system-integration"
598 (with-cleanup-api (api (hetzner-api))
599 (let* ((ssh-key (create-ssh-key api %ssh-key))
600 (server (create-server api ssh-key))
601 (action (hetzner-api-server-enable-rescue-system
602 api server #:ssh-keys (list ssh-key))))
603 (and (hetzner-action? action)
604 (equal? "enable_rescue"
605 (hetzner-action-command action))))))
606
607(test-skip %when-no-token)
608(test-assert "hetzner-api-server-power-on-integration"
609 (with-cleanup-api (api (hetzner-api))
610 (let* ((ssh-key (create-ssh-key api %ssh-key))
611 (server (create-server api ssh-key))
612 (action (hetzner-api-server-power-on api server)))
613 (and (hetzner-action? action)
614 (equal? "start_server"
615 (hetzner-action-command action))))))
616
617(test-skip %when-no-token)
618(test-assert "hetzner-api-server-power-off-integration"
619 (with-cleanup-api (api (hetzner-api))
620 (let* ((ssh-key (create-ssh-key api %ssh-key))
621 (server (create-server api ssh-key))
622 (action (hetzner-api-server-power-off api server)))
623 (and (hetzner-action? action)
624 (equal? "stop_server"
625 (hetzner-action-command action))))))
626
627(test-skip %when-no-token)
628(test-assert "hetzner-api-server-reboot-integration"
629 (with-cleanup-api (api (hetzner-api))
630 (let* ((ssh-key (create-ssh-key api %ssh-key))
631 (server (create-server api ssh-key))
632 (action (hetzner-api-server-reboot api server)))
633 (and (hetzner-action? action)
634 (equal? "reboot_server"
635 (hetzner-action-command action))))))
636
637(test-skip %when-no-token)
638(test-assert "hetzner-api-servers-integration"
639 (with-cleanup-api (api (hetzner-api))
640 (let* ((ssh-key (create-ssh-key api %ssh-key))
641 (server (create-server api ssh-key)))
642 (member server (hetzner-api-servers api)))))
643
644(test-skip %when-no-token)
645(test-assert "hetzner-api-ssh-key-create-integration"
646 (with-cleanup-api (api (hetzner-api))
647 (let ((ssh-key (create-ssh-key api %ssh-key)))
648 (and (hetzner-ssh-key? ssh-key)
649 (equal? (hetzner-ssh-key-fingerprint %ssh-key)
650 (hetzner-ssh-key-fingerprint ssh-key))
651 (equal? (hetzner-ssh-key-name %ssh-key)
652 (hetzner-ssh-key-name ssh-key))
653 (equal? (hetzner-ssh-key-public-key %ssh-key)
654 (hetzner-ssh-key-public-key ssh-key))))))
655
656(test-skip %when-no-token)
657(test-assert "hetzner-api-ssh-key-delete-integration"
658 (with-cleanup-api (api (hetzner-api))
659 (let ((ssh-key (create-ssh-key api %ssh-key)))
660 (and (equal? #t (hetzner-api-ssh-key-delete api ssh-key))
661 (not (member ssh-key (hetzner-api-ssh-keys api)))))))
662
663(test-skip %when-no-token)
664(test-assert "hetzner-api-ssh-keys-integration"
665 (with-cleanup-api (api (hetzner-api))
666 (let ((ssh-key (create-ssh-key api %ssh-key)))
667 (member ssh-key (hetzner-api-ssh-keys api)))))
668
669(test-end "machine-hetzner-api")
670
671;; Local Variables:
672;; eval: (put 'with-cleanup-api 'scheme-indent-function 1)
673;; End: