/**
 * Idempotent find-or-create provisioning helpers on top of the Hetzner client.
 *
 * These are the building blocks for "deploy X onto a Hetzner box" scripts:
 * each helper reuses an existing resource when one matches (by name, or by
 * key body for SSH keys) and creates it otherwise, so re-running a deploy
 * converges instead of failing on duplicates.
 */
import type { CreateServerOptions, HetznerClient, HetznerFirewallRule, HetznerServer } from './client';
export interface EnsuredResource {
    id: number;
    name: string;
    created: boolean;
}
export interface EnsureSshKeyOptions {
    /** Name used if the key needs to be registered. */
    name: string;
    /** OpenSSH public key (`<type> <base64> [comment]`). */
    publicKey: string;
    labels?: Record<string, string>;
}
/**
 * Register an SSH public key, reusing any already-registered key with the
 * same body (comment/whitespace differences ignored) regardless of its name.
 */
export declare function ensureSshKey(client: HetznerClient, options: EnsureSshKeyOptions): Promise<EnsuredResource>;
export interface EnsureFirewallOptions {
    name: string;
    rules: HetznerFirewallRule[];
    labels?: Record<string, string>;
}
/**
 * Find a firewall by name and sync its rules to the given set, or create it.
 * Rules are replaced in-place on reuse so the firewall always matches the
 * declared config.
 */
export declare function ensureFirewall(client: HetznerClient, options: EnsureFirewallOptions): Promise<EnsuredResource>;
export interface EnsureServerOptions extends CreateServerOptions {
    /** Wait until the (created or reused) server reaches `running`. @default true */
    waitForRunning?: boolean;
}
export interface EnsuredServer {
    server: HetznerServer;
    created: boolean;
}
/**
 * Find a server by name or create it, waiting until it is running by default.
 * Creation options (`userData`, `sshKeys`, `firewalls`, ...) only apply when
 * the server does not exist yet — an existing server is reused as-is.
 */
export declare function ensureServer(client: HetznerClient, options: EnsureServerOptions): Promise<EnsuredServer>;
/** The public IPv4 of a server, throwing when it has none. */
export declare function serverPublicIpv4(server: HetznerServer): string;
