github.com/spirius/terraform@v0.10.0-beta2.0.20170714185654-87b2c0cf8fea/config.go (about)

     1  //go:generate go run ./scripts/generate-plugins.go
     2  package main
     3  
     4  import (
     5  	"fmt"
     6  	"io/ioutil"
     7  	"log"
     8  	"os"
     9  
    10  	"github.com/hashicorp/hcl"
    11  	"github.com/hashicorp/terraform/command"
    12  )
    13  
    14  // Config is the structure of the configuration for the Terraform CLI.
    15  //
    16  // This is not the configuration for Terraform itself. That is in the
    17  // "config" package.
    18  type Config struct {
    19  	Providers    map[string]string
    20  	Provisioners map[string]string
    21  
    22  	DisableCheckpoint          bool `hcl:"disable_checkpoint"`
    23  	DisableCheckpointSignature bool `hcl:"disable_checkpoint_signature"`
    24  }
    25  
    26  // BuiltinConfig is the built-in defaults for the configuration. These
    27  // can be overridden by user configurations.
    28  var BuiltinConfig Config
    29  
    30  // PluginOverrides are paths that override discovered plugins, set from
    31  // the config file.
    32  var PluginOverrides command.PluginOverrides
    33  
    34  // ConfigFile returns the default path to the configuration file.
    35  //
    36  // On Unix-like systems this is the ".terraformrc" file in the home directory.
    37  // On Windows, this is the "terraform.rc" file in the application data
    38  // directory.
    39  func ConfigFile() (string, error) {
    40  	return configFile()
    41  }
    42  
    43  // ConfigDir returns the configuration directory for Terraform.
    44  func ConfigDir() (string, error) {
    45  	return configDir()
    46  }
    47  
    48  // LoadConfig loads the CLI configuration from ".terraformrc" files.
    49  func LoadConfig(path string) (*Config, error) {
    50  	// Read the HCL file and prepare for parsing
    51  	d, err := ioutil.ReadFile(path)
    52  	if err != nil {
    53  		return nil, fmt.Errorf(
    54  			"Error reading %s: %s", path, err)
    55  	}
    56  
    57  	// Parse it
    58  	obj, err := hcl.Parse(string(d))
    59  	if err != nil {
    60  		return nil, fmt.Errorf(
    61  			"Error parsing %s: %s", path, err)
    62  	}
    63  
    64  	// Build up the result
    65  	var result Config
    66  	if err := hcl.DecodeObject(&result, obj); err != nil {
    67  		return nil, err
    68  	}
    69  
    70  	// Replace all env vars
    71  	for k, v := range result.Providers {
    72  		result.Providers[k] = os.ExpandEnv(v)
    73  	}
    74  	for k, v := range result.Provisioners {
    75  		result.Provisioners[k] = os.ExpandEnv(v)
    76  	}
    77  
    78  	return &result, nil
    79  }
    80  
    81  // Merge merges two configurations and returns a third entirely
    82  // new configuration with the two merged.
    83  func (c1 *Config) Merge(c2 *Config) *Config {
    84  	var result Config
    85  	result.Providers = make(map[string]string)
    86  	result.Provisioners = make(map[string]string)
    87  	for k, v := range c1.Providers {
    88  		result.Providers[k] = v
    89  	}
    90  	for k, v := range c2.Providers {
    91  		if v1, ok := c1.Providers[k]; ok {
    92  			log.Printf("[INFO] Local %s provider configuration '%s' overrides '%s'", k, v, v1)
    93  		}
    94  		result.Providers[k] = v
    95  	}
    96  	for k, v := range c1.Provisioners {
    97  		result.Provisioners[k] = v
    98  	}
    99  	for k, v := range c2.Provisioners {
   100  		if v1, ok := c1.Provisioners[k]; ok {
   101  			log.Printf("[INFO] Local %s provisioner configuration '%s' overrides '%s'", k, v, v1)
   102  		}
   103  		result.Provisioners[k] = v
   104  	}
   105  	result.DisableCheckpoint = c1.DisableCheckpoint || c2.DisableCheckpoint
   106  	result.DisableCheckpointSignature = c1.DisableCheckpointSignature || c2.DisableCheckpointSignature
   107  
   108  	return &result
   109  }