diff options
| author | Sergey Trofimov <sarg@sarg.org.ru> | 2025-04-18 17:08:08 +0200 |
|---|---|---|
| committer | Ludovic Courtès <ludo@gnu.org> | 2025-04-21 23:55:50 +0200 |
| commit | 7a4193ec4a09fecc68dc726c1e0bbb5ad03d404a (patch) | |
| tree | dbb9740caaf85b85bc39c6b333b01c3609a4507e /gnu/machine | |
| parent | 5f1ee7ba730b5e2c0bb4b33878d0462dd22d2eb6 (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.scm | 25 | ||||
| -rw-r--r-- | gnu/machine/hetzner/http.scm | 37 |
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" |
