config: determine whether a variable is required properly
This commit is contained in:
parent
c9d8413431
commit
0008ff12c7
|
@ -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{
|
||||||
|
|
|
@ -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")
|
||||||
|
|
|
@ -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
|
||||||
|
<>
|
||||||
|
`
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
variable "foo" {}
|
||||||
|
variable "bar" {
|
||||||
|
default = ""
|
||||||
|
}
|
||||||
|
variable "baz" {
|
||||||
|
default = "foo"
|
||||||
|
}
|
Loading…
Reference in New Issue