Tags pushed with the default GITHUB_TOKEN don't trigger other
workflows' push events, so release.yml never ran after tag.yml
created a new tag. Add workflow_dispatch to release.yml and have
tag.yml call `gh workflow run release.yml --ref <tag>` right after
pushing the tag.
Adds a workflow_dispatch workflow that lets maintainers bump the
patch, minor (default), or major version using mdomke/git-semver,
then tags and pushes the result to trigger the existing release
workflow.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
unifi_device_vap_* and unifi_device_radio_* expose the radio identifier
(radio=ng/na/6e) but not the frequency band, so downstream consumers must
hard-code the ng/na/6e -> 2.4/5/6 GHz mapping to group or join by band.
UniFi does not carry band as its own field on the radio/VAP structs, so this
derives it from the radio identifier via a small radioBand() helper and adds
it as a "band" label (GHz: 2.4/5/6) on every series exportVAPtable and
exportRADtable emit. This mirrors the band label already present on the
RogueAP metrics, giving the per-radio/per-VAP series the same dimension.
Derived internally from p.Radio / v.Radio, so the exportVAPtable /
exportRADtable signatures are unchanged and the UAP/UDM/UDB/UBB call sites
need no edits.
unifi_device_vap_* and unifi_device_radio_* previously exposed only
(site_name, name, source) as per-device identifiers, none of which is a
stable primary key (name is user-editable, source is the controller
hostname). The device MAC is already available on the parent UAP/UDM/UDB/UBB
struct, so this threads d.Mac through exportVAPtable / exportRADtable and
adds it as a label on every series those functions emit.
This lets downstream consumers join VAP/radio series directly against
unifi_device_info (which already carries mac) without going through the
(site_name, name, source) intersection.
Applied at all four call sites: UAP, UDM, UDB, UBB.
Bumps the all group with 1 update: [golang.org/x/crypto](https://github.com/golang/crypto).
Updates `golang.org/x/crypto` from 0.51.0 to 0.52.0
- [Commits](https://github.com/golang/crypto/compare/v0.51.0...v0.52.0)
---
updated-dependencies:
- dependency-name: golang.org/x/crypto
dependency-version: 0.52.0
dependency-type: direct:production
update-type: version-update:semver-minor
dependency-group: all
...
Signed-off-by: dependabot[bot] <support@github.com>
Adds two new Prometheus metrics for UCI (UniFi Cable Internet) devices:
- unpoller_device_ci_state_operational (gauge): 1 if DOCSIS CI state ==
"Operational", else 0. Suitable for alerting on cable link health.
- unpoller_device_ci_state_info (gauge=1, info-style): exposes the full
DOCSIS CI state table as labels (ci_state, ci_sw_dl_status, ci_mac,
ci_version, ci_mode) for diagnostic dashboards.
The controller does expose a top-level `internet` boolean on UCI
devices, but it is not a reliable WAN-reachability signal — it stays
false even when the cable link is fully operational and the upstream
WAN is up. The UCI is a cable bridge with no independent internet-
reachability probe; real WAN health lives on the upstream gateway
(e.g. UDM wan1.up).
The ci_state field from ci_state_table IS reported reliably and is the
correct source-of-truth for DOCSIS link health.
Verified on a UCI in Operational state (ci_mode=D3.1).
Decouples Prometheus scrape cadence from upstream UniFi API calls so a
429 backoff loop on the controller side no longer stalls /metrics. The
output plugin now owns a 60s background poller (configurable) whose
result is served from an in-memory cache. Concurrent /scrape requests
for the same target are coalesced via singleflight to prevent a noisy
scraper from multiplying upstream load.
Adds two new metrics so operators can detect cache staleness and
refresh failures independently:
- unpoller_prometheus_cache_age_seconds
- unpoller_prometheus_refresh_failures_total
Background goroutine recovers from panics so a malformed input payload
no longer silently kills refreshes.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The v3.1.2 release failed because homebrew_casks filters archives by
goarch=[amd64 arm64], but universal_binaries.replace=true collapses the
darwin amd64+arm64 builds into a single darwin/all archive — which the
cask filter rejects.
Drop the universal_binaries block. The unpoller-mac build still produces
darwin amd64 and darwin arm64 separately, and the cask resolves them
into per-arch on_intel/on_arm blocks. Net effect on release artifacts:
the single universal macOS archive is replaced by two per-arch archives.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Rename archives.builds/nfpms.builds to ids; convert format/format_overrides.format to formats arrays.
- Collapse three dockers + six docker_manifests entries into one dockers_v2 block; update Dockerfile to use $TARGETPLATFORM for multi-arch buildx.
- Migrate brews to homebrew_casks (binary->binaries, url_template->url.template, install/post_install->hooks.post.install). Cask is macOS-only, so ids is reduced to unpoller-mac.
Per-arch image tags (e.g. :latest-amd64, :latest-arm64v8, :latest-armv7) are no longer published; only the multi-arch manifest tags (latest, v{Major}, full version) remain. Linuxbrew install path is dropped; Linux users should use the deb/rpm or Docker image.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Picks up the gzip decompression fix for the Site Manager remote API
(unpoller/unifi#220), which restores remote-API discovery for Official
UniFi Cloud Hosted consoles whose responses are gzip-compressed but
served without a Content-Encoding header.
Closes#997
Bumps github.com/unpoller/unifi/v5 from v5.26.0 to v5.27.0 along with
golang.org/x/crypto, term, sys, and text to their latest releases.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Influx and Datadog integration tests assert that the captured field/gauge
sets exactly match the YAML. Add the new uap uplink_* entries so the
TestInfluxV1Integration and Datadog integration tests stay green.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Exposes the uplink medium (wire vs wireless) and link speed for UniFi access
points so users can detect when an AP downgrades from gigabit to fast ethernet,
which was the original ask in #988. UAPs previously had zero uplink coverage
in any output plugin; now influxunifi, datadogunifi, and promunifi all report
uplink_type, uplink_speed, uplink_max_speed, and related fields.
Also brings Prometheus to parity with Influx/Datadog by emitting uplink
metrics for USW, UBB, and UDB devices (previously only USG/UDM/UXG had them
in promunifi). A new exportDeviceUplink helper in promunifi/usg.go reuses
the existing unpoller_device_uplink_* descriptors to avoid descriptor
collision (per c48b9917).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Closes#1001. Mirrors the DataDog plugin's global tags feature for
InfluxDB. Per-metric tags take precedence on key collision so
site/device identifiers can never be overwritten by a misconfigured
global. Configurable via TOML/JSON/YAML under influxdb.tags.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
descIntegrationDevice was registered with namespace prefix
"unpoller_device_", producing "unpoller_device_uptime_seconds" with
labels {device_id} and a different help string than the existing
descDevice() metric of the same FQDN (labels {type, site_name, name,
source, tag}, help "Device Uptime"). Prometheus MustRegister panics on
inconsistent descriptors for the same fully-qualified name, causing
v3.0.0 to crashloop on startup whenever the Prometheus output was
enabled.
Move the Integration/v1 device metrics under a dedicated
"integration_device_" name prefix, matching the convention used by the
other Integration/v1 collectors added in the same release (e.g.
wifi_broadcast_*, acl_rule_*, mclag_domain_*, pending_device_*), where
the bare namespace prefix is passed in and the type prefix is baked
into each metric name string.
Affected metric renames:
unpoller_device_uptime_seconds -> unpoller_integration_device_uptime_seconds
unpoller_device_cpu_utilization_pct -> unpoller_integration_device_cpu_utilization_pct
unpoller_device_memory_utilization_pct -> unpoller_integration_device_memory_utilization_pct
unpoller_device_load_average_{1,5,15}min -> unpoller_integration_device_load_average_{1,5,15}min
unpoller_device_radio_tx_retries_pct -> unpoller_integration_device_radio_tx_retries_pct
unpoller_device_uplink_{rx,tx}_rate_bps -> unpoller_integration_device_uplink_{rx,tx}_rate_bps
Fixes#1002Fixes#1004
The Homebrew formula's install/post_install blocks referenced
examples/up.conf, but the source tarball ships examples/up.conf.example,
causing brew install to fail with ENOENT. Update both references to use
the correct filename, matching how the rest of .goreleaser.yaml already
sources this file.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds 21 new data types from unifi v5.26.0 across all metric output plugins
(InfluxDB, Prometheus, DataDog). Per-site Integration/v1 calls are gated on
API key configuration and only run for user-configured sites; ErrEndpointNotFound
is handled gracefully so older firmware continues to work without log spam.
Also migrates events collection (collectAlarms, collectAnomalies, collectEvents,
collectIDs, collectProtectLogs) to handle Network 10.x+ endpoint removals via
ErrEndpointNotFound, with debug-level logging to avoid per-poll noise.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>