Commit Graph

33185 Commits

Author SHA1 Message Date
Martin Atkins
ca1d83fef7 engine/planning: Shallow adoption of states.ResourceInstanceObjectFull
This is just a minimal set of changes to introduce uses of the new
states.ResourceInstanceObjectFull to all of the leaf functions related to
planning managed and data resource instances.

The main goal here was just to prove that we'd reasonably be able to look
up objects with the new type in all of the places we'd need to. We're
planning some more substantial changes to the planning engine in future
commits (e.g. to generate execution graphs instead of traditional plans)
and so we'll plumb this in better as part of that work.

Signed-off-by: Martin Atkins <mart@degeneration.co.uk>
2025-12-05 12:27:12 -08:00
Martin Atkins
c89cd97505 execgraph: opManagedFinalPlan can use resource type from prior state
Previously we had a gap here where we only knew the resource type to use
when there was a "desired state" object to get it from, which isn't true
when we're planning to destroy an undesired object.

The new extended model for resource instance object state gives us direct
access to the resource type name, so we can now handle that properly.

Signed-off-by: Martin Atkins <mart@degeneration.co.uk>
2025-12-05 12:27:12 -08:00
Martin Atkins
a484919556 execgraph: Use states.ResourceInstanceObjectFull
Instead of states.ResourceInstanceObject, we'll now use the "full"
representation added in a recent commit. This new representation is a
better fit for execgraph because it tracks all of the relevant information
about a resource instance object inline without assuming that the object
is always used in conjunction with a pointer to the entire state.

We're not really making any special use of those new capabilities yet. This
is mostly just mechanical updates to refer to the new type, and to fill
in values for the extra fields as far as that's possible without doing
further refactoring.

Signed-off-by: Martin Atkins <mart@degeneration.co.uk>
2025-12-05 12:27:12 -08:00
Martin Atkins
c22d156f4e states: "full" variants of the ResourceInstanceObject representations
Our existing state model is designed with the assumption that anyone who
is accessing a ResourceInstanceObjectSrc will be doing so from an object
representing the entire state at once, and so they can separately fetch
information about the resource as a whole and the provider instance it
belongs to if needed.

In our new language runtime we want to be able to just pass around pointers
to individual resource instance object states rather than the entire state
data structure, and so these two new "full" variants extend the object
representation with a provider instance address and the name of the
resource type within that provider.

This also adopts a slightly different representation of the value itself,
making use of some newer Go language features, so that we don't need quite
so much duplication between the "source" and decoded versions of this
model. In practice it's only the Value field that needs to vary between
the two, because that's the part where we require provider schema
information to decode.

Signed-off-by: Martin Atkins <mart@degeneration.co.uk>
2025-12-05 12:27:12 -08:00
Martin Atkins
816e889b63 .github: Include initwd and registry packages in e2etest job
This is admittedly "scope creep" for a job that was originally intended
only to run the end-to-end tests, but we have a separate e2etest job
specifically because some of these tests interact with the live OpenTofu
Registry and certain GitHub repositories and so it's nice to have these
external dependencies isolated into their own job so that outages of any
of these external services should only affect this one test job.

The TF_ACC=1-constrained tests in packages initwd and registry are set up
that way because they too interact with OpenTofu Registry and GitHub
repositories, so grouping these together retains the idea of limited
these external dependencies to only one job while giving us a little more
test coverage for our PR checks.

The motivation for doing this now is that both of these packages had
acceptance tests that had been broken by changes in the past and we didn't
notice because nothing was routinely running these tests:
- package registry had been failing ever since OpenTofu existed because
  one of its tests seems to have been depending on an undocumented registry
  protocol feature that OpenTofu Registry has never implemented
- package initwd got broken more recently by a change to use a dependency
  inversion style for the module installer's use of module registry client
  and package fetcher, but these particular tests were not passing in
  working clients for the module installer to use.

Both of those problems were already fixed in earlier commits, and so this
is just an attempt to avoid similar problems happening again in future.

(This doesn't address the more common case of acceptance tests that require
live credentials to access a service that doesn't support anonymous access.
Those will still need to run manually in development environments because
we cannot pass live credentials to a job that runs in response to
third-party pull requests.)

Signed-off-by: Martin Atkins <mart@degeneration.co.uk>
2025-12-05 07:24:38 -08:00
Martin Atkins
b3f4437f7f registry: Don't test for undocumented protocol feature
TestAccLookupModuleVersions was previously testing for a property in the
registry's JSON response that is not part of the documented "modules.v1"
protocol.

Presumably this was covering some extension property in our predecessor's
public registry implementation, which therefore made this test pass in its
original form interacting with that specific registry implementation.
However, OpenTofu does not depend on this extension property in any way
outside of this test, so there's no benefit to testing for this behavior
in OpenTofu. Regardless, the OpenTofu Registry doesn't implement this
extension so this test cannot pass in its current form running against that
implementation of the registry protocol.

Signed-off-by: Martin Atkins <mart@degeneration.co.uk>
2025-12-05 07:24:38 -08:00
Martin Atkins
7780f69bbd initwd: Fix the TF_ACC=1 tests
Earlier work in opentofu/opentofu#2661 caused the module installer to
treat the registry client and the package fetcher as optional dependencies
so that local-only tests (by far our common case across the whole codebase)
could avoid instantiating the registry and go-getter client code and risk
accidentally depending on network services.

However, at the time I didn't notice that this package had TF_ACC=1
acceptance tests, and so although I made systematic updates across all the
tests which appeared to make them pass there were actually several that
were being skipped and so I didn't notice that I hadn't updated them well
enough.

This gets them all passing again by giving the ones that intentionally
access the real OpenTofu Registry and some test-only GitHub repositories
the clients they need to do that.

In a future commit I intend to add this package to our end-to-end test
job that runs as part of our pull request checks so that we're less likely
to forget to update these tests under future maintenance.

Signed-off-by: Martin Atkins <mart@degeneration.co.uk>
2025-12-05 07:24:38 -08:00
Ilia Gogotchuri
fd19a3763f Retain resource instances with a new lifecycle argument - destroy (#3409)
Signed-off-by: Ilia Gogotchuri <ilia.gogotchuri0@gmail.com>
Co-authored-by: Andrei Ciobanu <andrei.ciobanu@opentofu.org>
2025-12-04 18:49:57 +04:00
baa-ableton
c3fe83a177 create automated tests for the internal/flock package (#3366)
Signed-off-by: Babur Ayanlar <babur.ayanlar@ableton.com>
2025-12-02 12:07:25 -03:00
Diógenes Fernandes
530e5c4538 Fix linting on Windows (#3457)
Signed-off-by: Diogenes Fernandes <diofeher@gmail.com>
Signed-off-by: Diógenes Fernandes <diofeher@gmail.com>
Co-authored-by: Martin Atkins <mart@degeneration.co.uk>
2025-12-02 07:11:14 -03:00
Christian Mesh
ffc9c4d556 Split out provider schemas vs instances in new engine (#3530)
Signed-off-by: Christian Mesh <christianmesh1@gmail.com>
2025-12-01 13:09:58 -05:00
Christian Mesh
5e7397b8a3 Parallelize provider installation (#2729)
Signed-off-by: Christian Mesh <christianmesh1@gmail.com>
2025-12-01 11:55:53 -05:00
Christian Mesh
607d74c882 Defer provider checksum and parallelize schema fetching (#2730)
Signed-off-by: Christian Mesh <christianmesh1@gmail.com>
2025-12-01 11:28:52 -05:00
krishna sindhur
64d3940fc6 bug fix for Instance module without resources/outputs was not reporting correct length. (#3469)
Signed-off-by: KrishnaSindhur <krishna.sindhur@harness.io>
2025-12-01 09:15:10 -05:00
Martin Atkins
a89667e29c execgraph: Marshaling an unmarshaling of execution graphs
To support the workflow of saving a plan to disk and applying it on some
other machine we need to be able to represent the execution graph as a byte
stream and then reload it later to produce an equivalent execution graph.

This is an initial implementation of that, based on the way the execgraph
package currently represents execution graphs. We may change that
representation more in future as we get more experience working in the new
architecture, but this is intended as part of our "walking skeleton" phase
where we try to get the new architecture working end-to-end with simple
configurations as soon as possible to help verify that we're even on the
right track with this new approach, and try to find unknown unknowns that
we ought to deal with before we get too deep into this.

Signed-off-by: Martin Atkins <mart@degeneration.co.uk>
2025-11-26 10:34:17 -08:00
Andrei Ciobanu
4d16e6f28c Remove unused deprecation flags (#3528)
Signed-off-by: Andrei Ciobanu <andrei.ciobanu@opentofu.org>
2025-11-26 16:28:16 +02:00
Martin Atkins
4d1c6c151b go.mod: go get golang.org/x/crypto@v0.45.0
This is primarily to clear naive security scanner reports for GO-2025-4135,
which is a potential denial of service if attacker-controlled software can
send malformed packets back to OpenTofu through the SSH Agent proxy
channel.

We are not considering this a significant vulnerability for OpenTofu
because the SSH Agent forwarding pattern already assumes that software on
the remote system is trusted not to misuse the keys that are exposed though
the proxy channel.

Due to the Go team's policy of ratcheting upgrades between all of the
golang.org/x/* modules, this also requires upgrading three other modules.
I have reviewed the changes in those, and most appear to not affect
OpenTofu at all. There are some performance improvements to the HTTP2 and
QUIC implementations in x/net, but they don't seem to be a big concern for
us.

Signed-off-by: Martin Atkins <mart@degeneration.co.uk>
2025-11-24 11:37:32 -08:00
Divyanshu Singh
1e966f250a chore(keyprovider/gcp_kms): add logs for encryption and decryption keys (#3518)
Signed-off-by: divyanshu-vashu <vashusingh2004.jan@gmail.com>
Signed-off-by: Divyanshu Singh <89933176+divyanshu-vashu@users.noreply.github.com>
Co-authored-by: Diógenes Fernandes <diofeher@gmail.com>
2025-11-24 09:44:18 -03:00
Martin Atkins
09815665de backend/local: Scaffolding for new runtime can use providers
This is some minimal glue to help the new runtime use the providers that
were gathered up by the existing logic in the "command" package.

This is cheating a little because this is relying on "tofu init" still
using the old approach just enough to find out which providers are needed
and get them installed, but our current focus is on the main plan and
apply phases and so it's convenient to be able to leave that part untouched
for now and return to improve it later, once we have more of the
fundamentals in place.

Signed-off-by: Martin Atkins <mart@degeneration.co.uk>
2025-11-21 09:20:59 -08:00
Martin Atkins
102449c9ec backend/local: Use experimental runtime for planning, when enabled
This is a relatively uninteresting milestone where it's possible to load
and plan a root module that contains nothing except local values and
output values.

The module loader currently supports only local sources and the plugin
APIs just immediately return errors, so configurations more complicated
than that are likely to just fail immediately with one or more errors.
We'll gradually improve on this in later commits.

Signed-off-by: Martin Atkins <mart@degeneration.co.uk>
2025-11-21 09:20:59 -08:00
Martin Atkins
367244a8f9 local/backend: Stub dependency fetchers for new runtime glue
None of these actually work yet, but this satisfies the new-style config
loader enough for it to return a real error instead of immediately
panicking.

Signed-off-by: Martin Atkins <mart@degeneration.co.uk>
2025-11-21 09:20:59 -08:00
Martin Atkins
02f48f7b32 lang/eval: Re-export evalglue.UncompiledModule
We currently re-export evalglue.ExternalModules, but the method in that
interface requires returning evalglue.UncompiledModule and so we need to
export that too or else it's impossible to actually implement the interface
from outside this family of packages.

Signed-off-by: Martin Atkins <mart@degeneration.co.uk>
2025-11-21 09:20:59 -08:00
Martin Atkins
ae60da8e7c backend/local: Initial sketch of new-engine planning
This doesn't actually work yet. It's just to sketch out a minimal overall
sequence of steps to make this behave somewhat like the main implementation
of "tofu plan", and then we'll make it work better in subsequent commits.

The main omission as of this commit is that we don't yet pass module,
provider, and provisioner dependency access objects in the EvalContext,
and so config loading immediately fails trying to request the root module
from a nil object.

Signed-off-by: Martin Atkins <mart@degeneration.co.uk>
2025-11-21 09:20:59 -08:00
Martin Atkins
ff5f45520d backend/local: Opt-in to experimental plan/apply/refresh functions
To facilitate early development and testing of the new language runtime
we're introducing a temporary mechanism to opt in to using the new codepaths
based on an environment variable. This environment variable is effective
only for experiment-enabled builds of OpenTofu, and so it will be
completely ignored by official releases of OpenTofu.

This commit just deals with the "wiring" of this new mechanism, without
actually connecting it with the new language runtime yet. The goal here
is to disturb existing codepaths as little as possible to minimize both
the risk of making this change and the burden this causes for ongoing
maintenance unrelated to work on the new language runtime.

This strategy of switching at the local backend layer means that we will
have some duplicated logic in the experimental functions compared to the
non-experimental functions, which is an intentional tradeoff to allow us
to isolate what we're doing so we don't churn existing code while we're
still in this early exploration phase. In a later phase of the language
runtime project we may pivot to a different approach which switches at
a deeper point in the call stack, but for now we're keeping this broad
to give us flexibility.

Signed-off-by: Martin Atkins <mart@degeneration.co.uk>
2025-11-21 09:20:59 -08:00
Andrei Ciobanu
88b7d20cac Remove nil check that was returning nil schema for actual existing resources (#3517)
Signed-off-by: Andrei Ciobanu <andrei.ciobanu@opentofu.org>
2025-11-20 17:11:07 +02:00
Martin Atkins
05c27d982f main: Warn in logs if GODEBUG is set
The GODEBUG environment variable is a side-channel that allows dynamically
opting in to a million billion different variations of Go runtime and
standard library behavior, and we can obviously not routinely test
OpenTofu's behavior across all of those different variations.

Just in case someone encounters a problem caused by running OpenTofu with
a combination of settings that are not enabled in our default build
configuration, we'll include an explicit note in the logs so that we can
tell when we're investigating a bug report that it might only be
reproducible when the Go runtime behavior has been overridden in this way,
and so that someone debugging their own problem can notice that they are
using OpenTofu in an unsupported way and could potentially solve their own
problem by unsetting that environment variable.

This is a generalization of the previous addition of a log message when
running in FIPS 140-3 mode, which is also updated here to use [WARN]
instead of [WARNING] as the prefix because our logging system does not
actually understand "WARNING" as a valid prefix. Keeping the separate
specialized message for FIPS 140-3 mode is warranted because we _know_
that OpenTofu does not behave as intended when that mode is enabled, while
we've not tested with any other combination of settings so we cannot
predict whether they will cause misbehavior or not.

Signed-off-by: Martin Atkins <mart@degeneration.co.uk>
2025-11-20 07:22:38 -05:00
Martin Atkins
82fdad27fc website: "tofu providers schema" nested_type docs
At some point after this documentation was originally written the schema
structure grew to include the possibility of structural attribute types,
represented using "nested_type" instead of "type" in the attribute
definition, but it seems that the documentation was not updated to mention
that.

This is just a minimal extra note about that focused mainly on just
acknowledging that this possibility exists at all, in case anyone is
relying on these docs to build something to parse this format. It would
probably be helpful to expand both this and the existing documentation to
specify the format more precisely, but my focus here is just on quickly
filling in this missing piece so that the documentation is complete, even
if not detailed and precise.

Signed-off-by: Martin Atkins <mart@degeneration.co.uk>
2025-11-19 07:20:49 -08:00
Christian Mesh
95d75b3436 Fix import validation with resource reference (unknown value) (#3513)
Signed-off-by: Christian Mesh <christianmesh1@gmail.com>
2025-11-19 09:58:35 -05:00
Martin Atkins
8149270787 CHANGELOG: entry for opentofu/opentofu#3507
Signed-off-by: Martin Atkins <mart@degeneration.co.uk>
2025-11-18 06:59:35 -08:00
Martin Atkins
971513049d tofu: GraphNodeDestroyer can now have references
Previously the ReferenceTransformer just had a broad rule that any node
which implements GraphNodeDestroyer has its expression references
completely ignored.

Now that we're starting to allow dynamic expressions for destroy-related
settings like "prevent_destroy", we need to be able to represent the
dependencies implied by those expressions.

However, the assumption that configuration is mostly ignored when planning
destroy is load-bearing for minimizing awkward dependency problems in the
destroy-planning graph, so this introduces a new concept of "destroy
references" which means that we can implement only a small, curated subset
of references -- for now, just the ones from prevent_destroy -- that get
considered for any node type that implements GraphNodeDestroyer.

Having GraphNodeDestroyer effectively take priority over
GraphNodeReferencer seems like the least disruptive way to retrofit this
idea surgically as a small change to the previous unilateral rule against
any references at all, because in practice all of the destroy nodes embed
NodeAbstractResourceInstance and therefore implement GraphNodeReferencer,
so it is important that we continue to ignore that type's
GraphNodeReferencer implementation whenever it's embedded in something
that is also a GraphNodeDestroyer.

Signed-off-by: Martin Atkins <mart@degeneration.co.uk>
2025-11-18 06:59:35 -08:00
Martin Atkins
3b6bc5692a go.mod: Trivial upgrades for a few golang.org/x/* modules
The Go team tends to ratchet all of these libraries forward together even
if there have been no significant changes since the last release, and so
these three only include some fixes to typos in comments and test code
and some internal modernization to use the generic reflect.TypeFor instead
of the interface-based reflect.TypeOf.

Upgrading these should not affect OpenTofu's behavior in any material way,
and so this is just to get these easy ones out of the way before we deal
with the more significant changes in the other related modules that will
likely require closer review.

Signed-off-by: Martin Atkins <mart@degeneration.co.uk>
2025-11-17 14:02:13 -08:00
Diógenes Fernandes
e418276ed4 fix: use variables at enabled in nested modules (#3475)
Signed-off-by: Diogenes Fernandes <diofeher@gmail.com>
2025-11-17 13:33:40 +00:00
Martin Atkins
6c46636af4 Mention in logs and version output when FIPS-140-3 mode is enabled
Unfortunately the Go team has unilaterally decided that all programs built
with Go 1.24 and later always allow enabling FIPS-140-3 mode -- both in
its "on" and "only" configurations -- regardless of whether the authors
of that software intend to support running in that restricted mode, or
whether they are even testing their application in that configuration.

We have not yet made a final decision on how and whether we intend to
support this mode in our official builds, but we _do_ know that OpenTofu
cannot currently function correctly with this mode enabled because it
relies on standard library features and external libraries that are not
available in that case.

Therefore in the meantime we'll mention explicitly in both the internal
logs and in the "tofu version" output if we appear to be running in that
mode, meaning that if someone tries to use it and finds that it doesn't
work properly then if they open a GitHub issue and share those two
artifacts (as requested by our bug report template) then we can know that
we might need to turn on the special mode in order to reproduce the
reported problem, rather than wasting time trying to reproduce it in the
standard mode.

We do still need to make a final decision about what we want to do with
this in the long run, but this is intended as an short-term compromise
that allows folks to experiment with this unsupported mode if they wish
while hopefully making it clearer that in the mean time we may
deprioritize fixing problems that only occur when this unusual mode is
enabled.

Signed-off-by: Martin Atkins <mart@degeneration.co.uk>
2025-11-17 07:40:11 -05:00
James Humphries
f9abd97b91 Ensure Ephemeral values are handled by the diff transformer (#3495)
Signed-off-by: Andrei Ciobanu <andrei.ciobanu@opentofu.org>
Signed-off-by: James Humphries <james@james-humphries.co.uk>
Co-authored-by: Andrei Ciobanu <andrei.ciobanu@opentofu.org>
2025-11-14 12:18:05 +00:00
Martin Atkins
541fc48a7b tofu: TestContext2Plan_preventDestroy_dynamicFromDataResource synctest.Wait
The fake time implementation in package synctest does not create a
synchronization point itself, so the previous version of this test was
technically incorrect, though it was passing in practice due to other
effective constraints on the execution behavior.

A synctest.Wait after each fake time.Sleep creates a synchronization point
that helps ensure the correct execution order without relying on unrelated
implementation details such as the mutexes around the planned changes
and in-memory state data.

This does not actually change the current test behavior in any significant
way, but would avoid this test becoming more flaky if implementation
details of the language runtime were to change significantly in future.
(That seems pretty unlikely in practice -- we're intending to write a new
one instead of evolving this one significantly -- but I think it's still
worth making the effort to use the synctest API correctly as part of
learning to make effective use of it.)

Signed-off-by: Martin Atkins <mart@degeneration.co.uk>
2025-11-12 11:39:07 -08:00
Andrei Ciobanu
c29cd93f21 [main] Fixes for GH workflows for older OpenTofu versions (#3485)
Signed-off-by: Andrei Ciobanu <andrei.ciobanu@opentofu.org>
2025-11-11 11:12:20 +02:00
Martin Atkins
1cf9d209ed CHANGELOG: Entry for opentofu/opentofu#3474
Signed-off-by: Martin Atkins <mart@degeneration.co.uk>
2025-11-10 10:09:19 -08:00
Martin Atkins
172dd87443 tofu: Allow dynamic expressions in prevent_destroy arguments
Previously we evaluated prevent_destroy expressions immediately inside the
config loader, thereby forcing it to always be a constant expression
producing a bool value.

Now the config loader just saves whatever expression it was given and we
let the language runtime deal with it instead, which means we can allow
references to dynamically-chosen values from elsewhere in the same module.

The language runtime's "validate" phase still performs a type check for
bool that's equivalent to what we used to do during config loading to make
sure that the "tofu validate" command can catch a similar subset of
problems as it used to be able to catch, but we have more information
available during the plan phase that allows us to produce more complete and
relevant error messages, so for any expression that we can't evaluate
with a nil evaluation context we'll now let the plan phase deal with the
checks instead.

The policy for handling annoying cases such as unknown values, ephemeral
values, sensitive values, and references to local symbols like count.index
is intentionally the most conservative choice to start, because future
versions of OpenTofu can allow more once we've got more experience but
cannot permit less if we find that we've made a mistake. Future changes
could potentially make these rules a little more liberal, once we have
learned from feedback on this initial functionality.

Signed-off-by: Martin Atkins <mart@degeneration.co.uk>
2025-11-10 10:09:19 -08:00
Martin Atkins
3ffe148ac0 CHANGELOG: Entry for opentofu/opentofu#3479
Signed-off-by: Martin Atkins <mart@degeneration.co.uk>
2025-11-10 09:49:35 -08:00
Martin Atkins
e389a7f2fa website: Warn about "tofu output -raw" in a terminal
By design the "-raw" option to "tofu output" writes the literal output
value directly to stdout without any quoting or escaping, and so it's
risky to use it with an output value that could be controlled by an
attacker when stdout is a terminal.

This risk is inherent in the purpose of this option and is part of the
reason why this is not the default behavior (OpenTofu returns a quoted
representation of an output string by default) so here we just make that
risk explicit in the documentation, in the hope that operators will use
this operation mindfully.

Signed-off-by: Martin Atkins <mart@degeneration.co.uk>
2025-11-10 09:49:35 -08:00
Martin Atkins
6dec25c1fb command/format: FilterControlChars is now ReplaceControlChars
Since this is replacing C0 control characters with other control characters
rather than just removing them completely, "replace" is probably the more
intuitive name for this function.

This also removes the preallocation of the output buffer in the case where
control characters were present in the input, letting the strings.Builder
implementation manage the buffer growth automatically itself.

Signed-off-by: Martin Atkins <mart@degeneration.co.uk>
2025-11-10 09:49:35 -08:00
Martin Atkins
7cac1f0518 command/login: Filter C0 control characters in HCP Terraform motd
From reading the special-case login code for the HCP Terraform host it
appears that the intention of the special "motd.v1" protocol was that it
should return a message that uses the syntax defined by the "colorstring"
library to make use of a limited set of control characters, and that it
was not intended to allow the text to include arbitrary control characters
that might cause more significant effects on a terminal and would not be
filtered out properly when running in "no color" mode.

Therefore we'll make this slightly more robust by filtering out any control
characters, using format.FilterControlChars. Note that this behavior is
exclusive to the HCP Terraform hostname "app.terraform.io", which is
unlikely to be used in OpenTofu anyway (since that service is presumably
offered for Terraform's use) and so this is not a particularly significant
change but is just part of some work to avoid situations where remote
network services can potentially cause OpenTofu to emit arbitrary control
characters to a terminal.

Signed-off-by: Martin Atkins <mart@degeneration.co.uk>
2025-11-10 09:49:35 -08:00
Martin Atkins
ee8a0ece23 command/format: Filter C0 control characters in diagnostic output
A diagnostic message can potentially include substrings derived from data
fetched from untrusted sources, such as if a network request fails in a
way that causes part of the response data to be included verbatim in the
error message.

This new filtering ensures that if any such data is included then any
C0 control characters in the string cannot affect the state of a terminal
that stdout/stderr might be connected to, by replacing them with their
corresponding printable representations from Unicode's "Control Pictures"
block.

The filtering of source snippets and source filenames is not technically
necessary because those are under control of module authors only and
operators are already expected to review modules they use to ensure that
they can cause only desirable behavior, since modules are arbitrary code.
However, it's included here for defense-in-depth because there is little
reason for such characters to appear legitimately in either of those
contexts in practice.

Signed-off-by: Martin Atkins <mart@degeneration.co.uk>
2025-11-10 09:49:35 -08:00
Martin Atkins
5f4608c0fe command/format: FilterControlChars function
This utility function replaces C0 control characters in a given string with
their corresponding symbols from the "Control Pictures" Unicode block.

As of this commit nothing is using this, but in future commits we will use
this when preparing terminal UI output that may contain arbitrary strings
that are not subject to any other quoting/escaping to ensure that it is
not possible to affect virtual terminal state in sitations where that is
not intentionally allowed by OpenTofu.

Signed-off-by: Martin Atkins <mart@degeneration.co.uk>
2025-11-10 09:49:35 -08:00
Christian Mesh
cc8e86c998 Fix nil entry in state resource instance map from state hook (#3478)
Signed-off-by: Christian Mesh <christianmesh1@gmail.com>
2025-11-06 16:28:36 -05:00
Larry Bordowitz
a961f737b7 makefile: add .exe when building for Windows (#3452)
Signed-off-by: Larry Bo <laurence.bordowitz@gmail.com>
2025-11-05 12:36:22 -06:00
Martin Atkins
93d095c67e traceattrs: Functions for the commonly-used OCI-related attributes
We have a number of trace attributes that we use across all of our OCI
Distribution-based functionality, so this centralizes their definitions
in package traceattrs.

This intentionally ignores a few additional attribute names that are used
only in the code that interacts with Docker-style credential helpers,
because all of those are used only in a single function and so adding
indirection for those doesn't have enough benefit to offset the cost of
additional indirection.

Signed-off-by: Martin Atkins <mart@degeneration.co.uk>
2025-11-03 11:41:50 -08:00
Martin Atkins
35cd016693 tracing: Re-export semconv.OCIManifestDigest
We previously added re-exports for some of the functions we'd previously
been importing directly from semconv elsewhere in this codebase. For this
one we'd previously just hard-coded the standardized attribute name, but
for consistency we'll also use a re-export of a semconv function for this
one too.

Signed-off-by: Martin Atkins <mart@degeneration.co.uk>
2025-11-03 11:41:50 -08:00
Martin Atkins
4d84aa3e10 CHANGELOG: Entry for opentofu/opentofu#3456
Signed-off-by: Martin Atkins <mart@degeneration.co.uk>
2025-11-03 11:27:13 -08:00
Martin Atkins
dd8c6f5db6 main: Honor the BROWSER environment variable on Unix systems
Prevously OpenTofu delegated browser launching entirely to the third-party
module github.com/cli/browser, which consists of a number of
platform-specific lists of executable commands to try to run to launch
a web browser.

On Unix systems there is also a de-facto convention of using an environment
variable called BROWSER to explicitly specify what to launch. That variable
can either point directly to a browser, or can point to a script which
implements some more complex policy for choosing a browser, such as
detecting whether the command is running in a GUI context and launching
either a GUI or textmode browser.

The BROWSER variable has been most commonly implemented with similar
treatment to earlier variables like EDITOR and PAGER where it's expected
to be set to just a single command to run, with the URL given as the first
and only argument. There was also an attempt to define a more complex
interpretation of this variable at http://www.catb.org/~esr/BROWSER/ , but
that extended treatment was only implemented in a small amount of software,
and those which implemented it did so slightly inconsistently due to the
specification being ambiguous.

OpenTofu's implementation therefore follows the common simpler convention,
but will silently ignore variable values it cannot use so that OpenTofu
won't fail when run in an environment that has that variable set in a way
that's intended for use by some other software. In that case OpenTofu
will continue to perform the default behavior as implemented in the
third-party library.

Because this convention is Unix-specific, OpenTofu will check for and use
this environment variable only on operating systems that the Go toolchain
considers to be "unix". This means that in particular on Windows systems
OpenTofu will continue to follow the Windows convention of specifying
the default browser via an entry in the Windows Registry.

As usual with this sort of system-integration mechanism it isn't really
viable to test this end-to-end in a portable way, but the main logic is
separated out into testable functions, and I manually tested this on my
own Linux system to verify that it works in a real OpenTofu executable.

Signed-off-by: Martin Atkins <mart@degeneration.co.uk>
2025-11-03 11:27:13 -08:00