Setup provisioners for CLI

This commit is contained in:
Armon Dadgar 2014-07-09 14:47:37 -07:00
parent 9c49642b37
commit 1c4321a503
2 changed files with 73 additions and 1 deletions

View File

@ -16,7 +16,8 @@ import (
// This is not the configuration for Terraform itself. That is in the
// "config" package.
type Config struct {
Providers map[string]string
Providers map[string]string
Provisioners map[string]string
}
// BuiltinConfig is the built-in defaults for the configuration. These
@ -34,6 +35,9 @@ func init() {
BuiltinConfig.Providers = map[string]string{
"aws": "terraform-provider-aws",
}
BuiltinConfig.Provisioners = map[string]string{
"local-exec": "terraform-provisioner-local-exec",
}
}
// LoadConfig loads the CLI configuration from ".terraformrc" files.
@ -69,12 +73,19 @@ func LoadConfig(path string) (*Config, error) {
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 {
result.Providers[k] = v
}
for k, v := range c1.Provisioners {
result.Provisioners[k] = v
}
for k, v := range c2.Provisioners {
result.Provisioners[k] = v
}
return &result
}
@ -138,3 +149,63 @@ func (c *Config) providerFactory(path string) terraform.ResourceProviderFactory
}, nil
}
}
// ProvisionerFactories returns the mapping of prefixes to
// ResourceProvisionerFactory that can be used to instantiate a
// binary-based plugin.
func (c *Config) ProvisionerFactories() map[string]terraform.ResourceProvisionerFactory {
result := make(map[string]terraform.ResourceProvisionerFactory)
for k, v := range c.Provisioners {
result[k] = c.provisionerFactory(v)
}
return result
}
func (c *Config) provisionerFactory(path string) terraform.ResourceProvisionerFactory {
originalPath := path
return func() (terraform.ResourceProvisioner, error) {
// First look for the provider on the PATH.
path, err := exec.LookPath(path)
if err != nil {
// If that doesn't work, look for it in the same directory
// as the executable that is running.
exePath, err := osext.Executable()
if err == nil {
path = filepath.Join(
filepath.Dir(exePath),
filepath.Base(originalPath))
}
}
// If we still don't have a path set, then set it to the
// original path and let any errors that happen bubble out.
if path == "" {
path = originalPath
}
// Build the plugin client configuration and init the plugin
var config plugin.ClientConfig
config.Cmd = exec.Command(path)
config.Managed = true
client := plugin.NewClient(&config)
// Request the RPC client and service name from the client
// so we can build the actual RPC-implemented provider.
rpcClient, err := client.Client()
if err != nil {
return nil, err
}
service, err := client.Service()
if err != nil {
return nil, err
}
return &rpc.ResourceProvisioner{
Client: rpcClient,
Name: service,
}, nil
}
}

View File

@ -85,6 +85,7 @@ func wrappedMain() int {
// Initialize the TFConfig settings for the commands...
ContextOpts.Providers = config.ProviderFactories()
ContextOpts.Provisioners = config.ProvisionerFactories()
// Get the command line args. We shortcut "--version" and "-v" to
// just show the version.