summaryrefslogtreecommitdiff
path: root/gnu/machine
diff options
context:
space:
mode:
authorSergey Trofimov <sarg@sarg.org.ru>2025-04-18 17:08:08 +0200
committerLudovic Courtès <ludo@gnu.org>2025-04-21 23:55:50 +0200
commit7a4193ec4a09fecc68dc726c1e0bbb5ad03d404a (patch)
treedbb9740caaf85b85bc39c6b333b01c3609a4507e /gnu/machine
parent5f1ee7ba730b5e2c0bb4b33878d0462dd22d2eb6 (diff)
machine: hetzner: Allow attaching existing public IPs.
* gnu/machine/hetzner.scm (hetzner-configuration): Add ipv4 and ipv6 fields. Export accessors. * gnu/machine/hetzner/http.scm (hetnzer-api-primary-ips): New function. (<hetzner-primary-ip>): New json mapping. (hetzner-api-server-create): Pass IP addresses in request. * doc/guix.texi (Invoking guix deploy): Document it. Change-Id: I44509cc98e041762dc483e876566e79bde85b26a Signed-off-by: Ludovic Courtès <ludo@gnu.org>
Diffstat (limited to 'gnu/machine')
-rw-r--r--gnu/machine/hetzner.scm25
-rw-r--r--gnu/machine/hetzner/http.scm37
2 files changed, 56 insertions, 6 deletions
diff --git a/gnu/machine/hetzner.scm b/gnu/machine/hetzner.scm
index e8484e4d51e..ddac58dda0a 100644
--- a/gnu/machine/hetzner.scm
+++ b/gnu/machine/hetzner.scm
@@ -73,6 +73,8 @@
73 hetzner-configuration-authorize? 73 hetzner-configuration-authorize?
74 hetzner-configuration-build-locally? 74 hetzner-configuration-build-locally?
75 hetzner-configuration-delete? 75 hetzner-configuration-delete?
76 hetzner-configuration-ipv4
77 hetzner-configuration-ipv6
76 hetzner-configuration-labels 78 hetzner-configuration-labels
77 hetzner-configuration-location 79 hetzner-configuration-location
78 hetzner-configuration-server-type 80 hetzner-configuration-server-type
@@ -205,6 +207,10 @@ Have you run 'guix archive --generate-key'?")
205 (default "fsn1")) 207 (default "fsn1"))
206 (server-type hetzner-configuration-server-type ; string 208 (server-type hetzner-configuration-server-type ; string
207 (default "cx42")) 209 (default "cx42"))
210 (ipv4 hetzner-configuration-ipv4 ; boolean | string
211 (default #t))
212 (ipv6 hetzner-configuration-ipv6 ; boolean | string
213 (default #t))
208 (ssh-public-key hetzner-configuration-ssh-public-key ; public-key | string 214 (ssh-public-key hetzner-configuration-ssh-public-key ; public-key | string
209 (thunked) 215 (thunked)
210 (default (public-key-from-file (hetzner-configuration-ssh-key this-hetzner-configuration))) 216 (default (public-key-from-file (hetzner-configuration-ssh-key this-hetzner-configuration)))
@@ -445,6 +451,17 @@ values: list of output lines returned by CMD and its exit code."
445 (hetzner-configuration-api config) 451 (hetzner-configuration-api config)
446 #:params `(("name" . ,(machine-display-name machine))))))) 452 #:params `(("name" . ,(machine-display-name machine)))))))
447 453
454(define (hetzner-resolve-ip api name)
455 "Find the NAME IP address on the Hetzner API."
456 (or
457 (find (lambda (primary-ip)
458 (equal? name (hetzner-primary-ip-name primary-ip)))
459 (hetzner-api-primary-ips api #:params `(("name" . ,name))))
460
461 (raise-exception
462 (formatted-message (G_ "primary ip '~a' does not exist.")
463 name))))
464
448(define (hetzner-machine-create-server machine) 465(define (hetzner-machine-create-server machine)
449 "Create the Hetzner server for MACHINE." 466 "Create the Hetzner server for MACHINE."
450 (let* ((config (machine-configuration machine)) 467 (let* ((config (machine-configuration machine))
@@ -452,11 +469,19 @@ values: list of output lines returned by CMD and its exit code."
452 (server-type (hetzner-configuration-server-type config))) 469 (server-type (hetzner-configuration-server-type config)))
453 (format #t "creating '~a' server for '~a'...\n" server-type name) 470 (format #t "creating '~a' server for '~a'...\n" server-type name)
454 (let* ((ssh-key (hetzner-machine-ssh-key machine)) 471 (let* ((ssh-key (hetzner-machine-ssh-key machine))
472 (ipv4 (hetzner-configuration-ipv4 config))
473 (ipv6 (hetzner-configuration-ipv6 config))
455 (api (hetzner-configuration-api config)) 474 (api (hetzner-configuration-api config))
456 (server (hetzner-api-server-create 475 (server (hetzner-api-server-create
457 api 476 api
458 (machine-display-name machine) 477 (machine-display-name machine)
459 (list ssh-key) 478 (list ssh-key)
479 #:ipv4 (if (string? ipv4)
480 (hetzner-primary-ip-id (hetzner-resolve-ip api ipv4))
481 ipv4)
482 #:ipv6 (if (string? ipv6)
483 (hetzner-primary-ip-id (hetzner-resolve-ip api ipv6))
484 ipv6)
460 #:labels (hetzner-configuration-labels config) 485 #:labels (hetzner-configuration-labels config)
461 #:location (hetzner-configuration-location config) 486 #:location (hetzner-configuration-location config)
462 #:server-type (hetzner-configuration-server-type config))) 487 #:server-type (hetzner-configuration-server-type config)))
diff --git a/gnu/machine/hetzner/http.scm b/gnu/machine/hetzner/http.scm
index 51b4bff984f..bd12e8ee5eb 100644
--- a/gnu/machine/hetzner/http.scm
+++ b/gnu/machine/hetzner/http.scm
@@ -52,6 +52,7 @@
52 hetzner-api-actions 52 hetzner-api-actions
53 hetzner-api-create-ssh-key 53 hetzner-api-create-ssh-key
54 hetzner-api-locations 54 hetzner-api-locations
55 hetzner-api-primary-ips
55 hetzner-api-request-body 56 hetzner-api-request-body
56 hetzner-api-request-headers 57 hetzner-api-request-headers
57 hetzner-api-request-method 58 hetzner-api-request-method
@@ -100,6 +101,13 @@
100 hetzner-location-name 101 hetzner-location-name
101 hetzner-location-network-zone 102 hetzner-location-network-zone
102 hetzner-location? 103 hetzner-location?
104 hetzner-primary-ip
105 hetzner-primary-ip-created
106 hetzner-primary-ip-id
107 hetzner-primary-ip-ip
108 hetzner-primary-ip-labels
109 hetzner-primary-ip-name
110 hetzner-primary-ip-type
103 hetzner-public-net 111 hetzner-public-net
104 hetzner-public-net-ipv4 112 hetzner-public-net-ipv4
105 hetzner-public-net-ipv6 113 hetzner-public-net-ipv6
@@ -144,6 +152,7 @@
144 make-hetzner-ipv6 152 make-hetzner-ipv6
145 make-hetzner-location 153 make-hetzner-location
146 make-hetzner-public-net 154 make-hetzner-public-net
155 make-hetzner-primary-ip
147 make-hetzner-resource 156 make-hetzner-resource
148 make-hetzner-server 157 make-hetzner-server
149 make-hetzner-server-type 158 make-hetzner-server-type
@@ -296,6 +305,16 @@
296 (name hetzner-server-type-name) ; string 305 (name hetzner-server-type-name) ; string
297 (storage-type hetzner-server-type-storage-type "storage_type")) ; string 306 (storage-type hetzner-server-type-storage-type "storage_type")) ; string
298 307
308;; Reserved IP address. https://docs.hetzner.cloud/#primary-ips
309(define-json-mapping <hetzner-primary-ip>
310 make-hetzner-primary-ip hetzner-primary-ip? json->hetzner-primary-ip
311 (created hetzner-primary-ip-created "created" string->time) ; time
312 (id hetzner-primary-ip-id) ; integer
313 (ip hetzner-primary-ip-ip) ; string
314 (labels hetzner-primary-ip-labels) ; alist of string/string
315 (name hetzner-primary-ip-name) ; string
316 (type hetzner-primary-ip-type)) ; string
317
299(define-json-mapping <hetzner-ssh-key> 318(define-json-mapping <hetzner-ssh-key>
300 make-hetzner-ssh-key hetzner-ssh-key? json->hetzner-ssh-key 319 make-hetzner-ssh-key hetzner-ssh-key? json->hetzner-ssh-key
301 (created hetzner-ssh-key-created "created" string->time) ; time 320 (created hetzner-ssh-key-created "created" string->time) ; time
@@ -581,12 +600,11 @@
581(define* (hetzner-api-server-create 600(define* (hetzner-api-server-create
582 api name ssh-keys 601 api name ssh-keys
583 #:key 602 #:key
584 (enable-ipv4? #t) 603 (ipv4 #f)
585 (enable-ipv6? #t) 604 (ipv6 #f)
586 (image %hetzner-default-server-image) 605 (image %hetzner-default-server-image)
587 (labels '()) 606 (labels '())
588 (location %hetzner-default-server-location) 607 (location %hetzner-default-server-location)
589 (public-net #f)
590 (server-type %hetzner-default-server-type) 608 (server-type %hetzner-default-server-type)
591 (start-after-create? #f)) 609 (start-after-create? #f))
592 "Create a server with the Hetzner API." 610 "Create a server with the Hetzner API."
@@ -595,9 +613,11 @@
595 #:body `(("image" . ,image) 613 #:body `(("image" . ,image)
596 ("labels" . ,labels) 614 ("labels" . ,labels)
597 ("name" . ,name) 615 ("name" . ,name)
598 ("public_net" 616 ("public_net" .
599 . (("enable_ipv4" . ,enable-ipv4?) 617 (("enable_ipv4" . ,(and ipv4 #t))
600 ("enable_ipv6" . ,enable-ipv6?))) 618 ("enable_ipv6" . ,(and ipv6 #t))
619 ,@(if (integer? ipv4) `(("ipv4" . ,ipv4)) '())
620 ,@(if (integer? ipv6) `(("ipv6" . ,ipv6)) '())))
601 ("location" . ,location) 621 ("location" . ,location)
602 ("server_type" . ,server-type) 622 ("server_type" . ,server-type)
603 ("ssh_keys" . ,(apply vector (map hetzner-ssh-key-id ssh-keys))) 623 ("ssh_keys" . ,(apply vector (map hetzner-ssh-key-id ssh-keys)))
@@ -658,6 +678,11 @@
658 (apply hetzner-api-list api "/ssh_keys" "ssh_keys" 678 (apply hetzner-api-list api "/ssh_keys" "ssh_keys"
659 json->hetzner-ssh-key options)) 679 json->hetzner-ssh-key options))
660 680
681(define* (hetzner-api-primary-ips api . options)
682 "Get Primary IPs from the Hetzner API."
683 (apply hetzner-api-list api "/primary_ips" "primary_ips"
684 json->hetzner-primary-ip options))
685
661(define* (hetzner-api-server-types api . options) 686(define* (hetzner-api-server-types api . options)
662 "Get server types from the Hetzner API." 687 "Get server types from the Hetzner API."
663 (apply hetzner-api-list api "/server_types" "server_types" 688 (apply hetzner-api-list api "/server_types" "server_types"