-
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
feat: cloudformation condition chaining #1494
Merged
Merged
Changes from 3 commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
import { CloudFormationToken, FnJoin } from './cloudformation-token'; | ||
import { FnCondition } from './condition'; | ||
import { IConditionExpression } from './condition'; | ||
|
||
// tslint:disable:max-line-length | ||
|
||
|
@@ -148,7 +148,7 @@ export class Fn { | |
* @param conditions conditions to AND | ||
* @returns an FnCondition token | ||
*/ | ||
public static conditionAnd(...conditions: FnCondition[]): FnCondition { | ||
public static conditionAnd(...conditions: IConditionExpression[]): IConditionExpression { | ||
return new FnAnd(...conditions); | ||
} | ||
|
||
|
@@ -159,7 +159,7 @@ export class Fn { | |
* @param rhs A value of any type that you want to compare. | ||
* @returns an FnCondition token | ||
*/ | ||
public static conditionEquals(lhs: any, rhs: any): FnCondition { | ||
public static conditionEquals(lhs: any, rhs: any): IConditionExpression { | ||
return new FnEquals(lhs, rhs); | ||
} | ||
|
||
|
@@ -178,7 +178,7 @@ export class Fn { | |
* evaluates to false. | ||
* @returns an FnCondition token | ||
*/ | ||
public static conditionIf(conditionId: string, valueIfTrue: any, valueIfFalse: any): FnCondition { | ||
public static conditionIf(conditionId: string, valueIfTrue: any, valueIfFalse: any): IConditionExpression { | ||
return new FnIf(conditionId, valueIfTrue, valueIfFalse); | ||
} | ||
|
||
|
@@ -189,7 +189,7 @@ export class Fn { | |
* or false. | ||
* @returns an FnCondition token | ||
*/ | ||
public static conditionNot(condition: FnCondition): FnCondition { | ||
public static conditionNot(condition: IConditionExpression): IConditionExpression { | ||
return new FnNot(condition); | ||
} | ||
|
||
|
@@ -201,7 +201,7 @@ export class Fn { | |
* @param conditions conditions that evaluates to true or false. | ||
* @returns an FnCondition token | ||
*/ | ||
public static conditionOr(...conditions: FnCondition[]): FnCondition { | ||
public static conditionOr(...conditions: IConditionExpression[]): IConditionExpression { | ||
return new FnOr(...conditions); | ||
} | ||
|
||
|
@@ -212,7 +212,7 @@ export class Fn { | |
* @param value A string, such as "A", that you want to compare against a list of strings. | ||
* @returns an FnCondition token | ||
*/ | ||
public static conditionContains(listOfStrings: string[], value: string): FnCondition { | ||
public static conditionContains(listOfStrings: string[], value: string): IConditionExpression { | ||
return new FnContains(listOfStrings, value); | ||
} | ||
|
||
|
@@ -223,7 +223,7 @@ export class Fn { | |
* of strings. | ||
* @returns an FnCondition token | ||
*/ | ||
public conditionEachMemberEquals(listOfStrings: string[], value: string): FnCondition { | ||
public conditionEachMemberEquals(listOfStrings: string[], value: string): IConditionExpression { | ||
return new FnEachMemberEquals(listOfStrings, value); | ||
} | ||
|
||
|
@@ -238,7 +238,7 @@ export class Fn { | |
* strings_to_check parameter. | ||
* @returns an FnCondition token | ||
*/ | ||
public conditionEachMemberIn(stringsToCheck: string[], stringsToMatch: string): FnCondition { | ||
public conditionEachMemberIn(stringsToCheck: string[], stringsToMatch: string): IConditionExpression { | ||
return new FnEachMemberIn(stringsToCheck, stringsToMatch); | ||
} | ||
|
||
|
@@ -442,13 +442,23 @@ class FnCidr extends FnBase { | |
} | ||
} | ||
|
||
class FnConditionBase extends CloudFormationToken implements IConditionExpression { | ||
constructor(type: string, value: any) { | ||
super({ [type]: value }); | ||
} | ||
|
||
public toConditionJson() { | ||
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. Where is this called? 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. oops. will remove |
||
return this.resolve(); | ||
} | ||
} | ||
|
||
/** | ||
* Returns true if all the specified conditions evaluate to true, or returns false if any one | ||
* of the conditions evaluates to false. ``Fn::And`` acts as an AND operator. The minimum number of | ||
* conditions that you can include is 2, and the maximum is 10. | ||
*/ | ||
class FnAnd extends FnCondition { | ||
constructor(...condition: FnCondition[]) { | ||
class FnAnd extends FnConditionBase { | ||
constructor(...condition: IConditionExpression[]) { | ||
super('Fn::And', condition); | ||
} | ||
} | ||
|
@@ -457,7 +467,7 @@ class FnAnd extends FnCondition { | |
* Compares if two values are equal. Returns true if the two values are equal or false | ||
* if they aren't. | ||
*/ | ||
class FnEquals extends FnCondition { | ||
class FnEquals extends FnConditionBase { | ||
/** | ||
* Creates an ``Fn::Equals`` condition function. | ||
* @param lhs A value of any type that you want to compare. | ||
|
@@ -475,7 +485,7 @@ class FnEquals extends FnCondition { | |
* in the Resources section and Outputs sections of a template. You can use the AWS::NoValue | ||
* pseudo parameter as a return value to remove the corresponding property. | ||
*/ | ||
class FnIf extends FnCondition { | ||
class FnIf extends FnConditionBase { | ||
/** | ||
* Creates an ``Fn::If`` condition function. | ||
* @param condition A reference to a condition in the Conditions section. Use the condition's name to reference it. | ||
|
@@ -491,12 +501,12 @@ class FnIf extends FnCondition { | |
* Returns true for a condition that evaluates to false or returns false for a condition that evaluates to true. | ||
* ``Fn::Not`` acts as a NOT operator. | ||
*/ | ||
class FnNot extends FnCondition { | ||
class FnNot extends FnConditionBase { | ||
/** | ||
* Creates an ``Fn::Not`` condition function. | ||
* @param condition A condition such as ``Fn::Equals`` that evaluates to true or false. | ||
*/ | ||
constructor(condition: FnCondition) { | ||
constructor(condition: IConditionExpression) { | ||
super('Fn::Not', [ condition ]); | ||
} | ||
} | ||
|
@@ -506,20 +516,20 @@ class FnNot extends FnCondition { | |
* all of the conditions evaluates to false. ``Fn::Or`` acts as an OR operator. The minimum number | ||
* of conditions that you can include is 2, and the maximum is 10. | ||
*/ | ||
class FnOr extends FnCondition { | ||
class FnOr extends FnConditionBase { | ||
/** | ||
* Creates an ``Fn::Or`` condition function. | ||
* @param condition A condition that evaluates to true or false. | ||
*/ | ||
constructor(...condition: FnCondition[]) { | ||
constructor(...condition: IConditionExpression[]) { | ||
super('Fn::Or', condition); | ||
} | ||
} | ||
|
||
/** | ||
* Returns true if a specified string matches at least one value in a list of strings. | ||
*/ | ||
class FnContains extends FnCondition { | ||
class FnContains extends FnConditionBase { | ||
/** | ||
* Creates an ``Fn::Contains`` function. | ||
* @param listOfStrings A list of strings, such as "A", "B", "C". | ||
|
@@ -533,7 +543,7 @@ class FnContains extends FnCondition { | |
/** | ||
* Returns true if a specified string matches all values in a list. | ||
*/ | ||
class FnEachMemberEquals extends FnCondition { | ||
class FnEachMemberEquals extends FnConditionBase { | ||
/** | ||
* Creates an ``Fn::EachMemberEquals`` function. | ||
* @param listOfStrings A list of strings, such as "A", "B", "C". | ||
|
@@ -548,7 +558,7 @@ class FnEachMemberEquals extends FnCondition { | |
* Returns true if each member in a list of strings matches at least one value in a second | ||
* list of strings. | ||
*/ | ||
class FnEachMemberIn extends FnCondition { | ||
class FnEachMemberIn extends FnConditionBase { | ||
/** | ||
* Creates an ``Fn::EachMemberIn`` function. | ||
* @param stringsToCheck A list of strings, such as "A", "B", "C". AWS CloudFormation checks whether each member in the strings_to_check parameter is in the strings_to_match parameter. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
32 changes: 32 additions & 0 deletions
32
packages/@aws-cdk/cdk/test/cloudformation/test.condition.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import { Test } from 'nodeunit'; | ||
import cdk = require('../../lib'); | ||
|
||
export = { | ||
'chain conditions'(test: Test) { | ||
// GIVEN | ||
const stack = new cdk.Stack(); | ||
const param = new cdk.Parameter(stack, 'Param1', { type: 'String' }); | ||
const cond1 = new cdk.Condition(stack, 'Condition1', { expression: cdk.Fn.conditionEquals("a", "b") }); | ||
const cond2 = new cdk.Condition(stack, 'Condition2', { expression: cdk.Fn.conditionContains([ "a", "b", "c" ], "c") }); | ||
const cond3 = new cdk.Condition(stack, 'Condition3', { expression: cdk.Fn.conditionEquals(param, "hello") }); | ||
|
||
// WHEN | ||
new cdk.Condition(stack, 'Condition4', { | ||
expression: cdk.Fn.conditionOr(cond1, cond2, cdk.Fn.conditionNot(cond3)) | ||
}); | ||
|
||
// THEN | ||
test.deepEqual(stack.toCloudFormation(), { | ||
Parameters: { Param1: { Type: 'String' } }, | ||
Conditions: { | ||
Condition1: { 'Fn::Equals': [ 'a', 'b' ] }, | ||
Condition2: { 'Fn::Contains': [ [ 'a', 'b', 'c' ], 'c' ] }, | ||
Condition3: { 'Fn::Equals': [ { Ref: 'Param1' }, 'hello' ] }, | ||
Condition4: { 'Fn::Or': [ | ||
{ Condition: 'Condition1' }, | ||
{ Condition: 'Condition2' }, | ||
{ 'Fn::Not': [ { Condition: 'Condition3' } ] } ] } } }); | ||
|
||
test.done(); | ||
} | ||
}; |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
Why
resolve()
and not a more specific fucntion name? If you wantedresolve()
you could have accepted a Token, or aConditionBase
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.
But I wanted the Condition construct to implement it, so I had to define it as an interface. And I want the recursive resolution behavior of tokens to apply to full expressions, so I just faked it.
We should probably define an
IToken
with a resolve method so (reopened #79)