// Copyright (c) The OpenTofu Authors // SPDX-License-Identifier: MPL-2.0 // Copyright (c) 2023 HashiCorp, Inc. // SPDX-License-Identifier: MPL-2.0 package providers import ( "github.com/zclconf/go-cty/cty" "github.com/opentofu/opentofu/internal/configs/configschema" "github.com/opentofu/opentofu/internal/states" "github.com/opentofu/opentofu/internal/tfdiags" ) // Unconfigured represents a provider plugin that has not yet been configured. It has // limited functionality that must not depend on ConfigureProvider having been called. type Unconfigured interface { // GetMetadata is not yet implemented or used at this time. It may // be used in the future to avoid loading a provider's full schema // for initial validation. This could result in some potential // memory savings. // GetSchema returns the complete schema for the provider. GetProviderSchema() GetProviderSchemaResponse // ValidateProviderConfig allows the provider to validate the configuration. // The ValidateProviderConfigResponse.PreparedConfig field is unused. The // final configuration is not stored in the state, and any modifications // that need to be made must be made during the Configure method call. ValidateProviderConfig(ValidateProviderConfigRequest) ValidateProviderConfigResponse // ValidateResourceConfig allows the provider to validate the resource // configuration values. ValidateResourceConfig(ValidateResourceConfigRequest) ValidateResourceConfigResponse // ValidateDataResourceConfig allows the provider to validate the data source // configuration values. ValidateDataResourceConfig(ValidateDataResourceConfigRequest) ValidateDataResourceConfigResponse // MoveResourceState requests that the given resource data be moved from one // type to another, potentially between providers as well. MoveResourceState(MoveResourceStateRequest) MoveResourceStateResponse // CallFunction requests that the given function is called and response returned. // There is a bit of a quirk in OpenTofu-land. We allow providers to supply // additional functions via GetFunctions() after configuration. Those functions // will only be available via CallFunction after ConfigureProvider is called. CallFunction(CallFunctionRequest) CallFunctionResponse // Configure configures and initialized the provider. ConfigureProvider(ConfigureProviderRequest) ConfigureProviderResponse // Close shuts down the plugin process if applicable. Close() error // Stop is called when the provider should halt any in-flight actions. // // Stop should not block waiting for in-flight actions to complete. It // should take any action it wants and return immediately acknowledging it // has received the stop request. OpenTofu will not make any further API // calls to the provider after Stop is called. // // The error returned, if non-nil, is assumed to mean that signaling the // stop somehow failed and that the user should expect potentially waiting // a longer period of time. Stop() error } // Configured represents a provider plugin that has been configured. It has additional // functionallity on top of the Unconfigured interface that depends on ConfigureProvider // having been called. type Configured interface { // A configured provider can do anything a unconfigured provider can. Unconfigured // UpgradeResourceState is called when the state loader encounters an // instance state whose schema version is less than the one reported by the // currently-used version of the corresponding provider, and the upgraded // result is used for any further processing. UpgradeResourceState(UpgradeResourceStateRequest) UpgradeResourceStateResponse // ReadResource refreshes a resource and returns its current state. ReadResource(ReadResourceRequest) ReadResourceResponse // PlanResourceChange takes the current state and proposed state of a // resource, and returns the planned final state. PlanResourceChange(PlanResourceChangeRequest) PlanResourceChangeResponse // ApplyResourceChange takes the planned state for a resource, which may // yet contain unknown computed values, and applies the changes returning // the final state. ApplyResourceChange(ApplyResourceChangeRequest) ApplyResourceChangeResponse // ImportResourceState requests that the given resource be imported. ImportResourceState(ImportResourceStateRequest) ImportResourceStateResponse // ReadDataSource returns the data source's current state. ReadDataSource(ReadDataSourceRequest) ReadDataSourceResponse // GetFunctions returns a full list of functions defined in this provider. It should be a super // set of the functions returned in GetProviderSchema() GetFunctions() GetFunctionsResponse } // Interface represents the set of methods required for a complete resource // provider plugin. Longer term, we could remove this interface in favor of it's // component parts (Unconfigured, Configured) for added safety and clarity. type Interface interface { Configured } // GetProviderSchemaResponse is the return type for GetProviderSchema, and // should only be used when handling a value for that method. The handling of // of schemas in any other context should always use ProviderSchema, so that // the in-memory representation can be more easily changed separately from the // RCP protocol. type GetProviderSchemaResponse struct { // Provider is the schema for the provider itself. Provider Schema // ProviderMeta is the schema for the provider's meta info in a module ProviderMeta Schema // ResourceTypes map the resource type name to that type's schema. ResourceTypes map[string]Schema // DataSources maps the data source name to that data source's schema. DataSources map[string]Schema // Diagnostics contains any warnings or errors from the method call. Diagnostics tfdiags.Diagnostics // ServerCapabilities lists optional features supported by the provider. ServerCapabilities ServerCapabilities // Functions lists all functions supported by this provider. Functions map[string]FunctionSpec } // Schema pairs a provider or resource schema with that schema's version. // This is used to be able to upgrade the schema in UpgradeResourceState. // // This describes the schema for a single object within a provider. Type // "Schemas" (plural) instead represents the overall collection of schemas // for everything within a particular provider. type Schema struct { Version int64 Block *configschema.Block } // ServerCapabilities allows providers to communicate extra information // regarding supported protocol features. This is used to indicate availability // of certain forward-compatible changes which may be optional in a major // protocol version, but cannot be tested for directly. type ServerCapabilities struct { // PlanDestroy signals that this provider expects to receive a // PlanResourceChange call for resources that are to be destroyed. PlanDestroy bool // The GetProviderSchemaOptional capability indicates that this // provider does not require calling GetProviderSchema to operate // normally, and the caller can used a cached copy of the provider's // schema. // In other words, the providers for which GetProviderSchemaOptional is false // require their schema to be read after EVERY instantiation to function normally. GetProviderSchemaOptional bool } type FunctionSpec struct { // List of parameters required to call the function Parameters []FunctionParameterSpec // Optional Spec for variadic parameters VariadicParameter *FunctionParameterSpec // Type which the function will return Return cty.Type // Human-readable shortened documentation for the function Summary string // Human-readable documentation for the function Description string // Formatting type of the Description field DescriptionFormat TextFormatting // Human-readable message present if the function is deprecated DeprecationMessage string } type FunctionParameterSpec struct { // Human-readable display name for the parameter Name string // Type constraint for the parameter Type cty.Type // Null values allowed for the parameter AllowNullValue bool // Unknown Values allowed for the parameter // Individual provider implementations may interpret this as a // check using IsWhollyKnown instead cty's default of IsKnown. // If the input is not wholly known, the result should be // cty.UnknownVal(spec.returnType) AllowUnknownValues bool // Human-readable documentation for the parameter Description string // Formatting type of the Description field DescriptionFormat TextFormatting } type TextFormatting string const TextFormattingPlain = TextFormatting("Plain") const TextFormattingMarkdown = TextFormatting("Markdown") type ValidateProviderConfigRequest struct { // Config is the raw configuration value for the provider. Config cty.Value } type ValidateProviderConfigResponse struct { // PreparedConfig is unused and will be removed with support for plugin protocol v5. PreparedConfig cty.Value // Diagnostics contains any warnings or errors from the method call. Diagnostics tfdiags.Diagnostics } type ValidateResourceConfigRequest struct { // TypeName is the name of the resource type to validate. TypeName string // Config is the configuration value to validate, which may contain unknown // values. Config cty.Value } type ValidateResourceConfigResponse struct { // Diagnostics contains any warnings or errors from the method call. Diagnostics tfdiags.Diagnostics } type ValidateDataResourceConfigRequest struct { // TypeName is the name of the data source type to validate. TypeName string // Config is the configuration value to validate, which may contain unknown // values. Config cty.Value } type ValidateDataResourceConfigResponse struct { // Diagnostics contains any warnings or errors from the method call. Diagnostics tfdiags.Diagnostics } type UpgradeResourceStateRequest struct { // TypeName is the name of the resource type being upgraded TypeName string // Version is version of the schema that created the current state. Version int64 // RawStateJSON and RawStateFlatmap contain the state that needs to be // upgraded to match the current schema version. Because the schema is // unknown, this contains only the raw data as stored in the state. // RawStateJSON is the current json state encoding. // RawStateFlatmap is the legacy flatmap encoding. // Only on of these fields may be set for the upgrade request. RawStateJSON []byte RawStateFlatmap map[string]string } type UpgradeResourceStateResponse struct { // UpgradedState is the newly upgraded resource state. UpgradedState cty.Value // Diagnostics contains any warnings or errors from the method call. Diagnostics tfdiags.Diagnostics } type ConfigureProviderRequest struct { // OpenTofu version is the version string from the running instance of // tofu. Providers can use TerraformVersion to verify compatibility, // and to store for informational purposes. TerraformVersion string // Config is the complete configuration value for the provider. Config cty.Value } type ConfigureProviderResponse struct { // Diagnostics contains any warnings or errors from the method call. Diagnostics tfdiags.Diagnostics } type ReadResourceRequest struct { // TypeName is the name of the resource type being read. TypeName string // PriorState contains the previously saved state value for this resource. PriorState cty.Value // Private is an opaque blob that will be stored in state along with the // resource. It is intended only for interpretation by the provider itself. Private []byte // ProviderMeta is the configuration for the provider_meta block for the // module and provider this resource belongs to. Its use is defined by // each provider, and it should not be used without coordination with // HashiCorp. It is considered experimental and subject to change. ProviderMeta cty.Value } type ReadResourceResponse struct { // NewState contains the current state of the resource. NewState cty.Value // Diagnostics contains any warnings or errors from the method call. Diagnostics tfdiags.Diagnostics // Private is an opaque blob that will be stored in state along with the // resource. It is intended only for interpretation by the provider itself. Private []byte } type PlanResourceChangeRequest struct { // TypeName is the name of the resource type to plan. TypeName string // PriorState is the previously saved state value for this resource. PriorState cty.Value // ProposedNewState is the expected state after the new configuration is // applied. This is created by directly applying the configuration to the // PriorState. The provider is then responsible for applying any further // changes required to create the proposed final state. ProposedNewState cty.Value // Config is the resource configuration, before being merged with the // PriorState. Any value not explicitly set in the configuration will be // null. Config is supplied for reference, but Provider implementations // should prefer the ProposedNewState in most circumstances. Config cty.Value // PriorPrivate is the previously saved private data returned from the // provider during the last apply. PriorPrivate []byte // ProviderMeta is the configuration for the provider_meta block for the // module and provider this resource belongs to. Its use is defined by // each provider, and it should not be used without coordination with // HashiCorp. It is considered experimental and subject to change. ProviderMeta cty.Value } type PlanResourceChangeResponse struct { // PlannedState is the expected state of the resource once the current // configuration is applied. PlannedState cty.Value // RequiresReplace is the list of the attributes that are requiring // resource replacement. RequiresReplace []cty.Path // PlannedPrivate is an opaque blob that is not interpreted by tofu // core. This will be saved and relayed back to the provider during // ApplyResourceChange. PlannedPrivate []byte // Diagnostics contains any warnings or errors from the method call. Diagnostics tfdiags.Diagnostics // LegacyTypeSystem is set only if the provider is using the legacy SDK // whose type system cannot be precisely mapped into the OpenTofu type // system. We use this to bypass certain consistency checks that would // otherwise fail due to this imprecise mapping. No other provider or SDK // implementation is permitted to set this. LegacyTypeSystem bool } type ApplyResourceChangeRequest struct { // TypeName is the name of the resource type being applied. TypeName string // PriorState is the current state of resource. PriorState cty.Value // Planned state is the state returned from PlanResourceChange, and should // represent the new state, minus any remaining computed attributes. PlannedState cty.Value // Config is the resource configuration, before being merged with the // PriorState. Any value not explicitly set in the configuration will be // null. Config is supplied for reference, but Provider implementations // should prefer the PlannedState in most circumstances. Config cty.Value // PlannedPrivate is the same value as returned by PlanResourceChange. PlannedPrivate []byte // ProviderMeta is the configuration for the provider_meta block for the // module and provider this resource belongs to. Its use is defined by // each provider, and it should not be used without coordination with // HashiCorp. It is considered experimental and subject to change. ProviderMeta cty.Value } type ApplyResourceChangeResponse struct { // NewState is the new complete state after applying the planned change. // In the event of an error, NewState should represent the most recent // known state of the resource, if it exists. NewState cty.Value // Private is an opaque blob that will be stored in state along with the // resource. It is intended only for interpretation by the provider itself. Private []byte // Diagnostics contains any warnings or errors from the method call. Diagnostics tfdiags.Diagnostics // LegacyTypeSystem is set only if the provider is using the legacy SDK // whose type system cannot be precisely mapped into the OpenTofu type // system. We use this to bypass certain consistency checks that would // otherwise fail due to this imprecise mapping. No other provider or SDK // implementation is permitted to set this. LegacyTypeSystem bool } type ImportResourceStateRequest struct { // TypeName is the name of the resource type to be imported. TypeName string // ID is a string with which the provider can identify the resource to be // imported. ID string } type ImportResourceStateResponse struct { // ImportedResources contains one or more state values related to the // imported resource. It is not required that these be complete, only that // there is enough identifying information for the provider to successfully // update the states in ReadResource. ImportedResources []ImportedResource // Diagnostics contains any warnings or errors from the method call. Diagnostics tfdiags.Diagnostics } // ImportedResource represents an object being imported into OpenTofu with the // help of a provider. An ImportedObject is a RemoteObject that has been read // by the provider's import handler but hasn't yet been committed to state. type ImportedResource struct { // TypeName is the name of the resource type associated with the // returned state. It's possible for providers to import multiple related // types with a single import request. TypeName string // State is the state of the remote object being imported. This may not be // complete, but must contain enough information to uniquely identify the // resource. State cty.Value // Private is an opaque blob that will be stored in state along with the // resource. It is intended only for interpretation by the provider itself. Private []byte } // AsInstanceObject converts the receiving ImportedObject into a // ResourceInstanceObject that has status ObjectReady. // // The returned object does not know its own resource type, so the caller must // retain the ResourceType value from the source object if this information is // needed. // // The returned object also has no dependency addresses, but the caller may // freely modify the direct fields of the returned object without affecting // the receiver. func (ir ImportedResource) AsInstanceObject() *states.ResourceInstanceObject { return &states.ResourceInstanceObject{ Status: states.ObjectReady, Value: ir.State, Private: ir.Private, } } type MoveResourceStateRequest struct { // The address of the provider the resource is being moved from. SourceProviderAddress string // The resource type that the resource is being moved from. SourceTypeName string // The schema version of the resource type that the resource is being // moved from. SourceSchemaVersion uint64 // The raw state of the resource being moved. Only the json field is // populated, as there should be no legacy providers using the flatmap // format that support newly introduced RPCs. SourceStateJSON []byte SourceStateFlatmap map[string]string // Unused // The private state of the resource being moved. SourcePrivate []byte // The resource type that the resource is being moved to. TargetTypeName string } type MoveResourceStateResponse struct { // The state of the resource after it has been moved. TargetState cty.Value // The private state of the resource after it has been moved. TargetPrivate []byte // Diagnostics contains any warnings or errors from the method call. Diagnostics tfdiags.Diagnostics } type ReadDataSourceRequest struct { // TypeName is the name of the data source type to Read. TypeName string // Config is the complete configuration for the requested data source. Config cty.Value // ProviderMeta is the configuration for the provider_meta block for the // module and provider this resource belongs to. Its use is defined by // each provider, and it should not be used without coordination with // HashiCorp. It is considered experimental and subject to change. ProviderMeta cty.Value } type ReadDataSourceResponse struct { // State is the current state of the requested data source. State cty.Value // Diagnostics contains any warnings or errors from the method call. Diagnostics tfdiags.Diagnostics } type GetFunctionsResponse struct { Functions map[string]FunctionSpec Diagnostics tfdiags.Diagnostics } type CallFunctionRequest struct { Name string Arguments []cty.Value } type CallFunctionResponse struct { Result cty.Value Error error } type CallFunctionArgumentError struct { Text string FunctionArgument int } func (err *CallFunctionArgumentError) Error() string { return err.Text }