From 3cedfa00f46532d25a3d62cee321343ed1d5757c Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Tue, 28 Feb 2017 10:58:29 -0800 Subject: [PATCH] command: use backend.CLIIinit I made this interface way back with the original backend work and I guess I forgot to hook it up! This is becoming an issue as I'm working on our 2nd enhanced backend that requires this information and I realized it was hardcoded before. This propertly uses the CLIInit interface allowing any backend to gain access to this data. --- backend/cli.go | 6 +++++- backend/local/backend.go | 1 + backend/local/backend_test.go | 1 + backend/local/cli.go | 23 ++++++++++++++++++++ command/meta_backend.go | 40 +++++++++++++++++++++++++---------- 5 files changed, 59 insertions(+), 12 deletions(-) create mode 100644 backend/local/cli.go diff --git a/backend/cli.go b/backend/cli.go index b23616629..39935d406 100644 --- a/backend/cli.go +++ b/backend/cli.go @@ -25,7 +25,11 @@ type CLI interface { // CLIIinit is called once with options. The options passed to this // function may not be modified after calling this since they can be // read/written at any time by the Backend implementation. - CLIIinit(*CLIOpts) error + // + // This may be called before or after Configure is called, so if settings + // here affect configurable settings, care should be taken to handle + // whether they should be overwritten or not. + CLIInit(*CLIOpts) error } // CLIOpts are the options passed into CLIInit for the CLI interface. diff --git a/backend/local/backend.go b/backend/local/backend.go index 62cd71e06..00704940c 100644 --- a/backend/local/backend.go +++ b/backend/local/backend.go @@ -207,6 +207,7 @@ func (b *Local) schemaConfigure(ctx context.Context) error { } b.StatePath = path + b.StateOutPath = path } return nil diff --git a/backend/local/backend_test.go b/backend/local/backend_test.go index 6fb7865b1..5f86125f8 100644 --- a/backend/local/backend_test.go +++ b/backend/local/backend_test.go @@ -12,6 +12,7 @@ import ( func TestLocal_impl(t *testing.T) { var _ backend.Enhanced = new(Local) var _ backend.Local = new(Local) + var _ backend.CLI = new(Local) } func checkState(t *testing.T, path, expected string) { diff --git a/backend/local/cli.go b/backend/local/cli.go new file mode 100644 index 000000000..d81d87d84 --- /dev/null +++ b/backend/local/cli.go @@ -0,0 +1,23 @@ +package local + +import ( + "github.com/hashicorp/terraform/backend" +) + +// backend.CLI impl. +func (b *Local) CLIInit(opts *backend.CLIOpts) error { + b.CLI = opts.CLI + b.CLIColor = opts.CLIColor + b.ContextOpts = opts.ContextOpts + b.OpInput = opts.Input + b.OpValidation = opts.Validation + + // Only configure state paths if we didn't do so via the configure func. + if b.StatePath == "" { + b.StatePath = opts.StatePath + b.StateOutPath = opts.StateOutPath + b.StateBackupPath = opts.StateBackupPath + } + + return nil +} diff --git a/command/meta_backend.go b/command/meta_backend.go index 894ba8efa..86d7aaf7b 100644 --- a/command/meta_backend.go +++ b/command/meta_backend.go @@ -110,6 +110,28 @@ func (m *Meta) Backend(opts *BackendOpts) (backend.Enhanced, error) { log.Printf("[INFO] command: backend initialized: %T", b) } + // Setup the CLI opts we pass into backends that support it + cliOpts := &backend.CLIOpts{ + CLI: m.Ui, + CLIColor: m.Colorize(), + StatePath: statePath, + StateOutPath: stateOutPath, + StateBackupPath: backupPath, + ContextOpts: m.contextOpts(), + Input: m.Input(), + Validation: true, + } + + // If the backend supports CLI initialization, do it. + if cli, ok := b.(backend.CLI); ok { + if err := cli.CLIInit(cliOpts); err != nil { + return nil, fmt.Errorf( + "Error initializing backend %T: %s\n\n"+ + "This is a bug, please report it to the backend developer", + b, err) + } + } + // If the result of loading the backend is an enhanced backend, // then return that as-is. This works even if b == nil (it will be !ok). if enhanced, ok := b.(backend.Enhanced); ok { @@ -125,17 +147,13 @@ func (m *Meta) Backend(opts *BackendOpts) (backend.Enhanced, error) { } // Build the local backend - return &backendlocal.Local{ - CLI: m.Ui, - CLIColor: m.Colorize(), - StatePath: statePath, - StateOutPath: stateOutPath, - StateBackupPath: backupPath, - ContextOpts: m.contextOpts(), - OpInput: m.Input(), - OpValidation: true, - Backend: b, - }, nil + local := &backendlocal.Local{Backend: b} + if err := local.CLIInit(cliOpts); err != nil { + // Local backend isn't allowed to fail. It would be a bug. + panic(err) + } + + return local, nil } // Operation initializes a new backend.Operation struct.