main: load CLI config files from ~/.terraform.d/*.tfrc
Now that we are looking into the CLI config file for service host credentials, it's important to support multiple separate files so that users can keep credentials separate from other settings and credentials for different hosts separate from one another. There is no restriction on which settings can appear in which locations. This is up to the user to decide, depending on their security needs and e.g. on whether certain files are generated vs. manually-edited.
This commit is contained in:
parent
11ba1d2a4c
commit
1feb26f196
|
@ -1,6 +1,7 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
|
|
||||||
|
@ -361,9 +362,11 @@ func credentialsSource(config *Config) auth.CredentialsSource {
|
||||||
}
|
}
|
||||||
|
|
||||||
for helperType, helperConfig := range config.CredentialsHelpers {
|
for helperType, helperConfig := range config.CredentialsHelpers {
|
||||||
|
log.Printf("[DEBUG] Searching for credentials helper named %q", helperType)
|
||||||
available := pluginDiscovery.FindPlugins("credentials", globalPluginDirs())
|
available := pluginDiscovery.FindPlugins("credentials", globalPluginDirs())
|
||||||
available = available.WithName(helperType)
|
available = available.WithName(helperType)
|
||||||
if available.Count() == 0 {
|
if available.Count() == 0 {
|
||||||
|
log.Printf("[ERROR] Unable to find credentials helper %q; ignoring", helperType)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
40
config.go
40
config.go
|
@ -6,6 +6,7 @@ import (
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/hashicorp/hcl"
|
"github.com/hashicorp/hcl"
|
||||||
|
|
||||||
|
@ -79,6 +80,14 @@ func LoadConfig() (*Config, tfdiags.Diagnostics) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if configDir, err := ConfigDir(); err == nil {
|
||||||
|
if info, err := os.Stat(configDir); err == nil && info.IsDir() {
|
||||||
|
dirConfig, dirDiags := loadConfigDir(configDir)
|
||||||
|
diags = diags.Append(dirDiags)
|
||||||
|
config = config.Merge(dirConfig)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if envConfig := EnvConfig(); envConfig != nil {
|
if envConfig := EnvConfig(); envConfig != nil {
|
||||||
// envConfig takes precedence
|
// envConfig takes precedence
|
||||||
config = envConfig.Merge(config)
|
config = envConfig.Merge(config)
|
||||||
|
@ -94,6 +103,8 @@ func loadConfigFile(path string) (*Config, tfdiags.Diagnostics) {
|
||||||
var diags tfdiags.Diagnostics
|
var diags tfdiags.Diagnostics
|
||||||
result := &Config{}
|
result := &Config{}
|
||||||
|
|
||||||
|
log.Printf("Loading CLI configuration from %s", path)
|
||||||
|
|
||||||
// Read the HCL file and prepare for parsing
|
// Read the HCL file and prepare for parsing
|
||||||
d, err := ioutil.ReadFile(path)
|
d, err := ioutil.ReadFile(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -129,6 +140,35 @@ func loadConfigFile(path string) (*Config, tfdiags.Diagnostics) {
|
||||||
return result, diags
|
return result, diags
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func loadConfigDir(path string) (*Config, tfdiags.Diagnostics) {
|
||||||
|
var diags tfdiags.Diagnostics
|
||||||
|
result := &Config{}
|
||||||
|
|
||||||
|
entries, err := ioutil.ReadDir(path)
|
||||||
|
if err != nil {
|
||||||
|
diags = diags.Append(fmt.Errorf("Error reading %s: %s", path, err))
|
||||||
|
return result, diags
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, entry := range entries {
|
||||||
|
name := entry.Name()
|
||||||
|
// Ignoring errors here because it is used only to indicate pattern
|
||||||
|
// syntax errors, and our patterns are hard-coded here.
|
||||||
|
hclMatched, _ := filepath.Match("*.tfrc", name)
|
||||||
|
jsonMatched, _ := filepath.Match("*.tfrc.json", name)
|
||||||
|
if !(hclMatched || jsonMatched) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
filePath := filepath.Join(path, name)
|
||||||
|
fileConfig, fileDiags := loadConfigFile(filePath)
|
||||||
|
diags = diags.Append(fileDiags)
|
||||||
|
result = result.Merge(fileConfig)
|
||||||
|
}
|
||||||
|
|
||||||
|
return result, diags
|
||||||
|
}
|
||||||
|
|
||||||
// EnvConfig returns a Config populated from environment variables.
|
// EnvConfig returns a Config populated from environment variables.
|
||||||
//
|
//
|
||||||
// Any values specified in this config should override those set in the
|
// Any values specified in this config should override those set in the
|
||||||
|
|
Loading…
Reference in New Issue