# Go SDK (gotsw)

### Overview

The GoTSW library is the official Go client for the TeraSwitch API. It provides a simple, type-safe way to manage bare metal servers, SSH keys, and other TeraSwitch resources from your Go applications.

**Package**: `github.com/teraswitch/gotsw/v2` **Latest Version**: `v2.0.6` **Source Code**: [GitHub](https://github.com/teraswitch/gotsw)

### Requirements

* **Go**: Version 1.21 or later
* **TeraSwitch Account**: Access to the [TeraSwitch Console](https://console.tsw.io)
* **API Token**: [Create an API token](/account/api-tokens.md) for authentication

### Installation

```bash
go get github.com/teraswitch/gotsw/v2
```

### Quick Start

```go
package main

import (
	"context"
	"fmt"
	"os"

	"github.com/teraswitch/gotsw/v2"
)

func main() {
	// Initialize the client with your API key
	client := gotsw.New(os.Getenv("TSW_API_KEY"))

	// List your bare metal services
	resp, err := client.ListMetal(context.Background(), gotsw.ListMetalOptions{})
	if err != nil {
		fmt.Println("Error:", err)
		return
	}

	for _, server := range resp.Data {
		fmt.Printf("Server: %s (Status: %s)\n", server.DisplayName, server.Status)
	}
}
```

{% hint style="success" %}
Store your API key in the `TSW_API_KEY` environment variable to avoid hardcoding credentials.
{% endhint %}

### Client Configuration

#### Creating a Client

```go
client := gotsw.New(apiKey)
```

The `New()` function creates a client configured to use `https://api.tsw.io/v2/`.

#### Configuration Methods

The client supports method chaining for configuration:

```go
client := gotsw.New(os.Getenv("TSW_API_KEY")).
	SetLogBodies(true).
	SetPlainLogger(os.Stdout).
	SetLogger(slog.New(slog.NewTextHandler(os.Stdout, nil)))
```

| Method                      | Description                                |
| --------------------------- | ------------------------------------------ |
| `SetLogger(*slog.Logger)`   | Set a structured logger for debug output   |
| `SetPlainLogger(io.Writer)` | Enable human-readable HTTP traffic logging |
| `SetLogBodies(bool)`        | Toggle request/response body logging       |
| `SetAuthorization(string)`  | Update the API token                       |
| `SetClient(*http.Client)`   | Use a custom HTTP client                   |

### Metal Services API

Manage bare metal servers with the following methods.

#### ListMetal

List bare metal services with optional filtering.

```go
resp, err := client.ListMetal(ctx, gotsw.ListMetalOptions{
	Limit:  10,
	Region: "SLC1",
})
```

**Options:**

| Field    | Type     | Description                         |
| -------- | -------- | ----------------------------------- |
| `Limit`  | `int`    | Maximum number of results to return |
| `Region` | `string` | Filter by region identifier         |

#### GetMetalService

Retrieve details for a specific bare metal service.

```go
resp, err := client.GetMetalService(ctx, serviceID)
```

#### CreateMetalService

Provision a new bare metal server.

```go
resp, err := client.CreateMetalService(ctx, projectID, &gotsw.CreateBareMetalRequest{
	DisplayName: "my-server",
	RegionID:    "LAX1",
	TierID:      "2388g",
	MemoryGB:    64,
	ImageID:     "ubuntu-noble",
	SSHKeyIDs:   []int64{123},
	Disks: []gotsw.DiskConfiguration{
		{Slot: 0, StorageType: gotsw.NVME},
		{Slot: 1, StorageType: gotsw.NVME},
	},
	Partitions: []gotsw.PartitionConfiguration{
		{DiskSlot: 0, PartitionNumber: 1, SizeGB: 960},
		{DiskSlot: 1, PartitionNumber: 1, SizeGB: 960},
	},
	RaidArrays: []gotsw.RaidConfiguration{
		{
			ArrayNumber: 0,
			RaidType:    gotsw.Raid0,
			Filesystem:  "ext4",
			MountPoint:  "/",
			Partitions:  []string{"0:1", "1:1"},
		},
	},
})
```

**Request Fields:**

| Field         | Type                       | Description                              |
| ------------- | -------------------------- | ---------------------------------------- |
| `DisplayName` | `string`                   | Human-readable server name               |
| `RegionID`    | `string`                   | Deployment region (e.g., "LAX1", "SLC1") |
| `TierID`      | `string`                   | Hardware tier identifier                 |
| `MemoryGB`    | `int`                      | Memory allocation in GB                  |
| `ImageID`     | `string`                   | Operating system image                   |
| `SSHKeyIDs`   | `[]int64`                  | SSH keys for root access                 |
| `Disks`       | `[]DiskConfiguration`      | Disk configuration                       |
| `Partitions`  | `[]PartitionConfiguration` | Partition layout                         |
| `RaidArrays`  | `[]RaidConfiguration`      | RAID configuration                       |
| `UserData`    | `string`                   | Cloud-init user data                     |
| `Password`    | `string`                   | Root password (optional)                 |

#### ReinstallMetalService

Reinstall the operating system on an existing server.

```go
resp, err := client.ReinstallMetalService(ctx, serviceID, &gotsw.ReinstallMetalRequest{
	DisplayName: "my-server",
	ImageID:     "ubuntu-noble",
	SSHKeyIDs:   []int64{123},
})
```

#### SendPowerCommand

Control server power state.

```go
resp, err := client.SendPowerCommand(ctx, serviceID, gotsw.PowerOn)
```

**Available Commands:**

| Constant         | Description          |
| ---------------- | -------------------- |
| `gotsw.PowerOn`  | Power on the server  |
| `gotsw.PowerOff` | Power off the server |

#### RenameMetalService

Rename an existing server.

```go
resp, err := client.RenameMetalService(ctx, serviceID, "new-name")
```

#### GetMetalLogs

Retrieve event logs for a server.

```go
resp, err := client.GetMetalLogs(ctx, serviceID)
```

#### ListMetalTiers

List available hardware tiers.

```go
resp, err := client.ListMetalTiers(ctx, gotsw.Compute)
```

**Tier Types:**

| Constant        | Description            |
| --------------- | ---------------------- |
| `gotsw.Compute` | Standard compute tiers |
| `gotsw.GPU`     | GPU-enabled tiers      |

#### GetMetalAvailability

Check hardware availability in a region.

```go
resp, err := client.GetMetalAvailability(ctx, projectID, regionID)
```

### SSH Keys API

Manage SSH keys for server authentication.

#### ListSshKeys

List all SSH keys in your account.

```go
keys, err := client.ListSshKeys(ctx)
```

#### GetSshKey

Retrieve a specific SSH key.

```go
key, err := client.GetSshKey(ctx, keyID)
```

#### CreateSshKey

Create a new SSH key.

```go
key, err := client.CreateSshKey(ctx, projectID, gotsw.CreateSshKeyRequest{
	DisplayName: "my-laptop",
	Key:         "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI... user@host",
})
```

### Types Reference

#### Metal

Represents a bare metal service instance.

| Field          | Type         | Description               |
| -------------- | ------------ | ------------------------- |
| `ID`           | `int64`      | Unique service identifier |
| `DisplayName`  | `string`     | Human-readable name       |
| `Status`       | `Status`     | Current status            |
| `PowerState`   | `PowerState` | Power state               |
| `Region`       | `string`     | Deployment region         |
| `Tier`         | `string`     | Hardware tier             |
| `MemoryGB`     | `int`        | Memory in GB              |
| `IPAddresses`  | `[]string`   | Assigned IP addresses     |
| `MonthlyPrice` | `float64`    | Monthly cost              |
| `HourlyPrice`  | `float64`    | Hourly cost               |

#### SSHKey

Represents an SSH public key.

| Field         | Type     | Description           |
| ------------- | -------- | --------------------- |
| `ID`          | `int64`  | Unique key identifier |
| `DisplayName` | `string` | Human-readable name   |
| `Key`         | `string` | Public key content    |
| `ProjectID`   | `int64`  | Associated project    |

### Constants

#### Status Values

| Constant           | Description                  |
| ------------------ | ---------------------------- |
| `gotsw.Pending`    | Service is being provisioned |
| `gotsw.Active`     | Service is running           |
| `gotsw.Suspended`  | Service is suspended         |
| `gotsw.Terminated` | Service has been terminated  |
| `gotsw.Error`      | Service encountered an error |

#### Power States

| Constant          | Description            |
| ----------------- | ---------------------- |
| `gotsw.On`        | Server is powered on   |
| `gotsw.Off`       | Server is powered off  |
| `gotsw.Rebooting` | Server is rebooting    |
| `gotsw.Unknown`   | Power state is unknown |

#### Storage Types

| Constant     | Description       |
| ------------ | ----------------- |
| `gotsw.HDD`  | Hard disk drive   |
| `gotsw.SSD`  | Solid state drive |
| `gotsw.NVME` | NVMe storage      |

#### RAID Types

| Constant      | Description        |
| ------------- | ------------------ |
| `gotsw.None`  | No RAID            |
| `gotsw.Raid0` | RAID 0 (striping)  |
| `gotsw.Raid1` | RAID 1 (mirroring) |

### Error Handling

All methods return an error as the last return value. Errors are wrapped with context to help identify the source:

```go
resp, err := client.GetMetalService(ctx, serviceID)
if err != nil {
	// Handle error - may be network, authentication, or API error
	log.Printf("Failed to get service: %v", err)
	return
}
```

{% hint style="warning" %}
Always check the error return value before using the response data.
{% endhint %}

\## Complete Example

```go
package main

import (
	"context"
	"fmt"
	"log"
	"os"

	"github.com/teraswitch/gotsw/v2"
)

func main() {
	ctx := context.Background()

	// Initialize client
	client := gotsw.New(os.Getenv("TSW_API_KEY"))

	// Create an SSH key
	key, err := client.CreateSshKey(ctx, 480, gotsw.CreateSshKeyRequest{
		DisplayName: "deployment-key",
		Key:         "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI...",
	})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("Created SSH key: %s (ID: %d)\n", key.DisplayName, key.ID)

	// Check availability
	avail, err := client.GetMetalAvailability(ctx, "480", "LAX1")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("Available configurations: %d\n", len(avail.Data))

	// Create a bare metal server
	server, err := client.CreateMetalService(ctx, 480, &gotsw.CreateBareMetalRequest{
		DisplayName: "web-server-01",
		RegionID:    "LAX1",
		TierID:      "2388g",
		MemoryGB:    64,
		ImageID:     "ubuntu-noble",
		SSHKeyIDs:   []int64{key.ID},
	})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("Created server: %s (ID: %d)\n", server.Data.DisplayName, server.Data.ID)

	// List all servers
	servers, err := client.ListMetal(ctx, gotsw.ListMetalOptions{})
	if err != nil {
		log.Fatal(err)
	}
	for _, s := range servers.Data {
		fmt.Printf("- %s: %s (%s)\n", s.DisplayName, s.Status, s.Region)
	}
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.teraswitch.com/integrations/gotsw.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
