diff --git a/docs.json b/docs.json index ddee18f..18363f3 100644 --- a/docs.json +++ b/docs.json @@ -37,6 +37,7 @@ "pages": [ "connect-two-endpoints", "iroh-services/quickstart", + "iroh-services/endpoint-metadata", "iroh-services/net-diagnostics/quickstart", "protocols/using-quic", "examples/chat", diff --git a/iroh-services/endpoint-metadata.mdx b/iroh-services/endpoint-metadata.mdx new file mode 100644 index 0000000..d2ca92e --- /dev/null +++ b/iroh-services/endpoint-metadata.mdx @@ -0,0 +1,98 @@ +--- +title: "Endpoint Metadata: Attributes & Groups" +description: "Tag endpoints with a group and custom key-value attributes so you can find and filter them on the dashboard" +--- + +Beyond a [name](/iroh-services/quickstart), an endpoint connected to Iroh Services can carry two more pieces of cloud-side metadata: a single **group**, and a set of arbitrary **attributes** (key-value pairs). Use them to tag endpoints by whatever dimension matters to you — environment, region, tenant, app version — then find and filter on that dimension from the dashboard. + + +**Rust only, for now.** Groups and attributes are available in the `iroh-services` Rust crate. The Python, Swift, and Kotlin bindings (via `iroh-ffi`) currently only expose `name` / `set_name` — group and attribute support hasn't landed there yet. + + +## Prerequisites + +This tutorial assumes you already have an endpoint wired up to Iroh Services. If you don't, start with the [quickstart](/iroh-services/quickstart) — it covers getting an [API key](/iroh-services/access), adding the `iroh-services` crate, and connecting a client. + +```bash +cargo add iroh-services +``` + +## Set metadata at build time + +Like `name`, `group` and `attributes` can be set on the `ClientBuilder`. Both are validated locally before the client ever talks to the network; a failure to send them once connected is logged rather than returned, so use the `Client` setters below when you need explicit error handling for updates made after construction. + +```rust +use iroh_services::Client; + +let client = Client::builder(&endpoint) + .api_secret_from_env()? + .name("worker-7")? + .group("staging")? + .attributes([("region", "us-west"), ("app-version", "1.4.2")])? + .build() + .await?; +``` + +- **`group`** is a single string, 2 to 128 bytes of UTF-8 — the same rule as `name`. Uniqueness isn't enforced, so any number of endpoints can share a group. +- **`attributes`** takes any iterable of `(key, value)` pairs — an array of tuples, a `Vec`, a `HashMap`, a `BTreeMap`. Keys follow the same 2–128 byte rule as names; values may be empty and are capped at 128 bytes; the map is capped at 128 entries. + +## Update metadata later + +Each field can also be changed after the client is built. `set_group` and `set_attributes` mirror the builder methods; `set_attribute` is a convenience for changing one value without touching the rest: + +```rust +client.set_group("production").await?; + +// Replaces the whole attribute map +client.set_attributes([("region", "us-west"), ("app-version", "1.4.3")]).await?; + +// Merges a single key into the existing map instead +client.set_attribute("app-version", "1.4.4").await?; +``` + + +`set_attributes` fully replaces the map on every call — pass an empty iterator to clear it. Reach for `set_attribute` when you only want to change one value without re-sending the rest. + + +## Reading metadata back + +`client.name()` and `client.group()` return the locally cached value (`Option`) — whatever was last set successfully, whether from the builder or a `set_*` call. There's no `attributes()` getter yet; track the current map on your own side if you need to read it back. + +## See it on the dashboard + +Group and Attributes show up on your project's **Endpoints** page: + +- The search box matches by name, endpoint id, group, or attribute. +- The sidebar has a **Group** filter listing every distinct group in the project. +- **Group** and **Attributes** columns exist in the table but are hidden by default — click **Columns** above the table to turn them on. Attribute pills are capped at two per row before collapsing into a `+N` badge; hover a row to see the full set. +- Open an endpoint to see its full **Group** and **Attributes** on the detail page. + + +![Group and Attributes columns and filter on the endpoints list](/images/endpoints-list-group-attributes.png) + + + +![Group and Attributes on an endpoint's detail page](/images/endpoint-detail-group-attributes.png) + + +## Full example + +A runnable example that exercises both the builder and the update paths is [on GitHub](https://github.com/n0-computer/iroh-services/blob/main/examples/endpoint_meta.rs): + +```bash +IROH_SERVICES_API_SECRET=YOUR_API_KEY cargo run --example endpoint_meta +``` + +## What's next + + + Wire up your first endpoint and see it on the dashboard. + + + + Understand what an API key authorizes and how to get one. + + + + Run remote diagnostic reports on your users' endpoints to find out why connections fail. +