diff --git a/backend/init/deprecate_test.go b/backend/init/deprecate_test.go new file mode 100644 index 000000000..3c968151f --- /dev/null +++ b/backend/init/deprecate_test.go @@ -0,0 +1,32 @@ +package init + +import ( + "testing" + + "github.com/hashicorp/terraform/backend/remote-state/inmem" + "github.com/hashicorp/terraform/terraform" +) + +func TestDeprecateBackend(t *testing.T) { + deprecateMessage := "deprecated backend" + deprecatedBackend := deprecateBackend( + inmem.New(), + deprecateMessage, + )() + + warns, errs := deprecatedBackend.Validate(&terraform.ResourceConfig{}) + if errs != nil { + for _, err := range errs { + t.Error(err) + } + t.Fatal("validation errors") + } + + if len(warns) != 1 { + t.Fatalf("expected 1 warning, got %q", warns) + } + + if warns[0] != deprecateMessage { + t.Fatalf("expected %q, got %q", deprecateMessage, warns[0]) + } +} diff --git a/backend/init/init.go b/backend/init/init.go index ddebee6c8..1b5bee9ef 100644 --- a/backend/init/init.go +++ b/backend/init/init.go @@ -6,6 +6,7 @@ import ( "sync" "github.com/hashicorp/terraform/backend" + "github.com/hashicorp/terraform/terraform" backendatlas "github.com/hashicorp/terraform/backend/atlas" backendlegacy "github.com/hashicorp/terraform/backend/legacy" @@ -76,3 +77,41 @@ func Set(name string, f func() backend.Backend) { backends[name] = f } + +// deprecatedBackendShim is used to wrap a backend and inject a deprecation +// warning into the Validate method. +type deprecatedBackendShim struct { + backend.Backend + Message string +} + +// Validate the Backend then add the deprecation warning. +func (b deprecatedBackendShim) Validate(c *terraform.ResourceConfig) ([]string, []error) { + warns, errs := b.Backend.Validate(c) + warns = append(warns, b.Message) + return warns, errs +} + +// DeprecateBackend can be used to wrap a backend to retrun a deprecation +// warning during validation. +func deprecateBackend(b backend.Backend, message string) func() backend.Backend { + // Since a Backend wrapped by deprecatedBackendShim can no longer be + // asserted as an Enhanced or Local backend, disallow those types here + // entirely. If something other than a basic backend.Backend needs to be + // deprecated, we can add that functionality to schema.Backend or the + // backend itself. + if _, ok := b.(backend.Enhanced); ok { + panic("cannot use DeprecateBackend on an Enhanced Backend") + } + + if _, ok := b.(backend.Local); ok { + panic("cannot use DeprecateBackend on a Local Backend") + } + + return func() backend.Backend { + return deprecatedBackendShim{ + Backend: b, + Message: message, + } + } +}