125 lines
4.8 KiB
Markdown
125 lines
4.8 KiB
Markdown
# hhctl
|
|
|
|
A command-line tool and a Terraform provider for [Hammerhead](../hammerhead). Both talk only to Hammerhead's
|
|
public HTTP API with an API key, so they work against any server you can reach.
|
|
|
|
```
|
|
client/ Go API client (the only thing that speaks HTTP)
|
|
cmd/hhctl/ the CLI
|
|
cmd/terraform-provider-hammerhead/
|
|
internal/provider/ Terraform provider (terraform-plugin-framework)
|
|
internal/fakehh/ in-memory fake of the API, for tests
|
|
examples/ Terraform configuration and a shell script
|
|
```
|
|
|
|
Needs a Hammerhead with API-key support for server scope (branch `feature/api-tokens-hhctl`; see
|
|
`hammerhead/docs/api-automation.md` for the audit of what the API could and could not do before).
|
|
|
|
## Credentials
|
|
|
|
| Key | Made with | Can |
|
|
|---|---|---|
|
|
| Organization key | Hammerhead dashboard, or `POST /api/orgs/{org}/apikeys` | sites, ports, domains and alert channels of its organization; list edges it may use |
|
|
| Server key | `POST /api/admin/apikeys` as a signed-in server admin | everything above in any organization, plus edges, server alert channels and creating organizations |
|
|
|
|
The secret is shown once when the key is created. Keep it out of version control; pass it in the environment.
|
|
|
|
```sh
|
|
export HAMMERHEAD_URL=https://hammerhead.example.com
|
|
export HAMMERHEAD_TOKEN=hhk_...
|
|
export HAMMERHEAD_ORG=... # optional with an organization key
|
|
```
|
|
|
|
## CLI
|
|
|
|
```sh
|
|
go install git.veillax.com/Veillax/hhctl/cmd/hhctl@latest
|
|
|
|
hhctl orgs list
|
|
hhctl edges create --name fra --tunnel 203.0.113.5:51820 # server key; prints the edge's token
|
|
hhctl sites create --name home --tag lab # prints the agent's token
|
|
hhctl domains add --name example.com --edge fra
|
|
hhctl ports create --name web --proto https --edge fra --port 443 \
|
|
--hostname app.example.com --target home:192.168.1.30:8080
|
|
hhctl ports create -f port.json # any option, as JSON
|
|
hhctl ports list
|
|
hhctl alerts channel-create --name ops --kind email --target ops@example.com
|
|
hhctl alerts channels
|
|
hhctl ports delete <id>
|
|
```
|
|
|
|
Edges and sites can be given by name or ID. `-o json` prints the API's JSON (and the secret created, once) instead of a
|
|
table. Commands: `orgs`, `edges`, `sites`, `ports`, `domains` (`list`, `create`/`add`, `delete`) and `alerts`
|
|
(`list`, `channels`, `channel-create`, `channel-delete`, `channel-test`; `--server` for server-level ones).
|
|
See `hhctl -h`, and `examples/bootstrap.sh`.
|
|
|
|
## Terraform provider
|
|
|
|
Resources: `hammerhead_site`, `hammerhead_port`, `hammerhead_domain`, `hammerhead_edge`, `hammerhead_alert_channel`.
|
|
Data source: `hammerhead_edge` (by name).
|
|
|
|
```hcl
|
|
terraform {
|
|
required_providers {
|
|
hammerhead = { source = "veillax/hammerhead" }
|
|
}
|
|
}
|
|
|
|
provider "hammerhead" {} # url, token and org come from HAMMERHEAD_URL / _TOKEN / _ORG
|
|
|
|
resource "hammerhead_site" "home" {
|
|
name = "home"
|
|
tags = ["lab"]
|
|
}
|
|
|
|
resource "hammerhead_port" "web" {
|
|
name = "web"
|
|
proto = "https"
|
|
edge_id = data.hammerhead_edge.fra.id
|
|
port = 443
|
|
hostname = "app.example.com"
|
|
target {
|
|
site_id = hammerhead_site.home.id
|
|
host = "192.168.1.30"
|
|
port = 8080
|
|
}
|
|
}
|
|
```
|
|
|
|
A full example is in `examples/main.tf`. Notes:
|
|
|
|
- `hammerhead_site.token` and `hammerhead_edge.token` are sensitive outputs: hand them to the Bamboo / Blacktip program.
|
|
- Ports are replaced wholesale by the API. `password` and `pin` are sent only when they change, because changing
|
|
them signs every visitor out. Hammerhead never returns them, so out-of-band changes show up only as a
|
|
removed password.
|
|
- The server does not return an alert channel's webhook URL or Sandbar key, so those are kept as configured and
|
|
drift in them is not detected.
|
|
- Domains cannot be edited in place; any change replaces them.
|
|
- Deleting an edge or a site in Hammerhead also deletes the ports that depend on it; let Terraform order the
|
|
destroy via references as in the example.
|
|
- Import: `terraform import hammerhead_site.home <id>` (same for port, domain, edge); alert channels take `<id>` or
|
|
`server/<id>`, and need `target` set in configuration after import.
|
|
|
|
For local use, build the provider and point Terraform at it with a `dev_overrides` block in `~/.terraformrc`:
|
|
|
|
```sh
|
|
go build -o ~/go/bin/terraform-provider-hammerhead ./cmd/terraform-provider-hammerhead
|
|
```
|
|
|
|
```hcl
|
|
provider_installation {
|
|
dev_overrides { "veillax/hammerhead" = "/home/you/go/bin" }
|
|
direct {}
|
|
}
|
|
```
|
|
|
|
## Tests
|
|
|
|
```sh
|
|
go test ./...
|
|
```
|
|
|
|
The tests run against `internal/fakehh`, a small in-memory imitation of the API, and drive the provider's
|
|
CRUD methods directly (no `terraform` binary needed). The fake was checked by hand against a real Hammerhead
|
|
for the CLI flows; there are no automated acceptance tests (`terraform-plugin-testing`) yet.
|