feat(inventory): report agent health to Anchore Enterprise - #480
Draft
bradleyjones wants to merge 1 commit into
Draft
feat(inventory): report agent health to Anchore Enterprise#480bradleyjones wants to merge 1 commit into
bradleyjones wants to merge 1 commit into
Conversation
bradleyjones
marked this pull request as draft
August 17, 2026 12:50
bradleyjones
force-pushed
the
maam/integration-impl-giddy-quail
branch
from
August 17, 2026 12:54
3e99f25 to
3bd3d99
Compare
Register the agent as an `ecs_inventory_agent` integration and report per-cluster health on an interval, following the k8s-inventory prior art. - add internal/anchore client for the v2 registration and health-report endpoints - add pkg/integration (registration + identity from ECS task metadata) and pkg/healthreporter (periodic report + per-cluster result store) - add internal/time helpers for Enterprise's JSON encoding - return per-cluster results (including gather failures) from GetInventoryReportsForRegion - add health-report-interval-seconds and anchore-registration.* config keys Registration and health reporting degrade gracefully and never gate inventory reporting; --dry-run does neither. Signed-off-by: bradleyjones <jones.bradley@me.com>
bradleyjones
force-pushed
the
maam/integration-impl-giddy-quail
branch
from
August 17, 2026 12:56
3bd3d99 to
8b4e40c
Compare
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.
What this does
anchore-ecs-inventorynow registers itself with Anchore Enterprise as an integration oftype
ecs_inventory_agentand reports its health on an interval, following the prior artin
anchore/k8s-inventory.Until now the agent reported inventory and nothing else. There was no way to see from
Enterprise whether an agent was alive, and a failure that stopped it collecting anything —
expired AWS credentials, a revoked
ecs:ListClusters, a bad region — was only ever a linein the agent's own log. Those failures now mark the integration UNHEALTHY in Enterprise,
per ECS cluster.
New packages
internal/timeDatetime/Durationwith the JSON encoding Enterprise expects (RFC3339 strings, durations as bare seconds). Ported from k8s-inventory.internal/anchorepkg/reporterkeeps its own client — its v1/v2 fallback logic is unrelated.pkg/integrationpkg/healthreporterGetInventoryReportsForRegionnow returns what happened per cluster, including gatherfailures that were previously only a log line. Two new direct dependencies:
github.com/google/uuidandgithub.com/hashicorp/go-version(both already used byk8s-inventory).
Degradation is deliberate and never fatal
Against an Enterprise older than 6.2.0, one that rejects the new integration type, an
offline Enterprise, or a user missing the
registerIntegration/reportHealthRBACactions, the agent logs clearly and carries on reporting inventory. Registration runs
alongside the inventory loop rather than gating it, so an unbounded offline retry can never
starve inventory reporting.
--dry-runneither registers nor health-reports.API / contract
Two Anchore Enterprise v2 endpoints, in addition to the existing inventory endpoint:
POST /v2/system/integrations/registrationregisterIntegrationPOST /v2/system/integrations/{integration_uuid}/health-reportreportHealthOne substantive shape difference from the k8s agent:
account_ecs_inventory_reportsmaps each account to a list of per-cluster results (each with a required
cluster_arnand an optional
region), not to the single flat object the k8s agent sends. The ECS agentsweeps many clusters within a single Anchore account, so a k8s-shaped map would hide the
failures of all but one cluster. Several fields deliberately carry no
omitemptyandbatchesis initialised withmake(...)— a nil slice marshals tonulland Enterprise400s. A golden-JSON unit test pins this, and QA read the persisted shape back out of the
Enterprise database.
Registration identity. Enterprise keys an integration on the pair
(
registration_id,registration_instance_id) and creates a new record for any pair ithas not seen, marking superseded ones INACTIVE. ECS has no Deployment UID equivalent, so
identity is derived from the task metadata endpoint: the task family and the ECS
service name (falling back to the family for tasks in no service), each qualified with
the AWS account (read from the task ARN), the cluster the agent's own task runs in,
and the region it scans — e.g.
anchore-ecs-inventory/111122223333/anchore-qa/us-east-1.The task ARN is deliberately not used: ECS mints a new task id on every deployment, scale
event, health-check replacement and spot interruption, which would leave a new integration
record behind each time. Family and service name give stability; account, cluster and
region give uniqueness. Values set explicitly in
anchore-registration.*are used verbatimand are not qualified.
Nothing has shipped, so there is no migration — but any Enterprise instance used while
developing this branch holds stale integration records under earlier id shapes that will
not be reused.
Config
No new CLI flags. New config keys, env-overridable as usual with the
ANCHORE_ECS_INVENTORY_prefix:health-report-interval-secondsis validated to 30–600 at startup. Theanchore-registrationkeys are registered as viper defaults — without thatAutomaticEnvcannot resolve them at all, so the whole block would have been unreachable by environment
variable.
README.mdgains a Health reporting section (endpoints, RBAC actions, degradationbehaviour, identity rules and when to set the ids explicitly), and
docker-compose/anchore-ecs-inventory.yamlgains the same keys with commentary. There isno Helm chart or webhook in this repo, so neither was touched.
QA
Exercised end-to-end against a live Enterprise docker-compose stack (all 11 containers
healthy) with a binary confirmed built from the change (
anchore-ecs-inventory version→GitCommit: 1f1584681a1f7b9c2a307483e44ef993d03e1e1f). The stack was probed by contractrather than by version string, found not to carry the Enterprise change, and
a11b88453'sproduction files were synced into the api and catalog containers first — every result below
is against a stack carrying
a11b88453. 24 checks, 24 PASS, 0 FAIL.integration_status.state = active,reported_status.state = healthy, withuptime,last_seenandcluster_namepopulated; ECS inventory still landing in Enterprise. The persisted
health_datareadback out of the DB is the map-of-arrays shape,
batchesa real list (nevernull), anda cluster with zero containers correctly absent — neither claimed successful nor
failed.
/taskreports a bare cluster namewith identical family/service/region and differing only in AWS account register as two
distinct integrations. With one agent's region completely broken, both states were
sampled every 10s for 3.5 minutes — one healthy throughout, the other unhealthy
throughout, zero oscillation. An earlier revision flapped and hid a totally broken
agent; that is what the account qualifier fixes, and it is pinned by a regression test
QA independently confirmed fails without the fix.
TaskARN, so an agent wasrestarted after its task ARN was rewritten with a new task id — it re-registered onto the
same integration UUID with the count unchanged.
(unparseable ARN, and no metadata endpoint at all).
account/user missing
registerIntegration, areportHealth403, the verbatimpre-change 400, and offline exponential backoff. Inventory reporting continued in every
case and the process never died.
their exact edges (29 / 30 / 600 / 601); README prose verified against observed
behaviour rather than read in isolation.
go build,go vet,go test ./...,go test -race -count=1andmake lint(0 issues, gofmt clean) all pass.
pkg/integrationcoverage 89.7%.Follow-ups (not in this PR)
"validating-creds"dummy report POSTed to/v2/ecs-inventoryin
cmd/root.go— its own comment says health reporting should replace it. It predatesthis change and is retained here so credential validation still works against Enterprises
without the branch. Note it still fires under
--dry-run.definition register correctly as separate integrations but all display as
anchore-ecs-inventory, distinguishable bycluster_name/account_name. A READMEsentence recommending a per-deployment
anchore-registration.integration-namewouldclose it.
integration-name, the integration registers with an emptydisplay name (Enterprise accepts it).