config: providerconfigs can replace variables
This commit is contained in:
parent
3ccfd4d08c
commit
d2c3db552a
|
@ -7,7 +7,6 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/depgraph"
|
"github.com/hashicorp/terraform/depgraph"
|
||||||
"github.com/mitchellh/reflectwalk"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// ResourceGraphRoot is the name of the resource graph root that should be
|
// ResourceGraphRoot is the name of the resource graph root that should be
|
||||||
|
@ -77,6 +76,20 @@ type UserVariable struct {
|
||||||
key string
|
key string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ReplaceVariables replaces the variables in the configuration
|
||||||
|
// with the given values.
|
||||||
|
//
|
||||||
|
// This replacement is not in place. Instead, this function will
|
||||||
|
// return a new resource with the variables replaced.
|
||||||
|
func (r *ProviderConfig) ReplaceVariables(
|
||||||
|
vs map[string]string) *ProviderConfig {
|
||||||
|
result := *r
|
||||||
|
if err := replaceVariables(result.Config, vs); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return &result
|
||||||
|
}
|
||||||
|
|
||||||
// A unique identifier for this resource.
|
// A unique identifier for this resource.
|
||||||
func (r *Resource) Id() string {
|
func (r *Resource) Id() string {
|
||||||
return fmt.Sprintf("%s.%s", r.Type, r.Name)
|
return fmt.Sprintf("%s.%s", r.Type, r.Name)
|
||||||
|
@ -103,20 +116,18 @@ func (r *Resource) ProviderConfigName(pcs map[string]*ProviderConfig) string {
|
||||||
// return a new resource with the variables replaced.
|
// return a new resource with the variables replaced.
|
||||||
func (r *Resource) ReplaceVariables(vs map[string]string) *Resource {
|
func (r *Resource) ReplaceVariables(vs map[string]string) *Resource {
|
||||||
result := *r
|
result := *r
|
||||||
|
if err := replaceVariables(result.Config, vs); err != nil {
|
||||||
w := &variableReplaceWalker{
|
|
||||||
Values: vs,
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := reflectwalk.Walk(result.Config, w); err != nil {
|
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &result
|
return &result
|
||||||
}
|
}
|
||||||
|
|
||||||
// ResourceGraph returns a dependency graph of the resources from this
|
// ResourceGraph returns a dependency graph of the resources from this
|
||||||
// Terraform configuration.
|
// Terraform configuration.
|
||||||
|
//
|
||||||
|
// The graph can contain both *Resource and *ProviderConfig. When consuming
|
||||||
|
// the graph, you'll have to use type inference to determine what it is
|
||||||
|
// and the proper behavior.
|
||||||
func (c *Config) ResourceGraph() *depgraph.Graph {
|
func (c *Config) ResourceGraph() *depgraph.Graph {
|
||||||
// This tracks all the resource nouns
|
// This tracks all the resource nouns
|
||||||
nouns := make(map[string]*depgraph.Noun)
|
nouns := make(map[string]*depgraph.Noun)
|
||||||
|
|
|
@ -64,6 +64,45 @@ func TestNewUserVariable(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestProviderConfigReplaceVariables(t *testing.T) {
|
||||||
|
r := &ProviderConfig{
|
||||||
|
Config: map[string]interface{}{
|
||||||
|
"foo": "${var.bar}",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
values := map[string]string{
|
||||||
|
"var.bar": "value",
|
||||||
|
}
|
||||||
|
|
||||||
|
r2 := r.ReplaceVariables(values)
|
||||||
|
|
||||||
|
expected := &ProviderConfig{
|
||||||
|
Config: map[string]interface{}{
|
||||||
|
"foo": "value",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(r2, expected) {
|
||||||
|
t.Fatalf("bad: %#v", r2)
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
TODO(mitchellh): Eventually, preserve original config...
|
||||||
|
|
||||||
|
expectedOriginal := &Resource{
|
||||||
|
Name: "foo",
|
||||||
|
Type: "bar",
|
||||||
|
Config: map[string]interface{}{
|
||||||
|
"foo": "${var.bar}",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
if !reflect.DeepEqual(r, expectedOriginal) {
|
||||||
|
t.Fatalf("bad: %#v", r)
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
func TestResourceProviderConfigName(t *testing.T) {
|
func TestResourceProviderConfigName(t *testing.T) {
|
||||||
r := &Resource{
|
r := &Resource{
|
||||||
Name: "foo",
|
Name: "foo",
|
||||||
|
|
|
@ -16,6 +16,16 @@ func init() {
|
||||||
varRegexp = regexp.MustCompile(`(?i)(\$+)\{([-.a-z0-9_]+)\}`)
|
varRegexp = regexp.MustCompile(`(?i)(\$+)\{([-.a-z0-9_]+)\}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// replaceVariables takes a configuration and a mapping of variables
|
||||||
|
// and performs the structure walking necessary to properly replace
|
||||||
|
// all the variables.
|
||||||
|
func replaceVariables(
|
||||||
|
c map[string]interface{},
|
||||||
|
vs map[string]string) error {
|
||||||
|
w := &variableReplaceWalker{Values: vs}
|
||||||
|
return reflectwalk.Walk(c, w)
|
||||||
|
}
|
||||||
|
|
||||||
// variableDetectWalker implements interfaces for the reflectwalk package
|
// variableDetectWalker implements interfaces for the reflectwalk package
|
||||||
// (github.com/mitchellh/reflectwalk) that can be used to automatically
|
// (github.com/mitchellh/reflectwalk) that can be used to automatically
|
||||||
// pull out the variables that need replacing.
|
// pull out the variables that need replacing.
|
||||||
|
|
Loading…
Reference in New Issue