diff options
Diffstat (limited to 'vendor/github.com/hashicorp/terraform/svchost/auth')
6 files changed, 259 insertions, 0 deletions
diff --git a/vendor/github.com/hashicorp/terraform/svchost/auth/cache.go b/vendor/github.com/hashicorp/terraform/svchost/auth/cache.go new file mode 100644 index 0000000..4f0d168 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform/svchost/auth/cache.go | |||
@@ -0,0 +1,45 @@ | |||
1 | package auth | ||
2 | |||
3 | import ( | ||
4 | "github.com/hashicorp/terraform/svchost" | ||
5 | ) | ||
6 | |||
7 | // CachingCredentialsSource creates a new credentials source that wraps another | ||
8 | // and caches its results in memory, on a per-hostname basis. | ||
9 | // | ||
10 | // No means is provided for expiration of cached credentials, so a caching | ||
11 | // credentials source should have a limited lifetime (one Terraform operation, | ||
12 | // for example) to ensure that time-limited credentials don't expire before | ||
13 | // their cache entries do. | ||
14 | func CachingCredentialsSource(source CredentialsSource) CredentialsSource { | ||
15 | return &cachingCredentialsSource{ | ||
16 | source: source, | ||
17 | cache: map[svchost.Hostname]HostCredentials{}, | ||
18 | } | ||
19 | } | ||
20 | |||
21 | type cachingCredentialsSource struct { | ||
22 | source CredentialsSource | ||
23 | cache map[svchost.Hostname]HostCredentials | ||
24 | } | ||
25 | |||
26 | // ForHost passes the given hostname on to the wrapped credentials source and | ||
27 | // caches the result to return for future requests with the same hostname. | ||
28 | // | ||
29 | // Both credentials and non-credentials (nil) responses are cached. | ||
30 | // | ||
31 | // No cache entry is created if the wrapped source returns an error, to allow | ||
32 | // the caller to retry the failing operation. | ||
33 | func (s *cachingCredentialsSource) ForHost(host svchost.Hostname) (HostCredentials, error) { | ||
34 | if cache, cached := s.cache[host]; cached { | ||
35 | return cache, nil | ||
36 | } | ||
37 | |||
38 | result, err := s.source.ForHost(host) | ||
39 | if err != nil { | ||
40 | return result, err | ||
41 | } | ||
42 | |||
43 | s.cache[host] = result | ||
44 | return result, nil | ||
45 | } | ||
diff --git a/vendor/github.com/hashicorp/terraform/svchost/auth/credentials.go b/vendor/github.com/hashicorp/terraform/svchost/auth/credentials.go new file mode 100644 index 0000000..0372c16 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform/svchost/auth/credentials.go | |||
@@ -0,0 +1,63 @@ | |||
1 | // Package auth contains types and functions to manage authentication | ||
2 | // credentials for service hosts. | ||
3 | package auth | ||
4 | |||
5 | import ( | ||
6 | "net/http" | ||
7 | |||
8 | "github.com/hashicorp/terraform/svchost" | ||
9 | ) | ||
10 | |||
11 | // Credentials is a list of CredentialsSource objects that can be tried in | ||
12 | // turn until one returns credentials for a host, or one returns an error. | ||
13 | // | ||
14 | // A Credentials is itself a CredentialsSource, wrapping its members. | ||
15 | // In principle one CredentialsSource can be nested inside another, though | ||
16 | // there is no good reason to do so. | ||
17 | type Credentials []CredentialsSource | ||
18 | |||
19 | // NoCredentials is an empty CredentialsSource that always returns nil | ||
20 | // when asked for credentials. | ||
21 | var NoCredentials CredentialsSource = Credentials{} | ||
22 | |||
23 | // A CredentialsSource is an object that may be able to provide credentials | ||
24 | // for a given host. | ||
25 | // | ||
26 | // Credentials lookups are not guaranteed to be concurrency-safe. Callers | ||
27 | // using these facilities in concurrent code must use external concurrency | ||
28 | // primitives to prevent race conditions. | ||
29 | type CredentialsSource interface { | ||
30 | // ForHost returns a non-nil HostCredentials if the source has credentials | ||
31 | // available for the host, and a nil HostCredentials if it does not. | ||
32 | // | ||
33 | // If an error is returned, progress through a list of CredentialsSources | ||
34 | // is halted and the error is returned to the user. | ||
35 | ForHost(host svchost.Hostname) (HostCredentials, error) | ||
36 | } | ||
37 | |||
38 | // HostCredentials represents a single set of credentials for a particular | ||
39 | // host. | ||
40 | type HostCredentials interface { | ||
41 | // PrepareRequest modifies the given request in-place to apply the | ||
42 | // receiving credentials. The usual behavior of this method is to | ||
43 | // add some sort of Authorization header to the request. | ||
44 | PrepareRequest(req *http.Request) | ||
45 | |||
46 | // Token returns the authentication token. | ||
47 | Token() string | ||
48 | } | ||
49 | |||
50 | // ForHost iterates over the contained CredentialsSource objects and | ||
51 | // tries to obtain credentials for the given host from each one in turn. | ||
52 | // | ||
53 | // If any source returns either a non-nil HostCredentials or a non-nil error | ||
54 | // then this result is returned. Otherwise, the result is nil, nil. | ||
55 | func (c Credentials) ForHost(host svchost.Hostname) (HostCredentials, error) { | ||
56 | for _, source := range c { | ||
57 | creds, err := source.ForHost(host) | ||
58 | if creds != nil || err != nil { | ||
59 | return creds, err | ||
60 | } | ||
61 | } | ||
62 | return nil, nil | ||
63 | } | ||
diff --git a/vendor/github.com/hashicorp/terraform/svchost/auth/from_map.go b/vendor/github.com/hashicorp/terraform/svchost/auth/from_map.go new file mode 100644 index 0000000..f91006a --- /dev/null +++ b/vendor/github.com/hashicorp/terraform/svchost/auth/from_map.go | |||
@@ -0,0 +1,18 @@ | |||
1 | package auth | ||
2 | |||
3 | // HostCredentialsFromMap converts a map of key-value pairs from a credentials | ||
4 | // definition provided by the user (e.g. in a config file, or via a credentials | ||
5 | // helper) into a HostCredentials object if possible, or returns nil if | ||
6 | // no credentials could be extracted from the map. | ||
7 | // | ||
8 | // This function ignores map keys it is unfamiliar with, to allow for future | ||
9 | // expansion of the credentials map format for new credential types. | ||
10 | func HostCredentialsFromMap(m map[string]interface{}) HostCredentials { | ||
11 | if m == nil { | ||
12 | return nil | ||
13 | } | ||
14 | if token, ok := m["token"].(string); ok { | ||
15 | return HostCredentialsToken(token) | ||
16 | } | ||
17 | return nil | ||
18 | } | ||
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 @@ | |||
1 | package auth | ||
2 | |||
3 | import ( | ||
4 | "bytes" | ||
5 | "encoding/json" | ||
6 | "fmt" | ||
7 | "os/exec" | ||
8 | "path/filepath" | ||
9 | |||
10 | "github.com/hashicorp/terraform/svchost" | ||
11 | ) | ||
12 | |||
13 | type 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). | ||
30 | func 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 | |||
45 | func (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 | } | ||
diff --git a/vendor/github.com/hashicorp/terraform/svchost/auth/static.go b/vendor/github.com/hashicorp/terraform/svchost/auth/static.go new file mode 100644 index 0000000..5373fdd --- /dev/null +++ b/vendor/github.com/hashicorp/terraform/svchost/auth/static.go | |||
@@ -0,0 +1,28 @@ | |||
1 | package auth | ||
2 | |||
3 | import ( | ||
4 | "github.com/hashicorp/terraform/svchost" | ||
5 | ) | ||
6 | |||
7 | // StaticCredentialsSource is a credentials source that retrieves credentials | ||
8 | // from the provided map. It returns nil if a requested hostname is not | ||
9 | // present in the map. | ||
10 | // | ||
11 | // The caller should not modify the given map after passing it to this function. | ||
12 | func StaticCredentialsSource(creds map[svchost.Hostname]map[string]interface{}) CredentialsSource { | ||
13 | return staticCredentialsSource(creds) | ||
14 | } | ||
15 | |||
16 | type staticCredentialsSource map[svchost.Hostname]map[string]interface{} | ||
17 | |||
18 | func (s staticCredentialsSource) ForHost(host svchost.Hostname) (HostCredentials, error) { | ||
19 | if s == nil { | ||
20 | return nil, nil | ||
21 | } | ||
22 | |||
23 | if m, exists := s[host]; exists { | ||
24 | return HostCredentialsFromMap(m), nil | ||
25 | } | ||
26 | |||
27 | return nil, nil | ||
28 | } | ||
diff --git a/vendor/github.com/hashicorp/terraform/svchost/auth/token_credentials.go b/vendor/github.com/hashicorp/terraform/svchost/auth/token_credentials.go new file mode 100644 index 0000000..9358bcb --- /dev/null +++ b/vendor/github.com/hashicorp/terraform/svchost/auth/token_credentials.go | |||
@@ -0,0 +1,25 @@ | |||
1 | package auth | ||
2 | |||
3 | import ( | ||
4 | "net/http" | ||
5 | ) | ||
6 | |||
7 | // HostCredentialsToken is a HostCredentials implementation that represents a | ||
8 | // single "bearer token", to be sent to the server via an Authorization header | ||
9 | // with the auth type set to "Bearer" | ||
10 | type HostCredentialsToken string | ||
11 | |||
12 | // PrepareRequest alters the given HTTP request by setting its Authorization | ||
13 | // header to the string "Bearer " followed by the encapsulated authentication | ||
14 | // token. | ||
15 | func (tc HostCredentialsToken) PrepareRequest(req *http.Request) { | ||
16 | if req.Header == nil { | ||
17 | req.Header = http.Header{} | ||
18 | } | ||
19 | req.Header.Set("Authorization", "Bearer "+string(tc)) | ||
20 | } | ||
21 | |||
22 | // Token returns the authentication token. | ||
23 | func (tc HostCredentialsToken) Token() string { | ||
24 | return string(tc) | ||
25 | } | ||