Commit Graph

206 Commits

Author SHA1 Message Date
Alisdair McDiarmid b60f201eed json-output: Release format version 1.0 2021-09-01 15:15:18 -04:00
James Bardin 863963e7a6 de-linting 2021-09-01 11:36:21 -04:00
Martin Atkins 89b05050ec core: Functional-style API for terraform.Context
Previously terraform.Context was built in an unfortunate way where all of
the data was provided up front in terraform.NewContext and then mutated
directly by subsequent operations. That made the data flow hard to follow,
commonly leading to bugs, and also meant that we were forced to take
various actions too early in terraform.NewContext, rather than waiting
until a more appropriate time during an operation.

This (enormous) commit changes terraform.Context so that its fields are
broadly just unchanging data about the execution context (current
workspace name, available plugins, etc) whereas the main data Terraform
works with arrives via individual method arguments and is returned in
return values.

Specifically, this means that terraform.Context no longer "has-a" config,
state, and "planned changes", instead holding on to those only temporarily
during an operation. The caller is responsible for propagating the outcome
of one step into the next step so that the data flow between operations is
actually visible.

However, since that's a change to the main entry points in the "terraform"
package, this commit also touches every file in the codebase which
interacted with those APIs. Most of the noise here is in updating tests
to take the same actions using the new API style, but this also affects
the main-code callers in the backends and in the command package.

My goal here was to refactor without changing observable behavior, but in
practice there are a couple externally-visible behavior variations here
that seemed okay in service of the broader goal:
 - The "terraform graph" command is no longer hooked directly into the
   core graph builders, because that's no longer part of the public API.
   However, I did include a couple new Context functions whose contract
   is to produce a UI-oriented graph, and _for now_ those continue to
   return the physical graph we use for those operations. There's no
   exported API for generating the "validate" and "eval" graphs, because
   neither is particularly interesting in its own right, and so
   "terraform graph" no longer supports those graph types.
 - terraform.NewContext no longer has the responsibility for collecting
   all of the provider schemas up front. Instead, we wait until we need
   them. However, that means that some of our error messages now have a
   slightly different shape due to unwinding through a differently-shaped
   call stack. As of this commit we also end up reloading the schemas
   multiple times in some cases, which is functionally acceptable but
   likely represents a performance regression. I intend to rework this to
   use caching, but I'm saving that for a later commit because this one is
   big enough already.

The proximal reason for this change is to resolve the chicken/egg problem
whereby there was previously no single point where we could apply "moved"
statements to the previous run state before creating a plan. With this
change in place, we can now do that as part of Context.Plan, prior to
forking the input state into the three separate state artifacts we use
during planning.

However, this is at least the third project in a row where the previous
API design led to piling more functionality into terraform.NewContext and
then working around the incorrect order of operations that produces, so
I intend that by paying the cost/risk of this large diff now we can in
turn reduce the cost/risk of future projects that relate to our main
workflow actions.
2021-08-30 13:59:14 -07:00
Alisdair McDiarmid 40dd4292b8
Merge pull request #29438 from hashicorp/alisdair/init-force-copy-multiple-workspaces
command: Suppress prompt for init -force-copy
2021-08-20 15:21:43 -04:00
Alisdair McDiarmid 2762a940c0 command: Suppress prompt for init -force-copy
The -force-copy flag to init should automatically migrate state.
Previously this was not applied to one case: when migrating from
a backend with multiple workspaces to another backend supporting
multiple workspaces. I believe this was an oversight so this commit
fixes that.
2021-08-20 14:46:09 -04:00
Alisdair McDiarmid 70a4f7a6b6 command: Fix stale lock after running add 2021-08-20 13:22:11 -04:00
Martin Atkins 43d753e727 command: "terraform add" is experimental
We're aware of several quirks of this command's current design, which
result from some existing architectural limitations that we can't address
immediately.

However, we do still want to make this command available in its current
capacity as an incremental improvement, so as a compromise we'll document
it as experimental. Our intent here is to exclude it from the
Terraform 1.0 Compatibility Promises so that we can have the space to
continue to improve the design as other parts of the overall Terraform
system gain new capabilities.

We don't currently have any concrete plan for this command to be
stabilized and subject to compatibility promises. That decision will
follow from ongoing discussions with other teams whose systems may need to
change in order to support the final design of "terraform add".
2021-08-19 09:27:30 -07:00
James Bardin 68ed50616e handle null and unknown values in attr diffs
The code adopted from block diffs was not set to handle null and unknown
values, as those are not allowed for blocks.

We also revert the change to formatting nested object types as single
attributes, because the attribute formatter cannot handle sensitive
values from the schema. This presents some awkward syntax for diffs for
now, but should suffice until the entire formatter can be refactored to
better handle these new nested types.
2021-08-18 14:12:01 -04:00
Martin Atkins 383bbdeebc Upgrade to Go 1.17
This includes the addition of the new "//go:build" comment form in addition
to the legacy "// +build" notation, as produced by gofmt to ensure
consistent behavior between Go versions. The new directives are all
equivalent to what was present before, so there's no change in behavior.

Go 1.17 continues to use the Unicode 13 tables as in Go 1.16, so this
upgrade does not require also upgrading our Unicode-related dependencies.

This upgrade includes the following breaking changes which will also
appear as breaking changes for Terraform users, but that are consistent
with the Terraform v1.0 compatibility promises.

- On MacOS, Terraform now requires macOS 10.13 High Sierra or later.

This upgrade also includes the following breaking changes which will
appear as breaking changes for Terraform users that are inconsistent with
our compatibility promises, but have justified exceptions as follows:

- cidrsubnet, cidrhost, and cidrnetmask will now reject IPv4 CIDR
  addresses whose decimal components have leading zeros, where previously
  they would just silently ignore those leading zeros.

  This is a security-motivated exception to our compatibility promises,
  because some external systems interpret zero-prefixed octets as octal
  numbers rather than decimal, and thus the previous lenient parsing could
  lead to a different interpretation of the address between systems, and
  thus potentially allow bypassing policy when configuring firewall rules
  etc.

This upgrade also includes the following breaking changes which could
_potentially_ appear as breaking changes for Terraform users, but that do
not in practice for the reasons given:

- The Go net/url package no longer allows query strings with pairs
  separated by semicolons instead of ampersands. This primarily affects
  HTTP servers written in Go, and Terraform includes a special temporary
  HTTP server as part of its implementation of OAuth for "terraform login",
  but that server only needs to accept URLs created by Terraform itself
  and Terraform does not generate any URLs that would be rejected.
2021-08-17 15:20:05 -07:00
James Bardin a94155d0ca
Merge pull request #29397 from hashicorp/jbardin/format-id-name-marks
unmark object ID or Name for formatting
2021-08-17 14:58:56 -04:00
James Bardin a48b024c0a unmark object ID or Name for formatting 2021-08-17 12:24:43 -04:00
James Bardin 296a757ab4 check for null sets in diff rendering 2021-08-16 18:25:16 -04:00
James Bardin fbfb14142e render empty nested containers as attributes
Don't try to break down containers that are empty to render the diff, so
we can avoid having to check for empty vs null in all cases.
2021-08-16 18:13:55 -04:00
Alisdair McDiarmid 3b33dc1105 json-output: Add output changes to plan logs
Extend the outputs JSON log message to support an `action` field (and
make the `type` and `value` fields optional). This allows us to emit a
useful output change summary as part of the plan, bringing the JSON log
output into parity with the text output.

While we do have access to the before/after values in the output
changes, attempting to wedge those into a structured log message is not
appropriate. That level of detail can be extracted from the JSON plan
output from `terraform show -json`.
2021-08-05 15:32:26 -04:00
magodo 90e6a3dffb
modify test case 2021-07-26 11:25:47 +08:00
magodo 67afee693b
target resource in module check only when `-out` points to a module 2021-07-24 12:03:32 +08:00
magodo dea645797a
`terraform add -out` append to existing config 2021-07-24 11:35:15 +08:00
Kristin Laemmert 0b827ab6b6
format/diff: fix panic with null map in NestedType attrs (#29206) 2021-07-21 08:51:35 -04:00
Alisdair McDiarmid a456d030db Fix flapping JSON output test properly
This commit makes the output order of the resource drift messages
stable, by building a slice of changes and sorting it by address.
2021-07-15 13:30:11 -04:00
Alisdair McDiarmid c51112a30c Fix flapping JSON output test
This test would previously fail randomly due to the use of multiple
resource instances. Instance keys are iterated over as a map for
presentation, which has intentionally inconsistent ordering.

To fix this, I changed the test to use different resource addresses for
the three drift cases. I also extracted them to a separate test, and
tweaked the test helper functions to reduce the number of fatal exit
points, to make failed test debugging easier.
2021-07-15 12:03:01 -04:00
Alisdair McDiarmid 5a34825fc1
Merge pull request #29131 from hashicorp/alisdair/sequence-diff-commentary
Add comments explaining how ctySequenceDiff works
2021-07-13 16:05:05 -04:00
Alisdair McDiarmid 72a7c95353
Merge pull request #29072 from hashicorp/alisdair/json-ui-resource-drift
json-output: Add resource drift to machine readable UI
2021-07-12 09:54:42 -04:00
Alisdair McDiarmid ef0181cfbd Add comments explaining how ctySequenceDiff works
The logic behind this code took me a while to understand, so I wrote
down what I understand to be the reasoning behind how it works. The
trickiest part is rendering changing objects as updates. I think the
other pieces are fairly common to LCS sequence diff rendering, so I
didn't explain those in detail.
2021-07-09 13:14:20 -04:00
Martin Atkins ab350289ab addrs: Rename AbsModuleCallOutput to ModuleCallInstanceOutput
The previous name didn't fit with the naming scheme for addrs types:
The "Abs" prefix typically means that it's an addrs.ModuleInstance
combined with whatever type name appears after "Abs", but this is instead
a ModuleCallOutput combined with an InstanceKey, albeit structured the
other way around for convenience, and so the expected name for this would
be the suffix "Instance".

We don't have an "Abs" type corresponding with this one because it would
represent no additional information than AbsOutputValue.
2021-07-01 08:28:02 -07:00
Alisdair McDiarmid 71a067242d json-output: Add resource drift to machine readable UI 2021-06-30 14:57:55 -04:00
Kristin Laemmert 35c19d7c9f
command/jsonstate: remove redundant remarking of resource instance (#29049)
* command/jsonstate: remove redundant remarking of resource instance

ResourceInstanceObjectSrc.Decode already handles marking values with any marks stored in ri.Current.AttrSensitivePaths, so re-applying those marks is not necessary.

We've gotten reports of panics coming from this line of code, though I have yet to reproduce the panic in a test.

* Implement test to reproduce panic on #29042

Co-authored-by: David Alger <davidmalger@gmail.com>
2021-06-29 10:59:20 -04:00
Martin Atkins 70bc432f85 command/views/json: Never generate invalid diagnostic snippet offsets
Because our snippet generator is trying to select whole lines to include
in the snippet, it has some edge cases for odd situations where the
relevant source range starts or ends directly at a newline, which were
previously causing this logic to return out-of-bounds offsets into the
code snippet string.

Although arguably it'd be better for the original diagnostics to report
more reasonable source ranges, it's better for us to report a
slightly-inaccurate snippet than to crash altogether, and so we'll extend
our existing range checks to check both bounds of the string and thus
avoid downstreams having to deal with out-of-bounds indices.

For completeness here I also added some similar logic to the
human-oriented diagnostic formatter, which consumes the result of the
JSON diagnostic builder. That's not really needed with the additional
checks in the JSON diagnostic builder, but it's nice to reinforce that
this code can't panic (in this way, at least) even if its input isn't
valid.
2021-06-28 13:42:28 -07:00
James Bardin c687ebeaf1
Merge pull request #29039 from hashicorp/jbardin/sensitive
New marks.Sensitive type, and audit of sensitive marks usage
2021-06-25 17:11:59 -04:00
James Bardin 55ebb2708c remove IsMarked and ContainsMarked calls
Make sure sensitivity checks are looking for specific marks rather than
any marks at all.
2021-06-25 14:17:06 -04:00
James Bardin d9dfd451ea update to use typed sensitive marks 2021-06-25 12:49:07 -04:00
Kristin Laemmert 096010600d
terraform: use hcl.MergeBodies instead of configs.MergeBodies for pro… (#29000)
* terraform: use hcl.MergeBodies instead of configs.MergeBodies for provider configuration

Previously, Terraform would return an error if the user supplied provider configuration via interactive input iff the configuration provided on the command line was missing any required attributes - even if those attributes were already set in config.

That error came from configs.MergeBody, which was designed for overriding valid configuration. It expects that the first ("base") body has all required attributes. However in the case of interactive input for provider configuration, it is perfectly valid if either or both bodies are missing required attributes, as long as the final body has all required attributes. hcl.MergeBodies works very similarly to configs.MergeBodies, with a key difference being that it only checks that all required attributes are present after the two bodies are merged.

I've updated the existing test to use interactive input vars and a schema with all required attributes. This test failed before switching from configs.MergeBodies to hcl.MergeBodies.

* add a command package test that shows that we can still have providers with dynamic configuration + required + interactive input merging

This test failed when buildProviderConfig still used configs.MergeBodies instead of hcl.MergeBodies
2021-06-25 08:48:47 -04:00
Alisdair McDiarmid 3326ab7dae json-output: Omit unchanged resource_drift entries
Previously, if any resources were found to have drifted, the JSON plan
output would include a drift entry for every resource in state. This
commit aligns the JSON plan output with the CLI UI, and only includes
those resources where the old value does not equal the new value---i.e.
drift has been detected.

Also fixes a bug where the "address" field was missing from the drift
output, and adds some test coverage.
2021-06-17 15:09:16 -04:00
Kristin Laemmert 583859e510
commands: `terraform add` (#28874)
* command: new command, terraform add, generates resource templates

terraform add ADDRESS generates a resource configuration template with all required (and optionally optional) attributes set to null. This can optionally also pre-populate nonsesitive attributes with values from an existing resource of the same type in state (sensitive vals will be populated with null and a comment indicating sensitivity)

* website: terraform add documentation
2021-06-17 12:08:37 -04:00
Kristin Laemmert 329585d07d
jsonconfig: properly unwind and enumerate references (#28884)
The "references" included in the expression representation now properly unwrap for each traversal step, to match what was documented.
2021-06-14 09:22:22 -04:00
Kristin Laemmert ac03d35997
jsonplan and jsonstate: include sensitive_values in state representations (#28889)
* jsonplan and jsonstate: include sensitive_values in state representations

A sensitive_values field has been added to the resource in state and planned values which is a map of all sensitive attributes with the values set to true.

It wasn't entirely clear to me if the values in state would suffice, or if we also need to consult the schema - I believe that this is sufficient for state files written since v0.15, and if that's incorrect or insufficient, I'll add in the provider schema check as well.

I also updated the documentation, and, since we've considered this before, bumped the FormatVersions for both jsonstate and jsonplan.
2021-06-14 09:19:13 -04:00
James Bardin 09c33fa449 account for noop deposed instances in json plan
When rendering a json plan, we need to account for deposed instances
that have become a noop rather than a destroy.
2021-06-09 17:57:14 -04:00
Alisdair McDiarmid 24ace6ae7d
Merge pull request #28864 from hashicorp/alisdair/fix-remote-backend-multi-workspace-state-migration
Fix remote backend multi workspace state migration
2021-06-08 10:10:58 -04:00
Martin Atkins 1a8da65314 Refactoring of module source addresses and module installation
It's been a long while since we gave close attention to the codepaths for
module source address parsing and external module package installation.
Due to their age, these codepaths often diverged from our modern practices
such as representing address types in the addrs package, and encapsulating
package installation details only in a particular location.

In particular, this refactor makes source address parsing a separate step
from module installation, which therefore makes the result of that parsing
available to other Terraform subsystems which work with the configuration
representation objects.

This also presented the opportunity to better encapsulate our use of
go-getter into a new package "getmodules" (echoing "getproviders"), which
is intended to be the only part of Terraform that directly interacts with
go-getter.

This is largely just a refactor of the existing functionality into a new
code organization, but there is one notable change in behavior here: the
source address parsing now happens during configuration loading rather
than module installation, which may cause errors about invalid addresses
to be returned in different situations than before. That counts as
backward compatible because we only promise to remain compatible with
configurations that are _valid_, which means that they can be initialized,
planned, and applied without any errors. This doesn't introduce any new
error cases, and instead just makes a pre-existing error case be detected
earlier.

Our module registry client is still using its own special module address
type from registry/regsrc for now, with a small shim from the new
addrs.ModuleSourceRegistry type. Hopefully in a later commit we'll also
rework the registry client to work with the new address type, but this
commit is already big enough as it is.
2021-06-03 08:50:34 -07:00
Alisdair McDiarmid 3f0c6a2217 cli: Add -ignore-remote-version flag for init
When performing state migration to a remote backend target, Terraform
may fail due to mismatched remote and local Terraform versions. Here we
add the `-ignore-remote-version` flag to allow users to ignore this
version check when necessary.
2021-06-02 15:30:05 -04:00
Alisdair McDiarmid 6692336541 cli: Fix state migration version check
When migrating multiple local workspaces to a remote backend target
using the `prefix` argument, we need to perform the version check
against all existing workspaces returned by the `Workspaces` method.
Failing to do so will result in a version check error.
2021-06-02 15:23:56 -04:00
Alisdair McDiarmid 953738c128 command/views: Remove unused drift summary message
This was dead code, and there is no clear way to retrieve this
information, as we currently only derive the drift information as part
of the rendering process.
2021-05-25 15:54:57 -04:00
James Bardin 3bf498422c typo 2021-05-25 08:32:44 -04:00
James Bardin 45b5c289a0 no drift with only deposed changes
Changes to deposed instances should not triggers any drift to be
rendered, as they will have nothing to display.
2021-05-24 17:17:52 -04:00
James Bardin 57aa7c6025 skip drift rendering for deposed resources
Deposed instances have no current state and are only scheduled for
deletion, so there is no reason to try and render drift on these
instances.
2021-05-24 15:48:05 -04:00
James Bardin aae642fb07 fix schemas and add deposed test
The schemas for provider and the resources didn't match, so the changes
were not going to be rendered at all.

Add a test which contains a deposed resource.
2021-05-24 15:38:58 -04:00
Kristin Laemmert 649095c602
providers subcommand tests (#28744)
* getproviders ParsePlatform: add check for invalid platform strings with too many parts

The existing logic would not catch things like a platform string containing multiple underscores. I've added an explicit check for exactly 2 parts and some basic tests to prove it.

* command/providers-lock: add tests

This commit adds some simple tests for the providers lock command. While adding this test I noticed that there was a mis-copied error message, so I replaced that with a more specific message. I also added .terraform.lock.hcl to our gitignore for hopefully obvious reasons.

getproviders.ParsePlatform: use parts in place of slice range, since it's available

* command: Providers mirror tests

The providers mirror command is already well tested in e2e tests, so this includes only the most absolutely basic test case.
2021-05-19 12:56:16 -04:00
Kristin Laemmert 4928e1dd01
terraform: use ProtocolVersion from unmanaged providers' reattachConfig to chose the correct PluginClient (#28190)
* add/use ProtocolVersion with unmanaged providers reattach config
2021-05-18 10:59:14 -04:00
Alisdair McDiarmid 5fc3ba37a6 cli: Improve sensitivity change warning output
When an attribute value changes in sensitivity, we previously rendered
this in the diff with a `~` update action and a note about the
consequence of the sensitivity change. Since we also suppress the
attribute value, this made it impossible to know if the underlying value
was changing, too, which has significant consequences on the meaning of
the plan.

This commit adds an equality check of the old/new underlying values. If
these are unchanged, we add a note to the sensitivity warning to clarify
that only sensitivity is changing.
2021-05-18 10:33:25 -04:00
Martin Atkins d35bc05312 Update various non-code references to renamed Go packages
Previous commits have moved all of our Go packages under "internal", so
this is a retroactive update of non-Go references to those same packages.
2021-05-17 14:09:07 -07:00
Martin Atkins 36d0a50427 Move terraform/ to internal/terraform/
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
Martin Atkins f40800b3a4 Move states/ to internal/states/
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
Martin Atkins b40a4fb741 Move plugin/ and plugin6/ to internal/plugin{,6}/
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
Martin Atkins 034e944070 Move plans/ to internal/plans/
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
Martin Atkins cdd9464f9a Move lang/ to internal/lang/
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
Martin Atkins 31349a9c3a Move configs/ to internal/configs/
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
Martin Atkins ffe056bacb Move command/ to internal/command/
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