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
Conditionally adding metadata to translated resources #2224
Conversation
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.
could you please add some unit testing cases for this new change?
7ae6500
to
f29153d
Compare
@andrew-glenn It isn't clear what the purpose of this is for. Is it only for local tooling support? Why do you want to mutate underlying resources instead of the SAM Resources itself? |
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.
"Request changes" to indicate not to merge until the use-case is more understood.
@jfuss As an example, Rather than mess with the translator logic - which I'm not familiar with, and has a massive blast radius - I opted to surface a mapping of original SAM resource names --> Generated CFN Resources. Providing this mapping allows me (downstream) to iterate over the map and perform whatever actions I wish based on this data. Admittedly, this property wouldn't be used directly via the SAM CLI, but rather those that import SAM as a python library. |
@jfuss .. my understanding is that change will not affect the transformation logic, but will add some value for the sam translator library. |
@andrew-glenn and I discussed over slack yesterday afternoon. It is true this wouldn't impact the service but does mean we have to support this "overriding" locally. In the ideal world, I would like I scoped some time for myself on Thursday to think a little deeper and reach back out to @andrew-glenn to understand what he is trying to achieve with this and Open to other ideas here, just general cautious of features that only apply locally. |
For what it's worth to the studio audience, I'm now convinced having SAM copy the metadata is a better approach. I'll sync up with @jfuss tomorrow to determine the details |
f29153d
to
ecabca2
Compare
I've updated the PR to reflect the new approach (adding metadata in translation). I've set it to default disabled for backwards compatibility. |
Codecov Report
@@ Coverage Diff @@
## develop #2224 +/- ##
===========================================
+ Coverage 93.58% 94.40% +0.81%
===========================================
Files 90 97 +7
Lines 6124 7092 +968
Branches 1260 1436 +176
===========================================
+ Hits 5731 6695 +964
+ Misses 183 181 -2
- Partials 210 216 +6
Continue to review full report at Codecov.
|
{ | ||
"Resources": { | ||
"Images": { | ||
"Type": "AWS::S3::Bucket", |
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.
The bucket is defined in the template above, I don't think we want SAM to mutate that resource. I know we do today, but that is in very specific use-cases (adding events triggers).
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.
I'm not 100% seeing how this resource is being mutated, since it exists previously. What am I overlooking?
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.
Note, to save back and forth:
If we want to exclude certain resource types from the metadata passthrough, that's fine. I'll need a list of resource types that would apply here. I'm a little bit in the dark.
Edit: I see the issue here.
@@ -2,7 +2,7 @@ | |||
from samtranslator.parser.parser import Parser | |||
|
|||
|
|||
def transform(input_fragment, parameter_values, managed_policy_loader, feature_toggle=None): | |||
def transform(input_fragment, parameter_values, managed_policy_loader, feature_toggle=None, convert_metadata=False): |
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.
Nit: We aren't really converting anything for metadata here. Maybe something like add_metadata
or passthrough_metadata
is more clear for naming?
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.
Sure, no problem.
@@ -152,7 +153,10 @@ def translate(self, sam_template, parameter_values, feature_toggle=None): | |||
del template["Resources"][logical_id] | |||
for resource in translated: | |||
if verify_unique_logical_id(resource, sam_template["Resources"]): | |||
template["Resources"].update(resource.to_dict()) | |||
_r = resource.to_dict() |
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 convert the resources to dict? Should we just model Metadata with the resource pojo's we have?
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.
The current implementation (Line 155) converts it to a dictionary. I assumed this was done for a Very Good(tm) reason, so I simply followed the existing pattern.
@@ -152,7 +153,10 @@ def translate(self, sam_template, parameter_values, feature_toggle=None): | |||
del template["Resources"][logical_id] | |||
for resource in translated: | |||
if verify_unique_logical_id(resource, sam_template["Resources"]): | |||
template["Resources"].update(resource.to_dict()) | |||
_r = resource.to_dict() | |||
if resource_dict.get("Metadata") and convert_metadata: |
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.
I think a comment here could go a long away in understanding what is happening. It took me a while but I think what is happening is the following:
For each SAM resource in the source template, we translate to the underlying CloudFormation Resources. After we translate, we append any metadata in the SAM Resource to the translated CloudFormation Resources.
They generally works but I think there might be a couple edge cases outstanding:
- S3 buckets are updated (I made a comment below about this)
- I am not sure how generated resources work in this case. If you have an API Event on an
AWS::Serverless::Function.Event
what happens? Does the Metadata get pass through correctly? That is theMetadata
onAWS::Serverless::Function
gets added to all the API Gateway resources? This would be a good test case to add regardless of it it works in the current implementation or not.
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.
-
see above
-
Yes. A single SAM resource translates to multiple CFN resources. The metadata on the single SAM resource is passed through to the generated CFN resources, regardless of what the resource type is.
@moelasmar Can you re-review this? Things have changed since you last review |
need to re-review it again, PR changed since last time I reviewed it.
Exposing an additional
translated_resource_mapping
property in theTranslator
class allows downstream consumers to apply logic to translated resources.An example use case: copying cfn-lint metadata to new resources so that rule exceptions are honored.
See: aws-cloudformation/cfn-lint#2173