github.com/terramate-io/tf@v0.0.0-20230830114523-fce866b4dfcd/legacy/terraform/resource_provider.go (about)

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