coverage

package
v0.17.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 17, 2026 License: MIT Imports: 8 Imported by: 0

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

View Source
const (
	RegionCovered = "covered"
	RegionStale   = "stale"
	RegionMissing = "missing"
)

Region status string constants.

Variables

This section is empty.

Functions

func AlgorithmicUpstreamKey

func AlgorithmicUpstreamKey(discoType string) string

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 Names

func Names() []string

Names returns the sorted names of every registered provider.

func Register

func Register(p Provider)

Register adds a Provider to the global registry. Called from each provider package's init().

func RenderJSON

func RenderJSON(w io.Writer, matrices []Matrix) error

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

func RenderMarkdown(w io.Writer, matrices []Matrix) error

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

func RenderRegionsMarkdown(w io.Writer, rows []RegionRow) error

RenderRegionsMarkdown writes a markdown table of region rows.

func RenderRegionsTable added in v0.8.0

func RenderRegionsTable(w io.Writer, rows []RegionRow) error

RenderRegionsTable writes a tabwriter-aligned table of region rows.

func RenderTable

func RenderTable(w io.Writer, matrices []Matrix) error

RenderTable writes a tabwriter-aligned plain-text matrix. Bucket column supports shell filtering, e.g. `awk '$4 == "covered"'`.

Types

type Bucket

type Bucket string

Bucket classifies a single matrix row.

const (
	BucketCovered         Bucket = "covered"
	BucketUncovered       Bucket = "uncovered"
	BucketNotScannable    Bucket = "not-scannable"
	BucketUncatalogued    Bucket = "uncatalogued"
	BucketUpstreamMissing Bucket = "upstream-missing"
)

Bucket values; semantics documented in internal/coverage/CLAUDE.md.

type CanonicalKeyer added in v0.14.0

type CanonicalKeyer interface {
	CanonicalKey(upstreamKey string) string
}

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

type FetchOptions struct {
	Regions      []string
	Profile      string
	Subscription string
}

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

type Matrix struct {
	Provider string `json:"provider"`
	Rows     []Row  `json:"rows"`
}

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.

func All

func All() []Provider

All returns every registered Provider, sorted by Name.

func Get

func Get(name string) (Provider, bool)

Get returns the registered Provider by name.

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

func DiffRegions(static, live []string) []RegionRow

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

type Skipper interface {
	Skips() map[string]string // upstream-key -> rationale
}

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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL