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