github.com/opentofu/opentofu@v1.7.1/internal/legacy/tofu/resource_provider.go (about)

     1  // Copyright (c) The OpenTofu Authors
     2  // SPDX-License-Identifier: MPL-2.0
     3  // Copyright (c) 2023 HashiCorp, Inc.
     4  // SPDX-License-Identifier: MPL-2.0
     5  
     6  package tofu
     7  
     8  // ResourceProvider is a legacy interface for providers.
     9  //
    10  // This is retained only for compatibility with legacy code. The current
    11  // interface for providers is providers.Interface, in the sibling directory
    12  // named "providers".
    13  type ResourceProvider interface {
    14  	/*********************************************************************
    15  	* Functions related to the provider
    16  	*********************************************************************/
    17  
    18  	// ProviderSchema returns the config schema for the main provider
    19  	// configuration, as would appear in a "provider" block in the
    20  	// configuration files.
    21  	//
    22  	// Currently not all providers support schema. Callers must therefore
    23  	// first call Resources and DataSources and ensure that at least one
    24  	// resource or data source has the SchemaAvailable flag set.
    25  	GetSchema(*ProviderSchemaRequest) (*ProviderSchema, error)
    26  
    27  	// Input was used prior to v0.12 to ask the provider to prompt the user
    28  	// for input to complete the configuration.
    29  	//
    30  	// From v0.12 onwards this method is never called because OpenTofu Core
    31  	// is able to handle the necessary input logic itself based on the
    32  	// schema returned from GetSchema.
    33  	Input(UIInput, *ResourceConfig) (*ResourceConfig, error)
    34  
    35  	// Validate is called once at the beginning with the raw configuration
    36  	// (no interpolation done) and can return a list of warnings and/or
    37  	// errors.
    38  	//
    39  	// This is called once with the provider configuration only. It may not
    40  	// be called at all if no provider configuration is given.
    41  	//
    42  	// This should not assume that any values of the configurations are valid.
    43  	// The primary use case of this call is to check that required keys are
    44  	// set.
    45  	Validate(*ResourceConfig) ([]string, []error)
    46  
    47  	// Configure configures the provider itself with the configuration
    48  	// given. This is useful for setting things like access keys.
    49  	//
    50  	// This won't be called at all if no provider configuration is given.
    51  	//
    52  	// Configure returns an error if it occurred.
    53  	Configure(*ResourceConfig) error
    54  
    55  	// Resources returns all the available resource types that this provider
    56  	// knows how to manage.
    57  	Resources() []ResourceType
    58  
    59  	// Stop is called when the provider should halt any in-flight actions.
    60  	//
    61  	// This can be used to make a nicer Ctrl-C experience for OpenTofu.
    62  	// Even if this isn't implemented to do anything (just returns nil),
    63  	// OpenTofu will still cleanly stop after the currently executing
    64  	// graph node is complete. However, this API can be used to make more
    65  	// efficient halts.
    66  	//
    67  	// Stop doesn't have to and shouldn't block waiting for in-flight actions
    68  	// to complete. It should take any action it wants and return immediately
    69  	// acknowledging it has received the stop request. OpenTofu core will
    70  	// automatically not make any further API calls to the provider soon
    71  	// after Stop is called (technically exactly once the currently executing
    72  	// graph nodes are complete).
    73  	//
    74  	// The error returned, if non-nil, is assumed to mean that signaling the
    75  	// stop somehow failed and that the user should expect potentially waiting
    76  	// a longer period of time.
    77  	Stop() error
    78  
    79  	/*********************************************************************
    80  	* Functions related to individual resources
    81  	*********************************************************************/
    82  
    83  	// ValidateResource is called once at the beginning with the raw
    84  	// configuration (no interpolation done) and can return a list of warnings
    85  	// and/or errors.
    86  	//
    87  	// This is called once per resource.
    88  	//
    89  	// This should not assume any of the values in the resource configuration
    90  	// are valid since it is possible they have to be interpolated still.
    91  	// The primary use case of this call is to check that the required keys
    92  	// are set and that the general structure is correct.
    93  	ValidateResource(string, *ResourceConfig) ([]string, []error)
    94  
    95  	// Apply applies a diff to a specific resource and returns the new
    96  	// resource state along with an error.
    97  	//
    98  	// If the resource state given has an empty ID, then a new resource
    99  	// is expected to be created.
   100  	Apply(
   101  		*InstanceInfo,
   102  		*InstanceState,
   103  		*InstanceDiff) (*InstanceState, error)
   104  
   105  	// Diff diffs a resource versus a desired state and returns
   106  	// a diff.
   107  	Diff(
   108  		*InstanceInfo,
   109  		*InstanceState,
   110  		*ResourceConfig) (*InstanceDiff, error)
   111  
   112  	// Refresh refreshes a resource and updates all of its attributes
   113  	// with the latest information.
   114  	Refresh(*InstanceInfo, *InstanceState) (*InstanceState, error)
   115  
   116  	/*********************************************************************
   117  	* Functions related to importing
   118  	*********************************************************************/
   119  
   120  	// ImportState requests that the given resource be imported.
   121  	//
   122  	// The returned InstanceState only requires ID be set. Importing
   123  	// will always call Refresh after the state to complete it.
   124  	//
   125  	// IMPORTANT: InstanceState doesn't have the resource type attached
   126  	// to it. A type must be specified on the state via the Ephemeral
   127  	// field on the state.
   128  	//
   129  	// This function can return multiple states. Normally, an import
   130  	// will map 1:1 to a physical resource. However, some resources map
   131  	// to multiple. For example, an AWS security group may contain many rules.
   132  	// Each rule is represented by a separate resource in OpenTofu,
   133  	// therefore multiple states are returned.
   134  	ImportState(*InstanceInfo, string) ([]*InstanceState, error)
   135  
   136  	/*********************************************************************
   137  	* Functions related to data resources
   138  	*********************************************************************/
   139  
   140  	// ValidateDataSource is called once at the beginning with the raw
   141  	// configuration (no interpolation done) and can return a list of warnings
   142  	// and/or errors.
   143  	//
   144  	// This is called once per data source instance.
   145  	//
   146  	// This should not assume any of the values in the resource configuration
   147  	// are valid since it is possible they have to be interpolated still.
   148  	// The primary use case of this call is to check that the required keys
   149  	// are set and that the general structure is correct.
   150  	ValidateDataSource(string, *ResourceConfig) ([]string, []error)
   151  
   152  	// DataSources returns all of the available data sources that this
   153  	// provider implements.
   154  	DataSources() []DataSource
   155  
   156  	// ReadDataDiff produces a diff that represents the state that will
   157  	// be produced when the given data source is read using a later call
   158  	// to ReadDataApply.
   159  	ReadDataDiff(*InstanceInfo, *ResourceConfig) (*InstanceDiff, error)
   160  
   161  	// ReadDataApply initializes a data instance using the configuration
   162  	// in a diff produced by ReadDataDiff.
   163  	ReadDataApply(*InstanceInfo, *InstanceDiff) (*InstanceState, error)
   164  }
   165  
   166  // ResourceProviderCloser is an interface that providers that can close
   167  // connections that aren't needed anymore must implement.
   168  type ResourceProviderCloser interface {
   169  	Close() error
   170  }
   171  
   172  // ResourceType is a type of resource that a resource provider can manage.
   173  type ResourceType struct {
   174  	Name       string // Name of the resource, example "instance" (no provider prefix)
   175  	Importable bool   // Whether this resource supports importing
   176  
   177  	// SchemaAvailable is set if the provider supports the ProviderSchema,
   178  	// ResourceTypeSchema and DataSourceSchema methods. Although it is
   179  	// included on each resource type, it's actually a provider-wide setting
   180  	// that's smuggled here only because that avoids a breaking change to
   181  	// the plugin protocol.
   182  	SchemaAvailable bool
   183  }
   184  
   185  // DataSource is a data source that a resource provider implements.
   186  type DataSource struct {
   187  	Name string
   188  
   189  	// SchemaAvailable is set if the provider supports the ProviderSchema,
   190  	// ResourceTypeSchema and DataSourceSchema methods. Although it is
   191  	// included on each resource type, it's actually a provider-wide setting
   192  	// that's smuggled here only because that avoids a breaking change to
   193  	// the plugin protocol.
   194  	SchemaAvailable bool
   195  }
   196  
   197  // ResourceProviderFactory is a function type that creates a new instance
   198  // of a resource provider.
   199  type ResourceProviderFactory func() (ResourceProvider, error)
   200  
   201  // ResourceProviderFactoryFixed is a helper that creates a
   202  // ResourceProviderFactory that just returns some fixed provider.
   203  func ResourceProviderFactoryFixed(p ResourceProvider) ResourceProviderFactory {
   204  	return func() (ResourceProvider, error) {
   205  		return p, nil
   206  	}
   207  }
   208  
   209  func ProviderHasResource(p ResourceProvider, n string) bool {
   210  	for _, rt := range p.Resources() {
   211  		if rt.Name == n {
   212  			return true
   213  		}
   214  	}
   215  
   216  	return false
   217  }
   218  
   219  func ProviderHasDataSource(p ResourceProvider, n string) bool {
   220  	for _, rt := range p.DataSources() {
   221  		if rt.Name == n {
   222  			return true
   223  		}
   224  	}
   225  
   226  	return false
   227  }
   228  
   229  const errPluginInit = `
   230  Plugin reinitialization required. Please run "tofu init".
   231  
   232  Plugins are external binaries that OpenTofu uses to access and manipulate
   233  resources. The configuration provided requires plugins which can't be located,
   234  don't satisfy the version constraints, or are otherwise incompatible.
   235  
   236  OpenTofu automatically discovers provider requirements from your
   237  configuration, including providers used in child modules. To see the
   238  requirements and constraints, run "tofu providers".
   239  
   240  %s
   241  `