listclient

package
v0.3.0 Latest Latest
Warning

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

Go to latest
Published: Aug 24, 2026 License: MPL-2.0 Imports: 8 Imported by: 0

Documentation

Overview

Package listclient is stateless mode's client for the provider list protocol: the ListResource server-streaming RPC and the list resource schemas that parameterize it.

Listing is how stateless mode recovers the identity of resources whose identity is not in configuration. Admission path 2 (marker) lists a type filtered by ownership tags and reads the identity off each result; admission path 4 (list and content match) lists a type and binds by content. Both need the same three things from a provider, and this package is the whole surface for getting them:

  • which types the provider can list, from ListSchemas;
  • what a list call for a given type accepts as configuration, from TypeSchema.BuildConfig, which is where filtering is expressed for providers that support it;
  • the results, from List or Stream, each carrying the resource identity typed by that type's identity schema.

Not every provider lists

Listing arrived in plugin protocol 5.10 and 6.10. A provider built before that answers ListResource with gRPC status Unimplemented; a provider built after it may still list only some of its types. Neither is an error in the world, only an error for the caller that wanted to list, so both surface as ordinary error diagnostics naming the type. Nothing in this package panics on a provider that cannot list, and callers that want to check before asking can use Schemas.Supports.

Filtering is the provider's business

The list configuration schema is entirely provider-defined: the AWS provider offers EC2-style filter blocks for most of its listable types, other providers may offer nothing but a region. This package encodes whatever the caller builds against whatever schema the provider serves and makes no attempt to translate a general filter concept across providers. A caller that needs a filter the provider does not implement has to filter the results itself.

Where this sits

The protocol client proper lives on the concrete gRPC provider handles as ListResource and ListResourceStream methods (internal/plugin for protocol 5, internal/plugin6 for protocol 6). This package is the ergonomic layer over them: schema lookup, configuration construction, and result decoding in the shape discovery wants.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Stream

func Stream(ctx context.Context, provider any, req Request, emit func(Result) bool) tfdiags.Diagnostics

Stream enumerates the live instances of one resource type, calling emit once per result as it arrives instead of buffering. Returning false from emit ends the stream early, which is not an error.

Stream is the form to use when the result set may be large, or when the caller can stop as soon as it has found what it is looking for.

Types

type Lister

type Lister interface {
	// GetProviderSchema is the source of the list resource schemas.
	GetProviderSchema(ctx context.Context) providers.GetProviderSchemaResponse

	// ListResourceStream runs the ListResource streaming RPC, calling emit
	// once per result. Returning false from emit ends the stream.
	ListResourceStream(ctx context.Context, req providers.ListResourceRequest, emit func(providers.ListResourceEvent) bool) tfdiags.Diagnostics
}

Lister is the part of a provider handle this package uses. The concrete gRPC provider handles implement it: *plugin.GRPCProvider for plugin protocol 5 and *plugin6.GRPCProvider for protocol 6.

It is deliberately not providers.Interface. Listing is not something every provider implementation in the tree can do — the mocks and test doubles that satisfy providers.Interface have no list protocol behind them — so the capability is expressed as its own small interface and discovered by assertion rather than by widening the provider interface.

type Request

type Request struct {
	// TypeName is the resource type to enumerate, which must be one of the
	// types reported by [ListSchemas].
	TypeName string

	// Config is the list configuration, conforming to the type's list
	// configuration schema — build it with [TypeSchema.BuildConfig].
	// cty.NilVal means "set nothing", and is filled in from the schema.
	Config cty.Value

	// IncludeResource asks the provider to attach the full resource object
	// to every result. Providers may pay a read per result for this, so
	// leave it false when the identity is all that is wanted.
	IncludeResource bool

	// Limit caps the number of results; zero means no cap. This is a
	// request to the provider, which ends the stream once it is reached —
	// it is not a client-side truncation, so a provider that ignores it
	// will still send everything.
	Limit int64
}

Request is a single list call.

type Result

type Result struct {
	// TypeName is the resource type that was listed.
	TypeName string

	// Identity is the resource identity, an object typed by the resource
	// type's identity schema. It is cty.NilVal when the provider sent no
	// identity or serves no identity schema for the type; a caller that
	// needs an identity must check, because a provider is free to send a
	// result without one.
	Identity cty.Value

	// DisplayName is the provider's human-readable label for the result.
	// It is for display only: nothing guarantees it is unique or stable.
	DisplayName string

	// Resource is the full resource object, typed by the resource type's
	// schema. It is cty.NilVal unless the request set IncludeResource.
	Resource cty.Value

	// Diagnostics are the diagnostics the provider attached to this
	// individual result. A result can carry an error diagnostic and still
	// be delivered, because the rest of the stream stays valid; these are
	// not returned as call-level diagnostics for that reason.
	Diagnostics tfdiags.Diagnostics
}

Result is one listed resource instance.

func List

func List(ctx context.Context, provider any, typeName string, config cty.Value, includeResource bool) ([]Result, tfdiags.Diagnostics)

List enumerates the live instances of one resource type, buffering the whole stream.

The provider argument is a provider handle; it is typed as any so that a caller holding a providers.Interface can pass it and get a diagnostic rather than a compile error when that provider turns out not to speak the list protocol. config must conform to the type's list configuration schema, and cty.NilVal means "set nothing".

Diagnostics from the call itself are returned; diagnostics the provider attached to individual results ride on those results.

func (Result) HasIdentity

func (r Result) HasIdentity() bool

HasIdentity reports whether this result carries a usable identity object.

func (Result) IdentityAttr

func (r Result) IdentityAttr(name string) (string, bool)

IdentityAttr reads one string attribute out of the result's identity, for example "id" or "region". The second return is false when the result has no identity, when the identity has no such attribute, or when that attribute is null or not a string.

type Schemas

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

Schemas is a provider's list-protocol surface: every type it can list, with the schemas for listing it.

The zero value is a valid empty Schemas, which is what a provider that does not implement listing yields.

func ListSchemas

func ListSchemas(ctx context.Context, provider any) (Schemas, tfdiags.Diagnostics)

ListSchemas reports which resource types the given provider handle can list, and the schemas involved in listing each of them.

A provider that implements no listing at all yields an empty Schemas and no diagnostics: not supporting the list protocol is a fact about the provider, not a failure of this call. A provider handle that cannot speak the protocol at all — anything that is not a gRPC provider handle — is a programming error and does produce an error diagnostic.

func (Schemas) Get

func (s Schemas) Get(typeName string) (TypeSchema, bool)

Get returns the schemas for one listable type.

func (Schemas) Len

func (s Schemas) Len() int

Len is the number of types the provider can list.

func (Schemas) ResourceSchema added in v0.3.0

func (s Schemas) ResourceSchema(typeName string) (*configschema.Block, bool)

ResourceSchema returns the managed resource type's own schema for typeName, regardless of whether the provider offers a list route for it - the question Schemas.Get cannot answer for a type with no list resource. False for a type the provider does not implement at all.

func (Schemas) Supports

func (s Schemas) Supports(typeName string) bool

Supports reports whether the provider can list the named type.

func (Schemas) Types

func (s Schemas) Types() []string

Types returns every listable type name, sorted.

type TypeSchema

type TypeSchema struct {
	// TypeName is the resource type name, e.g. "aws_vpc". A list resource
	// type name is the same string as the managed resource type it
	// enumerates.
	TypeName string

	// Config is the schema of the configuration block a list call for this
	// type accepts. It is never nil for a TypeSchema obtained from
	// [ListSchemas]. Its contents are provider-defined; build values for it
	// with [TypeSchema.BuildConfig].
	Config *configschema.Block

	// Identity is the identity schema of the managed resource type, which
	// types the Identity field of every result. It is nil when the provider
	// serves no identity schema for this type, in which case results carry
	// no usable identity.
	Identity *configschema.Object

	// IdentityVersion is the version of Identity, for callers that persist
	// identities and need to detect a schema change.
	IdentityVersion int64

	// Resource is the managed resource type's schema, which types the
	// Resource field of a result when full objects were requested. It is
	// nil when the provider serves a list schema for a type it has no
	// managed resource schema for, which would be a provider bug.
	Resource *configschema.Block
}

TypeSchema is everything a caller needs to list one resource type and to make sense of the results.

func (TypeSchema) BuildConfig

func (ts TypeSchema) BuildConfig(vals map[string]cty.Value) (cty.Value, tfdiags.Diagnostics)

BuildConfig builds a list configuration value for this type from the given arguments, filling in everything the caller did not set.

Keys of vals name either attributes or nested block types of the list configuration schema. Every attribute the caller does not name is set to null, and every block type it does not name is set to that nesting mode's empty value, so the result always conforms to the schema's implied type — which is what the wire encoding requires. Values are converted to the schema's type where a conversion exists.

An unknown key, or a value that cannot be converted, is an error diagnostic naming the key and the type the provider wanted: a caller building a filter against a schema it guessed at should hear about it here rather than as an opaque provider error.

func (TypeSchema) EmptyConfig

func (ts TypeSchema) EmptyConfig() cty.Value

EmptyConfig is the list configuration that sets nothing: every argument null and every block empty. It is what List sends when the caller passes cty.NilVal.

func (TypeSchema) HasIdentity

func (ts TypeSchema) HasIdentity() bool

HasIdentity reports whether results for this type will carry a decodable identity.

Jump to

Keyboard shortcuts

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