-
Notifications
You must be signed in to change notification settings - Fork 4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix(core): prevent the error when the condition is split into groups of 10 and 1 in Fn.conditionOr()
#25708
fix(core): prevent the error when the condition is split into groups of 10 and 1 in Fn.conditionOr()
#25708
Changes from 1 commit
6174b91
7d2c99e
efdb0dc
78da890
ac4b16c
2901214
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -334,6 +334,10 @@ export class Fn { | |
if (conditions.length === 1) { | ||
return conditions[0] as ICfnRuleConditionExpression; | ||
} | ||
// prevent the error "Fn::Or object requires a list of at least 2" when the condition is split into groups of 10 and 1 | ||
if (conditions.length % 10 === 1) { | ||
return Fn.conditionOr(..._inGroupsOf(conditions, 9).map(group => new FnOr(...group))); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this can break when There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, but would it be necessary to consider conditions for numbers larger than 91 or 181...? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I guess yes, unless we are totally sure that there is no user to use such configuration. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree that if we can't be sure, I should respond. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see. I feel the solution @MalikAtalla-AWS proposed is also simple without any edge cases, but let's wait for comments from the maintainers. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Lets go with @MalikAtalla-AWS's solution. Something like this might work public static conditionOr(...conditions: ICfnConditionExpression[]): ICfnRuleConditionExpression {
if (conditions.length === 0) {
throw new Error('Fn.conditionOr() needs at least one argument');
}
if (conditions.length === 1) {
return conditions[0] as ICfnRuleConditionExpression;
}
// prevent the error "Fn::Or object requires a list of at least 2" when the condition is split into groups of 10 and 1
if (conditions.length > 10) {
return Fn.conditionOr(..._inGroupsOf(conditions, 10).map(group => Fn.conditionOr(...group));
}
return Fn.conditionOr(..._inGroupsOf(conditions, 10).map(group => new FnOr(...group)));
} |
||
} | ||
return Fn.conditionOr(..._inGroupsOf(conditions, 10).map(group => new FnOr(...group))); | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -59,4 +59,54 @@ describe('condition', () => { | |
}, | ||
}); | ||
}); | ||
|
||
test('condition length is 10n + 1', () => { | ||
// GIVEN | ||
const stack = new cdk.Stack(); | ||
const expression = cdk.Fn.conditionOr( | ||
cdk.Fn.conditionEquals('a', '1'), | ||
cdk.Fn.conditionEquals('b', '2'), | ||
cdk.Fn.conditionEquals('c', '3'), | ||
cdk.Fn.conditionEquals('d', '4'), | ||
cdk.Fn.conditionEquals('e', '5'), | ||
cdk.Fn.conditionEquals('f', '6'), | ||
cdk.Fn.conditionEquals('g', '7'), | ||
cdk.Fn.conditionEquals('h', '8'), | ||
cdk.Fn.conditionEquals('i', '9'), | ||
cdk.Fn.conditionEquals('j', '10'), | ||
cdk.Fn.conditionEquals('k', '11'), | ||
); | ||
|
||
// WHEN | ||
new cdk.CfnCondition(stack, 'Condition1', { expression }); | ||
|
||
// THEN | ||
expect(toCloudFormation(stack)).toEqual({ | ||
Conditions: { | ||
Condition1: { | ||
'Fn::Or': [ | ||
{ | ||
'Fn::Or': [ | ||
{ 'Fn::Equals': ['a', '1'] }, | ||
{ 'Fn::Equals': ['b', '2'] }, | ||
{ 'Fn::Equals': ['c', '3'] }, | ||
{ 'Fn::Equals': ['d', '4'] }, | ||
{ 'Fn::Equals': ['e', '5'] }, | ||
{ 'Fn::Equals': ['f', '6'] }, | ||
{ 'Fn::Equals': ['g', '7'] }, | ||
{ 'Fn::Equals': ['h', '8'] }, | ||
{ 'Fn::Equals': ['i', '9'] }, | ||
], | ||
}, | ||
{ | ||
'Fn::Or': [ | ||
{ 'Fn::Equals': ['j', '10'] }, | ||
{ 'Fn::Equals': ['k', '11'] }, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is totally a nice-to-have, but in terms of the simplicity of the resulting CFN snippet, I think it would be preferable to simply drop the last wrapping
|
||
], | ||
}, | ||
], | ||
}, | ||
}, | ||
}); | ||
}); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a matter of preference, but this seems more readable:
The three base cases are stated explicitly, falling back to the recursive case at the end.