diff options
Diffstat (limited to 'vendor/github.com/hashicorp/terraform/helper/experiment')
-rw-r--r-- | vendor/github.com/hashicorp/terraform/helper/experiment/experiment.go | 154 | ||||
-rw-r--r-- | vendor/github.com/hashicorp/terraform/helper/experiment/id.go | 34 |
2 files changed, 188 insertions, 0 deletions
diff --git a/vendor/github.com/hashicorp/terraform/helper/experiment/experiment.go b/vendor/github.com/hashicorp/terraform/helper/experiment/experiment.go new file mode 100644 index 0000000..18b8837 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform/helper/experiment/experiment.go | |||
@@ -0,0 +1,154 @@ | |||
1 | // experiment package contains helper functions for tracking experimental | ||
2 | // features throughout Terraform. | ||
3 | // | ||
4 | // This package should be used for creating, enabling, querying, and deleting | ||
5 | // experimental features. By unifying all of that onto a single interface, | ||
6 | // we can have the Go compiler help us by enforcing every place we touch | ||
7 | // an experimental feature. | ||
8 | // | ||
9 | // To create a new experiment: | ||
10 | // | ||
11 | // 1. Add the experiment to the global vars list below, prefixed with X_ | ||
12 | // | ||
13 | // 2. Add the experiment variable to the All listin the init() function | ||
14 | // | ||
15 | // 3. Use it! | ||
16 | // | ||
17 | // To remove an experiment: | ||
18 | // | ||
19 | // 1. Delete the experiment global var. | ||
20 | // | ||
21 | // 2. Try to compile and fix all the places where the var was referenced. | ||
22 | // | ||
23 | // To use an experiment: | ||
24 | // | ||
25 | // 1. Use Flag() if you want the experiment to be available from the CLI. | ||
26 | // | ||
27 | // 2. Use Enabled() to check whether it is enabled. | ||
28 | // | ||
29 | // As a general user: | ||
30 | // | ||
31 | // 1. The `-Xexperiment-name` flag | ||
32 | // 2. The `TF_X_<experiment-name>` env var. | ||
33 | // 3. The `TF_X_FORCE` env var can be set to force an experimental feature | ||
34 | // without human verifications. | ||
35 | // | ||
36 | package experiment | ||
37 | |||
38 | import ( | ||
39 | "flag" | ||
40 | "fmt" | ||
41 | "os" | ||
42 | "strconv" | ||
43 | "strings" | ||
44 | "sync" | ||
45 | ) | ||
46 | |||
47 | // The experiments that are available are listed below. Any package in | ||
48 | // Terraform defining an experiment should define the experiments below. | ||
49 | // By keeping them all within the experiment package we force a single point | ||
50 | // of definition and use. This allows the compiler to enforce references | ||
51 | // so it becomes easy to remove the features. | ||
52 | var ( | ||
53 | // Shadow graph. This is already on by default. Disabling it will be | ||
54 | // allowed for awhile in order for it to not block operations. | ||
55 | X_shadow = newBasicID("shadow", "SHADOW", false) | ||
56 | ) | ||
57 | |||
58 | // Global variables this package uses because we are a package | ||
59 | // with global state. | ||
60 | var ( | ||
61 | // all is the list of all experiements. Do not modify this. | ||
62 | All []ID | ||
63 | |||
64 | // enabled keeps track of what flags have been enabled | ||
65 | enabled map[string]bool | ||
66 | enabledLock sync.Mutex | ||
67 | |||
68 | // Hidden "experiment" that forces all others to be on without verification | ||
69 | x_force = newBasicID("force", "FORCE", false) | ||
70 | ) | ||
71 | |||
72 | func init() { | ||
73 | // The list of all experiments, update this when an experiment is added. | ||
74 | All = []ID{ | ||
75 | X_shadow, | ||
76 | x_force, | ||
77 | } | ||
78 | |||
79 | // Load | ||
80 | reload() | ||
81 | } | ||
82 | |||
83 | // reload is used by tests to reload the global state. This is called by | ||
84 | // init publicly. | ||
85 | func reload() { | ||
86 | // Initialize | ||
87 | enabledLock.Lock() | ||
88 | enabled = make(map[string]bool) | ||
89 | enabledLock.Unlock() | ||
90 | |||
91 | // Set defaults and check env vars | ||
92 | for _, id := range All { | ||
93 | // Get the default value | ||
94 | def := id.Default() | ||
95 | |||
96 | // If we set it in the env var, default it to true | ||
97 | key := fmt.Sprintf("TF_X_%s", strings.ToUpper(id.Env())) | ||
98 | if v := os.Getenv(key); v != "" { | ||
99 | def = v != "0" | ||
100 | } | ||
101 | |||
102 | // Set the default | ||
103 | SetEnabled(id, def) | ||
104 | } | ||
105 | } | ||
106 | |||
107 | // Enabled returns whether an experiment has been enabled or not. | ||
108 | func Enabled(id ID) bool { | ||
109 | enabledLock.Lock() | ||
110 | defer enabledLock.Unlock() | ||
111 | return enabled[id.Flag()] | ||
112 | } | ||
113 | |||
114 | // SetEnabled sets an experiment to enabled/disabled. Please check with | ||
115 | // the experiment docs for when calling this actually affects the experiment. | ||
116 | func SetEnabled(id ID, v bool) { | ||
117 | enabledLock.Lock() | ||
118 | defer enabledLock.Unlock() | ||
119 | enabled[id.Flag()] = v | ||
120 | } | ||
121 | |||
122 | // Force returns true if the -Xforce of TF_X_FORCE flag is present, which | ||
123 | // advises users of this package to not verify with the user that they want | ||
124 | // experimental behavior and to just continue with it. | ||
125 | func Force() bool { | ||
126 | return Enabled(x_force) | ||
127 | } | ||
128 | |||
129 | // Flag configures the given FlagSet with the flags to configure | ||
130 | // all active experiments. | ||
131 | func Flag(fs *flag.FlagSet) { | ||
132 | for _, id := range All { | ||
133 | desc := id.Flag() | ||
134 | key := fmt.Sprintf("X%s", id.Flag()) | ||
135 | fs.Var(&idValue{X: id}, key, desc) | ||
136 | } | ||
137 | } | ||
138 | |||
139 | // idValue implements flag.Value for setting the enabled/disabled state | ||
140 | // of an experiment from the CLI. | ||
141 | type idValue struct { | ||
142 | X ID | ||
143 | } | ||
144 | |||
145 | func (v *idValue) IsBoolFlag() bool { return true } | ||
146 | func (v *idValue) String() string { return strconv.FormatBool(Enabled(v.X)) } | ||
147 | func (v *idValue) Set(raw string) error { | ||
148 | b, err := strconv.ParseBool(raw) | ||
149 | if err == nil { | ||
150 | SetEnabled(v.X, b) | ||
151 | } | ||
152 | |||
153 | return err | ||
154 | } | ||
diff --git a/vendor/github.com/hashicorp/terraform/helper/experiment/id.go b/vendor/github.com/hashicorp/terraform/helper/experiment/id.go new file mode 100644 index 0000000..8e2f707 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform/helper/experiment/id.go | |||
@@ -0,0 +1,34 @@ | |||
1 | package experiment | ||
2 | |||
3 | // ID represents an experimental feature. | ||
4 | // | ||
5 | // The global vars defined on this package should be used as ID values. | ||
6 | // This interface is purposely not implement-able outside of this package | ||
7 | // so that we can rely on the Go compiler to enforce all experiment references. | ||
8 | type ID interface { | ||
9 | Env() string | ||
10 | Flag() string | ||
11 | Default() bool | ||
12 | |||
13 | unexported() // So the ID can't be implemented externally. | ||
14 | } | ||
15 | |||
16 | // basicID implements ID. | ||
17 | type basicID struct { | ||
18 | EnvValue string | ||
19 | FlagValue string | ||
20 | DefaultValue bool | ||
21 | } | ||
22 | |||
23 | func newBasicID(flag, env string, def bool) ID { | ||
24 | return &basicID{ | ||
25 | EnvValue: env, | ||
26 | FlagValue: flag, | ||
27 | DefaultValue: def, | ||
28 | } | ||
29 | } | ||
30 | |||
31 | func (id *basicID) Env() string { return id.EnvValue } | ||
32 | func (id *basicID) Flag() string { return id.FlagValue } | ||
33 | func (id *basicID) Default() bool { return id.DefaultValue } | ||
34 | func (id *basicID) unexported() {} | ||