From d27c8921494bdbb0440c5ff59f87b6010b239771 Mon Sep 17 00:00:00 2001 From: Yusuf Kanchwala Date: Sun, 11 Oct 2020 16:38:09 +0530 Subject: [PATCH] improve regex pattern, getLocalName method and string replace method for module references --- .../terraform/v12/module-references.go | 48 +++++++++---------- 1 file changed, 22 insertions(+), 26 deletions(-) diff --git a/pkg/iac-providers/terraform/v12/module-references.go b/pkg/iac-providers/terraform/v12/module-references.go index 5a72bdad6..40901c1a5 100644 --- a/pkg/iac-providers/terraform/v12/module-references.go +++ b/pkg/iac-providers/terraform/v12/module-references.go @@ -28,7 +28,7 @@ import ( var ( // reference patterns - moduleRefPattern = regexp.MustCompile(`\$\{module\.(.*)\.(.*)}`) + moduleRefPattern = regexp.MustCompile(`(\$\{)?module\.(?P\w*)\.(?P\w*)(\})?`) ) // isModuleRef return true if the given string has a cross module reference @@ -38,30 +38,24 @@ func isModuleRef(ref string) bool { // getModuleVarName extracts and returns the module and variable name from the // module reference string -func getModuleVarName(moduleRef string) (string, string) { - - var ( - modulePrefix = "${module." - moduleSuffix = "}" - ) - - // ex of moduleRef: ${module.name.variable} - // 1. split at "${var.", remove everything before - split := strings.Split(moduleRef, modulePrefix) - mod := split[1] - - // 2. split at "}", remove everything after - split = strings.Split(mod, moduleSuffix) - mod = split[0] - - // 3. split at "."; eg: "name.variable" - split = strings.Split(mod, ".") - if len(split) < 2 { - return "", "" +func getModuleVarName(moduleRef string) (string, string, string) { + + // 1. extract the exact module reference from the string + moduleExpr := moduleRefPattern.FindString(moduleRef) + + // 2. extract variable name from module reference + match := moduleRefPattern.FindStringSubmatch(moduleRef) + result := make(map[string]string) + for i, name := range moduleRefPattern.SubexpNames() { + if i != 0 && name != "" { + result[name] = match[i] + } } + moduleName := result["module"] + varName := result["variable"] - // return module name and variable name - return split[0], split[1] + zap.S().Debugf("extracted module %q variable %q from reference %q", moduleName, varName, moduleRef) + return moduleName, varName, moduleExpr } // ResolveModuleRef tries to resolve cross module references @@ -69,7 +63,7 @@ func (r *RefResolver) ResolveModuleRef(moduleRef string, children map[string]*hclConfigs.Config) interface{} { // get module and variable name - moduleName, varName := getModuleVarName(moduleRef) + moduleName, varName, moduleExpr := getModuleVarName(moduleRef) // module and variable names cannot be empty if moduleName == "" || varName == "" { @@ -106,9 +100,11 @@ func (r *RefResolver) ResolveModuleRef(moduleRef string, // replace the variable reference string with actual value if reflect.TypeOf(val).Kind() == reflect.String { valStr := val.(string) - resolvedVal := varRefPattern.ReplaceAll([]byte(moduleRef), []byte(valStr)) - return string(resolvedVal) + resolvedVal := strings.Replace(moduleRef, moduleExpr, valStr, 1) + zap.S().Debugf("resolved str module value ref: '%v', value: '%v'", moduleRef, resolvedVal) + return r.ResolveStrRef(resolvedVal) } + zap.S().Debugf("resolved module value ref: '%v', value: '%v'", moduleRef, val) return val } }