From 1e9de962adb0815cc3f9862516da89ed00a6fd39 Mon Sep 17 00:00:00 2001 From: Mahmoud-Emad Date: Fri, 28 Nov 2025 11:14:36 +0200 Subject: [PATCH] docs: Update Hetzner examples documentation - Refactor Hetzner examples to use environment variables - Clarify SSH key configuration for Hetzner - Improve documentation structure and readability --- examples/virt/hetzner/hetzner_env.sh | 3 + examples/virt/hetzner/hetzner_kristof1.vsh | 28 +++++++--- examples/virt/hetzner/hetzner_kristof2.vsh | 64 +++++++++------------- examples/virt/hetzner/hetzner_kristof3.vsh | 28 +++++++--- examples/virt/hetzner/hetzner_test1.vsh | 28 +++++++--- examples/virt/hetzner/readme.md | 53 ++++++++++++------ lib/virt/hetznermanager/readme.md | 50 +++++++++++++++-- 7 files changed, 165 insertions(+), 89 deletions(-) create mode 100755 examples/virt/hetzner/hetzner_env.sh diff --git a/examples/virt/hetzner/hetzner_env.sh b/examples/virt/hetzner/hetzner_env.sh new file mode 100755 index 00000000..5c74eb50 --- /dev/null +++ b/examples/virt/hetzner/hetzner_env.sh @@ -0,0 +1,3 @@ +export HETZNER_USER="#ws+JdQtGCdL" +export HETZNER_PASSWORD="Kds007kds!" +export HETZNER_SSHKEY_NAME="mahmoud" diff --git a/examples/virt/hetzner/hetzner_kristof1.vsh b/examples/virt/hetzner/hetzner_kristof1.vsh index ca82ab2a..6741f193 100755 --- a/examples/virt/hetzner/hetzner_kristof1.vsh +++ b/examples/virt/hetzner/hetzner_kristof1.vsh @@ -8,23 +8,33 @@ import time import os import incubaid.herolib.core.playcmds -name := 'kristof1' +// Server-specific configuration +const server_name = 'kristof1' +const server_whitelist = '2521602' -user := os.environ()['HETZNER_USER'] or { +// Load credentials from environment variables +// Source hetzner_env.sh before running: source examples/virt/hetzner/hetzner_env.sh +hetzner_user := os.environ()['HETZNER_USER'] or { println('HETZNER_USER not set') exit(1) } -passwd := os.environ()['HETZNER_PASSWORD'] or { + +hetzner_passwd := os.environ()['HETZNER_PASSWORD'] or { println('HETZNER_PASSWORD not set') exit(1) } +hetzner_sshkey_name := os.environ()['HETZNER_SSHKEY_NAME'] or { + println('HETZNER_SSHKEY_NAME not set') + exit(1) +} + hs := ' !!hetznermanager.configure - user:"${user}" - whitelist:"2521602,2555487,2573047" - password:"${passwd}" - sshkey:"kristof" + user:"${hetzner_user}" + whitelist:"${server_whitelist}" + password:"${hetzner_passwd}" + sshkey:"${hetzner_sshkey_name}" ' println(hs) @@ -42,7 +52,7 @@ mut cl := hetznermanager.get()! println(cl.servers_list()!) -mut serverinfo := cl.server_info_get(name: name)! +mut serverinfo := cl.server_info_get(name: server_name)! println(serverinfo) @@ -55,7 +65,7 @@ println(serverinfo) // console.print_header('SSH login') -cl.ubuntu_install(name: name, wait: true, hero_install: true)! +cl.ubuntu_install(name: server_name, wait: true, hero_install: true)! // cl.ubuntu_install(name: 'kristof20', wait: true, hero_install: true)! // cl.ubuntu_install(id:2550378, name: 'kristof21', wait: true, hero_install: true)! // cl.ubuntu_install(id:2550508, name: 'kristof22', wait: true, hero_install: true)! diff --git a/examples/virt/hetzner/hetzner_kristof2.vsh b/examples/virt/hetzner/hetzner_kristof2.vsh index 3df6077b..e82d8da0 100755 --- a/examples/virt/hetzner/hetzner_kristof2.vsh +++ b/examples/virt/hetzner/hetzner_kristof2.vsh @@ -8,61 +8,47 @@ import time import os import incubaid.herolib.core.playcmds -name := 'kristof2' +// Server-specific configuration +const server_name = 'kristof2' +const server_whitelist = '2555487' -user := os.environ()['HETZNER_USER'] or { +// Load credentials from environment variables +// Source hetzner_env.sh before running: source examples/virt/hetzner/hetzner_env.sh +hetzner_user := os.environ()['HETZNER_USER'] or { println('HETZNER_USER not set') exit(1) } -passwd := os.environ()['HETZNER_PASSWORD'] or { + +hetzner_passwd := os.environ()['HETZNER_PASSWORD'] or { println('HETZNER_PASSWORD not set') exit(1) } -hs := ' +hetzner_sshkey_name := os.environ()['HETZNER_SSHKEY_NAME'] or { + println('HETZNER_SSHKEY_NAME not set') + exit(1) +} + +hero_script := ' !!hetznermanager.configure - user:"${user}" - whitelist:"2521602,2555487" - password:"${passwd}" - sshkey:"kristof" + user:"${hetzner_user}" + whitelist:"${server_whitelist}" + password:"${hetzner_passwd}" + sshkey:"${hetzner_sshkey_name}" ' -println(hs) +playcmds.run(heroscript: hero_script)! +mut hetznermanager_ := hetznermanager.get()! -playcmds.run(heroscript: hs)! +mut serverinfo := hetznermanager_.server_info_get(name: server_name)! -console.print_header('Hetzner Test.') +println('${server_name} ${serverinfo.server_ip}') -mut cl := hetznermanager.get()! -// println(cl) +hetznermanager_.server_rescue(name: server_name, wait: true, hero_install: true)! +mut keys := hetznermanager_.keys_get()! -// for i in 0 .. 5 { -// println('test cache, first time slow then fast') -// } - -println(cl.servers_list()!) - -mut serverinfo := cl.server_info_get(name: name)! - -println(serverinfo) - -// cl.server_reset(name: 'kristof2', wait: true)! - -cl.server_rescue(name: name, wait: true, hero_install: true)! - -mut ks := cl.keys_get()! -println(ks) - -console.print_header('SSH login') mut b := builder.new()! mut n := b.node_new(ipaddr: serverinfo.server_ip)! -// this will put hero in debug mode on the system -// n.hero_install(compile: true)! - -cl.ubuntu_install(name: name, wait: true, hero_install: true)! +hetznermanager_.ubuntu_install(name: server_name, wait: true, hero_install: true)! n.shell('')! -// cl.ubuntu_install(name: 'kristof20', wait: true, hero_install: true)! -// cl.ubuntu_install(id:2550378, name: 'kristof21', wait: true, hero_install: true)! -// cl.ubuntu_install(id:2550508, name: 'kristof22', wait: true, hero_install: true)! -// cl.ubuntu_install(id: 2550253, name: 'kristof23', wait: true, hero_install: true)! diff --git a/examples/virt/hetzner/hetzner_kristof3.vsh b/examples/virt/hetzner/hetzner_kristof3.vsh index 4ecd44ef..3e0aecde 100755 --- a/examples/virt/hetzner/hetzner_kristof3.vsh +++ b/examples/virt/hetzner/hetzner_kristof3.vsh @@ -8,23 +8,33 @@ import time import os import incubaid.herolib.core.playcmds -name := 'kristof3' +// Server-specific configuration +const server_name = 'kristof3' +const server_whitelist = '2573047' -user := os.environ()['HETZNER_USER'] or { +// Load credentials from environment variables +// Source hetzner_env.sh before running: source examples/virt/hetzner/hetzner_env.sh +hetzner_user := os.environ()['HETZNER_USER'] or { println('HETZNER_USER not set') exit(1) } -passwd := os.environ()['HETZNER_PASSWORD'] or { + +hetzner_passwd := os.environ()['HETZNER_PASSWORD'] or { println('HETZNER_PASSWORD not set') exit(1) } +hetzner_sshkey_name := os.environ()['HETZNER_SSHKEY_NAME'] or { + println('HETZNER_SSHKEY_NAME not set') + exit(1) +} + hs := ' !!hetznermanager.configure - user:"${user}" - whitelist:"2521602,2555487,2573047" - password:"${passwd}" - sshkey:"kristof" + user:"${hetzner_user}" + whitelist:"${server_whitelist}" + password:"${hetzner_passwd}" + sshkey:"${hetzner_sshkey_name}" ' println(hs) @@ -42,7 +52,7 @@ mut cl := hetznermanager.get()! println(cl.servers_list()!) -mut serverinfo := cl.server_info_get(name: name)! +mut serverinfo := cl.server_info_get(name: server_name)! println(serverinfo) @@ -55,7 +65,7 @@ println(serverinfo) // console.print_header('SSH login') -cl.ubuntu_install(name: name, wait: true, hero_install: true)! +cl.ubuntu_install(name: server_name, wait: true, hero_install: true)! // cl.ubuntu_install(name: 'kristof20', wait: true, hero_install: true)! // cl.ubuntu_install(id:2550378, name: 'kristof21', wait: true, hero_install: true)! // cl.ubuntu_install(id:2550508, name: 'kristof22', wait: true, hero_install: true)! diff --git a/examples/virt/hetzner/hetzner_test1.vsh b/examples/virt/hetzner/hetzner_test1.vsh index 880ac755..8acbf52a 100755 --- a/examples/virt/hetzner/hetzner_test1.vsh +++ b/examples/virt/hetzner/hetzner_test1.vsh @@ -8,23 +8,33 @@ import time import os import incubaid.herolib.core.playcmds -name := 'test1' +// Server-specific configuration +const server_name = 'test1' +const server_whitelist = '2575034' -user := os.environ()['HETZNER_USER'] or { +// Load credentials from environment variables +// Source hetzner_env.sh before running: source examples/virt/hetzner/hetzner_env.sh +hetzner_user := os.environ()['HETZNER_USER'] or { println('HETZNER_USER not set') exit(1) } -passwd := os.environ()['HETZNER_PASSWORD'] or { + +hetzner_passwd := os.environ()['HETZNER_PASSWORD'] or { println('HETZNER_PASSWORD not set') exit(1) } +hetzner_sshkey_name := os.environ()['HETZNER_SSHKEY_NAME'] or { + println('HETZNER_SSHKEY_NAME not set') + exit(1) +} + hs := ' !!hetznermanager.configure - user:"${user}" - whitelist:"2575034" - password:"${passwd}" - sshkey:"kristof" + user:"${hetzner_user}" + whitelist:"${server_whitelist}" + password:"${hetzner_passwd}" + sshkey:"${hetzner_sshkey_name}" ' println(hs) @@ -42,7 +52,7 @@ mut cl := hetznermanager.get()! println(cl.servers_list()!) -mut serverinfo := cl.server_info_get(name: name)! +mut serverinfo := cl.server_info_get(name: server_name)! println(serverinfo) @@ -55,7 +65,7 @@ println(serverinfo) // console.print_header('SSH login') -cl.ubuntu_install(name: name, wait: true, hero_install: true)! +cl.ubuntu_install(name: server_name, wait: true, hero_install: true)! // cl.ubuntu_install(name: 'kristof20', wait: true, hero_install: true)! // cl.ubuntu_install(id:2550378, name: 'kristof21', wait: true, hero_install: true)! // cl.ubuntu_install(id:2550508, name: 'kristof22', wait: true, hero_install: true)! diff --git a/examples/virt/hetzner/readme.md b/examples/virt/hetzner/readme.md index 07cc2ec0..cf37dfdf 100644 --- a/examples/virt/hetzner/readme.md +++ b/examples/virt/hetzner/readme.md @@ -1,22 +1,31 @@ +# Hetzner Examples -## to get started +## Quick Start -This script is run from your own computer or a VM on which you develop. +### 1. Configure Environment Variables -Make sure you have hero_secrets loaded +Copy `hetzner_env.sh` and fill in your credentials: ```bash -hero git pull https://git.threefold.info/despiegk/hero_secrets -source ~/code/git.ourworld.tf/despiegk/hero_secrets/mysecrets.sh +export HETZNER_USER="your-robot-username" # Hetzner Robot API username +export HETZNER_PASSWORD="your-password" # Hetzner Robot API password +export HETZNER_SSHKEY_NAME="my-key" # Name of SSH key registered in Hetzner ``` -## to e.g. install test1 +Each script has its own server name and whitelist ID defined at the top. -``` -~/code/github/incubaid/herolib/examples/virt/hetzner/hetzner_test1.vsh +### 2. Run a Script + +```bash +source hetzner_env.sh +./hetzner_kristof2.vsh ``` -keys available: +## SSH Keys + +The `HETZNER_SSHKEY_NAME` must be the **name** of an SSH key already registered in your Hetzner Robot account. + +Available keys in our Hetzner account: - hossnys (RSA 2048) - Jan De Landtsheer (ED25519 256) @@ -24,17 +33,25 @@ keys available: - kristof (ED25519 256) - maxime (ED25519 256) -you can select another key in the script +To add a new key, use `key_create` in your script or the Hetzner Robot web interface. -> still to do, support our example key which is installed using mysecrets.sh +## Alternative: Using hero_secrets - -## hetzner troubleshoot info - -get the login passwd from: - -https://robot.hetzner.com/preferences/index +You can also use the shared secrets repository: ```bash -curl -u "#ws+JdQtGCdL:..." https://robot-ws.your-server.de/server +hero git pull https://git.threefold.info/despiegk/hero_secrets +source ~/code/git.ourworld.tf/despiegk/hero_secrets/mysecrets.sh +``` + +## Troubleshooting + +### Get Robot API credentials + +Get your login credentials from: https://robot.hetzner.com/preferences/index + +### Test API access + +```bash +curl -u "your-username:your-password" https://robot-ws.your-server.de/server ``` diff --git a/lib/virt/hetznermanager/readme.md b/lib/virt/hetznermanager/readme.md index 11e6bda0..2efece23 100644 --- a/lib/virt/hetznermanager/readme.md +++ b/lib/virt/hetznermanager/readme.md @@ -4,15 +4,55 @@ This module provides a V client for interacting with Hetzner's Robot API, allowi ## 1. Configuration -Before using the module, you need to configure at least one client instance with your Hetzner Robot credentials. This is done using the `hetznermanager.configure` action in HeroScript. It's recommended to store your password in an environment variable for security. +Before using the module, you need to configure at least one client instance with your Hetzner Robot credentials. It's recommended to store your credentials in environment variables for security. + +### 1.1 Environment Variables + +Create an environment file (e.g., `hetzner_env.sh`) with your credentials: + +```bash +export HETZNER_USER="your-robot-username" # Hetzner Robot API username +export HETZNER_PASSWORD="your-password" # Hetzner Robot API password +export HETZNER_SSHKEY_NAME="my-key" # Name of SSH key registered in Hetzner (NOT the key content) +``` + +Each script defines its own server name and whitelist at the top of the file. + +Source the env file before running your scripts: + +```bash +source hetzner_env.sh +./your_script.vsh +``` + +### 1.2 SSH Key Configuration + +**Important:** The `sshkey` parameter expects the **name** of an SSH key already registered in your Hetzner Robot account, not the actual key content. + +To register a new SSH key with Hetzner, use `key_create`: + +```hs +!!hetznermanager.key_create + key_name: 'my-laptop-key' + data: 'ssh-ed25519 AAAAC3...' # The actual public key content +``` + +Once registered, you can reference the key by name in `configure`: + +```hs +!!hetznermanager.configure + sshkey: 'my-laptop-key' # Reference the registered key by name +``` + +### 1.3 HeroScript Configuration ```hs !!hetznermanager.configure name:"main" - user:"" + user:"${HETZNER_USER}" password:"${HETZNER_PASSWORD}" - whitelist:"2111181, 2392178" // Optional: comma-separated list of server IDs to operate on - sshkey: "name of sshkey as used with hetzner" + whitelist:"1234567" // Server ID(s) specific to your script + sshkey:"${HETZNER_SSHKEY_NAME}" ``` ## 2. Usage @@ -61,7 +101,7 @@ HeroScript provides a simple, declarative way to execute server operations. You * `user` (string): Hetzner Robot username. * `password` (string): Hetzner Robot password. * `whitelist` (string, optional): Comma-separated list of server IDs to restrict operations to. - * `sshkey` (string, optional): Default public SSH key to deploy in rescue mode. + * `sshkey` (string, optional): **Name** of an SSH key registered in your Hetzner account (not the key content). * `!!hetznermanager.server_rescue`: Activates the rescue system. * `instance` (string, optional): The client instance to use (defaults to 'default'). * `server_name` or `id` (string/int): Identifies the target server.