have Meta.Backend use a Config rather than loading

Instead of providing the a path in BackendOpts, provide a loaded
*config.Config instead. This reduces the number of places where
configuration is loaded.
This commit is contained in:
James Bardin 2017-05-01 17:47:53 -04:00 committed by Martin Atkins
parent d7d8ea9543
commit 718ede0636
17 changed files with 184 additions and 75 deletions

View File

@ -132,10 +132,15 @@ func (c *ApplyCommand) Run(args []string) int {
}
*/
var conf *config.Config
if mod != nil {
conf = mod.Config()
}
// Load the backend
b, err := c.Backend(&BackendOpts{
ConfigPath: configPath,
Plan: plan,
Config: conf,
Plan: plan,
})
if err != nil {
c.Ui.Error(fmt.Sprintf("Failed to load backend: %s", err))

View File

@ -6,6 +6,7 @@ import (
"strings"
"github.com/hashicorp/terraform/backend"
"github.com/hashicorp/terraform/config"
"github.com/hashicorp/terraform/helper/wrappedstreams"
"github.com/hashicorp/terraform/repl"
@ -43,8 +44,16 @@ func (c *ConsoleCommand) Run(args []string) int {
return 1
}
var conf *config.Config
if mod != nil {
conf = mod.Config()
}
// Load the backend
b, err := c.Backend(&BackendOpts{ConfigPath: configPath})
b, err := c.Backend(&BackendOpts{
Config: conf,
})
if err != nil {
c.Ui.Error(fmt.Sprintf("Failed to load backend: %s", err))
return 1

View File

@ -43,8 +43,17 @@ func (c *EnvDeleteCommand) Run(args []string) int {
return 1
}
cfg, err := c.Config(configPath)
if err != nil {
c.Ui.Error(fmt.Sprintf("Failed to load root config module: %s", err))
return 1
}
// Load the backend
b, err := c.Backend(&BackendOpts{ConfigPath: configPath})
b, err := c.Backend(&BackendOpts{
Config: cfg,
})
if err != nil {
c.Ui.Error(fmt.Sprintf("Failed to load backend: %s", err))
return 1

View File

@ -26,8 +26,17 @@ func (c *EnvListCommand) Run(args []string) int {
return 1
}
cfg, err := c.Config(configPath)
if err != nil {
c.Ui.Error(fmt.Sprintf("Failed to load root config module: %s", err))
return 1
}
// Load the backend
b, err := c.Backend(&BackendOpts{ConfigPath: configPath})
b, err := c.Backend(&BackendOpts{
Config: cfg,
})
if err != nil {
c.Ui.Error(fmt.Sprintf("Failed to load backend: %s", err))
return 1

View File

@ -46,8 +46,16 @@ func (c *EnvNewCommand) Run(args []string) int {
return 1
}
conf, err := c.Config(configPath)
if err != nil {
c.Ui.Error(fmt.Sprintf("Failed to load root config module: %s", err))
}
// Load the backend
b, err := c.Backend(&BackendOpts{ConfigPath: configPath})
b, err := c.Backend(&BackendOpts{
Config: conf,
})
if err != nil {
c.Ui.Error(fmt.Sprintf("Failed to load backend: %s", err))
return 1

View File

@ -31,8 +31,17 @@ func (c *EnvSelectCommand) Run(args []string) int {
return 1
}
conf, err := c.Config(configPath)
if err != nil {
c.Ui.Error(fmt.Sprintf("Failed to load root config module: %s", err))
return 1
}
// Load the backend
b, err := c.Backend(&BackendOpts{ConfigPath: configPath})
b, err := c.Backend(&BackendOpts{
Config: conf,
})
if err != nil {
c.Ui.Error(fmt.Sprintf("Failed to load backend: %s", err))
return 1

View File

@ -6,6 +6,7 @@ import (
"strings"
"github.com/hashicorp/terraform/backend"
"github.com/hashicorp/terraform/config"
"github.com/hashicorp/terraform/config/module"
"github.com/hashicorp/terraform/dag"
"github.com/hashicorp/terraform/terraform"
@ -62,10 +63,15 @@ func (c *GraphCommand) Run(args []string) int {
}
}
var conf *config.Config
if mod != nil {
conf = mod.Config()
}
// Load the backend
b, err := c.Backend(&BackendOpts{
ConfigPath: configPath,
Plan: plan,
Config: conf,
Plan: plan,
})
if err != nil {
c.Ui.Error(fmt.Sprintf("Failed to load backend: %s", err))

View File

@ -7,6 +7,7 @@ import (
"strings"
"github.com/hashicorp/terraform/backend"
"github.com/hashicorp/terraform/config"
"github.com/hashicorp/terraform/config/module"
"github.com/hashicorp/terraform/terraform"
)
@ -60,8 +61,15 @@ func (c *ImportCommand) Run(args []string) int {
}
}
var conf *config.Config
if mod != nil {
conf = mod.Config()
}
// Load the backend
b, err := c.Backend(&BackendOpts{ConfigPath: configPath})
b, err := c.Backend(&BackendOpts{
Config: conf,
})
if err != nil {
c.Ui.Error(fmt.Sprintf("Failed to load backend: %s", err))
return 1

View File

@ -106,11 +106,7 @@ func (c *InitCommand) Run(args []string) int {
// If we're performing a get or loading the backend, then we perform
// some extra tasks.
if flagGet || flagBackend {
// Load the configuration in this directory so that we can know
// if we have anything to get or any backend to configure. We do
// this to improve the UX. Practically, we could call the functions
// below without checking this to the same effect.
conf, err := config.LoadDir(path)
conf, err := c.Config(path)
if err != nil {
c.Ui.Error(fmt.Sprintf(
"Error loading configuration: %s", err))
@ -145,7 +141,7 @@ func (c *InitCommand) Run(args []string) int {
}
opts := &BackendOpts{
ConfigPath: path,
Config: conf,
ConfigExtra: flagConfigExtra,
Init: true,
}

View File

@ -9,11 +9,9 @@ import (
"fmt"
"io/ioutil"
"log"
"os"
"path/filepath"
"strings"
"github.com/hashicorp/errwrap"
"github.com/hashicorp/go-multierror"
"github.com/hashicorp/hcl"
"github.com/hashicorp/terraform/backend"
@ -29,9 +27,9 @@ import (
// BackendOpts are the options used to initialize a backend.Backend.
type BackendOpts struct {
// ConfigPath is a path to a file or directory containing the backend
// configuration (declaration).
ConfigPath string
// Module is the root module from which we will extract the terraform and
// backend configuration.
Config *config.Config
// ConfigFile is a path to a file that contains configuration that
// is merged directly into the backend configuration when loaded
@ -178,71 +176,34 @@ func (m *Meta) Operation() *backend.Operation {
// backendConfig returns the local configuration for the backend
func (m *Meta) backendConfig(opts *BackendOpts) (*config.Backend, error) {
// If no explicit path was given then it is okay for there to be
// no backend configuration found.
emptyOk := opts.ConfigPath == ""
// Determine the path to the configuration.
path := opts.ConfigPath
// If we had no path set, it is an error. We can't initialize unset
if path == "" {
path = "."
}
// Expand the path
if !filepath.IsAbs(path) {
var err error
path, err = filepath.Abs(path)
if opts.Config == nil {
// check if the config was missing, or just not required
conf, err := m.Config(".")
if err != nil {
return nil, fmt.Errorf(
"Error expanding path to backend config %q: %s", path, err)
return nil, err
}
}
log.Printf("[DEBUG] command: loading backend config file: %s", path)
// We first need to determine if we're loading a file or a directory.
fi, err := os.Stat(path)
if err != nil {
if os.IsNotExist(err) && emptyOk {
log.Printf(
"[INFO] command: backend config not found, returning nil: %s",
path)
if conf == nil {
log.Println("[INFO] command: no config, returning nil")
return nil, nil
}
return nil, err
log.Println("[WARNING] BackendOpts.Config not set, but config found")
opts.Config = conf
}
var f func(string) (*config.Config, error) = config.LoadFile
if fi.IsDir() {
f = config.LoadDir
}
// Load the configuration
c, err := f(path)
if err != nil {
// Check for the error where we have no config files and return nil
// as the configuration type.
if errwrap.ContainsType(err, new(config.ErrNoConfigsFound)) {
log.Printf(
"[INFO] command: backend config not found, returning nil: %s",
path)
return nil, nil
}
return nil, err
}
c := opts.Config
// If there is no Terraform configuration block, no backend config
if c.Terraform == nil {
log.Println("[INFO] command: empty terraform config, returning nil")
return nil, nil
}
// Get the configuration for the backend itself.
backend := c.Terraform.Backend
if backend == nil {
log.Println("[INFO] command: empty backend config, returning nil")
return nil, nil
}

View File

@ -2,7 +2,9 @@ package command
import (
"fmt"
"log"
"os"
"path/filepath"
"strconv"
"github.com/hashicorp/errwrap"
@ -51,6 +53,66 @@ func (m *Meta) Module(path string) (*module.Tree, error) {
return mod, nil
}
// Config loads the root config for the path specified. Path may be a directory
// or file. The absence of configuration is not an error and returns a nil Config.
func (m *Meta) Config(path string) (*config.Config, error) {
// If no explicit path was given then it is okay for there to be
// no backend configuration found.
emptyOk := path == ""
// If we had no path set, it is an error. We can't initialize unset
if path == "" {
path = "."
}
// Expand the path
if !filepath.IsAbs(path) {
var err error
path, err = filepath.Abs(path)
if err != nil {
return nil, fmt.Errorf(
"Error expanding path to backend config %q: %s", path, err)
}
}
log.Printf("[DEBUG] command: loading backend config file: %s", path)
// We first need to determine if we're loading a file or a directory.
fi, err := os.Stat(path)
if err != nil {
if os.IsNotExist(err) && emptyOk {
log.Printf(
"[INFO] command: backend config not found, returning nil: %s",
path)
return nil, nil
}
return nil, err
}
var f func(string) (*config.Config, error) = config.LoadFile
if fi.IsDir() {
f = config.LoadDir
}
// Load the configuration
c, err := f(path)
if err != nil {
// Check for the error where we have no config files and return nil
// as the configuration type.
if errwrap.ContainsType(err, new(config.ErrNoConfigsFound)) {
log.Printf(
"[INFO] command: backend config not found, returning nil: %s",
path)
return nil, nil
}
return nil, err
}
return c, nil
}
// Plan returns the plan for the given path.
//
// This only has an effect if the path itself looks like a plan.

View File

@ -6,6 +6,7 @@ import (
"strings"
"github.com/hashicorp/terraform/backend"
"github.com/hashicorp/terraform/config"
"github.com/hashicorp/terraform/config/module"
)
@ -68,10 +69,14 @@ func (c *PlanCommand) Run(args []string) int {
}
}
var conf *config.Config
if mod != nil {
conf = mod.Config()
}
// Load the backend
b, err := c.Backend(&BackendOpts{
ConfigPath: configPath,
Plan: plan,
Config: conf,
Plan: plan,
})
if err != nil {
c.Ui.Error(fmt.Sprintf("Failed to load backend: %s", err))

View File

@ -52,7 +52,9 @@ func (c *ProvidersCommand) Run(args []string) int {
}
// Load the backend
b, err := c.Backend(&BackendOpts{ConfigPath: configPath})
b, err := c.Backend(&BackendOpts{
Config: root.Config(),
})
if err != nil {
c.Ui.Error(fmt.Sprintf("Failed to load backend: %s", err))
return 1

View File

@ -11,6 +11,7 @@ import (
"github.com/hashicorp/atlas-go/archive"
"github.com/hashicorp/atlas-go/v1"
"github.com/hashicorp/terraform/backend"
"github.com/hashicorp/terraform/config"
"github.com/hashicorp/terraform/terraform"
)
@ -98,9 +99,14 @@ func (c *PushCommand) Run(args []string) int {
return 1
}
var conf *config.Config
if mod != nil {
conf = mod.Config()
}
// Load the backend
b, err := c.Backend(&BackendOpts{
ConfigPath: configPath,
Config: conf,
})
if err != nil {
c.Ui.Error(fmt.Sprintf("Failed to load backend: %s", err))

View File

@ -6,6 +6,7 @@ import (
"strings"
"github.com/hashicorp/terraform/backend"
"github.com/hashicorp/terraform/config"
"github.com/hashicorp/terraform/terraform"
)
@ -43,8 +44,15 @@ func (c *RefreshCommand) Run(args []string) int {
return 1
}
var conf *config.Config
if mod != nil {
conf = mod.Config()
}
// Load the backend
b, err := c.Backend(&BackendOpts{ConfigPath: configPath})
b, err := c.Backend(&BackendOpts{
Config: conf,
})
if err != nil {
c.Ui.Error(fmt.Sprintf("Failed to load backend: %s", err))
return 1

View File

@ -43,9 +43,15 @@ func (c *UnlockCommand) Run(args []string) int {
return 1
}
conf, err := c.Config(configPath)
if err != nil {
c.Ui.Error(fmt.Sprintf("Failed to load root config module: %s", err))
return 1
}
// Load the backend
b, err := c.Backend(&BackendOpts{
ConfigPath: configPath,
Config: conf,
})
if err != nil {
c.Ui.Error(fmt.Sprintf("Failed to load backend: %s", err))

0
plugin/getter/get.go Normal file
View File