| // Copyright IBM Corp. 2014, 2026 | |
| // SPDX-License-Identifier: BUSL-1.1 | |
| package cloud | |
| import ( | |
| "github.com/hashicorp/hcl/v2/hclwrite" | |
| "github.com/hashicorp/terraform/internal/backend/backendrun" | |
| "github.com/hashicorp/terraform/internal/command/arguments" | |
| "github.com/hashicorp/terraform/internal/configs" | |
| "github.com/hashicorp/terraform/internal/terraform" | |
| "github.com/hashicorp/terraform/internal/tfdiags" | |
| ) | |
| func allowedSourceType(source terraform.ValueSourceType) bool { | |
| return source == terraform.ValueFromNamedFile || source == terraform.ValueFromCLIArg || source == terraform.ValueFromEnvVar | |
| } | |
| // ParseCloudRunVariables accepts a mapping of unparsed values and a mapping of variable | |
| // declarations and returns a name/value variable map appropriate for an API run context, | |
| // that is, containing variables only sourced from non-file inputs like CLI args | |
| // and environment variables. However, all variable parsing diagnostics are returned | |
| // in order to allow callers to short circuit cloud runs that contain variable | |
| // declaration or parsing errors. The only exception is that missing required values are not | |
| // considered errors because they may be defined within the cloud workspace. | |
| func ParseCloudRunVariables(vv map[string]arguments.UnparsedVariableValue, decls map[string]*configs.Variable) (map[string]string, tfdiags.Diagnostics) { | |
| declared, diags := backendrun.ParseDeclaredVariableValues(vv, decls) | |
| _, undedeclaredDiags := backendrun.ParseUndeclaredVariableValues(vv, decls) | |
| diags = diags.Append(undedeclaredDiags) | |
| ret := make(map[string]string, len(declared)) | |
| // Even if there are parsing or declaration errors, populate the return map with the | |
| // variables that could be used for cloud runs | |
| for name, v := range declared { | |
| if !allowedSourceType(v.SourceType) { | |
| continue | |
| } | |
| // RunVariables are always expressed as HCL strings | |
| tokens := hclwrite.TokensForValue(v.Value) | |
| ret[name] = string(tokens.Bytes()) | |
| } | |
| return ret, diags | |
| } | |
| // ParseCloudRunTestVariables is similar to ParseCloudVariables, except it does | |
| // not make any assumptions about variables needed by the configuration. | |
| // | |
| // Within a test run execution, variables can be defined inside test files and | |
| // inside child modules as well as the main configuration and it is a lot of | |
| // effort to track down exactly where variable definitions exist. We just accept | |
| // all values. | |
| func ParseCloudRunTestVariables(globals map[string]arguments.UnparsedVariableValue) (map[string]string, tfdiags.Diagnostics) { | |
| var diags tfdiags.Diagnostics | |
| ret := make(map[string]string, len(globals)) | |
| for name, v := range globals { | |
| variable, variableDiags := v.ParseVariableValue(configs.VariableParseLiteral) | |
| diags = diags.Append(variableDiags) | |
| if variableDiags.HasErrors() { | |
| continue | |
| } | |
| if !allowedSourceType(variable.SourceType) { | |
| continue | |
| } | |
| tokens := hclwrite.TokensForValue(variable.Value) | |
| ret[name] = string(tokens.Bytes()) | |
| } | |
| return ret, diags | |
| } |