Skip to content

Extend the Crossplane sync-state exporter past Repository β€” 90 of 110 managed resources are unobservedΒ #3052

Description

@devantler

πŸ€– Generated by the Agentic Engineer

Evidence

The crossplane-sync-exporter shipped in #2994 declares exactly one GVK β€”
repo.github.m.upbound.io/v1alpha1 Repository. Measured on the live cluster 2026-08-10:

API group resources kinds
repo.github.m.upbound.io 46 DefaultBranch, IssueLabels, Repository, RepositoryRuleset
team.github.m.upbound.io 41 Team, TeamMembership, TeamRepository
enterprise.github.m.upbound.io 11 OrganizationRuleset
dns.unifi.m.crossplane.io 7 Record
iam.aws.m.upbound.io 3 OpenIDConnectProvider, Policy, Role
route.unifi.m.crossplane.io 1 TrafficRoute
vpn.unifi.m.crossplane.io 1 Client

110 managed resources across 7 groups and 14 kinds. The exporter observes 20 of them β€” the
Repository kind alone. The other 90 (82%) produce no series at all, so the silent-failure mode
#2820 was opened for is still silent everywhere except one kind.

That is not an oversight in #2994: CustomResourceStateMetrics takes an exact groupVersionKind
with no wildcard and no categories: managed selector, so each kind needs its own entry. #2994
scoped itself to the kind carrying the observed failure and said so explicitly.

Audience and problem

Whoever is on the hook when a declared setting stops reaching a provider. Today that is detectable
for GitHub repositories and undetectable for the org's teams, rulesets, AWS IAM, and the UniFi
network β€” including the 9 resources deliberately held at ReconcilePaused, which cannot be told
apart from "not exported" while no series exists for their kinds.

Expected behaviour

A managed resource of any installed kind exports its conditions, so a query for the failing set
returns the failing set rather than the observable subset of it.

Worth weighing rather than deciding here: 14 hand-listed GVK entries is a maintenance surface that
grows with every new provider (a newly-installed provider silently goes unobserved until someone
adds it), which is the trade-off #2986 recorded against a small first-party exporter that could
enumerate categories: managed itself. A middle option is generating the ConfigMap's GVK list from
the installed CRDs at build time, so the enumeration stays declarative but is not hand-maintained.

Acceptance criteria

  • Every installed managed-resource kind exports its conditions, not only Repository.
  • A newly-installed provider's kinds are covered without a hand edit, or the gap fails loudly β€”
    silently unobserved is the state this issue exists to end.
  • The reason label still separates ReconcilePaused from ReconcileError. This is where it
    first becomes testable: the 9 paused resources are all in dns/route/vpn.unifi, which the
    current exporter does not cover at all, so today's "paused resources produce no series" passes
    for the wrong reason.
  • RED-proved against live data: the resources at reason=ReconcileError appear across more than
    one group, and the paused set is excluded by the reason filter rather than by absence.
  • No widening of the exporter's RBAC beyond read on the kinds it exports; no core secrets.

Rough size: M. Part of #2986.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    Status
    πŸ“₯ Backlog

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions