Skip to main content

Other types

Discover

Discover the live members of a service — container endpoints, pods, replicas — and hand them to the rest of the pipeline as an array.

The point is to stop hard-coding a list of addresses that changes every time something scales, restarts or reschedules. A discover action returns one entry per member, and any later action fans out across them with lookup::

actions:
- name: Members
discover:
kubernetes:
label_selector: app=api
port_name: http

- name: PollAll
lookup: a|Members|
lookup_partition: true # -> { succeeded: [...], failed: [...] }
actions:
- name: Health
http:
url: a|body::url|/healthz

Every backend returns the SAME item shape, so a config written against one orchestrator moves to another by changing only the backend block:

{
"name": "api-7d9f8b6c5d-x2ktp",
"address": "10.42.1.3",
"port": 8080,
"url": "http://10.42.1.3:8080",
"source": "kubernetes",
"ready": true,
"namespace": "default",
"node": "worker-1",
"image": "example/api:1.4.0",
"labels": { "app": "api" }
}

Fields a backend cannot know are omitted rather than faked — DNS returns addresses only, so it has no labels, image or ready. Filtering on a field a backend does not provide therefore matches nothing, which is why label_selector belongs to the backends that actually have labels.

FieldTypeDescription
dnsDiscoverDns (nullable)Resolve a DNS name to every address behind it. The portable option: no API access, no credentials, no RBAC, nothing to mount. In Kubernetes point it at a headless Service…
kubernetesDiscoverKubernetes (nullable)Query the Kubernetes API for pods. The richest option: real label selectors, plus namespace, node, readiness and image per pod. Requires a ServiceAccount with list on pods,…
dockerDiscoverDocker (nullable)Query the Docker Engine API for containers. For container hosts that are not Kubernetes: plain Docker, Compose, Swarm. Requires access to the Docker socket, which is equivalent…
staticArray<string> (nullable)An explicit list of host:port entries. Not discovery — the escape hatch for environments with none of the above, and what tests pin against. Keeping it in the same shape… Example ↓
includeDiscoverFilter (nullable)Keep only members matching these patterns. Applied before exclude.
excludeDiscoverFilter (nullable)Drop members matching these patterns. Exclusion wins over inclusion, deliberately: when the two disagree the safe reading of the operator's intent is "do not touch this one".
portDiscoverPort (nullable)Port to use when the backend does not supply one (DNS always, Kubernetes when neither port nor port_name is set). Without it those members are returned with no port and no…
schemestring (nullable)Scheme used to build each member's url. Defaults to http.
cache_ttl_secsnumber (nullable)How long to reuse a result before querying again, in seconds. Defaults to 10; 0 disables caching. This matters more than it looks. Without it, a discovery action on a…
fail_when_emptyboolean (nullable)Fail the action when discovery returns nothing. Defaults to false, so an empty result is an empty loop rather than an error — a service legitimately scaled to zero is not a…

Field examples

static

An explicit list of host:port entries.

Not discovery — the escape hatch for environments with none of the above, and what tests pin against. Keeping it in the same shape means a config can start static and move to real discovery without touching the actions that consume it.

Accepts either a YAML sequence or a single comma-separated string, so the whole list can come from ONE variable — which is how a member list is usually configured, and how AIRPIPE__WS_MESH_PEERS already works:

static: "10.0.0.1:8080, 10.0.0.2:8080"     # one variable
static: a|ap_var::MEMBERS| # ...including from a variable
static: ["10.0.0.1:8080", "10.0.0.2:8080"] # or a sequence

Empty and null entries are dropped rather than rejected. Configs are re-parsed AFTER interpolation, so an entry whose variable resolves to nothing (a|ap_var::MEMBER_2->default()|) arrives here as a bare -, i.e. YAML null. Failing there would break the config only in the environment where that variable happened to be unset — in production, having passed every test.

DiscoverDns

DNS-based discovery.

FieldTypeDescription
namestringRequired. The name to resolve — airpipe-mesh, api.default.svc.cluster.local, or a Compose service name. A bare name takes the action's port; name:port is honoured as written.
exclude_selfstring (nullable)Drop this node's own address from the results. Useful when a service discovers its peers and should not call itself. Needs the address to exclude, e.g. a|env::POD_IP|.

DiscoverKubernetes

Kubernetes API discovery.

FieldTypeDescription
namespacestring (nullable)Namespace to search. Defaults to the agent's own namespace, read from the ServiceAccount token mount — so the common case needs no configuration and stays inside the…
label_selectorstring (nullable)Standard Kubernetes label selector, e.g. app=api,tier!=canary. Passed through to the API server, so the same syntax as kubectl -l.
field_selectorstring (nullable)Standard field selector, e.g. status.phase=Running.
port_namestring (nullable)Take the port from a named container port (http, metrics). Preferred over a hard-coded number: the name survives a port change.
ready_onlyboolean (nullable)Return only pods whose containers are all ready. Defaults to true — an unready pod is one that has told you not to send it traffic.

DiscoverDocker

Docker Engine API discovery.

FieldTypeDescription
labelsMap<string, string> (nullable)Container labels to match, e.g. com.docker.compose.service: api. All listed labels must match.
networkstring (nullable)Docker network whose address should be reported for each container. With several networks attached and no choice made, the first is used.
socketstring (nullable)Path or URL of the Docker Engine socket. Defaults to /var/run/docker.sock.

DiscoverFilter

Regex patterns matched against a member's fields. An unset field matches everything; a field the backend does not populate never matches.

FieldTypeDescription
namestring (nullable)Regex against the member name (pod or container name).
imagestring (nullable)Regex against the full image reference, including registry and tag.
namespacestring (nullable)Regex against the namespace (Kubernetes only).

DiscoverPort

A port: a literal number, or a marker that resolves to one.

Every other field of a discover block interpolates, because they are strings. A bare u16 could not, so port: a|ap_var::SERVICE_PORT| did not merely fail to resolve — the marker was still marker TEXT when serde reached it, and the agent died at load with invalid type: string ... expected u16. A config that names its port the same way it names everything else should work, so the string form is accepted and parsed after interpolation.

One of:

  • number — port: 8080
  • string — port: a|ap_var::SERVICE_PORT->default(8080)|, or a quoted "8080". Still a marker at parse time; resolved once interpolation has run.

EmailAttachment

One file attached to an outgoing email.

FieldTypeDescription
filenamestringRequired. Filename shown to the recipient.
contentstringRequired. The file contents. base64 by default — pair it with the b64_encode post-transform, which is also what makes binary files (PDF, images) work. Use encoding: utf8 to attach…
content_typestring (nullable)MIME type, e.g. text/csv, application/pdf. Defaults to application/octet-stream.
encodingstring (nullable)How content is encoded: base64 (default) or utf8.

WsPublish

Publish a payload to realtime WebSocket channels (server push / fan-out). Every socket subscribed to any listed channel — on this node AND every peer node — receives the payload. Fire-and-forget: it does not wait for delivery.

Example

- name: Broadcast
ws_publish:
channels: a|body::rooms| # a string, an array, or an a|...| marker
data: a|OrderAction| # defaults to a|body| when omitted
FieldTypeDescription
channelsanyRequired. Channel key(s) to publish to: a string, an array of strings, or an a|... marker resolving to either.
dataanyThe payload pushed to subscribers. An a|... marker or inline JSON. Defaults to the request/message body when omitted.
retainanyStore the payload as the channel's RETAINED value, so a subscriber that connects (or reconnects) later immediately receives the current value on subscribe. Defaults to false.…

MqttPublish

A mqtt_publish action publishes a message from a pipeline to one or more MQTT topics. Every subscriber to a listed topic — on this node AND every peer node (via the realtime mesh) — receives the payload. This is the pipeline→topic direction (the inbound topic→pipeline direction is the ingest consumer). Fire-and-forget: it does not wait for broker acknowledgement.

Example

- name: Push
mqtt_publish:
topics: a|body::topic| # a string, an array, or an a|...| marker
data: a|Reading| # defaults to a|body| when omitted
qos: 1 # 0 (default) | 1 | 2
retain: false # default false
FieldTypeDescription
topicsanyRequired. Topic(s) to publish to: a string, an array of strings, or an a|... marker resolving to either.
dataanyThe payload published to subscribers. An a|... marker or inline JSON. A JSON string publishes as raw text; any other value publishes as its JSON encoding. Defaults to the…
qosnumber (nullable)MQTT quality of service for the published message: 0 (at most once, default), 1 (at least once), or 2 (exactly once).
retainanyWhether the broker retains this message as the topic's last-known-good value, delivered to future subscribers on subscribe. Defaults to false. Accepts a literal boolean OR an…

TransformAggregate

Reduce a JSON array to a summary (sum / avg / min / max / count), optionally grouped.

FieldTypeDescription
overstring (nullable)JSONPath to the array to aggregate. Omit to aggregate the whole data when it is itself an array.
keystring (nullable)Output field to hold the summary. Omit to replace the data with the summary.
sumArray<string> (nullable)Fields to sum.
avgArray<string> (nullable)Fields to average.
minArray<string> (nullable)Fields to take the minimum of.
maxArray<string> (nullable)Fields to take the maximum of.
countboolean (nullable)Include a row count in the summary (default true when no other op is given).
group_byArray<string> (nullable)Group rows by these fields; the summary is computed per group under groups.

HmacSign

Parameters for the hmac post-transform (signing).

Example

hmac:
key: signature
data: a|BuildPayload::body|
secret: a|Subscriber::secret|
algorithm: sha256
encoding: hex
FieldTypeDescription
keystringRequired. Output key the computed digest is written to.
datastringRequired. The message to sign. Supports interpolation.
secretstringRequired. The signing secret. Supports interpolation — use a|ap_var::NAME| or a per-recipient secret read from a prior action.
algorithmstring (nullable)Hash algorithm: sha1, sha256 (default), or sha512.
encodingstring (nullable)Digest encoding: hex (default) or base64.