Repository navigation
telemetry/allowlist-sync: export each AOP hostname's certificate expiry - #4535
Open
ben-malbeclabs wants to merge 1 commit into
Open
ben-malbeclabs wants to merge 1 commit into
ben-malbeclabs wants to merge 1 commit into
Conversation
ben-malbeclabs
requested review from
a team
and
a balanced review from Copilot
November 14, 2026 00:41
Contributor
There was a problem hiding this comment.
🟡 Changes recommended
The failed-read test discards logs, so it cannot detect removal or severity downgrading of the expected ERROR message.
1 open issue
What changed in this PR
This PR adds per-hostname Authenticated Origin Pulls (AOP) monitoring to the telemetry allowlist sync for certificate expiry alerts.
Changes:
- The sync exports certificate expiry and active-state metrics when operators configure both new flags.
- The sync reads settings after each pass and removes both metric series when a read fails.
- The Cloudflare client distinguishes missing settings from API failures through typed errors.
| File | Description |
|---|---|
telemetry/allowlist-sync/internal/allowlist/sync.go |
Adds optional AOP configuration and reads after each pass. |
telemetry/allowlist-sync/internal/allowlist/sync_test.go |
Tests metric updates, read failures, and shutdown behavior. |
telemetry/allowlist-sync/internal/allowlist/metrics.go |
Registers per-hostname expiry and active-state metrics. |
telemetry/allowlist-sync/internal/allowlist/http_test.go |
Tests response decoding, missing settings, and API errors. |
telemetry/allowlist-sync/internal/allowlist/cloudflare.go |
Extracts shared request handling and adds typed API errors. |
telemetry/allowlist-sync/internal/allowlist/aop.go |
Reads AOP settings and updates metrics within a timeout. |
telemetry/allowlist-sync/cmd/allowlist-sync/main.go |
Adds paired flags and connects the AOP reader. |
CHANGELOG.md |
Documents the metrics, configuration, and token permission. |
Review effort: Balanced
Comment on lines
+1126
to
+1128
| aop.errs = map[string]error{"gnmic.example": errors.New("HTTP 403")} | ||
| s.checkAOP(context.Background()) | ||
| assert.Equal(t, 1.0, counter(h.metrics.Errors, "aop")) |
bgm-malbeclabs
approved these changes
Nov 14, 2026
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Summary of Changes
--cloudflare-zone-id(CLOUDFLARE_ZONE_ID) and--aop-hostnames(AOP_HOSTNAMES), the allowlist sync reads each hostname's per-hostname Authenticated Origin Pulls setting from Cloudflare after every pass. It exportsdoublezero_telemetry_allowlist_sync_aop_certificate_expiry_timestamp_secondsanddoublezero_telemetry_allowlist_sync_aop_activeper hostname. This is the AOP certificate expiry alert of the gNMI lockdown spec (malbeclabs/infradocs/plans/2026-10-29-gnmi-restart-lockdown-design.md, section 8). When the client certificate expires, or AOP is off for gnmic's hostname, every device drops.aop_activeis 1 only when AOP is on for the hostname and both its association and its certificate are active. A hostname with no setting (Cloudflare's 404 with code 1553) reads 0 and has no expiry. Any other error, a wrong zone's 404 included, is a failed read.errors_total{stage="aop"}counts the failures, and each is logged at ERROR.callis split intocfCall, and a Cloudflare error is now a typedcfAPIError, so the AOP reader can tell "no setting" from a failed read. Its message is unchanged.The alert rule and the testnet overlay values are a malbeclabs/infra PR that pins the build of this commit.
Testing Verification
TestCloudflareAOP_ReadsTheSettingdecodes the fields as Cloudflare returned them forgnmic-testnet.doublezero.xyzon 2026-11-14, certificate left out.expires_on. They also pin each hostname's series: set, removed on a failed read and back on the next, and dropped when the setting is removed. They check that a failed read leaves the pass's writes andlast_successintact, and that a pass cut short by shutdown reads nothing.Active.go test -race,go vetandgolangci-lintare clean ontelemetry/allowlist-sync/....