From e45db75c889008147759c4481cbd2708819c2ff6 Mon Sep 17 00:00:00 2001 From: Johannes Liebermann Date: Tue, 11 Aug 2020 20:27:16 +0200 Subject: [PATCH] pkg/terraform: Unexport low-level functions ExecuteSync() and ExecuteAsync() are low level functions and are used mainly internally by pkg/terraform. Add a dedicated Output() method to the Executor API. Callers should not have to allow on low-level functions to get outputs. --- pkg/dns/dns.go | 2 +- pkg/terraform/executor.go | 26 ++++++++++++++++++-------- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/pkg/dns/dns.go b/pkg/dns/dns.go index edc8fea5c..dde1be621 100644 --- a/pkg/dns/dns.go +++ b/pkg/dns/dns.go @@ -107,7 +107,7 @@ func ManualConfigPrompt(c *Config) terraform.ExecutionHook { } func readDNSEntries(ex *terraform.Executor) ([]dnsEntry, error) { - output, err := ex.ExecuteSync("output", "-json", "dns_entries") + output, err := ex.OutputBytes("dns_entries") if err != nil { return nil, errors.Wrap(err, "failed to get DNS entries") } diff --git a/pkg/terraform/executor.go b/pkg/terraform/executor.go index fe7a22f0b..ea45e9be2 100644 --- a/pkg/terraform/executor.go +++ b/pkg/terraform/executor.go @@ -235,7 +235,7 @@ func (ex *Executor) executeVerbose(args ...string) error { } func (ex *Executor) execute(verbose bool, args ...string) error { - pid, done, err := ex.ExecuteAsync(args...) + pid, done, err := ex.executeAsync(args...) if err != nil { return fmt.Errorf( "executing Terraform with arguments '%s' in directory %s: %w", @@ -327,17 +327,17 @@ func (ex *Executor) LoadVars() (map[string]interface{}, error) { return nil, errors.New("Could not parse config as JSON object") } -// ExecuteAsync runs the given command and arguments against Terraform, and returns +// executeAsync runs the given command and arguments against Terraform, and returns // an identifier that can be used to read the output of the process as it is // executed and after. // -// ExecuteAsync is non-blocking, and takes a lock in the execution path. +// This function is non-blocking, and takes a lock in the execution path. // Locking is handled by Terraform itself. // // An error is returned if the Terraform binary could not be found, or if the // Terraform call itself failed, in which case, details can be found in the // output. -func (ex *Executor) ExecuteAsync(args ...string) (int, chan struct{}, error) { +func (ex *Executor) executeAsync(args ...string) (int, chan struct{}, error) { cmd := ex.generateCommand(args...) rPipe, wPipe := io.Pipe() cmd.Stdout = wPipe @@ -381,8 +381,8 @@ func (ex *Executor) ExecuteAsync(args ...string) (int, chan struct{}, error) { return cmd.Process.Pid, done, nil } -// ExecuteSync is like Execute, but synchronous. -func (ex *Executor) ExecuteSync(args ...string) ([]byte, error) { +// executeSync is like executeAsync, but synchronous. +func (ex *Executor) executeSync(args ...string) ([]byte, error) { // Initialize the signal handler. h := signalHandler(ex.logger) @@ -412,7 +412,7 @@ func (ex *Executor) Plan() error { // Output gets output value from Terraform in JSON format and tries to unmarshal it // to a given struct. func (ex *Executor) Output(key string, s interface{}) error { - o, err := ex.ExecuteSync("output", "-json", key) + o, err := ex.executeSync("output", "-json", key) if err != nil { return fmt.Errorf("failed getting Terraform output for key %q: %w", key, err) } @@ -420,6 +420,16 @@ func (ex *Executor) Output(key string, s interface{}) error { return json.Unmarshal(o, s) } +// OutputBytes returns the value of the Terraform output key in JSON format as a byte slice. +func (ex *Executor) OutputBytes(key string) ([]byte, error) { + o, err := ex.executeSync("output", "-json", key) + if err != nil { + return []byte{}, fmt.Errorf("getting Terraform output for key %q: %w", key, err) + } + + return o, nil +} + // GenerateCommand prepares a Terraform command with the given arguments // by setting up the command, configuration, working directory // (so the files such as terraform.tfstate are stored at the right place) and @@ -514,7 +524,7 @@ func (ex *Executor) logPath(id int) string { } func (ex *Executor) checkVersion() error { - vOutput, err := ex.ExecuteSync("--version") + vOutput, err := ex.executeSync("--version") if err != nil { return fmt.Errorf("Error checking Terraform version: %w", err) }