config: determine whether a variable is required properly

This commit is contained in:
Mitchell Hashimoto 2014-06-03 15:55:51 -07:00
parent c9d8413431
commit 0008ff12c7
4 changed files with 78 additions and 6 deletions

View File

@ -14,7 +14,7 @@ import (
type Config struct { type Config struct {
ProviderConfigs map[string]*ProviderConfig ProviderConfigs map[string]*ProviderConfig
Resources []*Resource Resources []*Resource
Variables map[string]Variable Variables map[string]*Variable
} }
// ProviderConfig is the configuration for a resource provider. // ProviderConfig is the configuration for a resource provider.
@ -36,9 +36,11 @@ type Resource struct {
Variables map[string]InterpolatedVariable Variables map[string]InterpolatedVariable
} }
// Variable is a variable defined within the configuration.
type Variable struct { type Variable struct {
Default string Default string
Description string Description string
defaultSet bool
} }
// An InterpolatedVariable is a variable that is embedded within a string // An InterpolatedVariable is a variable that is embedded within a string
@ -130,6 +132,11 @@ func (c *Config) ResourceGraph() *depgraph.Graph {
} }
} }
// Required tests whether a variable is required or not.
func (v *Variable) Required() bool {
return !v.defaultSet
}
func NewResourceVariable(key string) (*ResourceVariable, error) { func NewResourceVariable(key string) (*ResourceVariable, error) {
parts := strings.SplitN(key, ".", 3) parts := strings.SplitN(key, ".", 3)
return &ResourceVariable{ return &ResourceVariable{

View File

@ -23,18 +23,39 @@ func (t *libuclConfigurable) Close() error {
} }
func (t *libuclConfigurable) Config() (*Config, error) { func (t *libuclConfigurable) Config() (*Config, error) {
type LibuclVariable struct {
Default string
Description string
Fields []string `libucl:",decodedFields"`
}
var rawConfig struct { var rawConfig struct {
Variable map[string]Variable Variable map[string]*LibuclVariable
} }
if err := t.Object.Decode(&rawConfig); err != nil { if err := t.Object.Decode(&rawConfig); err != nil {
return nil, err return nil, err
} }
// Start building up the actual configuration. We first // Start building up the actual configuration. We start with
// copy the fields that can be directly assigned. // variables.
config := new(Config) config := new(Config)
config.Variables = rawConfig.Variable config.Variables = make(map[string]*Variable)
for k, v := range rawConfig.Variable {
defaultSet := false
for _, f := range v.Fields {
if f == "Default" {
defaultSet = true
break
}
}
config.Variables[k] = &Variable{
Default: v.Default,
Description: v.Description,
defaultSet: defaultSet,
}
}
// Build the provider configs // Build the provider configs
providers := t.Object.Get("provider") providers := t.Object.Get("provider")

View File

@ -66,6 +66,31 @@ func TestLoadBasic_import(t *testing.T) {
} }
} }
func TestLoad_variables(t *testing.T) {
c, err := Load(filepath.Join(fixtureDir, "variables.tf"))
if err != nil {
t.Fatalf("err: %s", err)
}
if c == nil {
t.Fatal("config should not be nil")
}
actual := variablesStr(c.Variables)
if actual != strings.TrimSpace(variablesVariablesStr) {
t.Fatalf("bad:\n%s", actual)
}
if !c.Variables["foo"].Required() {
t.Fatal("foo should be required")
}
if c.Variables["bar"].Required() {
t.Fatal("bar should not be required")
}
if c.Variables["baz"].Required() {
t.Fatal("baz should not be required")
}
}
// This helper turns a provider configs field into a deterministic // This helper turns a provider configs field into a deterministic
// string value for comparison in tests. // string value for comparison in tests.
func providerConfigsStr(pcs map[string]*ProviderConfig) string { func providerConfigsStr(pcs map[string]*ProviderConfig) string {
@ -135,7 +160,7 @@ func resourcesStr(rs []*Resource) string {
// This helper turns a variables field into a deterministic // This helper turns a variables field into a deterministic
// string value for comparison in tests. // string value for comparison in tests.
func variablesStr(vs map[string]Variable) string { func variablesStr(vs map[string]*Variable) string {
result := "" result := ""
for k, v := range vs { for k, v := range vs {
if v.Default == "" { if v.Default == "" {
@ -199,3 +224,15 @@ foo
bar bar
bar bar
` `
const variablesVariablesStr = `
foo
<>
<>
bar
<>
<>
baz
foo
<>
`

View File

@ -0,0 +1,7 @@
variable "foo" {}
variable "bar" {
default = ""
}
variable "baz" {
default = "foo"
}