aboutsummaryrefslogtreecommitdiffhomepage
path: root/vendor/github.com/hashicorp/terraform/svchost/auth/helper_program.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/hashicorp/terraform/svchost/auth/helper_program.go')
-rw-r--r--vendor/github.com/hashicorp/terraform/svchost/auth/helper_program.go80
1 files changed, 80 insertions, 0 deletions
diff --git a/vendor/github.com/hashicorp/terraform/svchost/auth/helper_program.go b/vendor/github.com/hashicorp/terraform/svchost/auth/helper_program.go
new file mode 100644
index 0000000..d72ffe3
--- /dev/null
+++ b/vendor/github.com/hashicorp/terraform/svchost/auth/helper_program.go
@@ -0,0 +1,80 @@
1package auth
2
3import (
4 "bytes"
5 "encoding/json"
6 "fmt"
7 "os/exec"
8 "path/filepath"
9
10 "github.com/hashicorp/terraform/svchost"
11)
12
13type helperProgramCredentialsSource struct {
14 executable string
15 args []string
16}
17
18// HelperProgramCredentialsSource returns a CredentialsSource that runs the
19// given program with the given arguments in order to obtain credentials.
20//
21// The given executable path must be an absolute path; it is the caller's
22// responsibility to validate and process a relative path or other input
23// provided by an end-user. If the given path is not absolute, this
24// function will panic.
25//
26// When credentials are requested, the program will be run in a child process
27// with the given arguments along with two additional arguments added to the
28// end of the list: the literal string "get", followed by the requested
29// hostname in ASCII compatibility form (punycode form).
30func HelperProgramCredentialsSource(executable string, args ...string) CredentialsSource {
31 if !filepath.IsAbs(executable) {
32 panic("NewCredentialsSourceHelperProgram requires absolute path to executable")
33 }
34
35 fullArgs := make([]string, len(args)+1)
36 fullArgs[0] = executable
37 copy(fullArgs[1:], args)
38
39 return &helperProgramCredentialsSource{
40 executable: executable,
41 args: fullArgs,
42 }
43}
44
45func (s *helperProgramCredentialsSource) ForHost(host svchost.Hostname) (HostCredentials, error) {
46 args := make([]string, len(s.args), len(s.args)+2)
47 copy(args, s.args)
48 args = append(args, "get")
49 args = append(args, string(host))
50
51 outBuf := bytes.Buffer{}
52 errBuf := bytes.Buffer{}
53
54 cmd := exec.Cmd{
55 Path: s.executable,
56 Args: args,
57 Stdin: nil,
58 Stdout: &outBuf,
59 Stderr: &errBuf,
60 }
61 err := cmd.Run()
62 if _, isExitErr := err.(*exec.ExitError); isExitErr {
63 errText := errBuf.String()
64 if errText == "" {
65 // Shouldn't happen for a well-behaved helper program
66 return nil, fmt.Errorf("error in %s, but it produced no error message", s.executable)
67 }
68 return nil, fmt.Errorf("error in %s: %s", s.executable, errText)
69 } else if err != nil {
70 return nil, fmt.Errorf("failed to run %s: %s", s.executable, err)
71 }
72
73 var m map[string]interface{}
74 err = json.Unmarshal(outBuf.Bytes(), &m)
75 if err != nil {
76 return nil, fmt.Errorf("malformed output from %s: %s", s.executable, err)
77 }
78
79 return HostCredentialsFromMap(m), nil
80}