Bumps [github.com/hashicorp/terraform-plugin-sdk/v2](https://github.com/hashicorp/terraform-plugin-sdk) from 2.24.1 to 2.26.0. - [Release notes](https://github.com/hashicorp/terraform-plugin-sdk/releases) - [Changelog](https://github.com/hashicorp/terraform-plugin-sdk/blob/main/CHANGELOG.md) - [Commits](https://github.com/hashicorp/terraform-plugin-sdk/compare/v2.24.1...v2.26.0) --- updated-dependencies: - dependency-name: github.com/hashicorp/terraform-plugin-sdk/v2 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com>
225 lines
6.8 KiB
Go
225 lines
6.8 KiB
Go
package tfexec
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"io"
|
|
"io/ioutil"
|
|
"log"
|
|
"os"
|
|
"sync"
|
|
|
|
"github.com/hashicorp/go-version"
|
|
)
|
|
|
|
type printfer interface {
|
|
Printf(format string, v ...interface{})
|
|
}
|
|
|
|
// Terraform represents the Terraform CLI executable and working directory.
|
|
//
|
|
// Typically this is constructed against the root module of a Terraform configuration
|
|
// but you can override paths used in some commands depending on the available
|
|
// options.
|
|
//
|
|
// All functions that execute CLI commands take a context.Context. It should be noted that
|
|
// exec.Cmd.Run will not return context.DeadlineExceeded or context.Canceled by default, we
|
|
// have augmented our wrapped errors to respond true to errors.Is for context.DeadlineExceeded
|
|
// and context.Canceled if those are present on the context when the error is parsed. See
|
|
// https://github.com/golang/go/issues/21880 for more about the Go limitations.
|
|
//
|
|
// By default, the instance inherits the environment from the calling code (using os.Environ)
|
|
// but it ignores certain environment variables that are managed within the code and prohibits
|
|
// setting them through SetEnv:
|
|
//
|
|
// - TF_APPEND_USER_AGENT
|
|
// - TF_IN_AUTOMATION
|
|
// - TF_INPUT
|
|
// - TF_LOG
|
|
// - TF_LOG_PATH
|
|
// - TF_REATTACH_PROVIDERS
|
|
// - TF_DISABLE_PLUGIN_TLS
|
|
// - TF_SKIP_PROVIDER_VERIFY
|
|
type Terraform struct {
|
|
execPath string
|
|
workingDir string
|
|
appendUserAgent string
|
|
disablePluginTLS bool
|
|
skipProviderVerify bool
|
|
env map[string]string
|
|
|
|
stdout io.Writer
|
|
stderr io.Writer
|
|
logger printfer
|
|
|
|
// TF_LOG environment variable, defaults to TRACE if logPath is set.
|
|
log string
|
|
|
|
// TF_LOG_CORE environment variable
|
|
logCore string
|
|
|
|
// TF_LOG_PATH environment variable
|
|
logPath string
|
|
|
|
// TF_LOG_PROVIDER environment variable
|
|
logProvider string
|
|
|
|
versionLock sync.Mutex
|
|
execVersion *version.Version
|
|
provVersions map[string]*version.Version
|
|
}
|
|
|
|
// NewTerraform returns a Terraform struct with default values for all fields.
|
|
// If a blank execPath is supplied, NewTerraform will error.
|
|
// Use hc-install or output from os.LookPath to get a desirable execPath.
|
|
func NewTerraform(workingDir string, execPath string) (*Terraform, error) {
|
|
if workingDir == "" {
|
|
return nil, fmt.Errorf("Terraform cannot be initialised with empty workdir")
|
|
}
|
|
|
|
if _, err := os.Stat(workingDir); err != nil {
|
|
return nil, fmt.Errorf("error initialising Terraform with workdir %s: %s", workingDir, err)
|
|
}
|
|
|
|
if execPath == "" {
|
|
err := fmt.Errorf("NewTerraform: please supply the path to a Terraform executable using execPath, e.g. using the github.com/hashicorp/hc-install module.")
|
|
return nil, &ErrNoSuitableBinary{
|
|
err: err,
|
|
}
|
|
}
|
|
tf := Terraform{
|
|
execPath: execPath,
|
|
workingDir: workingDir,
|
|
env: nil, // explicit nil means copy os.Environ
|
|
logger: log.New(ioutil.Discard, "", 0),
|
|
}
|
|
|
|
return &tf, nil
|
|
}
|
|
|
|
// SetEnv allows you to override environment variables, this should not be used for any well known
|
|
// Terraform environment variables that are already covered in options. Pass nil to copy the values
|
|
// from os.Environ. Attempting to set environment variables that should be managed manually will
|
|
// result in ErrManualEnvVar being returned.
|
|
func (tf *Terraform) SetEnv(env map[string]string) error {
|
|
prohibited := ProhibitedEnv(env)
|
|
if len(prohibited) > 0 {
|
|
// just error on the first instance
|
|
return &ErrManualEnvVar{prohibited[0]}
|
|
}
|
|
|
|
tf.env = env
|
|
return nil
|
|
}
|
|
|
|
// SetLogger specifies a logger for tfexec to use.
|
|
func (tf *Terraform) SetLogger(logger printfer) {
|
|
tf.logger = logger
|
|
}
|
|
|
|
// SetStdout specifies a writer to stream stdout to for every command.
|
|
//
|
|
// This should be used for information or logging purposes only, not control
|
|
// flow. Any parsing necessary should be added as functionality to this package.
|
|
func (tf *Terraform) SetStdout(w io.Writer) {
|
|
tf.stdout = w
|
|
}
|
|
|
|
// SetStderr specifies a writer to stream stderr to for every command.
|
|
//
|
|
// This should be used for information or logging purposes only, not control
|
|
// flow. Any parsing necessary should be added as functionality to this package.
|
|
func (tf *Terraform) SetStderr(w io.Writer) {
|
|
tf.stderr = w
|
|
}
|
|
|
|
// SetLog sets the TF_LOG environment variable for Terraform CLI execution.
|
|
// This must be combined with a call to SetLogPath to take effect.
|
|
//
|
|
// This is only compatible with Terraform CLI 0.15.0 or later as setting the
|
|
// log level was unreliable in earlier versions. It will default to TRACE when
|
|
// SetLogPath is called on versions 0.14.11 and earlier, or if SetLogCore and
|
|
// SetLogProvider have not been called before SetLogPath on versions 0.15.0 and
|
|
// later.
|
|
func (tf *Terraform) SetLog(log string) error {
|
|
err := tf.compatible(context.Background(), tf0_15_0, nil)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
tf.log = log
|
|
return nil
|
|
}
|
|
|
|
// SetLogCore sets the TF_LOG_CORE environment variable for Terraform CLI
|
|
// execution. This must be combined with a call to SetLogPath to take effect.
|
|
//
|
|
// This is only compatible with Terraform CLI 0.15.0 or later.
|
|
func (tf *Terraform) SetLogCore(logCore string) error {
|
|
err := tf.compatible(context.Background(), tf0_15_0, nil)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
tf.logCore = logCore
|
|
return nil
|
|
}
|
|
|
|
// SetLogPath sets the TF_LOG_PATH environment variable for Terraform CLI
|
|
// execution.
|
|
func (tf *Terraform) SetLogPath(path string) error {
|
|
tf.logPath = path
|
|
// Prevent setting the log path without enabling logging
|
|
if tf.log == "" && tf.logCore == "" && tf.logProvider == "" {
|
|
tf.log = "TRACE"
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// SetLogProvider sets the TF_LOG_PROVIDER environment variable for Terraform
|
|
// CLI execution. This must be combined with a call to SetLogPath to take
|
|
// effect.
|
|
//
|
|
// This is only compatible with Terraform CLI 0.15.0 or later.
|
|
func (tf *Terraform) SetLogProvider(logProvider string) error {
|
|
err := tf.compatible(context.Background(), tf0_15_0, nil)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
tf.logProvider = logProvider
|
|
return nil
|
|
}
|
|
|
|
// SetAppendUserAgent sets the TF_APPEND_USER_AGENT environment variable for
|
|
// Terraform CLI execution.
|
|
func (tf *Terraform) SetAppendUserAgent(ua string) error {
|
|
tf.appendUserAgent = ua
|
|
return nil
|
|
}
|
|
|
|
// SetDisablePluginTLS sets the TF_DISABLE_PLUGIN_TLS environment variable for
|
|
// Terraform CLI execution.
|
|
func (tf *Terraform) SetDisablePluginTLS(disabled bool) error {
|
|
tf.disablePluginTLS = disabled
|
|
return nil
|
|
}
|
|
|
|
// SetSkipProviderVerify sets the TF_SKIP_PROVIDER_VERIFY environment variable
|
|
// for Terraform CLI execution. This is no longer used in 0.13.0 and greater.
|
|
func (tf *Terraform) SetSkipProviderVerify(skip bool) error {
|
|
err := tf.compatible(context.Background(), nil, tf0_13_0)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
tf.skipProviderVerify = skip
|
|
return nil
|
|
}
|
|
|
|
// WorkingDir returns the working directory for Terraform.
|
|
func (tf *Terraform) WorkingDir() string {
|
|
return tf.workingDir
|
|
}
|
|
|
|
// ExecPath returns the path to the Terraform executable.
|
|
func (tf *Terraform) ExecPath() string {
|
|
return tf.execPath
|
|
}
|