* test: Update `testInputMap` and `(*UIInput) Input` to allow making assertions about what prompts a user has been shown. Make cleanup happen inside the helper.
* test: Update test to assert about prompt contents, showing how changes to `testInputMap` can be used
* docs: update godoc for testInputMap
* refactor: Check that the state storage provider is present when beginning to initialise a state store for use in a non-init command. Ensure reattached providers can be used.
Previously we passed all required providers into backend options to be used within `stateStoreConfig`, which is invoked via (Meta).Backend. The new approach enforces that the provider is present while assembling the backend options passed to (Meta).Backend from (Meta).backend, which is non-init specific. As this code is defending against users running non-init commands before an init, this place feels appropriate and isn't able to impact the init command.
* fix: Reattached PSS providers should return early when checking locks, and an empty locks file is only bad if there isn't a reattached PSS provider
* test: Assert that running init with reattached PSS provider is ok, via an E2E test that uses the reattach feature.
* fix: Allow builtin or reattached providers to be used for state stores when generating a plan file
* test: Expand E2E test to show using a reattached provider can be used for a workflow of init, plan with -out, and apply.
* chore: Replace 'io/ioutil' and format code in unmanaged e2e tests
* backend/inmem: Make it easier to use the backend in tests
* cloud: Make the cloud backend testable
* command/views: Introduce migration UI messages
* command/init: Add 3 tests for migrations from a backend to PSS
- TestInit_backend_to_stateStore_singleWorkspace
- TestInit_backend_to_stateStore_multipleWorkspaces
- TestInit_cloud_to_stateStore
* command/init: Implement migration from a backend to PSS
* address PR feedback
* remove local state after migration
* fix: Fail apply command if the plan file was generated for a workspace that isn't the selected workspace.
* Add change file
* test: Update test helper to include Workspace name in plan representation
* fix: Make error message more generic, so is applicable to backend and cloud blocks.
* fix: Make error message specific to backend or cloud block
* test: Add separate tests for backend/cloud usage
* test: Update remaining tests to include a value for Workspace in mocked plans
* Apply suggestions from code review
Co-authored-by: Radek Simko <radeksimko@users.noreply.github.com>
* fix: Panic when a plan file has missing workspace data
* test: Update test to match changes in error text
---------
Co-authored-by: Radek Simko <radeksimko@users.noreply.github.com>
* feat: Allow reading state store configuration from a planfile and using it to prepare a Local backend that uses the state store
* test: Assert that we can get and use state store configuration from a plan file
* test: Add integration test showing that an apply command can use a plan file to configure and use a state store
* test: Add E2E test showing pluggable state storage being used with the full init-plan-apply workflow
* feat: A plan file will report the state storage provider among its required providers, if PSS is in use.
See the code comment added in this commit. This addition does not impact an apply command as the missing provider will be detected before this code is executed. However I'm making this change so that the method is still accurate is being able to return a complete list of providers needed by the plan.
* fix: Include error messages when there is a problem parsing provider or state store config when getting a backend from a planfile
* feat: Add trace logs to BackendForLocalPlan indicating when the provider is launched and the state store is configured
* chore: Small grammar change in error diagnostic
* refactor: Remove suggestions when the plan's state store doesn't match the implementations in the provider
* test: Add test coverage of what happens when the contents of a plan file using PSS doesn't match the resources available in the project
* command/meta: Enable migration from PSS to a backend
* Address PR feedback
* Update internal/command/meta_backend.go
Co-authored-by: Sarah French <15078782+SarahFrench@users.noreply.github.com>
* meta_backend: Rename stateStore_c_S to stateStore_to_backend
---------
Co-authored-by: Sarah French <15078782+SarahFrench@users.noreply.github.com>
* Add a generic method for loading an operations backend in non-init commands
* Refactor commands to use new prepareBackend method: group 1
* Refactor commands to use new prepareBackend method: group 2, where config parsing needs to be explicitly added
* Refactor commands to use new prepareBackend method: group 3, where we can use already parsed config
* Additional, more nested, places where logic for accessing backends needs to be refactored
* Remove duplicated comment
* Add test coverage of `(m *Meta) prepareBackend()`
* Add TODO related to using plans for backend/state_store config in apply commands
* Add `testStateStoreMockWithChunkNegotiation` test helper
* Add assertions to tests about the backend (remote-state, local, etc) in use within operations backend
* Stop prepareBackend taking locks as argument
* Code comment in prepareBackend
* Replace c.Meta.prepareBackend with c.prepareBackend
* Change `c.Meta.loadSingleModule` to `c.loadSingleModule`
* Rename (Meta).prepareBackend to (Meta).backend, update godoc comment to make relationship to (Meta).Backend more obvious.
* Revert change from config.Module to config.Root.Module
* Update `(m *Meta) backend` method to parse config itself, and also to adhere to calling code's viewtype instructions
* Update all tests and calling code following previous commit
* Change how an operations backend is obtained by autocomplete code
* Update autocomplete to return nil if no workspace names are returned from the backend
* Add test coverage for autocompleting workspace names when using a pluggable state store
* Fix output command: pass view type data to new `backend` method
* Fix in plan command: pass correct view type to `backend` method
* Fix `providers schema` command to use correct viewtype when preparing a backend
* Pull determining of PSS provider's version from current locks into a separate method
* Add code for identifying when config and provider version match existing backend state (i.e. no changes)
* Update test - locks are now needed before it hits expected error diag return
* Add test showing successful init when no config changes are detected.
* Update `getStateStorageProviderVersion` to return nil versions for builtin and re-attached providers.
This makes comparison easier when determining if config has changed since last init.
* Add test coverage for `getStateStorageProviderVersion`
* Move testing fixtures around, preparing for different types of changed state_store config changes being tested
* Add test showing that changing the state_store config is detected as a change, but handling this scenario isn't implemented yet
* Update hashes in test fixture backend state file to be accurate
Previously dummy values were fine, but as tests using hashes to identify changes these values need to be accurate!
* Update existing test cases so that Terraform uses the same test provider version as described in the backend state file fixture for the test.
* Add test showing that changing the PSS provider's config is detected as a change, but handling this scenario isn't implemented yet
* Add test showing that swapping to a different state storage implementation in the same provider is detected as a change, but handling this scenario isn't implemented yet
* Add test showing that changing the provider used for PSS is detected as a change, but handling this scenario isn't implemented yet
* Add test showing that upgrading a provider is detected as a change, but handling this scenario isn't implemented yet
* Update test to use v1.2.3 for consistency with other tests
Just to avoid any confusion if copy-pasting happens in future.
* More corrections to existing test fixtures - unset config should be null, and replace dummy hash values with correct values.
* Fix test for using -reconfigure with state_store; the default workspace would already exist in this scenario
* Update TestInit_stateStore_configUnchanged to assert that init was a no-op for backend state
* Remove unused fixture
* Remove test that's replaced by new tests in command/init_test.go
* Replace old references to deleted "state-store-changed" test fixture & update test to not expect a value for region attr in provider config
* Make test fixture coupling a little more understandable
* Refactor detection of no need to migrate into a function
* Add TODO about more involved provider version change tests
We will allow downgrades to succeed as long as the schema version number is unchanged
* Update (configs.StateStore)Hash method to return a single hash that's impacted by: state store config, provider config, state store type, provider source
* Update calling code and test helper code to reflect that the nested provider block no longer has its own hash
* Remove test; there is now a single hash that SHOULD be affected by the provider block!
* Also use provider name, from config, in hash
* Update tests to reflect changes in how hashes are made
* Remove unused `stateStoreConfigNeedsMigration` function
* Remove duplicate isProviderReattached function.
* Fixes to affected tests
* Allow provider version to impact the state storage hash, update impacted tests and test fixtures
* Update tests that now require locks data to be present in test setup
* Update comment for accuracy
* Fixes to other test fixtures - remove excess hash field, set hash to 0 to indicate they're not set accurately.
* Make upgrade test actually use upgrade code path
* Add lock files to test fixture directories that represent a project that's had a successful prior init using PSS
* Minor fixes in diagnostics
This can only be done once modules have been parsed and the required providers data is available. There are multiple places where config is parsed, into either Config or Module structs, so this needs to be implemented in multiple places.
* Rename test to make it specific to use of backend block in config
* Update initBackend to accept whole initArgs collection
* Only process --backend-config data, when setting up a `backend`, if that data isn't empty
* Simplify how mock provider factories are made in tests
* Update mock provider's default logic to track and manage existing workspaces
* Add `ProviderSchema` method to `Pluggable` structs. This allows calling code to access the provider schema when using provider configuration data.
* Add function for converting a providerreqs.Version to a hashicorp/go-version Version.
This is needed for using locks when creating the backend state file.
* Implement initial version of init new working directories using `stateStore_C_s`. Default to creating the default workspace if no workspaces exist.
* Update test fixtures to match the hashicorp/test mock provider used in PSS tests
* Allow tests to obtain locks that include `testingOverrides` providers.
The `testingOverrides` field will only be set in tests, so this should not impact end users.
* Add tests showing TF can initialize a working directory for the first time (and do the same when forced by -reconfigure flag). Remove replaced tests.
* Add -create-default-workspace flag, to be used to disable creating the default workspace by default when -input=false (i.e for use in CI). Refactor creation of default workspace logic. Add tests.
* Allow reattached providers to be used during init for PSS
* Rename variable to `backendHash` so relation to `backend` is clearer
* Allow `(m *Meta) Backend` to return warning diagnostics
* Protect against nil testingOverrides in providerFactoriesFromLocks
* Add test case seeing what happens if default workspace selected, doesn't exist, but other workspaces do exist.
The consequences here are due to using `selectWorkspace` in `stateStore_C_s`, matching what's done in `backend_C_r_s`.
* Address code consistency check failure on PR
* Refactor use of mock in test that's experiencing EOF error...
* Remove test that requires test to supply input for user prompt
This test passes when run in isolation but fails when run alongside other tests, even when skipping all other tests using `testStdinPipe`. I don't think the value of this test is great enough to start changing how we test stdin input.
* Allow -create-default-workspace to be used regardless of whether input is enabled or disabled
* Add TF_SKIP_CREATE_DEFAULT_WORKSPACE environment variable
* Responses to feedback, including making testStdinPipe helper log details of errors copying data to stdin.
Note: We cannot call t.Fatal from a non-test goroutine.
* Use Errorf instead
* Allow backend state files to not include version data when a builtin or reattached provider is in use.
* Add clarifying comment about re-attached providers when finding the matching entry in required_providers
* Report that the default workspace was created to the view
* Refactor: use error comparison via `errors.Is` to identify when no workspaces exist.
* Move handling of TF_ENABLE_PLUGGABLE_STATE_STORAGE into init's ParseInit func.
* Validate that PSS-related flags can only be used when experiments are enabled, enforce coupling of PSS-related flags when in use.
* Slight rewording of output message about default workspace
* Update test to assert new output about default workspace
* Add SetStateStoreChunkSize to the mock provider for tests
* Implement configurable state chunk size
* Add chunk size negotiation to `savedStateStore`, update happy path test to assert it's set
* Update `savedStateStore` to return diagnostic if a nil factory is passed in, add unhappy path tests
* Add test coverage for stateStoreConfig, including use of config overrides with state stores
* Add godoc comment for backendInitFromConfig
* Avoid nil error in stateStoreConfig when there's no provider factory
* Add stateStoreInitFromConfig method and test coverage
* Refactor stateStoreInitFromConfig to accept factory directly, instead of accepting all BackendOpts
This is to avoid confusion, e.g. unnecessary duplication of config being passed in.
* Implement configurable state chunk size
* Remove TODO which has since been addressed
* Update happy path test for `stateStoreInitFromConfig` to check that chunk size is negotiated
* Update chunk size negotiation code in `stateStoreInitFromConfig` to error if the provider doesn't return a chunk size > 0
* Fix test error message
---------
Co-authored-by: Radek Simko <radek.simko@gmail.com>
* Add SetStateStoreChunkSize to the mock provider for tests
* Implement configurable state chunk size
* Add chunk size negotiation to `savedStateStore`, update happy path test to assert it's set
* Update `savedStateStore` to return diagnostic if a nil factory is passed in, add unhappy path tests
* Fix test error message
* Apply suggestions from code review
Co-authored-by: Radek Simko <radeksimko@users.noreply.github.com>
* Fix rename
---------
Co-authored-by: Radek Simko <radek.simko@gmail.com>
Co-authored-by: Radek Simko <radeksimko@users.noreply.github.com>
* Add test coverage for Meta's `savedBackend` method
* Add new Meta `savedStateStore` method and test coverage
* Streamline test - remove unneeded assertions and update comments
* Remove marks from config before configuring the provider
* Remove marks from config before configuring the state store
* Add test case for savedStateStore to assert marks aren't passed
* Fix call to ConfigureStateStore
* Show that tests pass despite not trying to remove marks
* Allow Config methods to add marks when reading pluggable state store config from the backend state file
* This code is now necessary to let the tests pass
* Stop adding marks to PSS-related config when it's parsed from the backend state file
* Stop removing marks that aren't there
* Remove unnecessary test related to marks
* Add method to allow accessing factories from locks that are in memory
* Create new getStateStoreProviderFactory method for accessing a factory from config
* Update getStateStoreProviderFactory to use in memory locks instead of reading them from the deps lock file. Update calling code to accommodate this.
* Add tests for getStateStoreProviderFactory, improve errors returned from method
* Update test following schema change in simple providers
* Move test case into e2etest package, so we protect against environments where building binaries isn't possible
* Fix issues with running test in e2etest package
* Update code comments
Co-authored-by: Radek Simko <radeksimko@users.noreply.github.com>
---------
Co-authored-by: Radek Simko <radeksimko@users.noreply.github.com>
* Fix S3 backend test affected by making the Workspaces method return errors via diagnostics
* Address diagnostics comparison issues in test by ensuring expected diagnostics are defined in the context of the config they're triggered by
* Fix failing test case `TestBackendConfig_EC2MetadataEndpoint/envvar_invalid_mode` by making `diagnosticBase` struct comparable
* Add compile-time checks that diagnostic types fulfil interfaces
* Stop diagnosticBase implementing ComparableDiagnostic, re-add S3-specific comparer code to s3 package
* Update tests to use the S3-specific comparer again
* Fix test case missed in refactoring
* Update the backend.Backend interface to use diagnostics as return value from StateMgr method
* Fix calls to `Fatalf`
* Add a helper for mocking a provider with a state store
* Update tests to use the new helper
* Update other test fixtures for consistency
The related tests pass before and after this change
* Update testing helper to return the underlying type, not the interface
* Update Backend interface to use diagnostics for `DeleteWorkspace` and `Workspaces` methods
* Update testing helpers in backend package
* Update pluggable package to match interface changes
* Update builtin terraform provider package to match interface changes
* Update code in Meta-related files in command package; update error check logic
* Update workspace commands; update error check logic
* Update Local backend package to match interface changes
* Update Cloud backend to match interface changes
* Update Remote backend to match interface changes
* Update cos remote-state backend to match interface changes
* Update inmem remote-state backend to match interface changes
* Update pg remote-state backend to match interface changes
* Update http remote-state backend to match interface changes
* Update consul remote-state backend to match interface changes
* Update oss remote-state backend to match interface changes
* Update kubernetes remote-state backend to match interface changes
* Update gcs remote-state backend to match interface changes
* Update s3 remote-state backend to match interface changes
* Update oci remote-state backend to match interface changes
* Update azure remote-state backend to match interface changes
* Allow warnings from Workspaces and DeleteWorkspace methods to be logged or returned to calling code
* Fix defect in inmem backend test
* Change how warnings from workspace-related methods are output to view/ui
* Store the FQN of the provider used in PSS in representations of the parsed config.
This can only be done once modules have been parsed and the required providers data is available. There are multiple places where config is parsed, into either Config or Module structs, so this needs to be implemented in multiple places.
* Update affected tests, improve error diagnostic
* Begin enabling method to return a backend.Backend made using state_store config.
State store config can now be received via BackendOpts and there is rough validation of whether the config makes sense (does the provider offer a store with the given name?).
* Update code's logic to include possibility of a state store being in use
At this point there are no cases that actually handle the state store scenarios though!
* Add empty cases for handle all broad init scenarios involving PSS
* Update default case's error to report state store variables
* Improve how we resolve the builtin terraform provider's address
* Add test that hits the code path for adding a state store to a new (or implied local) project
* Add test for use of `-reconfigure` flag; show that it hits the code path for adding a state store for the first time
* Add test that hits the code path for removing use of a state store, migrating to (implied) local backend
* Add test that hits the code path for changing a state store's configuration
* Update existing test names to be backend-specific
* Add tests that hits the code path for migrating between PSS and backends
* Consolidate PSS-related tests at end of the file
* Fix log text
* Add test showing that using variables is disallowed with state_store and nested provider blocks
* Update test name
* Fix test cases
* Add TODOs so we remember to remove experiments from tests
* Update state store-related tests to use t.Cleanup
* Remove use of `testChdir`
* Replace use of `testChdir` with `t.Chdir`
* Update tests to use temporary directories with copied content, instead of using directories in the repo directly.
* Remove stacks copy of testChdir function
This has been replaced with t.Chdir from the standard library
* Replace remaining simple usage of testChdir
* Update guidance for using `tempWorkingDir`
* Replace use of testChdir in a function reused in a single test
* Update comments to no longer recommend using testChdir
* Remove testChdir function!
* Add test coverage for Meta's determineInitReason method, fix error in diagnostic when migrating away from HCP Terraform
* Add godoc comment to determineInitReason method
For a very long time we've had an annoying discrepancy between the
in-memory state model and our state snapshot format where the in-memory
format stores output values for all modules whereas the snapshot format
only tracks the root module output values because those are all we
actually need to preserve between runs.
That design wart was a result of us using the state both as an internal
and an external artifact, due to having nowhere else to store the
transient values of non-root module output values while Terraform Core
does its work.
We now have namedvals.State to internally track all of the throwaway
results from named values that don't need to persist between runs, so now
we'll use that for our internal work instead and reserve the states.State
model only for the data that we will preserve between runs in state
snapshots.
The namedvals internal model isn't really designed to support enumerating
all of the output values for a particular module call, but our expression
evaluator currently depends on being able to do that and so we have a
temporary inefficient implementation of that which just scans the entire
table of values as a stopgap just to avoid this commit growing even larger
than it already is. In a future commit we'll rework the evaluator to
support the PartialEval mode and at the same time move the responsiblity
for enumerating all of the output values into the evaluator itself, since
it should be able to determine what it's expecting by analyzing the
configuration rather than just by trusting that earlier evaluation has
completed correctly.
Because our legacy state string serialization previously included output
values for all modules, some of our context tests were accidentally
depending on the implementation detail of how those got stored internally.
Those tests are updated here to test only the data that is a real part
of Terraform Core's result, by ensuring that the relevant data appears
somewhere either in a root output value or in a resource attribute.
It displays a run header with link to web UI, like starting a new plan does, then confirms the run
and streams the apply logs. If you can't apply the run (it's from a different workspace, is in an
unconfirmable state, etc. etc.), it displays an error instead.
Notable points along the way:
* Implement `WrappedPlanFile` sum type, and update planfile consumers to use it instead of a plain `planfile.Reader`.
* Enable applying a saved cloud plan
* Update TFC mocks — add org name to workspace, and minimal support for includes on MockRuns.ReadWithOptions.
Several times over the years we've considered adding tracing
instrumentation to Terraform, since even when running in isolation as a
CLI program it has a "distributed system-like" structure, with lots of
concurrent internal work and also some work delegated to provider plugins
that are essentially temporarily-running microservices.
However, it's always felt a bit overwhelming to do it because much of
Terraform predates the Go context.Context idiom and so it's tough to get
a clean chain of context.Context values all the way down the stack without
disturbing a lot of existing APIs.
This commit aims to just get that process started by establishing how a
context can propagate from "package main" into the command package,
focusing initially on "terraform init" and some other commands that share
some underlying functions with that command.
OpenTelemetry has emerged as a de-facto industry standard and so this uses
its API directly, without any attempt to hide it behind an abstraction.
The OpenTelemetry API is itself already an adapter layer, so we should be
able to swap in any backend that uses comparable concepts. For now we just
discard the tracing reports by default, and allow users to opt in to
delivering traces over OTLP by setting an environment variable when
running Terraform (the environment variable was established in an earlier
commit, so this commit builds on that.)
When tracing collection is enabled, every Terraform CLI run will generate
at least one overall span representing the command that was run. Some
commands might also create child spans, but most currently do not.
This commit replaces `ioutil.TempDir` with `t.TempDir` in tests. The
directory created by `t.TempDir` is automatically removed when the test
and all its subtests complete.
Prior to this commit, temporary directory created using `ioutil.TempDir`
needs to be removed manually by calling `os.RemoveAll`, which is omitted
in some tests. The error handling boilerplate e.g.
defer func() {
if err := os.RemoveAll(dir); err != nil {
t.Fatal(err)
}
}
is also tedious, but `t.TempDir` handles this for us nicely.
Reference: https://pkg.go.dev/testing#T.TempDir
Signed-off-by: Eng Zer Jun <engzerjun@gmail.com>
When running `terraform init` against a backend with multiple
workspaces, none of which are the currently indicated local workspace,
Terraform prompts the user to choose a workspace from the list. In
automation, using the `-input=false` argument should disable asking for
input, but previously would hang instead.
When initializing a backend, if the currently selected workspace does
not exist, the user is prompted to select from the list of workspaces
the backend provides.
Instead, we should automatically select the only workspace available
_if_ that's all that's there.
Although with being a nice bit of polish, this enables future
improvments with Terraform Cloud in potentially removing the implicit
depenency on always using the 'default' workspace when the current
configuration is mapped to a single TFC workspace.
Thus far our various interactions with the bits of state we keep
associated with a working directory have all been implemented directly
inside the "command" package -- often in the huge command.Meta type -- and
not managed collectively via a single component.
There's too many little codepaths reading and writing from the working
directory and data directory to refactor it all in one step, but this is
an attempt at a first step towards a future where everything that reads
and writes from the current working directory would do so via an object
that encapsulates the implementation details and offers a high-level API
to read and write all of these session-persistent settings.
The design here continues our gradual path towards using a dependency
injection style where "package main" is solely responsible for directly
interacting with the OS command line, the OS environment, the OS working
directory, the stdio streams, and the CLI configuration, and then
communicating the resulting information to the rest of Terraform by wiring
together objects. It seems likely that eventually we'll have enough wiring
code in package main to justify a more explicit organization of that code,
but for this commit the new "workdir.Dir" object is just wired directly in
place of its predecessors, without any significant change of code
organization at that top layer.
This first commit focuses on the main files and directories we use to
find provider plugins, because a subsequent commit will lightly reorganize
the separation of concerns for plugin launching with a similar goal of
collecting all of the relevant logic together into one spot.
This is part of a general effort to move all of Terraform's non-library
package surface under internal in order to reinforce that these are for
internal use within Terraform only.
If you were previously importing packages under this prefix into an
external codebase, you could pin to an earlier release tag as an interim
solution until you've make a plan to achieve the same functionality some
other way.
This is part of a general effort to move all of Terraform's non-library
package surface under internal in order to reinforce that these are for
internal use within Terraform only.
If you were previously importing packages under this prefix into an
external codebase, you could pin to an earlier release tag as an interim
solution until you've make a plan to achieve the same functionality some
other way.
This is part of a general effort to move all of Terraform's non-library
package surface under internal in order to reinforce that these are for
internal use within Terraform only.
If you were previously importing packages under this prefix into an
external codebase, you could pin to an earlier release tag as an interim
solution until you've make a plan to achieve the same functionality some
other way.
This is part of a general effort to move all of Terraform's non-library
package surface under internal in order to reinforce that these are for
internal use within Terraform only.
If you were previously importing packages under this prefix into an
external codebase, you could pin to an earlier release tag as an interim
solution until you've make a plan to achieve the same functionality some
other way.
2021-05-17 14:09:07 -07:00
Renamed from command/meta_backend_test.go (Browse further)