Documentation
¶
Overview ¶
Package entitycore provides a shared embedded core for Plugin Framework entities: ResourceBase centralizes resource.ResourceWithConfigure Configure wiring, the Metadata method required by resource.Resource, and stores the configured *clients.ProviderClientFactory for use via ResourceBase.Client. Data sources use envelope generics.
Data source patterns ¶
Plugin Framework data sources use **envelope generics** — NewKibanaDataSource or NewElasticsearchDataSource — which eliminate Read orchestration boilerplate. The constructor owns config decode, scoped client resolution, and state persistence. The concrete package provides only a schema factory (without connection blocks), a model that embeds KibanaConnectionField or ElasticsearchConnectionField, and a pure read function that performs the entity-specific API call and model mapping.
Example envelope data source:
type myModel struct {
entitycore.KibanaConnectionField
ID types.String `tfsdk:"id"`
}
func readMyEntity(ctx context.Context, client *clients.KibanaScopedClient, model myModel) (myModel, diag.Diagnostics) {
// API call and model population …
return model, nil
}
func NewDataSource() datasource.DataSource {
return entitycore.NewKibanaDataSource[myModel](
entitycore.ComponentKibana,
"my_entity",
getDataSourceSchema, // func(ctx context.Context) datasource.Schema, without kibana_connection block
readMyEntity,
)
}
Resource patterns ¶
Resources have three patterns:
**Struct-based embedding** — embed *ResourceBase and implement resource.Resource directly. This is the right choice when Create and Update flows diverge significantly from a uniform shape.
**Elasticsearch resource envelope** — use NewElasticsearchResource for Elasticsearch-backed CRUD resources whose lifecycle matches the envelope's shape (decode → client → version checks → callback → read-after-write → optional post-read). The model must satisfy ElasticsearchResourceModel; callbacks and options live on ElasticsearchResourceOptions. Resources that still override Create or Update may pass PlaceholderElasticsearchWriteCallback until their logic is migrated into envelope callbacks. The envelope does not implement ImportState; concrete resources add that when needed. See type docs in resource_envelope.go for the full contract.
**Kibana resource envelope** — use NewKibanaResource for Kibana-backed resources whose Create, Read, Update, and Delete flows match a common shape. The model must satisfy KibanaResourceModel (value-receiver GetID for composite or plain state ID, GetResourceID for the write key such as name or API-assigned UUID, GetSpaceID for the Kibana space, and GetKibanaConnection). Supply a schema factory (without kibana_connection block), read and delete callbacks, and required create and update callbacks (KibanaCreateFunc, KibanaUpdateFunc). The envelope injects the kibana_connection block, resolves resource identity via composite-ID-or-fallback for Read, Update, and Delete, validates spaceID for Create, resolves the scoped Kibana client, and owns state persistence. Create callbacks receive the plan model (and can call plan.GetResourceID() for user-ID resources); Update callbacks receive both plan and prior state. It does not implement ImportState; concrete resources add that when needed. Resources that override Create or Update may pass PlaceholderKibanaWriteCallbacks until their logic is migrated into envelope callbacks. Constructor shape and callback types are defined on NewKibanaResource in kibana_resource_envelope.go.
Component is a typed Terraform resource type-name namespace segment (for example "elasticsearch", "kibana"). It is not a client-resolution kind: the same API family can use different component strings for Terraform naming, such as APM resources using the "apm" segment while calling Kibana APIs.
The resourceName argument to NewResourceBase is the final literal suffix segment in the Terraform type name, joined without normalization. Callers must preserve existing spellings for compatibility (for example "agentbuilder_tool" versus "agent_builder_tool").
Index ¶
- func EnforceVersionRequirements(ctx context.Context, client MinVersionClient, model any) diag.Diagnostics
- func NewElasticsearchDataSource[T ElasticsearchDataSourceModel](component Component, name string, ...) datasource.DataSource
- func NewKibanaDataSource[T KibanaDataSourceModel](component Component, name string, ...) datasource.DataSource
- func PlaceholderKibanaWriteCallbacks[T KibanaResourceModel]() (KibanaCreateFunc[T], KibanaUpdateFunc[T])
- type Component
- type DataSourceBase
- type ElasticsearchConnectionField
- type ElasticsearchDataSourceModel
- type ElasticsearchResource
- func (r *ElasticsearchResource[T]) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse)
- func (r *ElasticsearchResource[T]) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse)
- func (r *ElasticsearchResource[T]) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse)
- func (r *ElasticsearchResource[T]) Schema(ctx context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse)
- func (r *ElasticsearchResource[T]) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse)
- type ElasticsearchResourceModel
- type ElasticsearchResourceOptions
- type KibanaConnectionField
- type KibanaCreateFunc
- type KibanaDataSourceModel
- type KibanaResource
- func (r *KibanaResource[T]) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse)
- func (r *KibanaResource[T]) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse)
- func (r *KibanaResource[T]) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse)
- func (r *KibanaResource[T]) Schema(ctx context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse)
- func (r *KibanaResource[T]) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse)
- type KibanaResourceModel
- type KibanaUnscopedSpace
- type KibanaUpdateFunc
- type MinVersionClient
- type PostReadFunc
- type ResourceBase
- type VersionRequirement
- type WithReadResourceID
- type WithVersionRequirements
- type WriteFunc
- type WriteRequest
- type WriteResult
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func EnforceVersionRequirements ¶ added in v0.15.2
func EnforceVersionRequirements(ctx context.Context, client MinVersionClient, model any) diag.Diagnostics
EnforceVersionRequirements checks whether model implements WithVersionRequirements and, if so, evaluates each requirement against the scoped client. It returns any diagnostics produced. Entity envelopes call this automatically; concrete resources whose Create/Update bypass the envelope can invoke it directly to honor the model's declared requirements.
func NewElasticsearchDataSource ¶
func NewElasticsearchDataSource[T ElasticsearchDataSourceModel]( component Component, name string, schemaFactory func(context.Context) dsschema.Schema, readFunc func(context.Context, *clients.ElasticsearchScopedClient, T) (T, diag.Diagnostics), ) datasource.DataSource
NewElasticsearchDataSource returns a datasource.DataSource that wraps the provided schema and read function with automatic elasticsearch_connection block injection, config decode, scoped client resolution, and state persistence.
The concrete model T must embed ElasticsearchConnectionField.
func NewKibanaDataSource ¶
func NewKibanaDataSource[T KibanaDataSourceModel]( component Component, name string, schemaFactory func(context.Context) dsschema.Schema, readFunc func(context.Context, *clients.KibanaScopedClient, T) (T, diag.Diagnostics), ) datasource.DataSource
NewKibanaDataSource returns a datasource.DataSource that wraps the provided schema and read function with automatic kibana_connection block injection, config decode, scoped client resolution, and state persistence.
The concrete model T must embed KibanaConnectionField so that the connection block can be decoded alongside entity attributes.
Example usage (package doc):
type myModel struct {
entitycore.KibanaConnectionField
ID types.String `tfsdk:"id"`
}
func NewDataSource() datasource.DataSource {
return entitycore.NewKibanaDataSource[myModel](
entitycore.ComponentKibana,
"my_entity",
getDataSourceSchema, // func(ctx context.Context) datasource.Schema, without kibana_connection block
readMyEntity,
)
}
func PlaceholderKibanaWriteCallbacks ¶
func PlaceholderKibanaWriteCallbacks[T KibanaResourceModel]() (KibanaCreateFunc[T], KibanaUpdateFunc[T])
PlaceholderKibanaWriteCallbacks returns create and update callbacks that fail if invoked. Use when a concrete resource type still defines its own Create and Update methods that override the envelope so Terraform never calls these placeholders.
Types ¶
type Component ¶
type Component string
Component is a Terraform type-name namespace segment used when building the full resource type name. See package documentation.
const ( ComponentElasticsearch Component = "elasticsearch" ComponentKibana Component = "kibana" ComponentFleet Component = "fleet" ComponentAPM Component = "apm" )
Well-known Terraform type-name namespace segments for ResourceBase.Metadata.
type DataSourceBase ¶ added in v0.15.2
type DataSourceBase struct {
// contains filtered or unexported fields
}
DataSourceBase holds shared Plugin Framework data source wiring: typed naming parts and the provider client factory from Configure. Embed *DataSourceBase in concrete data sources to reuse Configure, Metadata, and Client.
func NewDataSourceBase ¶ added in v0.15.2
func NewDataSourceBase(component Component, dataSourceName string) *DataSourceBase
NewDataSourceBase returns a DataSourceBase for the given namespace segment and literal data source name suffix. dataSourceName is not normalized; see package documentation.
func (*DataSourceBase) Client ¶ added in v0.15.2
func (d *DataSourceBase) Client() *clients.ProviderClientFactory
Client returns the client factory from the last successful Configure call, or nil if none has been stored yet. A nil *DataSourceBase returns nil so callers can surface diagnostics instead of panicking.
func (*DataSourceBase) Configure ¶ added in v0.15.2
func (d *DataSourceBase) Configure(_ context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse)
Configure implements datasource.DataSourceWithConfigure, converting provider data with clients.ConvertProviderDataToFactory and appending diagnostics. If the response has error diagnostics, it returns without assigning a new factory, leaving any prior successful client unchanged.
func (*DataSourceBase) Metadata ¶ added in v0.15.2
func (d *DataSourceBase) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse)
Metadata implements the Metadata method of datasource.DataSource, setting the Terraform type name to "<providerTypeName>_<component>_<dataSourceName>".
type ElasticsearchConnectionField ¶
type ElasticsearchConnectionField struct {
ElasticsearchConnection types.List `tfsdk:"elasticsearch_connection"`
}
ElasticsearchConnectionField is an embeddable struct that provides the elasticsearch_connection block field for data source models used with NewElasticsearchDataSource.
func (ElasticsearchConnectionField) GetElasticsearchConnection ¶
func (f ElasticsearchConnectionField) GetElasticsearchConnection() types.List
GetElasticsearchConnection returns the elasticsearch_connection block value.
type ElasticsearchDataSourceModel ¶
ElasticsearchDataSourceModel is the type constraint for models passed to NewElasticsearchDataSource. It is satisfied by any struct that embeds ElasticsearchConnectionField (or otherwise provides a GetElasticsearchConnection method).
type ElasticsearchResource ¶
type ElasticsearchResource[T ElasticsearchResourceModel] struct { *ResourceBase // contains filtered or unexported fields }
ElasticsearchResource implements resource.Resource and related interfaces for Elasticsearch-backed resources. It embeds *ResourceBase to reuse Configure, Metadata, and Client.
The envelope owns Schema (with elasticsearch_connection block injection), Create, Read, Update, and Delete. Concrete resources may override Create or Update when their lifecycle does not fit the callback contract, and may choose to implement ImportState.
func NewElasticsearchResource ¶
func NewElasticsearchResource[T ElasticsearchResourceModel](name string, opts ElasticsearchResourceOptions[T]) *ElasticsearchResource[T]
NewElasticsearchResource returns an *ElasticsearchResource that owns Schema, Create, Read, Update, and Delete for the Elasticsearch namespace. Concrete resources supply callbacks in opts; Schema, Read, Delete, Create, and Update must be non-nil or the envelope surfaces configuration error diagnostics instead of invoking nil callbacks.
func (*ElasticsearchResource[T]) Create ¶
func (r *ElasticsearchResource[T]) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse)
Create implements resource.Resource: decode plan, resolve client, invoke the create callback, read-after-write, then persist state from readFunc.
func (*ElasticsearchResource[T]) Delete ¶
func (r *ElasticsearchResource[T]) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse)
Delete implements resource.Resource with the standard prelude, then delegates to the concrete deleteFunc.
func (*ElasticsearchResource[T]) Read ¶
func (r *ElasticsearchResource[T]) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse)
Read implements resource.Resource with the standard prelude: deserialize prior state into the generic model T, resolve read identity from the model and/or composite ID, resolve the scoped Elasticsearch client, enforce optional version requirements when the model reports requirement diagnostics with an error severity (matching Kibana envelope semantics), then delegate to the concrete readFunc.
func (*ElasticsearchResource[T]) Schema ¶
func (r *ElasticsearchResource[T]) Schema(ctx context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse)
Schema implements resource.Resource, injecting the elasticsearch_connection block into the schema returned by the concrete schema factory.
func (*ElasticsearchResource[T]) Update ¶
func (r *ElasticsearchResource[T]) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse)
Update implements resource.Resource with the same prelude as Create, additionally decoding prior state for the update callback.
type ElasticsearchResourceModel ¶
type ElasticsearchResourceModel interface {
GetID() types.String
// GetResourceID returns the plan-safe write identity (for example name or
// username). Create and Update use this instead of GetID because computed
// id values may be unknown in create plans.
GetResourceID() types.String
GetElasticsearchConnection() types.List
}
ElasticsearchResourceModel is the type constraint for models passed to NewElasticsearchResource. Concrete types must provide value-receiver methods GetID, GetResourceID, and GetElasticsearchConnection.
type ElasticsearchResourceOptions ¶ added in v0.15.2
type ElasticsearchResourceOptions[T ElasticsearchResourceModel] struct { Schema func(context.Context) rschema.Schema Read elasticsearchReadFunc[T] Delete elasticsearchDeleteFunc[T] Create WriteFunc[T] Update WriteFunc[T] PostRead PostReadFunc[T] }
ElasticsearchResourceOptions configures NewElasticsearchResource. PostRead is optional; Schema, Read, Delete, Create, and Update must be non-nil or the envelope surfaces configuration diagnostics instead of invoking nil callbacks. Create and Update share the WriteFunc type so callers may pass the same function for both when the logic is identical.
type KibanaConnectionField ¶
KibanaConnectionField is an embeddable struct that provides the kibana_connection block field for Kibana entity models used with NewKibanaDataSource or NewKibanaResource.
func (KibanaConnectionField) GetKibanaConnection ¶
func (f KibanaConnectionField) GetKibanaConnection() types.List
GetKibanaConnection returns the kibana_connection block value.
type KibanaCreateFunc ¶
type KibanaCreateFunc[T KibanaResourceModel] func( context.Context, *clients.KibanaScopedClient, string, T, ) (T, diag.Diagnostics)
KibanaCreateFunc performs the create after the envelope decodes the plan, validates the space ID, resolves the scoped Kibana client, and passes the planned model. It returns the model to persist in state.
type KibanaDataSourceModel ¶
KibanaDataSourceModel is the type constraint for models passed to NewKibanaDataSource. It is satisfied by any struct that embeds KibanaConnectionField (or otherwise provides a GetKibanaConnection method).
type KibanaResource ¶
type KibanaResource[T KibanaResourceModel] struct { *ResourceBase // contains filtered or unexported fields }
KibanaResource implements resource.Resource and related interfaces for Kibana-backed resources. It embeds *ResourceBase to reuse Configure, Metadata, and Client.
The envelope owns Schema (with kibana_connection block injection), Create, Read, Update, and Delete. Concrete resources may override Create or Update when their lifecycle does not fit the callback contract, and may choose to implement ImportState.
func NewKibanaResource ¶
func NewKibanaResource[T KibanaResourceModel]( component Component, name string, schemaFactory func(context.Context) rschema.Schema, readFunc kibanaReadFunc[T], deleteFunc kibanaDeleteFunc[T], createFunc KibanaCreateFunc[T], updateFunc KibanaUpdateFunc[T], ) *KibanaResource[T]
NewKibanaResource returns an *KibanaResource that owns Schema, Create, Read, Update, and Delete. Concrete resources supply a schema factory (without kibana_connection block), read, delete, create, and update callbacks. All callbacks must be non-nil; otherwise Create or Update surface a configuration error diagnostic instead of invoking the callback.
func (*KibanaResource[T]) Create ¶
func (r *KibanaResource[T]) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse)
Create implements resource.Resource: decode plan, validate spaceID, resolve client, invoke the create callback, then persist the returned model.
func (*KibanaResource[T]) Delete ¶
func (r *KibanaResource[T]) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse)
Delete implements resource.Resource with the standard prelude, then delegates to the concrete deleteFunc.
func (*KibanaResource[T]) Read ¶
func (r *KibanaResource[T]) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse)
Read implements resource.Resource with the standard prelude: decode state, resolve identity via composite-ID-or-fallback, validate resourceID, resolve scoped Kibana client, then delegate to the concrete readFunc. When readFunc reports found==true, the returned model is persisted via resp.State.Set; when found==false, the resource is removed from state.
func (*KibanaResource[T]) Schema ¶
func (r *KibanaResource[T]) Schema(ctx context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse)
Schema implements resource.Resource, injecting the kibana_connection block into the schema returned by the concrete schema factory.
func (*KibanaResource[T]) Update ¶
func (r *KibanaResource[T]) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse)
Update implements resource.Resource: decode plan and prior state, resolve identity on the plan model, validate resourceID, resolve client, invoke the update callback, then persist the returned model.
type KibanaResourceModel ¶
type KibanaResourceModel interface {
GetID() types.String
// GetResourceID returns the plan-safe write identity (for example name or
// API-assigned UUID). Read, Update, and Delete use this when the state ID
// is not a composite.
GetResourceID() types.String
GetSpaceID() types.String
GetKibanaConnection() types.List
}
KibanaResourceModel is the type constraint for models passed to NewKibanaResource. Concrete types must provide value-receiver methods GetID, GetResourceID, GetSpaceID, and GetKibanaConnection.
type KibanaUnscopedSpace ¶ added in v0.15.2
type KibanaUnscopedSpace interface {
IsUnscopedSpace() bool
}
KibanaUnscopedSpace is implemented by KibanaResourceModel values whose Kibana API is not space-scoped. Only these models may use an empty space identifier on Create; others still require a non-empty, known space ID.
type KibanaUpdateFunc ¶
type KibanaUpdateFunc[T KibanaResourceModel] func( context.Context, *clients.KibanaScopedClient, string, string, T, T, ) (T, diag.Diagnostics)
KibanaUpdateFunc performs the update after the envelope decodes the plan and prior state, resolves the resource identity, resolves the scoped Kibana client, and passes both the plan and prior models. It returns the model to persist in state.
type MinVersionClient ¶ added in v0.15.2
type MinVersionClient interface {
EnforceMinVersion(ctx context.Context, minVersion *version.Version) (bool, diag.Diagnostics)
}
MinVersionClient is implemented by scoped API clients used by entity envelopes for minimum server version checks.
type PostReadFunc ¶ added in v0.15.2
type PostReadFunc[T ElasticsearchResourceModel] func( ctx context.Context, client *clients.ElasticsearchScopedClient, model T, privateState any, ) diag.Diagnostics
PostReadFunc runs after a successful read that persisted state, including read-after-write refresh. It is optional. The privateState argument is the framework response Private field (typically *internal/privatestate.ProviderData).
type ResourceBase ¶
type ResourceBase struct {
// contains filtered or unexported fields
}
ResourceBase holds shared Plugin Framework resource wiring: typed naming parts and the provider client factory from Configure. Embed *ResourceBase in concrete resources to reuse Configure, Metadata, and Client.
func NewResourceBase ¶
func NewResourceBase(component Component, resourceName string) *ResourceBase
NewResourceBase returns a ResourceBase for the given namespace segment and literal resource name suffix. resourceName is not normalized; see package documentation.
func (*ResourceBase) Client ¶
func (c *ResourceBase) Client() *clients.ProviderClientFactory
Client returns the client factory from the last successful ResourceBase.Configure assignment, or nil if none has been stored yet. A nil *ResourceBase (e.g. a partially constructed embed) returns nil so callers can surface diagnostics instead of panicking.
func (*ResourceBase) Configure ¶
func (c *ResourceBase) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse)
Configure implements resource.ResourceWithConfigure, converting provider data with clients.ConvertProviderDataToFactory and appending diagnostics. If the response has error diagnostics, it returns without assigning a new factory, leaving any prior successful client unchanged (same pattern as resources such as fleet integration and kibana agent builder tool).
func (*ResourceBase) Metadata ¶
func (c *ResourceBase) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse)
Metadata implements the Metadata method of resource.Resource, setting the Terraform type name to "<providerTypeName>_<component>_<resourceName>".
type VersionRequirement ¶ added in v0.15.2
type VersionRequirement struct {
// MinVersion is the minimum server version required.
MinVersion version.Version
// ErrorMessage is the human-readable detail added to the
// "Unsupported server version" diagnostic when the server does not
// satisfy MinVersion.
ErrorMessage string
}
VersionRequirement describes a minimum server version that an entity model requires before the envelope invokes the concrete lifecycle callback.
type WithReadResourceID ¶ added in v0.15.2
type WithReadResourceID interface {
GetReadResourceID() string
}
WithReadResourceID is an optional interface for models that need a stable read identity distinct from the composite state ID segment used as the default.
type WithVersionRequirements ¶
type WithVersionRequirements interface {
GetVersionRequirements() ([]VersionRequirement, diag.Diagnostics)
}
WithVersionRequirements is an optional interface that entity models may implement to declare server version requirements. When a decoded model satisfies this interface, Kibana and Elasticsearch envelopes evaluate the requirements after scoped client resolution and before invoking the concrete lifecycle callback.
type WriteFunc ¶ added in v0.15.2
type WriteFunc[T ElasticsearchResourceModel] func( context.Context, *clients.ElasticsearchScopedClient, WriteRequest[T], ) (WriteResult[T], diag.Diagnostics)
WriteFunc performs Create or Update after the envelope decodes the plan (and prior state for Update), validates the write identity, resolves the scoped Elasticsearch client, and evaluates optional version requirements. Inspect req.Prior == nil to detect Create when sharing a single function for both Create and Update.
func PlaceholderElasticsearchWriteCallback ¶ added in v0.15.2
func PlaceholderElasticsearchWriteCallback[T ElasticsearchResourceModel]() WriteFunc[T]
type WriteRequest ¶ added in v0.15.2
type WriteRequest[T ElasticsearchResourceModel] struct { Plan T Prior *T Config T WriteID string }
WriteRequest is passed to WriteFunc. Config is the Terraform configuration decoded into T by the envelope before the callback is invoked. Prior is non-nil only for Update; Create receives Prior == nil. The same WriteRequest type is shared by Create and Update so a single function can serve both when the logic does not differ.
type WriteResult ¶ added in v0.15.2
type WriteResult[T ElasticsearchResourceModel] struct { Model T }
WriteResult is returned by write callbacks; the envelope read-after-write flow uses Model when resolving refresh identity and calling readFunc.