hetzner

package
v0.23.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 18, 2026 License: AGPL-3.0 Imports: 45 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func NewHetznerCloudProvider

func NewHetznerCloudProvider() cloud.CloudProvider

func WaitForDNSResolution added in v0.23.0

func WaitForDNSResolution(ctx context.Context, fqdns []string, expectedIP string) error

WaitForDNSResolution blocks until every fqdn in fqdns resolves to expectedIP through the OS resolver, ctx is cancelled, or dnsTotalTimeout passes (the wait fails closed — interactive bootstrap can't loop forever on a missing record).

No skip option: bypassing the wait would just push the failure into a later stage (cert-manager's first ACME HTTP-01, NetBird OIDC callback, etc.) where the symptom is harder to diagnose. Better to fail here with a clear "DNS records still not resolving" + cache- flush hint than to half-bootstrap and debug from a downstream pod's 503.

func WaitForIngressLBDNS added in v0.23.0

func WaitForIngressLBDNS(ctx context.Context, clusterClient client.Client) error

WaitForIngressLBDNS gates bootstrap on the operator pointing the public-facing FQDNs (keycloak.dns / netbird.dns / netbird.stunDNS / netbird.turnDNS) at the Traefik LB's public IP. Run as SyncAllArgoCDApps's beforeRemainingApps gate — after ccm + traefik are synced (so the LB is being provisioned) but before the application-layer apps (netbird, keycloakx) whose Ingress certificates depend on DNS resolving. We poll the Service for status.loadBalancer.ingress[0].ip and only then prompt the operator.

cert-manager's ACME challenges for keycloakx / netbird Ingresses retry with exponential backoff. Putting the DNS prompt here lets the next retry succeed instead of leaving the apps unhealthy while the operator scrambles to figure out which IP to point at.

No-op when no FQDNs are configured (workload clusters, or VPN clusters with no Keycloak/NetBird DNS set).

Types

type ActivateHRobotLinuxInstallationResponseBody added in v0.23.0

type ActivateHRobotLinuxInstallationResponseBody struct {
	Linux struct {
		Dist          string   `json:"dist"`
		Lang          string   `json:"lang"`
		Password      string   `json:"password"`
		AuthorizedKey []string `json:"authorized_key"`
		Active        bool     `json:"active"`
	} `json:"linux"`
}

type CreateVSwitchResponseBody added in v0.16.0

type CreateVSwitchResponseBody struct {
	ID int `json:"id"`

	Name   string `json:"name"`
	VLANID int    `json:"vlan"`

	Cancelled bool `json:"cancelled"`
}

type FailoverIPDetails added in v0.12.0

type FailoverIPDetails struct {
	ActiveServerIP string `json:"active_server_ip"`
}

type GetFailoverIPDetailsResponse added in v0.12.0

type GetFailoverIPDetailsResponse struct {
	Failover FailoverIPDetails `json:"failover"`
}

type GetKeysResponse added in v0.21.0

type GetKeysResponse []struct {
	Key Key `json:"key"`
}

type GetServerResponseBody added in v0.20.0

type GetServerResponseBody struct {
	Server Server `json:"server"`
}

type HCloudMachineTemplateUpdates added in v0.18.0

type HCloudMachineTemplateUpdates struct {
	NewImageName string
}

type HRobotResetResponseBody added in v0.23.0

type HRobotResetResponseBody struct {
	Reset struct {
		ServerIP string `json:"server_ip"`
		Type     string `json:"type"`
	} `json:"reset"`
}

type Hetzner

type Hetzner struct {
	// contains filtered or unexported fields
}

func (*Hetzner) AttachHCloudServerToNetwork added in v0.20.0

func (h *Hetzner) AttachHCloudServerToNetwork(ctx context.Context, serverID, networkID int) error

AttachHCloudServerToNetwork attaches the given HCloud server to the given Hetzner Network.

func (*Hetzner) AttachServerToVSwitch added in v0.20.0

func (h *Hetzner) AttachServerToVSwitch(ctx context.Context, serverID string, vswitchID int) error

func (*Hetzner) ConnectVSwitchWithHetznerNetwork added in v0.20.0

func (h *Hetzner) ConnectVSwitchWithHetznerNetwork(ctx context.Context, network *hcloud.Network) error

When using Hetzner Bare Metal, we need to establish private connectivity between them and the HCloud servers in a Hetzner Network, using a VSwitch.

func (*Hetzner) CreateHCloudSSHKey added in v0.21.0

func (h *Hetzner) CreateHCloudSSHKey(ctx context.Context, name string, sshKeyPair config.SSHKeyPairConfig) error

CreateHCloudSSHKey creates the given SSH key in HCloud, if it doesn't already exist.

func (*Hetzner) CreateHetznerBareMetalSSHKey added in v0.21.0

func (h *Hetzner) CreateHetznerBareMetalSSHKey(
	ctx context.Context,
	name string,
	sshKeyPair config.SSHKeyPairConfig,
) error

CreateHetznerBareMetalSSHKey creates the given SSH key in Hetzner Bare Metal, if it doesn't already exist.

func (*Hetzner) CreateLB added in v0.21.0

func (h *Hetzner) CreateLB(ctx context.Context,
	clusterName string,
	network *hcloud.Network,
	location string,
	enablePublicInterface bool,
) (*hcloud.LoadBalancer, error)

CreateLB creates the Hetzner control-plane LB if it doesn't already exist. enablePublicInterface controls whether the LB carries a public IPv4 — true during bootstrap (NetBird isn't routing the private subnet yet), false in steady state.

func (*Hetzner) CreateNATGateway added in v0.21.0

func (h *Hetzner) CreateNATGateway(ctx context.Context, networkID int) error

func (*Hetzner) CreateNetwork added in v0.20.0

func (h *Hetzner) CreateNetwork(ctx context.Context) (*hcloud.Network, error)

CreateNetwork creates the Hetzner Network, if it doesn't already exist.

func (*Hetzner) CreateVSwitch added in v0.16.0

func (h *Hetzner) CreateVSwitch(ctx context.Context) (int, error)

A VSwitch is used to establish private connectivity between Hetzner Bare Metal servers (and a Hetzner Network, when spinning up a Hetzner hybrid cluster). This function is responsible for creating that VSwitch, if it doesn't already exist. The VSwitch ID gets returned.

func (*Hetzner) DisableControlPlaneLBPublicInterface added in v0.23.0

func (h *Hetzner) DisableControlPlaneLBPublicInterface(ctx context.Context) error

DisableControlPlaneLBPublicInterface is the post-bootstrap finalize call: clusters whose control-plane LB ran with a public interface during bootstrap (so kubeadm join, ArgoCD setup, etc. could reach the apiserver before NetBird was up) flip it off here, leaving the LB reachable only through its private IP via the NetBird mesh.

Applies to the two modes that pre-create the LB during bootstrap:

  • VPN clusters: this cluster IS the VPN, bootstraps behind a public LB and transitions to private-via-NetBird once netbird itself is Healthy. Until v1.x of this code the guard skipped these because HCloudVPNCluster is nil for the VPN itself, which left the control-plane public on a freshly bootstrapped VPN cluster — fixed by including cluster.type=vpn in the gate.

  • workload clusters connecting to an existing VPN: same public- during-join / private-after-NetBird lifecycle, signaled by a non-nil HCloudVPNCluster pointing at the parent VPN.

Other modes (bare-metal CP, plain workload without a parent VPN) never had a public HCloud LB to disable — early return.

Also gated on hostname being configured: without an FQDN the LB's public IP is the operator's only entry point to kube-apiserver, and disabling it would lock them out of their own cluster.

func (*Hetzner) DisableDeletionProtection added in v0.23.0

func (h *Hetzner) DisableDeletionProtection(ctx context.Context) error

DisableDeletionProtection disables deletion protection on the KubeAPI LB and NAT Gateway server so that CAPH can delete them during cluster teardown.

func (*Hetzner) GenerateStoragePlans added in v0.20.0

func (h *Hetzner) GenerateStoragePlans(ctx context.Context, hetznerConfig *config.HetznerConfig) error

func (*Hetzner) GetHCloudServerIDsForCluster added in v0.20.0

func (h *Hetzner) GetHCloudServerIDsForCluster(ctx context.Context, name string) ([]int, error)

GetHCloudServerIDsForCluster returns IDs of the HCloud servers associated with the given Kubernetes cluster which was provisioned using Cluster API Provider Hetzner (CAPH).

func (*Hetzner) GetVMSpecs

func (h *Hetzner) GetVMSpecs(ctx context.Context, machineType string) (*cloud.VMSpec, error)

func (*Hetzner) InstallOSOnAllHBMS added in v0.23.0

func (h *Hetzner) InstallOSOnAllHBMS(ctx context.Context) error

InstallOSOnAllHBMS installs Ubuntu on each HBMS in parallel. HBMS that are already SSH-reachable are skipped (idempotency). Since each HBMS's OS installation takes ~8-12 minutes regardless of others, processing them in parallel bounds total wall-clock time to that of the slowest single host.

func (*Hetzner) PointFailoverIPToInitMasterNode added in v0.12.0

func (h *Hetzner) PointFailoverIPToInitMasterNode(ctx context.Context) error

func (*Hetzner) ProvisionPrerequisiteInfrastructure added in v0.21.0

func (h *Hetzner) ProvisionPrerequisiteInfrastructure(ctx context.Context) error

ProvisionPrerequisiteInfrastructure provisions infrastructure required before CAPH starts spinning up the cluster.

func (*Hetzner) SetControlPlaneLBPublicInterface added in v0.23.0

func (h *Hetzner) SetControlPlaneLBPublicInterface(
	ctx context.Context, clusterName string, enabled bool,
) (*hcloud.LoadBalancer, error)

SetControlPlaneLBPublicInterface ensures the LB's public interface matches enabled. Idempotent — no-op when already in the desired state. Used both during bootstrap (enable) and post-bootstrap finalize (disable) once NetBird routes the private endpoint.

func (*Hetzner) SetupDisasterRecovery

func (*Hetzner) SetupDisasterRecovery(_ context.Context) error

func (*Hetzner) UpdateCapiClusterValuesFile added in v0.18.0

func (*Hetzner) UpdateCapiClusterValuesFile(ctx context.Context, path string, updates any) error

func (*Hetzner) UpdateMachineTemplate

func (*Hetzner) UpdateMachineTemplate(ctx context.Context,
	clusterClient client.Client,
	name string,
	updates any,
) error

type HetznerBareMetalMachineTemplateUpdates added in v0.18.0

type HetznerBareMetalMachineTemplateUpdates struct {
	NewImagePath string
}

type HetznerMachineTemplateUpdates added in v0.18.0

type HetznerMachineTemplateUpdates struct {
	HCloudMachineTemplateUpdates
	HetznerBareMetalMachineTemplateUpdates
}

type Key added in v0.21.0

type Key struct {
	Name        string `json:"name"`
	Fingerprint string `json:"fingerprint"`
}

type ListVSwitchResponseBody added in v0.16.0

type ListVSwitchResponseBody = []struct {
	ID int `json:"id"`

	Name   string `json:"name"`
	VLANID int    `json:"vlan"`

	Cancelled bool `json:"cancelled"`
}

type Server added in v0.20.0

type Server struct {
	IP string `json:"server_ip"`
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL