mirror of
https://github.com/opentofu/opentofu.git
synced 2025-02-25 18:45:20 -06:00
Draft: TofuPipes experiment v1
Signed-off-by: AbstractionFactory <179820029+abstractionfactory@users.noreply.github.com>
This commit is contained in:
parent
ecac914580
commit
499a3de7a6
@ -228,8 +228,10 @@ func (o *Operation) Parse() tfdiags.Diagnostics {
|
|||||||
// desirable for the arguments package to handle the gathering of variables
|
// desirable for the arguments package to handle the gathering of variables
|
||||||
// directly, returning a map of variable values.
|
// directly, returning a map of variable values.
|
||||||
type Vars struct {
|
type Vars struct {
|
||||||
vars *flagNameValueSlice
|
vars *flagNameValueSlice
|
||||||
varFiles *flagNameValueSlice
|
varFiles *flagNameValueSlice
|
||||||
|
varCommands *flagNameValueSlice
|
||||||
|
varUpstream *flagNameValueSlice
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *Vars) All() []FlagNameValue {
|
func (v *Vars) All() []FlagNameValue {
|
||||||
@ -279,10 +281,17 @@ func extendedFlagSet(name string, state *State, operation *Operation, vars *Vars
|
|||||||
if vars != nil {
|
if vars != nil {
|
||||||
varsFlags := newFlagNameValueSlice("-var")
|
varsFlags := newFlagNameValueSlice("-var")
|
||||||
varFilesFlags := varsFlags.Alias("-var-file")
|
varFilesFlags := varsFlags.Alias("-var-file")
|
||||||
|
varCommandsFlags := varsFlags.Alias("-var-command")
|
||||||
|
varUpstreamFlags := varsFlags.Alias("-var-upstream")
|
||||||
|
|
||||||
vars.vars = &varsFlags
|
vars.vars = &varsFlags
|
||||||
vars.varFiles = &varFilesFlags
|
vars.varFiles = &varFilesFlags
|
||||||
|
vars.varCommands = &varCommandsFlags
|
||||||
|
vars.varUpstream = &varUpstreamFlags
|
||||||
f.Var(vars.vars, "var", "var")
|
f.Var(vars.vars, "var", "var")
|
||||||
f.Var(vars.varFiles, "var-file", "var-file")
|
f.Var(vars.varFiles, "var-file", "var-file")
|
||||||
|
f.Var(vars.varCommands, "var-command", "var-command")
|
||||||
|
f.Var(vars.varUpstream, "var-upstream", "var-upstream")
|
||||||
}
|
}
|
||||||
|
|
||||||
return f
|
return f
|
||||||
|
@ -611,8 +611,12 @@ func (m *Meta) varFlagSet(f *flag.FlagSet) {
|
|||||||
}
|
}
|
||||||
varValues := m.variableArgs.Alias("-var")
|
varValues := m.variableArgs.Alias("-var")
|
||||||
varFiles := m.variableArgs.Alias("-var-file")
|
varFiles := m.variableArgs.Alias("-var-file")
|
||||||
|
varCommands := m.variableArgs.Alias("-var-command")
|
||||||
|
varUpstream := m.variableArgs.Alias("var-upstream")
|
||||||
f.Var(varValues, "var", "variables")
|
f.Var(varValues, "var", "variables")
|
||||||
f.Var(varFiles, "var-file", "variable file")
|
f.Var(varFiles, "var-file", "variable file")
|
||||||
|
f.Var(varCommands, "var-command", "run this external command to obtain variable values")
|
||||||
|
f.Var(varUpstream, "var-upstream", "obtain values from this OpenTofu project's outputs")
|
||||||
}
|
}
|
||||||
|
|
||||||
// extendedFlagSet adds custom flags that are mostly used by commands
|
// extendedFlagSet adds custom flags that are mostly used by commands
|
||||||
|
@ -6,9 +6,12 @@
|
|||||||
package command
|
package command
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/hashicorp/hcl/v2"
|
"github.com/hashicorp/hcl/v2"
|
||||||
@ -120,7 +123,22 @@ func (m *Meta) collectVariableValues() (map[string]backend.UnparsedVariableValue
|
|||||||
case "-var-file":
|
case "-var-file":
|
||||||
moreDiags := m.addVarsFromFile(rawFlag.Value, tofu.ValueFromNamedFile, ret)
|
moreDiags := m.addVarsFromFile(rawFlag.Value, tofu.ValueFromNamedFile, ret)
|
||||||
diags = diags.Append(moreDiags)
|
diags = diags.Append(moreDiags)
|
||||||
|
case "-var-upstream":
|
||||||
|
moreDiags := m.addVarsFromCommand(
|
||||||
|
[]string{os.Args[0], "-chdir=" + rawFlag.Value, "output", "-json"},
|
||||||
|
tofu.ValueFromUpstreamProject,
|
||||||
|
ret,
|
||||||
|
)
|
||||||
|
diags = diags.Append(moreDiags)
|
||||||
|
case "-var-command":
|
||||||
|
var args []string
|
||||||
|
if runtime.GOOS == "" {
|
||||||
|
args = []string{"cmd", "/C"}
|
||||||
|
} else {
|
||||||
|
args = []string{"/bin/sh", "-c"}
|
||||||
|
}
|
||||||
|
moreDiags := m.addVarsFromCommand(append(args, rawFlag.Value), tofu.ValueFromExternalCommand, ret)
|
||||||
|
diags = diags.Append(moreDiags)
|
||||||
default:
|
default:
|
||||||
// Should never happen; always a bug in the code that built up
|
// Should never happen; always a bug in the code that built up
|
||||||
// the contents of m.variableArgs.
|
// the contents of m.variableArgs.
|
||||||
@ -163,6 +181,28 @@ func (m *Meta) addVarsFromDir(currDir string, ret map[string]backend.UnparsedVar
|
|||||||
return diags
|
return diags
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *Meta) addVarsFromCommand(args []string, sourceType tofu.ValueSourceType, to map[string]backend.UnparsedVariableValue) tfdiags.Diagnostics {
|
||||||
|
var diags tfdiags.Diagnostics
|
||||||
|
cmd := exec.CommandContext(m.CommandContext(), args[0], args[1:]...)
|
||||||
|
output := &bytes.Buffer{}
|
||||||
|
cmd.Stdout = output
|
||||||
|
cmd.Stderr = os.Stderr
|
||||||
|
if err := cmd.Run(); err != nil {
|
||||||
|
diags = diags.Append(tfdiags.Sourceless(
|
||||||
|
tfdiags.Error,
|
||||||
|
"Failed to execute external command",
|
||||||
|
err.Error(),
|
||||||
|
))
|
||||||
|
return diags
|
||||||
|
}
|
||||||
|
data := output.Bytes()
|
||||||
|
var json = false
|
||||||
|
if len(data) > 0 && data[0] == '{' {
|
||||||
|
json = true
|
||||||
|
}
|
||||||
|
return m.loadVariableSource("", json, sourceType, to, data)
|
||||||
|
}
|
||||||
|
|
||||||
func (m *Meta) addVarsFromFile(filename string, sourceType tofu.ValueSourceType, to map[string]backend.UnparsedVariableValue) tfdiags.Diagnostics {
|
func (m *Meta) addVarsFromFile(filename string, sourceType tofu.ValueSourceType, to map[string]backend.UnparsedVariableValue) tfdiags.Diagnostics {
|
||||||
var diags tfdiags.Diagnostics
|
var diags tfdiags.Diagnostics
|
||||||
|
|
||||||
@ -184,17 +224,6 @@ func (m *Meta) addVarsFromFile(filename string, sourceType tofu.ValueSourceType,
|
|||||||
return diags
|
return diags
|
||||||
}
|
}
|
||||||
|
|
||||||
loader, err := m.initConfigLoader()
|
|
||||||
if err != nil {
|
|
||||||
diags = diags.Append(err)
|
|
||||||
return diags
|
|
||||||
}
|
|
||||||
|
|
||||||
// Record the file source code for snippets in diagnostic messages.
|
|
||||||
loader.Parser().ForceFileSource(filename, src)
|
|
||||||
|
|
||||||
var f *hcl.File
|
|
||||||
|
|
||||||
extJSON := strings.HasSuffix(filename, ".json")
|
extJSON := strings.HasSuffix(filename, ".json")
|
||||||
extTfvars := strings.HasSuffix(filename, DefaultVarsExtension)
|
extTfvars := strings.HasSuffix(filename, DefaultVarsExtension)
|
||||||
|
|
||||||
@ -202,7 +231,26 @@ func (m *Meta) addVarsFromFile(filename string, sourceType tofu.ValueSourceType,
|
|||||||
// Ex: -var-file=<(./scripts/vars.sh)
|
// Ex: -var-file=<(./scripts/vars.sh)
|
||||||
detectJSON := !extJSON && !extTfvars && strings.HasPrefix(strings.TrimSpace(string(src)), "{")
|
detectJSON := !extJSON && !extTfvars && strings.HasPrefix(strings.TrimSpace(string(src)), "{")
|
||||||
|
|
||||||
if extJSON || detectJSON {
|
return m.loadVariableSource(filename, extJSON || detectJSON, sourceType, to, src)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Meta) loadVariableSource(filename string, json bool, sourceType tofu.ValueSourceType, to map[string]backend.UnparsedVariableValue, src []byte) tfdiags.Diagnostics {
|
||||||
|
var diags tfdiags.Diagnostics
|
||||||
|
|
||||||
|
loader, err := m.initConfigLoader()
|
||||||
|
if err != nil {
|
||||||
|
diags = diags.Append(err)
|
||||||
|
return diags
|
||||||
|
}
|
||||||
|
|
||||||
|
// Record the file source code for snippets in diagnostic messages.
|
||||||
|
if filename != "" {
|
||||||
|
loader.Parser().ForceFileSource(filename, src)
|
||||||
|
}
|
||||||
|
|
||||||
|
var f *hcl.File
|
||||||
|
|
||||||
|
if json {
|
||||||
var hclDiags hcl.Diagnostics
|
var hclDiags hcl.Diagnostics
|
||||||
f, hclDiags = hcljson.Parse(src, filename)
|
f, hclDiags = hcljson.Parse(src, filename)
|
||||||
diags = diags.Append(hclDiags)
|
diags = diags.Append(hclDiags)
|
||||||
|
@ -107,6 +107,14 @@ const (
|
|||||||
// ValueFromCaller indicates that the value was explicitly overridden by
|
// ValueFromCaller indicates that the value was explicitly overridden by
|
||||||
// a caller to Context.SetVariable after the context was constructed.
|
// a caller to Context.SetVariable after the context was constructed.
|
||||||
ValueFromCaller ValueSourceType = 'S'
|
ValueFromCaller ValueSourceType = 'S'
|
||||||
|
|
||||||
|
// ValueFromExternalCommand indicates that the value was obtained by executing
|
||||||
|
// an external command.
|
||||||
|
ValueFromExternalCommand ValueSourceType = 'X'
|
||||||
|
|
||||||
|
// ValueFromUpstreamProject indicates that the value was obtained by querying
|
||||||
|
// the state of an upstream project.
|
||||||
|
ValueFromUpstreamProject ValueSourceType = 'U'
|
||||||
)
|
)
|
||||||
|
|
||||||
func (v *InputValue) GoString() string {
|
func (v *InputValue) GoString() string {
|
||||||
|
Loading…
Reference in New Issue
Block a user