Help us shape the future of Go! Take the 2026 Go Developer Survey

gcpsweep

package
v0.32.0 Latest Latest
Warning

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

Go to latest
Published: Oct 29, 2026 License: MPL-2.0 Imports: 23 Imported by: 0

Documentation

Overview

Package gcpsweep is the GCP estate sweep's client (GitHub issue #1119, the GCP platform epic): which live resources in a set of projects carry this estate's owner label, so that one whose block the configuration no longer declares can be proposed for removal, exactly as the AWS tagging sweep and the Kubernetes label list do on their substrates.

The package is public and engine-neutral (GitHub issue #2281): the caller names the owner and address label keys (Config.Markers; choudoufu's are tofu-estate and tofu-address, which the examples below use) and hands over the authenticated HTTP client every call goes through (Config.HTTPClient). It builds no credential of its own.

What a sweep is here

GCP has a cross-service, label-filtered search, which Kubernetes lacks and AWS has in the Resource Groups Tagging API: Cloud Asset Inventory's searchAllResources (https://cloud.google.com/asset-inventory/docs/reference/rest/v1/TopLevel/searchAllResources). One query per project, labels.tofu-estate=ESTATE, paged until the response carries no nextPageToken, returns every indexed resource of every asset type that carries the label. The scope is a project, never a folder or an organization: the GCP fence is ruled project-scoped for now (GitHub issue #1121), and a project is what a provider block names.

The query's label operator is "=", an exact match. ":" is a token match, under which labels.tofu-estate:prod would also find a resource labelled prod-east, so Client.Search also drops any result whose own label is not exactly the estate. A query the service cannot parse is an INVALID_ARGUMENT and fails the search; it is never read as "nothing found".

Failure is never an empty answer

Every way a project's search can fail is an error, and four of them are typed so that the discovery leg can name the fix rather than print a raw HTTP body: ServiceDisabledError (enable cloudasset.googleapis.com on the project), PermissionDeniedError (grant the permission it names, cloudasset.assets.searchAllResources), PartialError (a page after the first failed, so the pages already read are discarded rather than returned as the whole answer), and UncoveredProjectError (the sweep was asked about a project no configured credential is set to search). A 200 with no results is the one empty answer, and it means the index holds nothing labelled for the estate in that project.

Credentials

ProviderAttrs reads the hashicorp/google provider block the way the provider itself resolves it, and Attrs.Auth names which source a client will authenticate with: access_token, then credentials, then Application Default Credentials, each optionally impersonating impersonate_service_account. The provider's environment fallbacks apply to any argument the block leaves unset (Attrs.WithEnv). HTTPClient builds a client by that precedence for a caller that wants the provider's rule, except that a block pointed at a loopback endpoint (an emulator run, Attrs.Local) never authenticates through a credentials file or Application Default Credentials, which would fetch a token from Google: an access_token is sent as given, and with none the calls carry no credential. Such a client also refuses any call whose own endpoint was left at Google's public default.

Per-type lists

The index lags a create, so it cannot show the second of two objects two concurrent applies made of a type whose identity the API assigns. Client.ListType lists each such labelled type (CoveredTypes) through its own service's list method instead, under the provider's base path for the product, and keeps what carries the estate's label exactly. It fails the way Client.Search does, with the type's own service and permission named (typelist.go).

The fakes' shapes

testdata/README.md writes down the exact request Client.Search sends and every response shape this package's tests serve, with the Google document each was taken from. It is the specification the emulator's Asset Inventory surface (lex00/floci-gcp#7) is to be checked against.

Index

Constants

View Source
const PageSize = 500

PageSize is the page size every search asks for: the API's maximum.

View Source
const Permission = "cloudasset.assets.searchAllResources"

Permission is the one IAM permission a project's search needs. A PERMISSION_DENIED that does not name a permission of its own is reported as missing this one, since the search asks for nothing else.

View Source
const ReadMask = "name,assetType,project,location,labels,createTime,updateTime"

ReadMask is the fields every search asks for, which are exactly Asset's.

View Source
const Service = "cloudasset.googleapis.com"

Service is the API a sweep calls, which is what a project has to have enabled.

Variables

View Source
var NotCovered = map[string]string{
	"google_dialogflow_cx_intent": "its list is under its agent (parent), which is another resource's attribute at plan time",
}

NotCovered is each labelled server-assigned google type with no per-type lister, and why. It binds through Asset Inventory alone, and the collision claim does not cover it. google_assured_workloads_workload left this list in INTENTIUS/choudoufu#2274: its list is under the organization its own required argument names (handwrittenlist.go).

View Source
var ScopeVars = map[string]bool{"project": true, "region": true, "zone": true, "location": true}

ScopeVars are the placeholders that say where a list is made rather than under which parent object: a value given as a self link or a full name ("projects/p", ".../zones/z") counts by its last segment.

View Source
var Services = map[string]ListService{}

Services are the services derived types are listed through, by host. The hosts are plunge gcplist.Services' hosts; the endpoint arguments are hashicorp/google's spelling of the same arguments (live/e2e/lib/gcp-provider-endpoints.txt, with api_gateway_custom_endpoint from google-beta, which serves the API Gateway types).

Functions

func AddressQuery

func AddressQuery(keys markerkeys.Keys, estate, address string) string

AddressQuery is the search query for estate's owner label and one address label value together, under keys. Both terms are exact matches, joined with AND as the search syntax spells a conjunction.

func CoveredTypes

func CoveredTypes() []string

CoveredTypes is every covered type, sorted: the hand-written ones and the derived ones.

func EnvNames

func EnvNames() []string

EnvNames are every environment variable Attrs.WithEnv reads, so a test can clear them all.

func Filter

func Filter(keys markerkeys.Keys, estate string) string

Filter is the AIP-160 filter a list that takes one is sent: the estate's owner label under keys, exactly.

func HandwrittenImportID

func HandwrittenImportID(typeName, assetName string) (string, bool)

HandwrittenImportID is the import ID of a [handwrittenLists] type's object from its Asset name: the name's path, when the name has the type's Asset host and the path the shape of its ImportSyntax. ok is false for any other type or name.

func IsLoopback

func IsLoopback(raw string) bool

IsLoopback reports whether raw, a URL or a bare host[:port], names localhost or a loopback address.

func Query

func Query(keys markerkeys.Keys, estate string) string

Query is the search query for estate's owner label under keys.

func Uncovered

func Uncovered(typeName string) string

Uncovered says why typeName has no per-type lister, or "" when it has one.

Types

type AddressSearcher

type AddressSearcher interface {
	// SearchAddress returns every resource in project carrying both
	// labels, all pages read, or an error and no resources, with the same
	// typed errors as [Searcher.Search].
	SearchAddress(ctx context.Context, project, estate, address string) ([]Asset, error)
}

AddressSearcher is the narrower search live-mv asks before it rewrites a tofu-address label (internal/live/mv): which resources in project carry tofu-estate=estate and tofu-address=address together. Client serves it; a test stands in for it as it does for Searcher.

type Asset

type Asset struct {
	// AssetType is the Cloud Asset type: "compute.googleapis.com/Network".
	AssetType string
	// Name is the full resource name:
	// "//compute.googleapis.com/projects/p/global/networks/n".
	Name string
	// Project is the project the resource is in, as the index spells it:
	// "projects/" and the project NUMBER, never the id the caller searched
	// by.
	Project string
	// Location is the resource's region, zone or "global".
	Location string
	// Labels are the resource's labels, the estate's among them.
	Labels map[string]string
	// CreateTime and UpdateTime are the resource's own timestamps, RFC
	// 3339, or "" for an asset type that reports none.
	CreateTime string
	UpdateTime string
}

Asset is one resource the Asset Inventory index holds with this estate's label, as searchAllResources returned it.

The index is eventually consistent, the GCP counterpart of the AWS tagging index's lag (internal/live/discovery's tagging leg): a resource created moments ago may be missing from a search, and one deleted moments ago may still be listed, with its labels as they were. Google documents no bound; its own guidance is minutes (https://cloud.google.com/asset-inventory/docs/overview#data_freshness_and_consistency). A listed Asset is therefore a resource the index last saw carrying the label, not proof it exists now, and a resource missing from the answer may exist. A caller proposing a removal reads the resource itself before acting, and a caller asked whether a just-applied create is visible has to allow for the lag.

type Attrs

type Attrs struct {
	// Credentials is the provider's credentials argument: a path to a
	// service account key or other credentials file, or its JSON contents.
	Credentials string
	// AccessToken is the provider's access_token argument: an OAuth 2.0
	// access token, or a path to a file holding one.
	AccessToken string
	// ImpersonateServiceAccount is the service account email every call is
	// made as, through the base credential, and ImpersonateDelegates its
	// delegation chain.
	ImpersonateServiceAccount string
	ImpersonateDelegates      []string
	// Scopes overrides the provider's default OAuth scopes.
	Scopes []string

	// Project, Region and Zone are the block's defaults. Only Project
	// bears on a sweep: it is the project a client searches when its
	// caller names none ([Client.Project]).
	Project string
	Region  string
	Zone    string

	// BillingProject and UserProjectOverride are how the provider sends a
	// quota project: with the override on, every call carries
	// X-Goog-User-Project, BillingProject's value when set, else the
	// project the call is about.
	BillingProject      string
	UserProjectOverride bool
	// UniverseDomain is the provider's universe_domain, for a sovereign
	// cloud; empty is googleapis.com.
	UniverseDomain string

	// CloudAssetEndpoint is the provider's cloud_asset_custom_endpoint, a
	// base path ending in the API version as the provider writes it
	// ("https://cloudasset.googleapis.com/v1/"); an emulator or a test
	// sets it. IAMCredentialsEndpoint is iam_credentials_custom_endpoint,
	// where an impersonated token is minted.
	CloudAssetEndpoint     string
	IAMCredentialsEndpoint string

	// Endpoints are the *_custom_endpoint arguments of the products the
	// per-type listers call ([TypeList.Endpoint]), by argument name, each
	// a base path as the provider writes it. An unset one is absent.
	Endpoints map[string]string

	// ExternalCredentials is whether the block declares an
	// external_credentials block (workload identity federation through
	// the provider's own exchange). The sweep does not perform that
	// exchange, so [New] refuses such a block rather than search as
	// whatever Application Default Credentials happen to be.
	ExternalCredentials bool

	// Marked names the arguments the block sets to a marked value that
	// [ProviderAttrs] therefore left unread. [New] refuses a client when
	// one of them would change who the sweep authenticates as or which
	// endpoint it calls ([Attrs.refusedMarks]).
	Marked []string
}

Attrs are the hashicorp/google provider block arguments the sweep understands, read off its evaluated configuration by ProviderAttrs. The names are the provider's own (8.6.0 schema); an empty field is an argument the block leaves unset.

func ProviderAttrs

func ProviderAttrs(val cty.Value, ok bool) Attrs

ProviderAttrs reads the arguments the GCP sweep understands off the evaluated hashicorp/google provider block, mirroring internal/live/substrate's KubernetesSweepAttrs: a marked value is left unread rather than unmarked, the same rule internal/command's projectionProviders.region applies to a sensitive region, EXCEPT for the two arguments that are themselves the credential, credentials and access_token, which are unmarked and read. GitHub issue #1527 is what leaving a credential unread cost on Kubernetes: every ordinary way of supplying one marks it (a key from a `sensitive = true` variable, a token from a data source the provider declares sensitive), and the sweep then called the API as someone other than the provider did, while the provider, handed the same value unmarked over RPC, read it fine. They go into an OAuth token source and out over TLS; nothing here renders them, and Credentials keeps only which source was chosen.

Every other marked argument is named in Attrs.Marked, so that one whose absence would change the sweep's identity or target refuses the client instead of being silently dropped.

func (Attrs) Auth

func (a Attrs) Auth() Credentials

Auth is the precedence hashicorp/google's provider applies (transport_tpg's Config.GetCredentials): access_token if set, else credentials if set, else Application Default Credentials, and in every case through impersonate_service_account when that is set. Call it on Attrs.WithEnv's result to see what a client built from the same Attrs uses.

func (Attrs) Local

func (a Attrs) Local() bool

Local reports whether a points any custom endpoint at a loopback host: an emulator run. Every call a client built from a makes then has to stay on local endpoints, its credential's token fetches included.

func (Attrs) RefusedMarks

func (a Attrs) RefusedMarks() []string

RefusedMarks are the arguments a client built from a is refused over: set from a marked value, and each one changes who the calls are made as or where they go. A caller building its own client checks them as New does.

func (Attrs) WithEnv

func (a Attrs) WithEnv(getenv func(string) string) Attrs

WithEnv fills every argument a left unset from the environment variable the provider reads for it, looked up through getenv (os.Getenv). An argument the block sets, or left unread because it was marked, is never replaced: the block wins, as it does in the provider, and a marked value is not to be stood in for by a different one. Note what that means for precedence: GOOGLE_OAUTH_ACCESS_TOKEN fills access_token even when the block sets credentials, and access_token wins (Attrs.Auth), exactly as in the provider.

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client is Searcher over the Cloud Asset API, authenticated as one provider block's credential.

func New

func New(ctx context.Context, a Attrs, cfg Config) (*Client, error)

New builds a client from a provider block's arguments, with the provider's environment fallbacks applied (Attrs.WithEnv), over the caller's HTTP client. Nothing is called until Client.Search.

func (*Client) Credentials

func (c *Client) Credentials() Credentials

Credentials is how this client authenticates.

func (*Client) ListType

func (c *Client) ListType(ctx context.Context, typeName string, scope ListScope, estate string) ([]Asset, error)

ListType is TypeLister.ListType over the type's own service, authenticated as this client's credential.

func (*Client) Project

func (c *Client) Project() string

Project is the provider block's project, the one project this client is set to search when the configuration names no other: what a Coverage built from provider blocks keys the client by. "" when the block and the environment name none.

func (*Client) ProviderScope

func (c *Client) ProviderScope() ProviderScope

ProviderScope is the provider block's project, region and zone, the defaults a list scope falls back to (ProviderScope.Default).

func (*Client) Region

func (c *Client) Region() string

Region is the provider block's region, the location a per-type list of a type whose block names none is made under (TypeList.Location).

func (*Client) Search

func (c *Client) Search(ctx context.Context, project, estate string) ([]Asset, error)

Search reads every page of project's search for estate's label. It returns all of them or none: a failure on any page is an error, typed (ServiceDisabledError, PermissionDeniedError) when the API's answer is one of those, and a PartialError wrapping it when it came after the first page. A 200 with no results is an empty answer and a nil error.

A result whose own tofu-estate label is not exactly estate is dropped: the query asks for an exact match, and this is the same test made again on what came back, so that a token match can never read a neighbouring estate's resource as this one's.

func (*Client) SearchAddress

func (c *Client) SearchAddress(ctx context.Context, project, estate, address string) ([]Asset, error)

SearchAddress is Client.Search narrowed by one more label term: every resource in project whose tofu-estate is exactly estate and whose tofu-address is exactly address. Results are checked against both labels again, for the reason Search checks the estate.

func (*Client) Zone

func (c *Client) Zone() string

Zone is the provider block's zone, the zone hashicorp/google puts a zonal resource in when its block names none.

type Config

type Config struct {
	// Markers names the owner and address label keys a search matches.
	Markers markerkeys.Keys
	// HTTPClient carries every call, the Cloud Asset search and each
	// per-type list, already authenticated as the caller decided. Nothing
	// here reads a credentials file, searches for Application Default
	// Credentials or asks the metadata server. [HTTPClient] builds one the
	// way hashicorp/google's provider does; a caller with its own rule
	// passes its own.
	HTTPClient *http.Client
	// Credentials is what diagnostics name the credential as.
	Credentials Credentials
}

Config is what the caller supplies a Client (GitHub issue #2281): the marker vocabulary and the authenticated HTTP client. The package builds no credential of its own.

type Coverage

type Coverage map[string]Searcher

Coverage is which client searches which project: the project id a provider block names, keyed to the client its credential built.

type CredentialSource

type CredentialSource string

CredentialSource is which of the provider block's credential arguments a client authenticates with.

const (
	// SourceAccessToken is the access_token argument, a bearer token used
	// as given.
	SourceAccessToken CredentialSource = "access_token"
	// SourceCredentials is the credentials argument, a credentials file's
	// JSON or its path.
	SourceCredentials CredentialSource = "credentials"
	// SourceADC is Application Default Credentials: the block names no
	// credential, so the environment's own (GOOGLE_APPLICATION_CREDENTIALS,
	// gcloud's application-default login, the metadata server) is used.
	SourceADC CredentialSource = "application default credentials"
	// SourceNone is no credential at all: the block points at local
	// endpoints and names no access_token, so the calls go unauthenticated
	// rather than through a credential that fetches its token from Google
	// ([HTTPClient]).
	SourceNone CredentialSource = "no credential (the provider's custom endpoints are local)"
	// SourceCaller is a client whose credential the caller built and
	// handed over in [Config].
	SourceCaller CredentialSource = "the caller's client"
)

type Credentials

type Credentials struct {
	Source CredentialSource
	// Impersonate is the service account every call is made as, through
	// Source, or "" when the block impersonates no one.
	Impersonate string
	// Delegates is Impersonate's delegation chain.
	Delegates []string
}

Credentials is how a client was told to authenticate, so that a failure can be reported against what was actually used. It never holds the credential itself.

func HTTPClient

func HTTPClient(ctx context.Context, a Attrs) (*http.Client, Credentials, error)

HTTPClient builds the HTTP client a Config carries, authenticated the way hashicorp/google's provider would be from a, with the environment fallbacks applied (Attrs.WithEnv): Attrs.Auth's precedence, the scopes, the universe and impersonation through IAM Credentials. It is a helper for a caller that wants the provider's own rule; New never calls it.

It never reaches Google's public auth endpoints for a block pointed at local endpoints (Attrs.Local): a credentials file mints its tokens at the token_uri it names, and Application Default Credentials look in GOOGLE_APPLICATION_CREDENTIALS, gcloud's login and the metadata server, none of which may be reached for an emulator run. For such a block an access_token is sent as given, and with none the calls carry no credential at all (an emulator takes an anonymous call); impersonation mints only through a local iam_credentials_custom_endpoint. Anything else is refused rather than fallen back from.

func (Credentials) String

func (c Credentials) String() string

String is the one line a diagnostic names the credential with: "access_token", or "credentials impersonating sa@p.iam.gserviceaccount.com".

type Endpoint

type Endpoint struct {
	Arg     string
	Env     string
	Default string
}

Endpoint is one hashicorp/google product's base path: the provider block argument and environment variable that override it, and its default. Default may carry {{region}} or {{location}}, which the provider fills with the resource's own location, and so does Client.ListType.

type ListScope

type ListScope struct {
	Project string
	// Location is the region or location the type's list is under, or ""
	// for a type listed per project ([TypeList.Location] is "").
	Location string
	// Collection is a derived type's list path with every variable filled
	// ([TypeList.Scope]), and Query its encoded query, if any. "" for a
	// hand-written type, whose path is filled from Project and Location;
	// for a derived type it is filled the same way when the path needs no
	// other variable.
	Collection string
	Query      string
}

ListScope is where one list call is made: a project, and for a type listed per location, the location.

func (ListScope) String

func (s ListScope) String() string

type ListService

type ListService struct {
	// Host is the service host Asset names carry: "pubsub.googleapis.com".
	Host string
	// Root is the service's REST root with its version, as hashicorp/google
	// 8.6.0's default base path spells it: "https://pubsub.googleapis.com/v1/".
	Root string
	// EndpointArg is the provider block's custom endpoint argument for the
	// service, and EndpointEnv the environment variable the provider reads
	// when the block leaves it unset. The value replaces Root, version
	// included, as the provider reads it; floci-gcp sets it.
	EndpointArg string
	EndpointEnv string
	// Items is the list response's field holding the objects. "" is AIP-132's:
	// the collection's own name ("topics"). Compute Engine and Cloud Storage
	// use "items".
	Items string
	// Consistency is Google's statement of the list's consistency, when it
	// publishes one.
	Consistency string
}

ListService is one Google Cloud service a derived type is listed through.

type PartialError

type PartialError struct {
	Project string
	// PagesRead is how many pages arrived before the failure, and
	// ResultsRead how many results they held, for a log line; the results
	// themselves are gone.
	PagesRead   int
	ResultsRead int
	Err         error
}

PartialError is a search that read at least one page and then failed: the pages already read are discarded rather than returned, because a sweep that reads them as the whole answer would miss every resource on the pages it never read, and a missed resource is an orphan nobody is told about. Err is the failure of page PagesRead+1, and may itself be a ServiceDisabledError or PermissionDeniedError (errors.As reaches it).

func (*PartialError) Error

func (e *PartialError) Error() string

func (*PartialError) Unwrap

func (e *PartialError) Unwrap() error

type PermissionDeniedError

type PermissionDeniedError struct {
	Project    string
	Permission string
	// Credentials is what the client authenticated with.
	Credentials Credentials
	Err         error
}

PermissionDeniedError is a search the credential is not allowed to make: HTTP 403 PERMISSION_DENIED for any reason but a disabled API. Permission is the permission the error's own ErrorInfo names when it names one, else Permission.

func (*PermissionDeniedError) Error

func (e *PermissionDeniedError) Error() string

func (*PermissionDeniedError) Unwrap

func (e *PermissionDeniedError) Unwrap() error

type ProjectResult

type ProjectResult struct {
	Project string
	Assets  []Asset
	Err     error
}

ProjectResult is one project's sweep: its assets, or the error that stopped it and no assets. Assets nil with Err nil is a project that holds nothing labelled for the estate.

func Sweep

func Sweep(ctx context.Context, cov Coverage, projects []string, estate string) []ProjectResult

Sweep searches each of projects for estate's label with the client cov assigns it, in projects' order, each project once. A project cov has no client for is an UncoveredProjectError result, never a missing row. A failed project does not stop the others: each result stands alone, so the discovery leg can report a gap for the project that failed and still read the ones that answered.

type ProviderScope

type ProviderScope struct {
	Project string
	Region  string
	Zone    string
}

ProviderScope is the provider block's project, region and zone: what a list scope's variable falls back to when the resource's own block names none (ProviderScope.Default).

func (ProviderScope) Default

func (p ProviderScope) Default(name string) string

Default is the value the scope variable name takes when the resource's block leaves it unset. project, region and zone are the provider block's, as hashicorp/google defaults them. location is the provider block's region: a block with no location is listed in the provider's region, the one rule both engines apply (GitHub issue #2273, ruled 2026-10-26: plunge already fell back this way, and the google provider places a regional resource with no location there). Any other variable has no provider default, and "" is returned.

type Searcher

type Searcher interface {
	// Search returns every resource in project carrying the label
	// tofu-estate=estate, all pages read, or an error and no resources.
	Search(ctx context.Context, project, estate string) ([]Asset, error)
}

Searcher is what a sweep asks of one credential's client, so a test can stand in for the API.

type ServiceDisabledError

type ServiceDisabledError struct {
	// Project is the project the search was for.
	Project string
	// Service is the disabled service the error names, normally [Service].
	Service string
	// ActivationURL is the console link the error's own metadata gives for
	// enabling it, or "" when it gave none.
	ActivationURL string
	// Err is the API's own error.
	Err error
}

ServiceDisabledError is a project on which cloudasset.googleapis.com is not enabled: HTTP 403, an ErrorInfo detail with reason SERVICE_DISABLED, and a message that reads "Cloud Asset API has not been used in project N before or it is disabled". The fix is enabling the API on the project, never a retry and never a grant.

func (*ServiceDisabledError) Error

func (e *ServiceDisabledError) Error() string

func (*ServiceDisabledError) Unwrap

func (e *ServiceDisabledError) Unwrap() error

type TypeList

type TypeList struct {
	// Type is the google resource type: "google_vertex_ai_index_endpoint".
	Type string
	// Service is the API the list is made on, which is what the project has
	// to have enabled: "aiplatform.googleapis.com".
	Service string
	// AssetType is the Cloud Asset type the same object is indexed as,
	// which a listed [Asset] carries so that it reads like a search hit:
	// "aiplatform.googleapis.com/IndexEndpoint".
	AssetType string
	// Location is the resource argument the type's location comes from
	// ("region" or "location"), or "" for a type listed per project.
	// FixedLocation is the location of a type the API lists under one
	// location only ("global").
	Location      string
	FixedLocation string
	// Path is the list path under the service's base URL, in the
	// provider's ReplaceVars syntax: "projects/{{project}}/locations/{{location}}/indexEndpoints".
	// {{location}} stands for the location whatever the argument is called.
	Path string
	// Field is the list response's array field: "indexEndpoints".
	Field string
	// Filter is whether the list method takes an AIP-160 filter, so the
	// label test is also made server side. The test is always made again
	// on what comes back.
	Filter bool
	// Permission is the IAM permission the list needs.
	Permission string
	// Endpoint is the provider's base path for the type's product.
	Endpoint Endpoint

	// Derived is set for a type listed by the rule in servicelist.go (its
	// Asset name's parent collection, at a service in [Services]) rather
	// than by a row of [typeLists]. Asset is its Asset name template, Query
	// any query parameters its list takes (Cloud Storage's project), and
	// Consistency Google's statement of the list's consistency, if any.
	Derived     bool
	Asset       string
	Query       map[string]string
	Consistency string

	// For a type with no Asset name (handwrittenlist.go): AssetHost is the
	// host its documented Asset name carries when that is not Service
	// (Cloud SQL's is cloudsql.googleapis.com), NameByLocation names each
	// listed object from its own location field (GKE, listed at
	// locations/-), and Import is its import ID's shape, the type's
	// ImportSyntax in pkg/identity.
	AssetHost      string
	NameByLocation bool
	Import         string
}

TypeList is how one covered type is listed.

func Covered

func Covered(typeName string) (TypeList, bool)

Covered returns how typeName is listed, and whether it is covered: a hand-written row of [typeLists], else a type derived from its Asset name and its service (servicelist.go).

func (TypeList) Names

func (t TypeList) Names(a Asset) bool

Names reports whether a, a Cloud Asset Inventory hit, is an object of t: of t's asset type for a hand-written type, and named by t's Asset template for a derived one, whose asset type is only spelled from its collection.

func (TypeList) Placeholders

func (t TypeList) Placeholders() []string

Placeholders lists the variables a derived type's list path and query need, in order, each once.

func (TypeList) Scope

func (t TypeList) Scope(vars func(name string) (string, bool)) (ListScope, error)

Scope fills a derived type's list path and query from vars, or names the variables it has no value for. The scope's Location is the region, zone or location the path is under, if any.

type TypeLister

type TypeLister interface {
	// ListType returns every object of typeName at scope whose tofu-estate
	// label is exactly estate, with the same typed errors as
	// [Searcher.Search]. A type [Covered] does not name is an error.
	ListType(ctx context.Context, typeName string, scope ListScope, estate string) ([]Asset, error)
}

TypeLister lists one covered type's objects carrying an estate's label, all pages read, or an error and no objects. Client serves it; a test stands in for it.

type UncoveredProjectError

type UncoveredProjectError struct {
	Project string
}

UncoveredProjectError is a project the sweep was asked to search that no client in its Coverage is set to search: no provider block's credential was matched to it. It is reported rather than skipped, since a skipped project is one whose orphans nobody hears about.

func (*UncoveredProjectError) Error

func (e *UncoveredProjectError) Error() string

Directories

Path Synopsis
Package gcpsweeptest is a fake GCP sweep for tests in any module (GitHub issue #2281): an in-memory index that answers gcpsweep.Searcher, gcpsweep.AddressSearcher and gcpsweep.TypeLister by the same label match the real client makes, under the caller's marker vocabulary, and records what it was asked.
Package gcpsweeptest is a fake GCP sweep for tests in any module (GitHub issue #2281): an in-memory index that answers gcpsweep.Searcher, gcpsweep.AddressSearcher and gcpsweep.TypeLister by the same label match the real client makes, under the caller's marker vocabulary, and records what it was asked.

Jump to

Keyboard shortcuts

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