Documentation
¶
Overview ¶
Package coverage builds the disco-vs-upstream type coverage matrix for every registered cloud provider. Each provider implements Provider and registers itself via init() — see internal/providers/<p>/coverage.go.
Coverage truth source = the emits []TypeDecl declared on each scanner's serviceEntry, aggregated through the provider's Emits() method. Upstream truth source = a live registry call (CFN ListTypes / ARM Providers/List / GCP Discovery API) executed at command time. The matching engine reconciles the two sets via per-provider alias maps to produce the final matrix.
Index ¶
- Constants
- func AlgorithmicUpstreamKey(discoType string) string
- func Names() []string
- func Register(p Provider)
- func RenderJSON(w io.Writer, matrices []Matrix) error
- func RenderMarkdown(w io.Writer, matrices []Matrix) error
- func RenderRegionsMarkdown(w io.Writer, rows []RegionRow) error
- func RenderRegionsTable(w io.Writer, rows []RegionRow) error
- func RenderTable(w io.Writer, matrices []Matrix) error
- type Bucket
- type CanonicalKeyer
- type FetchOptions
- type Matrix
- type Provider
- type RegionLister
- type RegionRow
- type ResolverAuditor
- type ResolverInfo
- type Row
- type Skipper
- type TypeDecl
- type UpstreamType
Constants ¶
const ( RegionCovered = "covered" RegionStale = "stale" RegionMissing = "missing" )
Region status string constants.
Variables ¶
This section is empty.
Functions ¶
func AlgorithmicUpstreamKey ¶
AlgorithmicUpstreamKey is the fallback used when no alias is registered for a disco-type. Today it's just the lowercased disco-type itself — alias maps are the source of truth for accurate matching; the fallback only lets providers whose upstream-key shape equals the disco-type skip alias entries.
Per-provider algorithmic conversions (CFN PascalCase, ARM camelCase, GCP resource-collection forms) live in the provider's coverage.go alias-map builder, alongside the provider's other quirks.
func Register ¶
func Register(p Provider)
Register adds a Provider to the global registry. Called from each provider package's init().
func RenderJSON ¶
RenderJSON emits a structured matrix slice for tooling. Shape mirrors the in-memory Matrix/Row types directly so consumers can decode into the same structs.
func RenderMarkdown ¶
RenderMarkdown writes a per-provider markdown matrix (covered / uncovered / uncatalogued / upstream-missing). Suitable for `disco coverage -o markdown` piped into docs/coverage.md or pasted into the README.
func RenderRegionsMarkdown ¶ added in v0.8.0
RenderRegionsMarkdown writes a markdown table of region rows.
func RenderRegionsTable ¶ added in v0.8.0
RenderRegionsTable writes a tabwriter-aligned table of region rows.
Types ¶
type CanonicalKeyer ¶ added in v0.14.0
CanonicalKeyer is an optional interface a Provider may implement to collapse the same physical resource spelled differently across two upstream catalogs (AWS's CloudFormation ∪ Service Reference union). It maps an upstream key to a catalog-agnostic identity; Build treats an unmatched upstream key as covered when its identity equals an already-covered key's identity (the cross-catalog duplicate case). No impl → no canonical dedup (Azure/GCP single-catalog).
type FetchOptions ¶
FetchOptions carry per-invocation knobs from the cmd. Each provider reads only the fields it cares about — AWS uses Regions/Profile, Azure uses Subscription, GCP ignores all three.
Regions is a slice so multi-region sweeps can union upstream type lists across regions in one call. Empty slice = provider-default (AWS falls back to "us-east-1" for CloudFormation ListTypes; Azure ARM types are subscription-scoped so a no-op; GCP Discovery is region-agnostic).
type Matrix ¶
Matrix groups rows by provider for rendering.
func Build ¶
func Build(providerName string, emits []TypeDecl, aliases map[string]string, algorithmic func(string) string, upstream []UpstreamType, skips map[string]string, canonical func(string) string) Matrix
Build assembles the coverage matrix for one provider. emits and upstream are deduped by canonical keys (DiscoType / UpstreamKey) first. A disco-type whose alias resolves to a live upstream key is covered; a miss falls to BucketUncatalogued if flagged Uncatalogued (expected registry gap for a scanned resource), else BucketUpstreamMissing — the drift signal in ROADMAP G5. Uncatalogued is checked only after a failed match, so such a type auto-upgrades to covered once the registry lists it. skips maps a (case-insensitive) upstream key to why disco doesn't scan it; matching leftover-upstream entries become BucketNotScannable instead of BucketUncovered. Pass nil if the provider declares no skips.
type Provider ¶
type Provider interface {
Name() string
Fetch(ctx context.Context, opts FetchOptions) ([]UpstreamType, error)
Emits() []TypeDecl
Aliases() map[string]string // disco-type -> upstream key (overrides)
AlgorithmicKey(discoType string) string // fallback when no alias entry exists
}
Provider is implemented by each cloud provider package. Aggregates emits from registeredServices, exposes the live Fetch, and supplies the alias map + an algorithmic fallback used when a disco-type has no explicit alias.
type RegionLister ¶ added in v0.8.0
type RegionLister interface {
FetchRegions(ctx context.Context, opts FetchOptions) ([]string, error)
}
RegionLister is implemented by Provider impls that can fetch the cloud's authoritative region/location list via SDK. Optional — providers without an SDK list endpoint don't implement it. Drives `disco coverage --regions`.
type RegionRow ¶ added in v0.8.0
type RegionRow struct {
Provider string `json:"provider"`
Region string `json:"region"`
Status string `json:"status"`
}
RegionRow categorises a single region across the static-vs-live diff. Status values:
- "covered" — region appears in both disco's static RegionNames list and the cloud's live API response.
- "stale" — disco lists it but the live API doesn't return it (region retired or typo in the static list).
- "missing" — live API returns it but disco's static list lacks it (refresh internal/providers/<p>/regions.go).
func DiffRegions ¶ added in v0.8.0
DiffRegions categorises every region across the union of static and live lists. Output is sorted by region name for diff-stable rendering. Provider field on each row is left empty; the caller fills it in.
type ResolverAuditor ¶ added in v0.10.0
type ResolverAuditor interface {
ListResolvers() []ResolverInfo // one entry per registered resolver, registration order
ResolverEdgeSources() []string // distinct EdgeDecl.Source disco-types across all resolvers
}
ResolverAuditor is an optional interface a Provider may implement to expose its relationship-resolver registry to `disco coverage resolvers`. Keeping it behind the registry (rather than a direct provider-package import in cmd) lets cmd stay provider-agnostic, so a slim build that excludes the provider simply reports the auditor as unavailable. AWS, Azure, and GCP implement it.
type ResolverInfo ¶ added in v0.10.0
type ResolverInfo struct {
Name string `json:"name"`
EdgeCount int `json:"edge_count"`
Services []string `json:"services,omitempty"`
}
ResolverInfo summarises one registered relationship resolver for the `disco coverage resolvers` tooling: the resolver function name, the count of declared EdgeDecls, and the distinct disco service segments its edges touch. EdgeCount==0 marks an unannotated (intentional no-op or pending) resolver.
type Row ¶
type Row struct {
Provider string `json:"provider"`
Service string `json:"service"`
DiscoType string `json:"disco_type,omitempty"` // empty when row is upstream-only (uncovered/not-scannable)
UpstreamKey string `json:"upstream_key,omitempty"` // empty when row is uncatalogued
Bucket Bucket `json:"bucket"`
Reason string `json:"reason,omitempty"` // not-scannable rationale, or "duplicate of <key>" on a cross-catalog twin
}
Row is one entry in the coverage matrix.
type Skipper ¶ added in v0.14.0
Skipper is an optional interface a Provider may implement to declare upstream resource keys it deliberately does not scan — CFN sub-resource/association types with no standalone List API, ephemeral task/quote/report records, preview services with no public SDK, or duplicates of an already-scanned type. Each entry maps the upstream key to a one-line rationale. Build reclassifies matching leftover-upstream rows from BucketUncovered to BucketNotScannable so the uncovered bucket reflects genuine, actionable gaps only.
type TypeDecl ¶
type TypeDecl struct {
Service string // disco's service segment (e.g. "ec2", "compute", "microsoft.compute")
DiscoType string // canonical disco type, e.g. "aws:ec2:instance"
// Uncatalogued marks a real resource disco scans via the SDK that no
// upstream registry (CFN/SR, ARM, Discovery) lists — e.g. aws:kms:grant,
// the Azure Entra identities. Suppresses the upstream-missing drift signal
// on the no-match path; auto-upgrades to covered if the registry later
// lists it.
Uncatalogued bool
// Leaf marks a type as intentionally edge-less: its scanner upserts rows
// but the resource has no outbound refs to other scanned types
// (account-level configs, registry policies, leaf catalogue items).
// `disco coverage --missing-resolvers` filters these out so the orphan
// list only contains genuinely wire-able candidates.
Leaf bool
}
TypeDecl is one disco resource type declared by a scanner's emits field.
type UpstreamType ¶
type UpstreamType struct {
Key string // canonical upstream identifier, provider-specific shape
Service string // grouping bucket for matrix rendering
}
UpstreamType is one entry returned by a provider's live registry Fetch.