Skip to content
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(events): allow adding same target to rule multiple times #3187

Merged
merged 9 commits into from
Jul 19, 2019

Conversation

jogold
Copy link
Contributor

@jogold jogold commented Jul 3, 2019

As rule targets can have different input configurations adding the same target multiple times
must be possible.

Move rule target id generation to aws-events where it's easy to simply increment a counter. This
id is passed as an argument to bind() for targets that need to know their given id (e.g. EcsTask).

Add permissionsNode on IFunction to handle permission checks for both functions and singleton
functions.

Fixes #3173


Please read the contribution guidelines and follow the pull-request checklist.

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license

As rule targets can have different input configurations adding the same target multiple times
must be possible.

Move rule target id generation to `aws-events` where it's easy to simply increment a counter. This
id is passed as an argument to `bind()` for targets that need to know their given id (e.g. `EcsTask`).

Add `permissionsNode` on `IFunction` to handle permission checks for both functions and singleton
functions.

Fixes aws#3173
@jogold jogold requested review from RomainMuller, skinny85 and a team as code owners July 3, 2019 12:13
const id = sanitizeId(targetProps.id);
const inputProps = targetProps.input && targetProps.input.bind(this);
// Simply increment id for each `addTarget` call. This is guaranteed to be unique.
const id = `Target${this.targets.length}`;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure this will work correctly if we update a list of 2 elements to a list of 2 different elements.

I believe what will happen is CloudFormation will call addTarget("Rule1", { ... }) (the new Rule1), and then removeTarget("Rule1") (intending to remove the old rule1).

Anything that depends on addition order is super scary to me. I'd rather have a different consistent way of generating IDs.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Either an optional "id" field on every target that can be used in lieu of the default id, or we hash in the target configuration to make the ID unique.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure? CF will likely use PutTargets which updates everything in one go?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK I get what you mean, let's hash the configuration.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How do you suggest passing the id to the EcsTask target (which needs the id for its AwsCustomResource) if we hash it in aws-events after receiving the full configuration?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure this will work correctly if we update a list of 2 elements to a list of 2 different elements.

Actually I tested this and it works fine. If this was the case we would already have a problem with the current implementation because when you change a target configuration (let's say message for targets.SnsTopic) you are basically updating the target but keeping the same id. Rule targets are not CF resources by themselves, they are properties of AWS::Events::Rule.

You can try the following:
First depoy:

event.addTarget(new targets.SqsQueue(queue));
event.addTarget(new targets.SnsTopic(topic));

Second deploy:

event.addTarget(new targets.SnsTopic(topic));
event.addTarget(new targets.SqsQueue(queue));

After second deploy targets are correctly inverted.

Let me know if you still think that the id generation should be updated.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do they have an ID then... :x

@rix0rrr rix0rrr requested a review from a team as a code owner July 12, 2019 10:58
@rix0rrr
Copy link
Contributor

rix0rrr commented Jul 12, 2019

Oh well I guess this breaks API compatibility now.

err  - METHOD @aws-cdk/aws-events-targets.CodeBuildProject.bind: returns @aws-cdk/aws-events.RuleTargetConfig: formerly required property 'id' is missing in @aws-cdk/aws-events.RuleTargetConfig [change-return-type:@aws-cdk/aws-events-targets.CodeBuildProject.bind]

@jogold
Copy link
Contributor Author

jogold commented Jul 12, 2019

This is rather technical/internal... what do you suggest?

@rix0rrr
Copy link
Contributor

rix0rrr commented Jul 17, 2019

I have to context switch to get back into it... but offhand: id can't be removed. So can you make it so that it is used if nonempty, and the new behavior applies if the string is empty?

Not as good as an optional id field, but it'll have to do.

@jogold
Copy link
Contributor Author

jogold commented Jul 18, 2019

@rix0rrr this is now non breaking.

(shouldn't jsii-diff consider a change from required to optional as non breaking?)

@rix0rrr
Copy link
Contributor

rix0rrr commented Jul 19, 2019

(shouldn't jsii-diff consider a change from required to optional as non breaking?)

Not if the field is on a struct that is returned from a function. Consider the following:

interface OutputStruct {
  value: string;
}

const struct : OutputStruct = giveMeTheStruct();
functionThatExpectsAString(struct.value);

Now change value to be optional -- the code breaks! It used to be able to expect that value was always there, but that's no longer true.

@rix0rrr rix0rrr merged commit 9188b47 into aws:master Jul 19, 2019
@rix0rrr
Copy link
Contributor

rix0rrr commented Jul 19, 2019

After merging it it broke master, so I undid the merge and revived the PR here: #3352

@rix0rrr
Copy link
Contributor

rix0rrr commented Jul 19, 2019

This is a better pR: #3353

skinny85 pushed a commit that referenced this pull request Jul 19, 2019
As rule targets can have different input configurations adding the same target multiple times
must be possible.

Move rule target id generation to `aws-events` where it's easy to simply increment a counter. This
id is passed as an argument to `bind()` for targets that need to know their given id (e.g. `EcsTask`).

Add `permissionsNode` on `IFunction` to handle permission checks for both functions and singleton
functions.

Fixes #3173
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Permission check in aws-events-targets does not work with singleton functions
2 participants