forked from hashicorp/terraform
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathconfig.go
142 lines (120 loc) · 3.95 KB
/
config.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
//go:generate go run ./scripts/generate-plugins.go
package main
import (
"fmt"
"io/ioutil"
"log"
"os"
"github.com/hashicorp/hcl"
"github.com/hashicorp/terraform/command"
)
const pluginCacheDirEnvVar = "TF_PLUGIN_CACHE_DIR"
// Config is the structure of the configuration for the Terraform CLI.
//
// This is not the configuration for Terraform itself. That is in the
// "config" package.
type Config struct {
Providers map[string]string
Provisioners map[string]string
DisableCheckpoint bool `hcl:"disable_checkpoint"`
DisableCheckpointSignature bool `hcl:"disable_checkpoint_signature"`
// If set, enables local caching of plugins in this directory to
// avoid repeatedly re-downloading over the Internet.
PluginCacheDir string `hcl:"plugin_cache_dir"`
}
// BuiltinConfig is the built-in defaults for the configuration. These
// can be overridden by user configurations.
var BuiltinConfig Config
// PluginOverrides are paths that override discovered plugins, set from
// the config file.
var PluginOverrides command.PluginOverrides
// ConfigFile returns the default path to the configuration file.
//
// On Unix-like systems this is the ".terraformrc" file in the home directory.
// On Windows, this is the "terraform.rc" file in the application data
// directory.
func ConfigFile() (string, error) {
return configFile()
}
// ConfigDir returns the configuration directory for Terraform.
func ConfigDir() (string, error) {
return configDir()
}
// LoadConfig loads the CLI configuration from ".terraformrc" files.
func LoadConfig(path string) (*Config, error) {
// Read the HCL file and prepare for parsing
d, err := ioutil.ReadFile(path)
if err != nil {
return nil, fmt.Errorf(
"Error reading %s: %s", path, err)
}
// Parse it
obj, err := hcl.Parse(string(d))
if err != nil {
return nil, fmt.Errorf(
"Error parsing %s: %s", path, err)
}
// Build up the result
var result Config
if err := hcl.DecodeObject(&result, obj); err != nil {
return nil, err
}
// Replace all env vars
for k, v := range result.Providers {
result.Providers[k] = os.ExpandEnv(v)
}
for k, v := range result.Provisioners {
result.Provisioners[k] = os.ExpandEnv(v)
}
if result.PluginCacheDir != "" {
result.PluginCacheDir = os.ExpandEnv(result.PluginCacheDir)
}
return &result, nil
}
// EnvConfig returns a Config populated from environment variables.
//
// Any values specified in this config should override those set in the
// configuration file.
func EnvConfig() *Config {
config := &Config{}
if envPluginCacheDir := os.Getenv(pluginCacheDirEnvVar); envPluginCacheDir != "" {
// No Expandenv here, because expanding environment variables inside
// an environment variable would be strange and seems unnecessary.
// (User can expand variables into the value while setting it using
// standard shell features.)
config.PluginCacheDir = envPluginCacheDir
}
return config
}
// Merge merges two configurations and returns a third entirely
// new configuration with the two merged.
func (c1 *Config) Merge(c2 *Config) *Config {
var result Config
result.Providers = make(map[string]string)
result.Provisioners = make(map[string]string)
for k, v := range c1.Providers {
result.Providers[k] = v
}
for k, v := range c2.Providers {
if v1, ok := c1.Providers[k]; ok {
log.Printf("[INFO] Local %s provider configuration '%s' overrides '%s'", k, v, v1)
}
result.Providers[k] = v
}
for k, v := range c1.Provisioners {
result.Provisioners[k] = v
}
for k, v := range c2.Provisioners {
if v1, ok := c1.Provisioners[k]; ok {
log.Printf("[INFO] Local %s provisioner configuration '%s' overrides '%s'", k, v, v1)
}
result.Provisioners[k] = v
}
result.DisableCheckpoint = c1.DisableCheckpoint || c2.DisableCheckpoint
result.DisableCheckpointSignature = c1.DisableCheckpointSignature || c2.DisableCheckpointSignature
result.PluginCacheDir = c1.PluginCacheDir
if result.PluginCacheDir == "" {
result.PluginCacheDir = c2.PluginCacheDir
}
return &result
}