-
-
Notifications
You must be signed in to change notification settings - Fork 4.2k
Enable EventBridge API destinations and connections #11896
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
Conversation
…re (for now), quick copy of send_event_to_api_destination to get values from new store
…secret name validation in secretsmanager, add more tests for secret contents
# Some providers need to create keys which are not usually creatable by users | ||
if not any( | ||
tag_entry["Key"] == "BYPASS_SECRET_ID_VALIDATION" | ||
for tag_entry in request.get("Tags", []) | ||
): | ||
self._raise_if_invalid_secret_id(request["Name"]) | ||
else: | ||
request["Tags"] = [ | ||
tag_entry | ||
for tag_entry in request.get("Tags", []) | ||
if tag_entry["Key"] != "BYPASS_SECRET_ID_VALIDATION" | ||
] |
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.
We sadly need something to bypass the name validation here, as eventbridge connection secrets contain a !
, which is not allowed. I used a tag here, but there are other options should we decide against it.
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.
which is not allowed
I'm not sure I'm following here. Not allowed as in our SecretsManager service should support it, but doesn't? Or how would this otherwise work on AWS?
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.
Are AWS services able to create keys with names that we (as external users) can't?
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.
It seems that way. The error message clearly states it should not be allowed, the aws console also does not allow it. So maybe aws services have some bypass for it.
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.
Nice! 🏆 Think it's a good idea to move from the transient state in the provider to directly using the entities from the store. Much simpler and less error-prone.
The somewhat weird workaround with the secret names might be worth looking into later again. Maybe we can just detect it as an internal call via headers/request context and then allow arbitrary keys? We can discuss this at a later date though.
@@ -1754,7 +1754,7 @@ | |||
] | |||
} | |||
}, | |||
"tests/aws/services/events/test_events.py::TestEvents::test_create_connection_validations": { | |||
"tests/aws/services/events/test_events.py::TestEvents::test_create_connection_validations": { |
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.
comment: interesting 🤨
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.
Didn’t notice that, that is really interesting. Did someone manually mess with this file?
"recorded-content": { | ||
"create-connection": { | ||
"ConnectionArn": "connection-arn", | ||
"ConnectionArn": "arn:<partition>:events:<region>:111111111111:connection/<connection-name>/<resource:1>", |
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.
❤️: nice attention to detail with the ARN decomposition in the snapshots 🙌
"LastAuthorizedTime": "datetime", | ||
"LastModifiedTime": "datetime", | ||
"Name": "<connection-name>", | ||
"SecretArn": "arn:<partition>:secretsmanager:<region>:111111111111:secret:events!connection/<connection-name>/<secret-uuid>-<secret-id-suffix>", |
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.
comment: that !
is certainly an interesting choice on AWS's side
yield _create_connection | ||
|
||
try: | ||
aws_client.events.delete_connection(Name=connection_name) | ||
except Exception as e: | ||
LOG.debug("Error cleaning up connection: %s", e) |
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.
Nice catch. Kinda reminding me of the fact that it might be nice to revive the client-based cleanups at some point 😁
# Some providers need to create keys which are not usually creatable by users | ||
if not any( | ||
tag_entry["Key"] == "BYPASS_SECRET_ID_VALIDATION" | ||
for tag_entry in request.get("Tags", []) | ||
): | ||
self._raise_if_invalid_secret_id(request["Name"]) | ||
else: | ||
request["Tags"] = [ | ||
tag_entry | ||
for tag_entry in request.get("Tags", []) | ||
if tag_entry["Key"] != "BYPASS_SECRET_ID_VALIDATION" | ||
] |
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.
which is not allowed
I'm not sure I'm following here. Not allowed as in our SecretsManager service should support it, but doesn't? Or how would this otherwise work on AWS?
@pytest.mark.skipif( | ||
is_old_provider(), | ||
reason="V1 provider does not support this feature", | ||
) |
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.
@dfangl going above and beyond 🚀
ConnectionDict = dict[ConnectionName, DescribeConnectionResponse] | ||
ApiDestinationDict = dict[ApiDestinationName, DescribeApiDestinationResponse] |
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.
Guess that's something for service owners to judge, but I don't see this blocking for this iteration.
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.
This is really a temporary shortcut to get some typing, I would also think this needs another iteration at some point.
@@ -390,6 +391,10 @@ class EventsTargetSender(TargetSender): | |||
def send_event(self, event): | |||
# TODO add validation and tests for eventbridge to eventbridge requires Detail, DetailType, and Source | |||
# https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/events/client/put_events.html | |||
target_arn = self.target["Arn"] | |||
if ":api-destination/" in target_arn or ":destination/" in target_arn: | |||
send_event_to_api_destination(target_arn, event, self.target.get("HttpParameters")) |
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.
@maxhoheiser Might be something were instrumentation for EventStudio might be a good idea in a follow up
# TODO use service role as described here: https://docs.aws.amazon.com/eventbridge/latest/userguide/using-service-linked-roles-service-action-1.html | ||
# not too important as it is created automatically on AWS anyway, with the right permissions |
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.
even when using the API or only via the AWS Console?
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.
Should also be the case with the api.
@@ -339,33 +338,112 @@ def _create_connection_arn( | |||
self, context: RequestContext, name: str, connection_uuid: str | |||
) -> str: | |||
"""Create a standardized connection ARN.""" | |||
return f"arn:aws:events:{context.region}:{context.account_id}:connection/{name}/{connection_uuid}" | |||
return f"arn:{get_partition(context.region)}:events:{context.region}:{context.account_id}:connection/{name}/{connection_uuid}" |
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.
nice catch here as well 👍
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.
LGTM 🚀 Thanks a lot @dfangl
Motivation
In the current v2 provider, we do not support eventbridge API destinations.
As we do want this in 4.0.1, and I am unsure if we should do such a big code change, I staggered the commits in terms of escalating changes / complexity.
93822dd has the minimal changes necessary to make the feature work, we could cherry pick that into a separate PR.
After this commit, we increasingly increase parity, with more snapshots, creation of eventbridge secrets, bypass of secretmanager name assertions (since official EventBridge secrets contain a
!
in the name).It might be too much for a release tomorrow, but I will let the reviewers judge that.
Changes
snapshot
name directly (honestly a preference, but I did quite some work in the tests)