npm package: @infrasamurai/hetzner
Description: Hetzner Cloud provider for InfraSamurai hosting
Latest version: 0.0.2

# @infrasamurai/hetzner

Hetzner Cloud provider implementation for InfraSamurai hosting.

## Installation

```bash
npm install @infrasamurai/hetzner
# or
yarn add @infrasamurai/hetzner
```

## Quick Start

```typescript
import { HetznerProvider } from '@infrasamurai/hetzner';

const hetzner = new HetznerProvider('your-hetzner-api-token');

// Validate credentials
const { valid, error } = await hetzner.validateCredentials();

// Get available resources
const locations = await hetzner.getLocations();
const serverTypes = await hetzner.getServerTypes('fsn1');
const images = await hetzner.getImages();
const networks = await hetzner.getNetworks();

// Create a server
const server = await hetzner.createServer({
  name: 'my-server',
  serverType: 'cx21',
  image: 'ubuntu-22.04',
  location: 'fsn1',
  sshKeyIds: ['12345'],
  providerOptions: {
    networks: ['67890'],
    enablePublicIpv4: true,
    enablePublicIpv6: true,
  },
});

// Wait for server to be ready
const details = await hetzner.waitForServerReady(server.serverId);
console.log(`Server running at ${details.publicIpv4}`);

// Delete server
await hetzner.deleteServer(server.serverId);
```

## API

### Constructor

```typescript
const hetzner = new HetznerProvider(apiToken: string, options?: BaseProviderOptions);
```

Options:
- `logger` - Custom logger implementing `ProviderLogger`
- `httpTimeout` - Request timeout in ms (default: 30000)
- `maxRetries` - Max retry attempts (default: 3)
- `retryDelayMs` - Initial retry delay in ms (default: 1000)
- `pollInterval` - Polling interval for waitForServerReady (default: 5000)
- `maxWaitTime` - Max wait time for waitForServerReady (default: 300000)

### Methods

#### Credentials

```typescript
validateCredentials(): Promise<{ valid: boolean; error?: string }>
```

#### Locations

```typescript
getLocations(): Promise<ServerLocation[]>
```

Returns Hetzner datacenters: `fsn1`, `nbg1`, `hel1`, `ash`, `hil`.

#### Server Types

```typescript
getServerTypes(location?: string): Promise<ServerType[]>
```

Returns available server sizes. Filter by location to get accurate pricing.

#### Images

```typescript
getImages(): Promise<ServerImage[]>
```

Returns available OS images (Ubuntu, Debian, CentOS, etc.).

#### SSH Keys

```typescript
getSshKeys(): Promise<ProviderSshKey[]>
createSshKey(name: string, publicKey: string): Promise<ProviderSshKey>
deleteSshKey(keyId: string): Promise<void>
```

#### Networks

```typescript
getNetworks(): Promise<ProviderNetwork[]>
```

Returns private networks for internal server communication.

#### Servers

```typescript
createServer(request: CreateServerRequest): Promise<CreateServerResponse>
getServer(serverId: string): Promise<ServerDetails>
waitForServerReady(serverId: string, timeoutMs?: number): Promise<ServerDetails>
deleteServer(serverId: string): Promise<void>
```

### CreateServerRequest

```typescript
interface CreateServerRequest {
  name: string;
  serverType: string;           // e.g., 'cx21', 'cpx11'
  image: string;                // e.g., 'ubuntu-22.04'
  location: string;             // e.g., 'fsn1'
  sshKeyIds?: string[];         // Hetzner SSH key IDs
  userData?: string;            // Cloud-init script
  labels?: Record<string, string>;
  providerOptions?: {
    networks?: string[];        // Network IDs to attach
    firewalls?: string[];       // Firewall IDs to apply
    enablePublicIpv4?: boolean; // Default: true
    enablePublicIpv6?: boolean; // Default: true
    placementGroup?: string;    // Placement group ID
    volumes?: string[];         // Volume IDs to attach
  };
}
```

## UI Schema

The package exports a UI schema for building dynamic forms:

```typescript
import { hetznerUISchema } from '@infrasamurai/hetzner';

console.log(hetznerUISchema.displayName);  // "Hetzner Cloud"
console.log(hetznerUISchema.capabilities); // Available features
```

### Capabilities

- Private Networks
- Cloud Firewalls
- Load Balancers
- Block Storage (Volumes)
- Floating IPs
- Snapshots
- Automatic Backups
- Placement Groups
- Primary IPs

## Hetzner Cloud API

This provider uses the [Hetzner Cloud API v1](https://docs.hetzner.cloud/).

### Getting an API Token

1. Log in to [Hetzner Cloud Console](https://console.hetzner.cloud/)
2. Select your project
3. Go to **Security** > **API Tokens**
4. Click **Generate API Token**
5. Give it a name and select **Read & Write** permissions

## Error Handling

```typescript
import { HostingError, HostingErrorType } from '@infrasamurai/hosting-core';

try {
  await hetzner.createServer({ ... });
} catch (error) {
  if (error instanceof HostingError) {
    switch (error.errorType) {
      case HostingErrorType.QUOTA_EXCEEDED:
        console.error('Server limit reached');
        break;
      case HostingErrorType.API_RATE_LIMITED:
        console.error('Rate limited, retry later');
        break;
      case HostingErrorType.API_AUTH_FAILED:
        console.error('Invalid API token');
        break;
    }
  }
}
```

## License

MIT