diff --git a/commands.go b/commands.go index 39e30220d..d5e53cf6f 100644 --- a/commands.go +++ b/commands.go @@ -1,6 +1,7 @@ package main import ( + "log" "os" "os/signal" @@ -361,9 +362,11 @@ func credentialsSource(config *Config) auth.CredentialsSource { } for helperType, helperConfig := range config.CredentialsHelpers { + log.Printf("[DEBUG] Searching for credentials helper named %q", helperType) available := pluginDiscovery.FindPlugins("credentials", globalPluginDirs()) available = available.WithName(helperType) if available.Count() == 0 { + log.Printf("[ERROR] Unable to find credentials helper %q; ignoring", helperType) break } diff --git a/config.go b/config.go index fc55e9f6b..3c546b876 100644 --- a/config.go +++ b/config.go @@ -6,6 +6,7 @@ import ( "io/ioutil" "log" "os" + "path/filepath" "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 { // envConfig takes precedence config = envConfig.Merge(config) @@ -94,6 +103,8 @@ func loadConfigFile(path string) (*Config, tfdiags.Diagnostics) { var diags tfdiags.Diagnostics result := &Config{} + log.Printf("Loading CLI configuration from %s", path) + // Read the HCL file and prepare for parsing d, err := ioutil.ReadFile(path) if err != nil { @@ -129,6 +140,35 @@ func loadConfigFile(path string) (*Config, tfdiags.Diagnostics) { 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. // // Any values specified in this config should override those set in the