aboutsummaryrefslogtreecommitdiffhomepage
path: root/vendor/github.com/hashicorp/terraform/plugin/discovery/requirements.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/hashicorp/terraform/plugin/discovery/requirements.go')
-rw-r--r--vendor/github.com/hashicorp/terraform/plugin/discovery/requirements.go105
1 files changed, 105 insertions, 0 deletions
diff --git a/vendor/github.com/hashicorp/terraform/plugin/discovery/requirements.go b/vendor/github.com/hashicorp/terraform/plugin/discovery/requirements.go
new file mode 100644
index 0000000..75430fd
--- /dev/null
+++ b/vendor/github.com/hashicorp/terraform/plugin/discovery/requirements.go
@@ -0,0 +1,105 @@
1package discovery
2
3import (
4 "bytes"
5)
6
7// PluginRequirements describes a set of plugins (assumed to be of a consistent
8// kind) that are required to exist and have versions within the given
9// corresponding sets.
10type PluginRequirements map[string]*PluginConstraints
11
12// PluginConstraints represents an element of PluginRequirements describing
13// the constraints for a single plugin.
14type PluginConstraints struct {
15 // Specifies that the plugin's version must be within the given
16 // constraints.
17 Versions Constraints
18
19 // If non-nil, the hash of the on-disk plugin executable must exactly
20 // match the SHA256 hash given here.
21 SHA256 []byte
22}
23
24// Allows returns true if the given version is within the receiver's version
25// constraints.
26func (s *PluginConstraints) Allows(v Version) bool {
27 return s.Versions.Allows(v)
28}
29
30// AcceptsSHA256 returns true if the given executable SHA256 hash is acceptable,
31// either because it matches the constraint or because there is no such
32// constraint.
33func (s *PluginConstraints) AcceptsSHA256(digest []byte) bool {
34 if s.SHA256 == nil {
35 return true
36 }
37 return bytes.Equal(s.SHA256, digest)
38}
39
40// Merge takes the contents of the receiver and the other given requirements
41// object and merges them together into a single requirements structure
42// that satisfies both sets of requirements.
43//
44// Note that it doesn't make sense to merge two PluginRequirements with
45// differing required plugin SHA256 hashes, since the result will never
46// match any plugin.
47func (r PluginRequirements) Merge(other PluginRequirements) PluginRequirements {
48 ret := make(PluginRequirements)
49 for n, c := range r {
50 ret[n] = &PluginConstraints{
51 Versions: Constraints{}.Append(c.Versions),
52 SHA256: c.SHA256,
53 }
54 }
55 for n, c := range other {
56 if existing, exists := ret[n]; exists {
57 ret[n].Versions = ret[n].Versions.Append(c.Versions)
58
59 if existing.SHA256 != nil {
60 if c.SHA256 != nil && !bytes.Equal(c.SHA256, existing.SHA256) {
61 // If we've been asked to merge two constraints with
62 // different SHA256 hashes then we'll produce a dummy value
63 // that can never match anything. This is a silly edge case
64 // that no reasonable caller should hit.
65 ret[n].SHA256 = []byte(invalidProviderHash)
66 }
67 } else {
68 ret[n].SHA256 = c.SHA256 // might still be nil
69 }
70 } else {
71 ret[n] = &PluginConstraints{
72 Versions: Constraints{}.Append(c.Versions),
73 SHA256: c.SHA256,
74 }
75 }
76 }
77 return ret
78}
79
80// LockExecutables applies additional constraints to the receiver that
81// require plugin executables with specific SHA256 digests. This modifies
82// the receiver in-place, since it's intended to be applied after
83// version constraints have been resolved.
84//
85// The given map must include a key for every plugin that is already
86// required. If not, any missing keys will cause the corresponding plugin
87// to never match, though the direct caller doesn't necessarily need to
88// guarantee this as long as the downstream code _applying_ these constraints
89// is able to deal with the non-match in some way.
90func (r PluginRequirements) LockExecutables(sha256s map[string][]byte) {
91 for name, cons := range r {
92 digest := sha256s[name]
93
94 if digest == nil {
95 // Prevent any match, which will then presumably cause the
96 // downstream consumer of this requirements to report an error.
97 cons.SHA256 = []byte(invalidProviderHash)
98 continue
99 }
100
101 cons.SHA256 = digest
102 }
103}
104
105const invalidProviderHash = "<invalid>"