diff --git a/pkg/config/config.go b/pkg/config/config.go index f21eac7227..1112bcadf5 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -960,3 +960,17 @@ func (b *Blueprint) checkBlueprintName() error { return nil } + +// WalkModules walks all modules in the blueprint and calls the walker function +func (b *Blueprint) WalkModules(walker func(*Module) error) error { + for ig := range b.DeploymentGroups { + g := &b.DeploymentGroups[ig] + for im := range g.Modules { + m := &g.Modules[im] + if err := walker(m); err != nil { + return err + } + } + } + return nil +} diff --git a/pkg/config/expand.go b/pkg/config/expand.go index 656626870f..43fb6673ca 100644 --- a/pkg/config/expand.go +++ b/pkg/config/expand.go @@ -47,8 +47,7 @@ var ( // consume all whitespace at beginning and end // consume only up to first period to get variable source // consume only up to whitespace to get variable name - literalSplitExp *regexp.Regexp = regexp.MustCompile(`^\(\([[:space:]]*(.*?)\.(.*?)[[:space:]]*\)\)$`) - deploymentVariableExp *regexp.Regexp = regexp.MustCompile(`^\$\(vars\.(.*)\)$`) + literalSplitExp *regexp.Regexp = regexp.MustCompile(`^\(\([[:space:]]*(.*?)\.(.*?)[[:space:]]*\)\)$`) ) // expand expands variables and strings in the yaml config. Used directly by @@ -86,6 +85,9 @@ func (dc *DeploymentConfig) expand() { if err := dc.expandVariables(); err != nil { log.Fatalf("failed to expand variables: %v", err) } + if err := expandRequiredApis(&dc.Config); err != nil { + log.Fatalf("failed to expand required_apis: %v", err) + } } func (dc *DeploymentConfig) addSettingsToModules() { @@ -874,11 +876,6 @@ func expandSimpleVariable(context varContext, trackModuleGraph bool) (string, er return fmt.Sprintf("((%s))", varRef.HclString()), nil } -// isDeploymentVariable checks if the entire string is just a single deployment variable -func isDeploymentVariable(str string) bool { - return deploymentVariableExp.MatchString(str) -} - // isSimpleVariable checks if the entire string is just a single variable func isSimpleVariable(str string) bool { return simpleVariableExp.MatchString(str) @@ -972,21 +969,37 @@ func (dc *DeploymentConfig) expandVariables() error { if err != nil { return err } + } + } + return nil +} - // ensure that variable references to projects in required APIs are expanded - for projectID, requiredAPIs := range mod.RequiredApis { - if isDeploymentVariable(projectID) { - s, err := handleVariable(projectID, context, false) - if err != nil { - return err - } - mod.RequiredApis[s.(string)] = slices.Clone(requiredAPIs) - delete(mod.RequiredApis, projectID) +func expandRequiredApis(bp *Blueprint) error { + return bp.WalkModules(func(m *Module) error { + for project, apis := range m.RequiredApis { + resolved := project + if hasVariable(project) { + exp, err := SimpleVarToExpression(project) + if err != nil { + return err } + ev, err := exp.Eval(*bp) + if err != nil { + return err + } + if ev.Type() != cty.String { + ty := ev.Type().FriendlyName() + return fmt.Errorf("module %s required_api project_id must be a string, got %s", m.ID, ty) + } + resolved = ev.AsString() + } + if project != resolved { + m.RequiredApis[resolved] = slices.Clone(apis) + delete(m.RequiredApis, project) } } - } - return nil + return nil + }) } // this function adds default validators to the blueprint. diff --git a/pkg/config/expand_test.go b/pkg/config/expand_test.go index 47961e5623..ecd779bd05 100644 --- a/pkg/config/expand_test.go +++ b/pkg/config/expand_test.go @@ -447,36 +447,6 @@ func (s *MySuite) TestApplyGlobalVariables(c *C) { c.Assert(err, IsNil) } -func (s *MySuite) TestIsGlobalVariable(c *C) { - // True: Correct global variable - got := isDeploymentVariable("$(vars.name)") - c.Assert(got, Equals, true) - // False: Missing $ - got = isDeploymentVariable("(vars.name)") - c.Assert(got, Equals, false) - // False: Missing ( - got = isDeploymentVariable("$vars.name)") - c.Assert(got, Equals, false) - // False: Missing ) - got = isDeploymentVariable("$(vars.name") - c.Assert(got, Equals, false) - // False: Contains Prefix - got = isDeploymentVariable("prefix-$(vars.name)") - c.Assert(got, Equals, false) - // False: Contains Suffix - got = isDeploymentVariable("$(vars.name)-suffix") - c.Assert(got, Equals, false) - // False: Contains prefix and suffix - got = isDeploymentVariable("prefix-$(vars.name)-suffix") - c.Assert(got, Equals, false) - // False: empty string - got = isDeploymentVariable("") - c.Assert(got, Equals, false) - // False: is a variable, but not global - got = isDeploymentVariable("$(moduleid.name)") - c.Assert(got, Equals, false) -} - func (s *MySuite) TestIsSimpleVariable(c *C) { // True: Correct simple variable got := isSimpleVariable("$(some_text)")