# 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 ``` 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 ` (same for port, domain, edge); alert channels take `` or `server/`, 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.