Skip to content

Commit

Permalink
addressed feedback
Browse files Browse the repository at this point in the history
  • Loading branch information
alpacamybags118 committed Feb 9, 2021
1 parent b156172 commit cbe3ee7
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 107 deletions.
7 changes: 5 additions & 2 deletions modules/terraform/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,13 @@ func (err VarFileNotFound) Error() string {

// InputFileKeyNotFound occurs when tfvar file does not contain a value for the key
// specified in the function call
type InputFileKeyNotFound string
type InputFileKeyNotFound struct {
FilePath string
Key string
}

func (err InputFileKeyNotFound) Error() string {
return fmt.Sprintf("tfvar file doesn't contain a value for the key %q", string(err))
return fmt.Sprintf("tfvar file %q doesn't contain a value for the key %q", err.FilePath, err.Key)
}

type HclDecodeError struct {
Expand Down
107 changes: 52 additions & 55 deletions modules/terraform/options.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package terraform

import (
"errors"
"fmt"
"io/ioutil"
"reflect"
Expand Down Expand Up @@ -110,8 +111,8 @@ func WithDefaultRetryableErrors(t *testing.T, originalOptions *Options) *Options

// GetVariableAsStringFromVarFile Gets the string represention of a variable from a provided input file found in VarFile
// For list or map, use GetVariableAsListFromVarFile or GetVariableAsMapFromVarFile, respectively.
func GetVariableAsStringFromVarFile(t *testing.T, option *Options, fileName string, key string) string {
result, err := GetVariableAsStringFromVarFileE(t, option, fileName, key)
func GetVariableAsStringFromVarFile(t *testing.T, fileName string, key string) string {
result, err := GetVariableAsStringFromVarFileE(t, fileName, key)
require.NoError(t, err)

return result
Expand All @@ -120,8 +121,10 @@ func GetVariableAsStringFromVarFile(t *testing.T, option *Options, fileName stri
// GetVariableAsStringFromVarFileE Gets the string represention of a variable from a provided input file found in VarFile
// Will return an error if GetAllVariablesFromVarFileE returns an error or the key provided does not exist in the file.
// For list or map, use GetVariableAsListFromVarFile or GetVariableAsMapFromVarFile, respectively.
func GetVariableAsStringFromVarFileE(t *testing.T, option *Options, fileName string, key string) (string, error) {
variables, err := GetAllVariablesFromVarFileE(t, option, fileName)
func GetVariableAsStringFromVarFileE(t *testing.T, fileName string, key string) (string, error) {
var variables map[string]interface{}

err := GetAllVariablesFromVarFileE(t, fileName, &variables)

if err != nil {
return "", err
Expand All @@ -130,121 +133,115 @@ func GetVariableAsStringFromVarFileE(t *testing.T, option *Options, fileName str
variable, exists := variables[key]

if !exists {
return "", InputFileKeyNotFound(key)
return "", InputFileKeyNotFound{FilePath: fileName, Key: key}
}

return fmt.Sprintf("%v", variable), nil
}

// GetVariableAsMapFromVarFile Gets the map represention of a variable from a provided input file found in VarFile
func GetVariableAsMapFromVarFile(t *testing.T, option *Options, fileName string, key string) map[string]string {
result, err := GetVariableAsMapFromVarFileE(t, option, fileName, key)
// Note that this returns a map of strings. For maps containing complex types, use GetAllVariablesFromVarFile.
func GetVariableAsMapFromVarFile(t *testing.T, fileName string, key string) map[string]string {
result, err := GetVariableAsMapFromVarFileE(t, fileName, key)
require.NoError(t, err)

return result
}

// GetVariableAsMapFromVarFileE Gets the map represention of a variable from a provided input file found in VarFile
// GetVariableAsMapFromVarFileE Gets the map represention of a variable from a provided input file found in VarFile.
// Note that this returns a map of strings. For maps containing complex types, use GetAllVariablesFromVarFile
// Returns an error if GetAllVariablesFromVarFileE returns an error, the key provided does not exist, or the value associated with the key is not a map
func GetVariableAsMapFromVarFileE(t *testing.T, option *Options, fileName string, key string) (map[string]string, error) {
func GetVariableAsMapFromVarFileE(t *testing.T, fileName string, key string) (map[string]string, error) {
var variables map[string]interface{}

resultMap := make(map[string]string)
variables, err := GetAllVariablesFromVarFileE(t, option, fileName)
err := GetAllVariablesFromVarFileE(t, fileName, &variables)

if err != nil {
return nil, err
}

_, exists := variables[key]
variable, exists := variables[key]

if !exists {
return nil, InputFileKeyNotFound(key)
return nil, InputFileKeyNotFound{FilePath: fileName, Key: key}
}

if reflect.TypeOf(variables[key]).String() != "[]map[string]interface {}" {
return nil, UnexpectedOutputType{Key: key, ExpectedType: "map", ActualType: reflect.TypeOf(variables[key]).String()}
if reflect.TypeOf(variable).String() != "[]map[string]interface {}" {
return nil, UnexpectedOutputType{Key: key, ExpectedType: "[]map[string]interface {}", ActualType: reflect.TypeOf(variable).String()}
}

mapKeys := variables[key].([]map[string]interface{})[0]
mapKeys := variable.([]map[string]interface{})

if len(mapKeys) == 0 {
return nil, errors.New("no map keys could be found for given map")
}

for mapKey, mapVal := range mapKeys {
for mapKey, mapVal := range mapKeys[0] {
resultMap[mapKey] = fmt.Sprintf("%v", mapVal)
}

return resultMap, nil
}

// GetVariableAsListFromVarFile Gets the string list represention of a variable from a provided input file found in VarFile
func GetVariableAsListFromVarFile(t *testing.T, option *Options, fileName string, key string) []string {
result, err := GetVariableAsListFromVarFileE(t, option, fileName, key)
// Note that this returns a list of strings. For lists containing complex types, use GetAllVariablesFromVarFile.
func GetVariableAsListFromVarFile(t *testing.T, fileName string, key string) []string {
result, err := GetVariableAsListFromVarFileE(t, fileName, key)
require.NoError(t, err)

return result
}

// GetVariableAsListFromVarFileE Gets the string list represention of a variable from a provided input file found in VarFile
// Note that this returns a list of strings. For lists containing complex types, use GetAllVariablesFromVarFile.
// Will return error if GetAllVariablesFromVarFileE returns an error, the key provided does not exist, or the value associated with the key is not a list
func GetVariableAsListFromVarFileE(t *testing.T, option *Options, fileName string, key string) ([]string, error) {
func GetVariableAsListFromVarFileE(t *testing.T, fileName string, key string) ([]string, error) {
var variables map[string]interface{}
resultArray := []string{}
variables, err := GetAllVariablesFromVarFileE(t, option, fileName)
err := GetAllVariablesFromVarFileE(t, fileName, &variables)

if err != nil {
return nil, err
}

if _, exists := variables[key]; !exists {
return nil, InputFileKeyNotFound(key)
variable, exists := variables[key]

if !exists {
return nil, InputFileKeyNotFound{FilePath: fileName, Key: key}
}

if reflect.TypeOf(variables[key]).String() != "[]interface {}" {
return nil, UnexpectedOutputType{Key: key, ExpectedType: "list", ActualType: reflect.TypeOf(variables[key]).String()}
if reflect.TypeOf(variable).String() != "[]interface {}" {
return nil, UnexpectedOutputType{Key: key, ExpectedType: "[]interface {}", ActualType: reflect.TypeOf(variable).String()}
}

for _, item := range variables[key].([]interface{}) {
for _, item := range variable.([]interface{}) {
resultArray = append(resultArray, fmt.Sprintf("%v", item))
}

return resultArray, nil
}

// GetAllVariablesFromVarFile Parses all data from a provided input file found in VarFile and returns them as a key-value map
func GetAllVariablesFromVarFile(t *testing.T, option *Options, fileName string) map[string]interface{} {
variableMaps, err := GetAllVariablesFromVarFileE(t, option, fileName)
// GetAllVariablesFromVarFile Parses all data from a provided input file found in VarFile and stores the result in the value pointed to by out
func GetAllVariablesFromVarFile(t *testing.T, fileName string, out interface{}) {
err := GetAllVariablesFromVarFileE(t, fileName, out)
require.NoError(t, err)

return variableMaps
}

// GetAllVariablesFromVarFileE Parses all data from a provided input file found ind in VarFile and returns them as a key-value map
// Retursn an error if the specified file does not exist, the specified file is not readable, or the specified file cannot be decoded from HCL
func GetAllVariablesFromVarFileE(t *testing.T, option *Options, fileName string) (map[string]interface{}, error) {
variableMap := map[string]interface{}{}
fileIndex := -1
if len(option.VarFiles) == 0 {
return variableMap, nil
}

for index, file := range option.VarFiles {
if file == fileName {
fileIndex = index
break
}
}

if fileIndex == -1 {
return nil, VarFileNotFound{Path: fileName}
}

fileContents, err := ioutil.ReadFile(option.VarFiles[fileIndex])
// GetAllVariablesFromVarFileE Parses all data from a provided input file found ind in VarFile and stores the result in the value pointed to by out
// Returns an error if the specified file does not exist, the specified file is not readable, or the specified file cannot be decoded from HCL
func GetAllVariablesFromVarFileE(t *testing.T, fileName string, out interface{}) error {
fileContents, err := ioutil.ReadFile(fileName)

if err != nil {
return nil, err
return err
}

err = hcl.Decode(&variableMap, string(fileContents))
err = hcl.Decode(out, string(fileContents))

if err != nil {
return nil, HclDecodeError{FilePath: option.VarFiles[fileIndex], ErrorText: err.Error()}
return HclDecodeError{FilePath: fileName, ErrorText: err.Error()}
}

return variableMap, nil
return nil
}
70 changes: 20 additions & 50 deletions modules/terraform/options_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,11 @@ func TestGetVariablesFromVarFilesAsString(t *testing.T) {
WriteFile(t, randomFileName, testHcl)
defer os.Remove(randomFileName)

stringVal := GetVariableAsStringFromVarFile(t, &Options{
VarFiles: []string{randomFileName},
}, randomFileName, "aws_region")
stringVal := GetVariableAsStringFromVarFile(t, randomFileName, "aws_region")

boolString := GetVariableAsStringFromVarFile(t, &Options{
VarFiles: []string{randomFileName},
}, randomFileName, "boolean_type")
boolString := GetVariableAsStringFromVarFile(t, randomFileName, "boolean_type")

numString := GetVariableAsStringFromVarFile(t, &Options{
VarFiles: []string{randomFileName},
}, randomFileName, "number_type")
numString := GetVariableAsStringFromVarFile(t, randomFileName, "number_type")

require.Equal(t, "us-east-2", stringVal)
require.Equal(t, "true", boolString)
Expand All @@ -58,9 +52,7 @@ func TestGetVariablesFromVarFilesAsStringKeyDoesNotExist(t *testing.T) {
WriteFile(t, randomFileName, testHcl)
defer os.Remove(randomFileName)

_, err := GetVariableAsStringFromVarFileE(t, &Options{
VarFiles: []string{randomFileName},
}, randomFileName, "badkey")
_, err := GetVariableAsStringFromVarFileE(t, randomFileName, "badkey")

require.Error(t, err)
}
Expand All @@ -81,9 +73,7 @@ func TestGetVariableAsMapFromVarFile(t *testing.T) {
WriteFile(t, randomFileName, testHcl)
defer os.Remove(randomFileName)

val := GetVariableAsMapFromVarFile(t, &Options{
VarFiles: []string{randomFileName},
}, randomFileName, "tags")
val := GetVariableAsMapFromVarFile(t, randomFileName, "tags")

require.Equal(t, expected, val)
}
Expand All @@ -102,9 +92,7 @@ func TestGetVariableAsMapFromVarFileNotMap(t *testing.T) {
WriteFile(t, randomFileName, testHcl)
defer os.Remove(randomFileName)

_, err := GetVariableAsMapFromVarFileE(t, &Options{
VarFiles: []string{randomFileName},
}, randomFileName, "aws_region")
_, err := GetVariableAsMapFromVarFileE(t, randomFileName, "aws_region")

require.Error(t, err)
}
Expand All @@ -123,9 +111,7 @@ func TestGetVariableAsMapFromVarFileKeyDoesNotExist(t *testing.T) {
WriteFile(t, randomFileName, testHcl)
defer os.Remove(randomFileName)

_, err := GetVariableAsMapFromVarFileE(t, &Options{
VarFiles: []string{randomFileName},
}, randomFileName, "badkey")
_, err := GetVariableAsMapFromVarFileE(t, randomFileName, "badkey")

require.Error(t, err)
}
Expand All @@ -145,9 +131,7 @@ func TestGetVariableAsListFromVarFile(t *testing.T) {
WriteFile(t, randomFileName, testHcl)
defer os.Remove(randomFileName)

val := GetVariableAsListFromVarFile(t, &Options{
VarFiles: []string{randomFileName},
}, randomFileName, "list")
val := GetVariableAsListFromVarFile(t, randomFileName, "list")

require.Equal(t, expected, val)
}
Expand All @@ -166,9 +150,7 @@ func TestGetVariableAsListNotList(t *testing.T) {
WriteFile(t, randomFileName, testHcl)
defer os.Remove(randomFileName)

_, err := GetVariableAsListFromVarFileE(t, &Options{
VarFiles: []string{randomFileName},
}, randomFileName, "tags")
_, err := GetVariableAsListFromVarFileE(t, randomFileName, "tags")

require.Error(t, err)
}
Expand All @@ -187,31 +169,21 @@ func TestGetVariableAsListKeyDoesNotExist(t *testing.T) {
WriteFile(t, randomFileName, testHcl)
defer os.Remove(randomFileName)

_, err := GetVariableAsListFromVarFileE(t, &Options{
VarFiles: []string{randomFileName},
}, randomFileName, "badkey")
_, err := GetVariableAsListFromVarFileE(t, randomFileName, "badkey")

require.Error(t, err)
}

func TestGetAllVariablesFromVarFileENotInVarFiles(t *testing.T) {
_, err := GetAllVariablesFromVarFileE(t, &Options{
VarFiles: []string{"filea"},
}, "fileb")

//require.Equal(t, "open thisdoesntexist: no such file or directory", err.Error())
require.Error(t, err)
}

func TestGetAllVariablesFromVarFileEFileDoesNotExist(t *testing.T) {
_, err := GetAllVariablesFromVarFileE(t, &Options{
VarFiles: []string{"filea"},
}, "filea")
var variables map[string]interface{}

err := GetAllVariablesFromVarFileE(t, "filea", variables)

require.Equal(t, "open filea: no such file or directory", err.Error())
}

func TestGetAllVariablesFromVarFileBadFile(t *testing.T) {
var variables map[string]interface{}

randomFileName := fmt.Sprintf("./%s.tfvars", random.UniqueId())
testHcl := []byte(`
thiswillnotwork`)
Expand All @@ -225,9 +197,7 @@ func TestGetAllVariablesFromVarFileBadFile(t *testing.T) {

defer os.Remove(randomFileName)

_, err = GetAllVariablesFromVarFileE(t, &Options{
VarFiles: []string{randomFileName},
}, randomFileName)
err = GetAllVariablesFromVarFileE(t, randomFileName, variables)

if err == nil {
t.FailNow()
Expand All @@ -239,6 +209,8 @@ func TestGetAllVariablesFromVarFileBadFile(t *testing.T) {
}

func TestGetAllVariablesFromVarFile(t *testing.T) {
var variables map[string]interface{}

randomFileName := fmt.Sprintf("./%s.tfvars", random.UniqueId())
testHcl := []byte(`
aws_region = "us-east-2"
Expand All @@ -253,9 +225,7 @@ func TestGetAllVariablesFromVarFile(t *testing.T) {

defer os.Remove(randomFileName)

val, err := GetAllVariablesFromVarFileE(t, &Options{
VarFiles: []string{randomFileName},
}, randomFileName)
err = GetAllVariablesFromVarFileE(t, randomFileName, &variables)

if err != nil {
t.FailNow()
Expand All @@ -264,7 +234,7 @@ func TestGetAllVariablesFromVarFile(t *testing.T) {
expected := make(map[string]interface{})
expected["aws_region"] = "us-east-2"

require.Equal(t, expected, val)
require.Equal(t, expected, variables)

}

Expand Down

0 comments on commit cbe3ee7

Please sign in to comment.