Cloud API Kotlin

Solidblocks hetzner-cloud is Kotlin implementation for the Hetzner Cloud API.

Usage

To use Solidblocks hetzner-cloud just add the dependency to your Gradle or Maven build

build.gradle.kts

plugins {
    id("org.jetbrains.kotlin.jvm") version "2.2.10"
}

repositories {
    mavenCentral()
    mavenLocal()
}

dependencies {
    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.2")
    implementation("de.solidblocks:hetzner-cloud:0.5.4")
}

tasks.named<Test>("test") {
    useJUnitPlatform()
}

Basics

The library supports Kotlin coroutines, thus all API calls must be made from a coroutine context. The root api has to be initialized using a Hetzner cloud api token, from there all supports resources are available grouped by resource type.

package de.solidblocks.hetzner

import de.solidblocks.hetzner.cloud.HetznerApi
import kotlinx.coroutines.runBlocking

fun BasicUsage() {
    runBlocking {
        val api = HetznerApi(System.getenv("HCLOUD_TOKEN"))

        //api.servers.shutdown(123)
        //api.firewalls.delete(12)
        //api.volumes.create(...)
    }
}

Create and Get

All resources support listing, as well as filtering by resource attributes or labels

package de.solidblocks.hetzner

import de.solidblocks.hetzner.cloud.HetznerApi
import de.solidblocks.hetzner.cloud.model.HetznerLocation
import de.solidblocks.hetzner.cloud.model.HetznerServerType
import de.solidblocks.hetzner.cloud.resources.ServerCreateRequest
import kotlinx.coroutines.runBlocking

fun CreateAndGetResources() {
    runBlocking {
        val api = HetznerApi(System.getenv("HCLOUD_TOKEN"))

        val server = api.servers.create(
            ServerCreateRequest(
                "server1",
                HetznerLocation.nbg1,
                HetznerServerType.cx23,
                image = "debian-12",
            )
        )

        val serverByName = api.servers.get("server1") ?: throw RuntimeException("could not find server1")
        val serverById = api.servers.get(server.server.id) ?: throw RuntimeException("could not find server with id '${server.server.id}'")
    }
}

Listing and Filtering

All resources support resource creation and retrieval by name and id.

package de.solidblocks.hetzner

import de.solidblocks.hetzner.cloud.HetznerApi
import de.solidblocks.hetzner.cloud.model.LabelSelectorValue.Equals
import de.solidblocks.hetzner.cloud.resources.ImageType
import de.solidblocks.hetzner.cloud.resources.ImageTypeFilter
import kotlinx.coroutines.runBlocking

fun Filtering() {
    runBlocking {
        val api = HetznerApi(System.getenv("HCLOUD_TOKEN"))

        // list all images
        api.images.list()

        // filter by image type
        api.images.list(listOf(ImageTypeFilter(ImageType.app)))

        // filter by label
        api.servers.list(labelSelectors = mapOf("label1" to Equals("foo-bar")))
    }
}

Actions

Waiters are available for resources that are created or updated asynchronosly

package de.solidblocks.hetzner

import de.solidblocks.hetzner.cloud.HetznerApi
import de.solidblocks.hetzner.cloud.model.HetznerLocation
import de.solidblocks.hetzner.cloud.model.HetznerServerType
import de.solidblocks.hetzner.cloud.resources.ServerCreateRequest
import kotlinx.coroutines.runBlocking

fun WaitForActions() {
    runBlocking {
        val api = HetznerApi(System.getenv("HCLOUD_TOKEN"))

        val server = api.servers.create(
            ServerCreateRequest(
                "server1",
                HetznerLocation.nbg1,
                HetznerServerType.cx23,
                image = "debian-12",
            )
        )

        api.servers.waitForAction(server.action)
    }
}

Exceptions

For failing API calls the exception HetznerApiException provides type access to the underlying Hetzner error.

package de.solidblocks.hetzner

import de.solidblocks.hetzner.cloud.HetznerApi
import de.solidblocks.hetzner.cloud.model.HetznerApiErrorType
import de.solidblocks.hetzner.cloud.model.HetznerApiException
import de.solidblocks.hetzner.cloud.model.HetznerLocation
import de.solidblocks.hetzner.cloud.resources.VolumeCreateRequest
import de.solidblocks.hetzner.cloud.resources.VolumeFormat
import kotlinx.coroutines.runBlocking

fun Exceptions() {
    runBlocking {
        val api = HetznerApi(System.getenv("HCLOUD_TOKEN"))

        try {
            api.volumes.create(VolumeCreateRequest("volume1", 16, HetznerLocation.nbg1, VolumeFormat.ext4, false))
        } catch (e: HetznerApiException) {
            if (e.error.code == HetznerApiErrorType.RESOURCE_LIMIT_EXCEEDED) {
                print("volume quota reached")
            }
        }
    }
}