Skip to content

Commit ef1b476

Browse files
committed
Fix unresolved conditions bug with sub modules
1 parent 1da527c commit ef1b476

File tree

8 files changed

+86
-31
lines changed

8 files changed

+86
-31
lines changed

cft/pkg/conditions.go

Lines changed: 14 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import (
55
"slices"
66

77
"github.com/aws-cloudformation/rain/cft"
8-
"github.com/aws-cloudformation/rain/internal/config"
98
"github.com/aws-cloudformation/rain/internal/node"
109
"github.com/aws-cloudformation/rain/internal/s11n"
1110
"gopkg.in/yaml.v3"
@@ -102,21 +101,15 @@ func (module *Module) ProcessConditions() error {
102101
condName := conditionNode.Value
103102
condResult, ok := module.ConditionValues[condName]
104103
if !ok {
105-
msg := "%s Condition not found in %s"
106-
107104
// Is this a condition that we could not
108105
// fully resolve, or a condition that doesn't exist?
109106

110-
config.Debugf(msg, condName, module.Config.Source)
107+
if slices.Contains(unResolved, condName) {
108+
// Prepend the module name to the condition
109+
newName := module.Config.Name + conditionNode.Value
110+
conditionNode.Value = newName
111111

112-
if !slices.Contains(unResolved, condName) {
113-
// If it's not in that list, it's likely a mistake
114-
return fmt.Errorf(msg, condName, module.Config.Source)
115112
}
116-
117-
// Prepend the module name to the condition
118-
newName := module.Config.Name + conditionNode.Value
119-
conditionNode.Value = newName
120113
} else {
121114
if !condResult {
122115
itemsToRemove = append(itemsToRemove, itemName)
@@ -144,23 +137,27 @@ func (module *Module) ProcessConditions() error {
144137
}
145138

146139
if len(unResolved) == 0 {
147-
config.Debugf("No unresolved conditions in %s", module.Config.Name)
148140
node.RemoveFromMap(module.Node, string(cft.Conditions))
149141
} else {
150142
// Only remove those that we fully resolved.
151143
// Emit the rest into the parent template.
152144
for _, name := range resolved {
153145
node.RemoveFromMap(module.ConditionsNode, name)
154146
}
147+
148+
// Ensure that the parent template has a Conditions section
155149
t := module.ParentTemplate
156150
tc, err := t.GetSection(cft.Conditions)
157151
if err != nil {
158152
tc, _ = t.AddMapSection(cft.Conditions)
159153
}
154+
155+
// Record the existing conditions in the parent
160156
tcNames := make(map[string]*yaml.Node)
161157
for i := 0; i < len(tc.Content); i += 2 {
162158
tcNames[tc.Content[i].Value] = tc.Content[i+1]
163159
}
160+
164161
for i, condNode := range module.ConditionsNode.Content {
165162
if i%2 == 0 {
166163
// Prepend the module name to the condition
@@ -172,12 +169,12 @@ func (module *Module) ProcessConditions() error {
172169
"%s that conflicts with a Condition in the parent"
173170
return fmt.Errorf(msg, module.Config.Source, name)
174171
}
172+
} else {
173+
nameNode := node.MakeScalar(name)
174+
node.Append(tc, nameNode)
175+
cloned := node.Clone(val)
176+
node.Append(tc, cloned)
175177
}
176-
nameNode := node.MakeScalar(name)
177-
node.Append(tc, nameNode)
178-
cloned := node.Clone(module.ConditionsNode.Content[i+1])
179-
node.Append(tc, cloned)
180-
break
181178
}
182179
}
183180

@@ -190,9 +187,6 @@ func (module *Module) ProcessConditions() error {
190187
func (module *Module) EvalCond(
191188
name string, val *yaml.Node) (EvalResult, error) {
192189

193-
config.Debugf("module.EvalCond %s %s:\n%s",
194-
module.Config.Name, name, node.YamlStr(val))
195-
196190
// Handle mapping node (most condition functions)
197191
if val.Kind == yaml.MappingNode && len(val.Content) >= 2 {
198192
key := val.Content[0].Value
@@ -343,10 +337,6 @@ func (module *Module) EvalEquals(n *yaml.Node) (EvalResult, error) {
343337
}
344338
}
345339

346-
// This looks like an unresolved reference
347-
config.Debugf("EvalEquals unresolved val1: %s, val2: %s",
348-
node.YamlStr(val1), node.YamlStr(val2))
349-
350340
return UnResolved, nil
351341
}
352342

cft/pkg/module.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,12 +242,20 @@ func processModule(
242242
return err
243243
}
244244

245-
err = processAddedSections(moduleAsTemplate, moduleAsTemplate.Node.Content[0],
245+
// processAddedSections is where we recurse on sub-modules
246+
err = processAddedSections(moduleAsTemplate,
247+
moduleAsTemplate.Node.Content[0],
246248
parsedModule.RootDir, parsedModule.FS, m)
247249
if err != nil {
248250
return err
249251
}
250252

253+
// Process conditions again to emit sub-module conditions into the parent
254+
err = m.ProcessConditions()
255+
if err != nil {
256+
return err
257+
}
258+
251259
err = m.ValidateOverrides()
252260
if err != nil {
253261
return err

cft/pkg/tmpl/awscli-modules/cond-unres-expect.yaml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,19 @@
1+
Parameters:
2+
P:
3+
Type: String
14
Conditions:
25
FooIsRegionUsEast1:
36
Fn::Equals:
47
- Ref: AWS::Region
58
- us-east-1
9+
FooIsPTrue:
10+
Fn::Equals:
11+
- !Ref P
12+
- true
13+
FooSubIsParam:
14+
Fn::Equals:
15+
- !Ref P
16+
- true
617

718
Resources:
819
FooS3Bucket:
@@ -16,3 +27,9 @@ Resources:
1627
- FooIsRegionUsEast1
1728
- a-east
1829
- a-not-east
30+
FooSubB:
31+
Type: A::B::C
32+
Condition: FooSubIsParam
33+
FooC:
34+
Type: D::E::F
35+
Condition: FooIsPTrue

cft/pkg/tmpl/awscli-modules/cond-unres-module.yaml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,22 @@
1+
Parameters:
2+
P:
3+
Type: String
4+
15
Conditions:
26
IsRegionUsEast1:
37
Fn::Equals:
48
- Ref: AWS::Region
59
- us-east-1
10+
IsPTrue:
11+
Fn::Equals:
12+
- !Ref P
13+
- true
14+
15+
Modules:
16+
Sub:
17+
Source: cond-unres-submodule.yaml
18+
Properties:
19+
P: !Ref P
620

721
Resources:
822
S3Bucket:
@@ -16,3 +30,6 @@ Resources:
1630
- IsRegionUsEast1
1731
- a-east
1832
- a-not-east
33+
C:
34+
Type: D::E::F
35+
Condition: IsPTrue
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
Parameters:
2+
P:
3+
Type: String
4+
5+
Conditions:
6+
IsParam:
7+
Fn::Equals:
8+
- !Ref P
9+
- true
10+
11+
Resources:
12+
B:
13+
Condition: IsParam
14+
Type: A::B::C
Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
Parameters:
2+
P:
3+
Type: String
4+
15
Modules:
26
Foo:
3-
Source: cond-unres-module.yaml
7+
Source: cond-unres-module.yaml
8+
Properties:
9+
P: !Ref P

cft/pkg/tmpl/awscli-modules/conditional-module.yaml

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,17 @@ Parameters:
55

66
LambdaRoleName:
77
Type: String
8-
Description: If set, allow the lambda function to access this table
98
Default: ""
109

10+
HasLambda:
11+
Type: Boolean
12+
Default: false
13+
1114
Conditions:
1215
IfLambdaRoleIsSet:
13-
Fn::Not:
14-
- Fn::Equals:
15-
- !Ref LambdaRoleName
16-
- ""
16+
Fn::Equals:
17+
- !Ref HasLambda
18+
- true
1719

1820
Nested:
1921
Fn::And:

cft/pkg/tmpl/awscli-modules/conditional-template.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ Modules:
44
Properties:
55
TableName: table-a
66
LambdaRoleName: my-role
7+
HasLambda: true
78
B:
89
Source: ./conditional-module.yaml
910
Properties:

0 commit comments

Comments
 (0)