Commit graph

101 commits

Author SHA1 Message Date
Sarah French
9f5f21f1d8
test: Enable mocking http provider sources in tests (#38206)
* test: Update`MockSource` to be able to present providers as being installed via HTTP, add `newMockProviderSourceViaHTTP` for direct use in tests.

Compare newMockProviderSourceViaHTTP to the existing newMockProviderSource. newMockProviderSource uses FakeInstallablePackageMeta, which creates metadata for providers that says it's being sourced from a local archive. In newMockProviderSourceViaHTTP the metadata reports the provider is downloaded via HTTP. The URL is created using a base URL that should be obtained from a test http server created in the test.

* test: Add `newMockProviderSourceUsingTestHttpServer` helper, to abstract away making the http test server. Add test showing it in use.

* refactor: Update test helpers to call t.Cleanup internally
2026-02-26 10:24:13 +00:00
Radek Simko
0fe906fa8c make copyrightfix 2026-02-17 13:56:34 +00:00
Sarah French
6b73f710f8
PSS: Implement initialisation of new working directory (or use of -reconfigure flag) while using state_store (#37732)
* 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
2025-10-15 10:44:21 +01:00
Sarah French
0dfa115d7d
First step to enable use of TF_REATTACH_PROVIDERS with PSS (#37634)
* Add test coverage for `parseReattachProviders`

* Add unhappy path test cases to parseReattachProviders test

* Add `isProviderReattached` function, to help identify when a reattached provider is being used for PSS

* Move reattach config-related code into its own package

* Make calling code not need to know what the ENV is for reattach providers

* Refactor IsProviderReattached to use pre-existing logic

* Add test case, make spell check happy with US English

* Add headers

* Make calling code responsible for reading in the related ENV

* Add godoc comment to TF_REATTACH_PROVIDERS const

* Update internal/getproviders/reattach/reattach.go
2025-09-19 11:42:13 +00:00
Samsondeen
ede46c0b81
Allow successful init when constraint matches at least one valid version (#37137) 2025-05-21 09:06:22 +02:00
Martin Atkins
5f2eab6944 providerreqs: Provider requirement/version types in their own package
As we previously found with "package addrs", any package that contains
types used as identifiers or addresses tends to get imported from all over,
which means that if we mix real logic with those types in the same package
then a lot more packages end up depending indirectly on our external
dependencies.

In this case, the getproviders package depends on various things we need
only during provider installation, such as the library we use for GPG
signature verification. Lots of different packages in Terraform need to
talk about provider requirements, but only the CLI layer actually needs to
do provider installation, and so this commit splits the types we use to
talk about requirements into a new package "providerreqs", which
package getproviders then depends on.

To keep the size of this diff relatively small to start I've left
forwarding aliases in package getproviders, which means that not all of
the callers needed to be updated all at once. This commit does update
all of the packages that the remote state backends depend on though,
because that then allows us to reduce the set of indirect dependencies
for each of those backends.

The nested module go.mod files show that this has disconnected the indirect
dependencies on github.com/ProtonMail/go-crypto and on
github.com/cloudflare/circl , both of which Terraform CLI uses only for
provider installation.
2024-03-11 12:52:24 -07:00
thirdkeyword
8284cde302 remove repetitive words
Signed-off-by: thirdkeyword <fliterdashen@gmail.com>
2024-03-06 21:48:30 +08:00
James Bardin
0d4a29f7f3 ignore expired provider signing keys
Provider developers are not currently required to keep the signing keys
stored in the registry up to date, and older releases may be signed with
a key which has since expired.

For our purposes here however, we are validating the key and signature
used at the time of publishing, and given that the registry has
previously vouched for the validity of the key used, we can continue to
trust that key returned by the registry for installation.
2023-10-06 11:00:11 -04:00
James Bardin
86667375fd remove errant debug print 2023-10-06 10:00:24 -04:00
hashicorp-copywrite[bot]
53c34ff49c
Update copyright file headers to BUSL-1.1 2023-08-10 23:43:27 +01:00
Liam Cervante
1fe57d457d
upgrade golang.org/x/crypto/openpgp to github.com/ProtoMail/go-crypto (#33406) 2023-06-22 08:32:12 +02:00
hashicorp-copywrite[bot]
325d18262e [COMPLIANCE] Add Copyright and License Headers 2023-05-02 15:33:06 +00:00
Martin Atkins
783a07d9e8 build: Use Go 1.19
Go 1.19's "fmt" has some awareness of the new doc comment formatting
conventions and adjusts the presentation of the source comments to make
it clearer how godoc would interpret them. Therefore this commit includes
various updates made by "go fmt" to acheve that.

In line with our usual convention that we make stylistic/grammar/spelling
tweaks typically only when we're "in the area" changing something else
anyway, I also took this opportunity to review most of the comments that
this updated to see if there were any other opportunities to improve them.
2022-08-22 10:59:12 -07:00
Radek Simko
b82eee6c9f
getproviders: account for occasionally missing Host header in errors (#31542) 2022-07-29 10:23:50 +01:00
Liam Cervante
9f0d1d0630
terraform init: add link to documentation when a checksum is missing from the lock file (#31408)
* terraform init: add suggested fix for when a checksum is missing from the lock file

* improve error message

* add link to the documentation

* cleanup leftovers from previous attempt

* fix tests

* s/,/;

* fix imports
2022-07-20 13:28:16 +01:00
Radek Simko
7feef1c4aa
Use hashicorp/terraform-registry-address as a decoupled library (#28338)
* refactor: Use tfaddr for provider address parsing

* refactor: Use tfaddr for module address parsing

* deps: introduce hashicorp/terraform-registry-address
2022-07-08 14:46:29 +01:00
Radek Simko
746af015ea
internal/getproviders: Add URL to error message for clarity (#30810)
* internal/getproviders: Add URL to error message for clarity

Occasionally `terraform init` on some providers may return the following error message:

Error while installing citrix/citrixadc v1.13.0: could not query provider
registry for registry.terraform.io/citrix/citrixadc: failed to retrieve
authentication checksums for provider: 403 Forbidden

The 403 is most often returned from GitHub (rather than Registry API)
and this change makes it more obvious.

* Use Host instead of full URL
2022-04-14 16:14:50 +01:00
Krista LaFentres
2fc4e06890 Fix failing lint check for deprecated x/crypto/openpgp library 2021-11-18 14:59:29 -06:00
Alisdair McDiarmid
fb58f9e6d2 cli: Fix flaky init cancel test
There is a race between the MockSource and ShutdownCh which sometimes
causes this test to fail. Add a HangingSource implementation of Source
which hangs until the context is cancelled, so that there is always time
for a user-initiated shutdown to trigger the cancellation code path
under test.
2021-10-19 09:10:49 -04:00
Radek Simko
2496bc2b1e
internal/registry: Add URL to error message for clarity (#29298) 2021-08-10 15:20:40 +01:00
Paddy
8bdea502ab
Add support for protocol 6 providers during init. (#29153)
Update the version constraints for what providers will be downloaded
from the registry, allowing protocol 6 providers to be downloaded from
the registry.
2021-07-15 09:39:40 -07:00
Martin Atkins
e5f52e56f8 addrs: Rename DefaultRegistryHost to DefaultProviderRegistryHost
As the comment notes, this hostname is the default for provide source
addresses. We'll shortly be adding some address types to represent module
source addresses too, and so we'll also have DefaultModuleRegistryHost
for that situation.

(They'll actually both contain the the same hostname, but that's a
coincidence rather than a requirement.)
2021-06-03 08:50:34 -07: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
Martin Atkins
b9a93a0fe7 Move addrs/ to internal/addrs/
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
4c254cc2be Move httpclient/ to internal/httpclient/
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
James Bardin
a4a6b40bee update getproviders tests for new key 2021-04-23 11:18:58 -04:00
James Bardin
e1d790be61 update HC PublicKey 2021-04-23 11:18:58 -04:00
Pam Selle
242f319638
Give suggestions & remind users to use required_providers when provider not in registry (#28014)
* Add helper suggestion when failed registry err

When someone has a failed registry error on init, remind them that
they should have required_providers in every module

* Give suggestion for a provider based on reqs

Suggest another provider on a registry error, from the list of
requirements we have on init. This skips the legacy lookup
process if there is a similar provider existing in requirements.
2021-03-11 08:54:18 -05:00
Alex Chan
4ec80fa18d Correct the spelling of heirarchy/hierarchy throughout 2021-02-05 15:07:04 +00:00
Romain Philibert
5ae5c99ba0 fix: do not fail when provider symlink is broken. Only print a warning.
fix https://github.com/hashicorp/terraform/issues/27445
2021-01-08 12:51:09 +01:00
Martin Atkins
4b3e237668 command/init: Hint about providers in other namespaces
If a user forgets to specify the source address for a provider, Terraform
will assume they meant a provider in the registry.terraform.io/hashicorp/
namespace. If that ultimately doesn't exist, we'll now try to see if
there's some other provider source address recorded in the registry's
legacy provider lookup table, and suggest it if so.

The error message here is a terse one addressed primarily to folks who are
already somewhat familiar with provider source addresses and how to
specify them. Terraform v0.13 had a more elaborate version of this error
message which directed the user to try the v0.13 automatic upgrade tool,
but we no longer have that available in v0.14 and later so the user must
make the fix themselves.
2020-12-10 10:11:27 -08:00
James Bardin
f0c3ddf5a1 internal/getproviders: staticcheck 2020-12-02 13:59:19 -05:00
Alisdair McDiarmid
b1bc0e5d92 getproviders: Normalize versions before dedupe
When rendering a set of version constraints to a string, we normalize
partially-constrained versions. This means converting a version
like 2.68.* to 2.68.0.

Prior to this commit, this normalization was done after deduplication.
This could result in a version constraints string with duplicate
entries, if multiple partially-constrained versions are equivalent. This
commit fixes this by normalizing before deduplicating and sorting.
2020-11-02 10:45:45 -05:00
Martin Atkins
430318e262 getproviders: Consistent ordering of terms in VersionConstraintsString
An earlier commit made this remove duplicates, which set the precedent
that this function is trying to canonically represent the _meaning_ of
the version constraints rather than exactly how they were expressed in
the configuration.

Continuing in that vein, now we'll also apply a consistent (though perhaps
often rather arbitrary) ordering to the terms, so that it doesn't change
due to irrelevant details like declarations being written in a different
order in the configuration.

The ordering here is intended to be reasonably intuitive for simple cases,
but constraint strings with many different constraints are hard to
interpret no matter how we order them so the main goal is consistency,
so those watching how the constraints change over time (e.g. in logs of
Terraform output, or in the dependency log file) will see fewer noisy
changes that don't actually mean anything.
2020-10-26 12:44:15 -07:00
Alisdair McDiarmid
fe9a9fadfb internal: Suppress duplicate version constraints
A set of version constraints can contain duplicates. This can happen if
multiple identical constraints are specified throughout a configuration.

When rendering the set, it is confusing to display redundant
constraints. This commit changes the string renderer to only show the
first instance of a given constraint, and adds unit tests for this
function to cover this change.

This also fixes a bug with the locks file generation: previously, a
configuration with redundant constraints would result in this error on
second init:

Error: Invalid provider version constraints

  on .terraform.lock.hcl line 6:
  (source code not available)

The recorded version constraints for provider
registry.terraform.io/hashicorp/random must be written in normalized form:
"3.0.0".
2020-10-22 12:08:00 -04:00
Alisdair McDiarmid
7a31e56cb7
Merge pull request #26637 from hashicorp/alisdair/fix-locksfile-unconstrained-versions
internal: Fix lockfile constraint output for 1.2.*
2020-10-21 12:05:19 -04:00
Martin Atkins
1fe314b70b getproviders: Don't log if EvalSymlinks changes nothing
Previously this codepath was generating a confusing message in the absense
of any symlinks, because filepath.EvalSymlinks returns a successful result
if the target isn't a symlink.

Now we'll emit the log line only if filepath.EvalSymlinks returns a
result that's different in a way that isn't purely syntactic (which
filepath.Clean would "fix").

The new message is a little more generic because technically we've not
actually ensured that a difference here was caused by a symlink and so
we shouldn't over-promise and generate something potentially misleading.
2020-10-21 07:49:11 -07:00
Alisdair McDiarmid
9576a5b2d8 internal: Fix lockfile constraint output for 1.2.*
If a configuration requires a partial provider version (with some parts
unspecified), Terraform considers this as a constrained-to-zero version.
For example, a version constraint of 1.2 will result in an attempt to
install version 1.2.0, even if 1.2.1 is available.

When writing the dependency locks file, we previously would write 1.2.*,
as this is the in-memory representation of 1.2. This would then cause an
error on re-reading the locks file, as this is not a valid constraint
format.

Instead, we now explicitly convert the constraint to its zero-filled
representation before writing the locks file. This ensures that it
correctly round-trips.

Because this change is made in getproviders.VersionConstraintsString, it
also affects the output of the providers sub-command.
2020-10-20 10:14:03 -04:00
James Bardin
0b31ffa587 use a single log writer
Use a single log writer instance for all std library logging.

Setup the std log writer in the logging package, and remove boilerplate
from test packages.
2020-10-19 14:29:54 -04:00
James Bardin
6ca477f042 move helper/logging to internal
remove a dead code file too
2020-10-19 14:27:53 -04:00
Martin Atkins
b3f5c7f1e6 command/init: Read, respect, and update provider dependency locks
This changes the approach used by the provider installer to remember
between runs which selections it has previously made, using the lock file
format implemented in internal/depsfile.

This means that version constraints in the configuration are considered
only for providers we've not seen before or when -upgrade mode is active.
2020-10-09 09:26:23 -07:00
Martin Atkins
59b116f7bf command/init: Remove support for legacy provider addresses
We no longer need to support 0.12-and-earlier-style provider addresses
because users should've upgraded their existing configurations and states
on Terraform 0.13 already.

For now this is only checked in the "init" command, because various test
shims are still relying on the idea of legacy providers the core layer.
However, rejecting these during init is sufficient grounds to avoid
supporting legacy provider addresses in the new dependency lock file
format, and thus sets the stage for a more severe removal of legacy
provider support in a later commit.
2020-09-30 08:54:57 -07:00
Martin Atkins
0b734a2803 command: Make provider installation interruptible
In earlier commits we started to make the installation codepath
context-aware so that it could be canceled in the event of a SIGINT, but
we didn't complete wiring that through the API of the getproviders
package.

Here we make the getproviders.Source interface methods, along with some
other functions that can make network requests, take a context.Context
argument and act appropriately if that context is cancelled.

The main providercache.Installer.EnsureProviderVersions method now also
has some context-awareness so that it can abort its work early if its
context reports any sort of error. That avoids waiting for the process
to wind through all of the remaining iterations of the various loops,
logging each request failure separately, and instead returns just
a single aggregate "canceled" error.

We can then set things up in the "terraform init" and
"terraform providers mirror" commands so that the context will be
cancelled if we get an interrupt signal, allowing provider installation
to abort early while still atomically completing any local-side effects
that may have started.
2020-09-29 10:00:35 -07:00
Martin Atkins
ef64df950c getproviders: Prepare for having multiple valid hashes per package
As we continue iterating towards saving valid hashes for a package in a
depsfile lock file after installation and verifying them on future
installation, this prepares getproviders for the possibility of having
multiple valid hashes per package.

This will arise in future commits for two reasons:
- We will need to support both the legacy "zip hash" hashing scheme and
  the new-style content-based hashing scheme because currently the
  registry protocol is only able to produce the legacy scheme, but our
  other installation sources prefer the content-based scheme. Therefore
  packages will typically have a mixture of hashes of both types.
- Installing from an upstream registry will save the hashes for the
  packages across all supported platforms, rather than just the current
  platform, and we'll consider all of those valid for future installation
  if we see both successful matching of the current platform checksum and
  a signature verification for the checksums file as a whole.

This also includes some more preparation for the second case above in that
signatureAuthentication now supports AcceptableHashes and returns all of
the zip-based hashes it can find in the checksums file. This is a bit of
an abstraction leak because previously that authenticator considered its
"document" to just be opaque bytes, but we want to make sure that we can
only end up trusting _all_ of the hashes if we've verified that the
document is signed. Hopefully we'll make this better in a future commit
with some refactoring, but that's deferred for now in order to minimize
disruption to existing codepaths while we work towards a provider locking
MVP.
2020-09-24 14:01:54 -07:00
Martin Atkins
6694cfaa0e getproviders: Add a real type Hash for package hashes
The logic for what constitutes a valid hash and how different hash schemes
are represented was starting to get sprawled over many different files and
packages.

Consistently with other cases where we've used named types to gather the
definition of a particular string into a single place and have the Go
compiler help us use it properly, this introduces both getproviders.Hash
representing a hash value and getproviders.HashScheme representing the
idea of a particular hash scheme.

Most of this changeset is updating existing uses of primitive strings to
uses of getproviders.Hash. The new type definitions are in
internal/getproviders/hash.go.
2020-09-24 14:01:54 -07:00
Martin Atkins
264a3cf031 depsfile: Flatten the "hashes" locks to a single set of strings
Although origin registries return specific [filename, hash] pairs, our
various different installation methods can't produce a structured mapping
from platform to hash without breaking changes.

Therefore, as a compromise, we'll continue to do platform-specific checks
against upstream data in the cases where that's possible (installation
from origin registry or network mirror) but we'll treat the lock file as
just a flat set of equally-valid hashes, at least one of which must match
after we've completed whatever checks we've made against the
upstream-provided checksums/signatures.

This includes only the minimal internal/getproviders updates required to
make this compile. A subsequent commit will update that package to
actually support the idea of verifying against multiple hashes.
2020-09-24 14:01:54 -07:00
Martin Atkins
b2c0ccdf96 internal/getproviders: Allow PackageMeta to carry acceptable hashes
The "acceptable hashes" for a package is a set of hashes that the upstream
source considers to be good hashes for checking whether future installs
of the same provider version are considered to match this one.

Because the acceptable hashes are a package authentication concern and
they already need to be known (at least in part) to implement the
authenticators, here we add AcceptableHashes as an optional extra method
that an authenticator can implement.

Because these are hashes chosen by the upstream system, the caller must
make its own determination about their trustworthiness. The result of
authentication is likely to be an input to that, for example by
distrusting hashes produced by an authenticator that succeeds but doesn't
report having validated anything.
2020-09-24 14:01:54 -07:00
Martin Atkins
e843097e52 internal/getproviders: Formalize the "ziphash" hashing scheme
This is the pre-existing hashing scheme that was initially built for
releases.hashicorp.com and then later reused for the provider registry
protocol, which takes a SHA256 hash of the official distribution .zip file
and formats it as lowercase hex.

This is a non-ideal hash scheme because it works only for
PackageLocalArchive locations, and so we can't verify package directories
on local disk against such hashes. However, the registry protocol is now
a compatibility constraint and so we're going to need to support this
hashing scheme for the foreseeable future.
2020-09-24 14:01:54 -07:00
Martin Atkins
92723661d0 internal/depsfile: Loading locks from HCL files on disk
This is the initial implementation of the parser/decoder portion of the
new dependency lock file handler. It's currently dead code because the
caller isn't written yet. We'll continue to build out this functionality
here until we have the basic level of both load and save functionality
before introducing this into the provider installer codepath.
2020-09-08 09:50:58 -07:00
Martin Atkins
6993ecb0a6 internal/getproviders: VersionConstraintsString for "~> 2" input
The version constraint parser allows "~> 2", but it behavior is identical
to "~> 2.0". Due to a quirk of the constraint parser (caused by the fact
that it supports both Ruby-style and npm/cargo-style constraints), it
ends up returning "~> 2" with the minor version marked as "unconstrained"
rather than as zero, but that means the same thing as zero in this context
anyway and so we'll prefer to stringify as "~> 2.0" so that we can be
clearer about how Terraform is understanding that version constraint.
2020-09-08 09:50:58 -07:00