-
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(core): acknowledge warnings #26144
Merged
Changes from 1 commit
Commits
Show all changes
35 commits
Select commit
Hold shift + click to select a range
5ce3b70
feat(core): acknowledge annotation warning messages
corymhall fca3a1a
adding deprecation
corymhall 707be7f
updating all references from `addWarning` to `addWarningV2`
corymhall 5229dc9
updated readme
corymhall bb217e3
fixing lint errors
corymhall 9e19207
fixing tests
corymhall a9f506e
Merge branch 'main' into corymhall/core/ack-warnings
corymhall 4b8ad28
adding to breaking change
corymhall eb244d8
couple more
corymhall 54a2910
adding examples
corymhall 06f8559
adding adr
corymhall 4af1135
formatting the messages
corymhall 9198add
Merge remote-tracking branch 'origin/main' into pr/corymhall/26144
rix0rrr 957c238
Keep warning suppression synth-side by means of an App global
rix0rrr f0ce23b
Don't need these breaking changes anymore
rix0rrr 6412029
Comment
rix0rrr df8a853
Update adr
rix0rrr 5aba9ac
Undo test change
rix0rrr ee9fc76
addWarning -> addWarningV2
rix0rrr 56625ac
Linterrrr
rix0rrr cd72788
Update tests
rix0rrr 87b3b12
More tests
rix0rrr c0b5319
Oops
rix0rrr a95dde9
Test again
rix0rrr acca007
Merge branch 'main' into corymhall/core/ack-warnings
rix0rrr da5211d
Foutje
rix0rrr 9e9a6fd
Merge branch 'corymhall/core/ack-warnings' of github.com:corymhall/aw…
rix0rrr 52ecb54
Merge branch 'main' into corymhall/core/ack-warnings
rix0rrr 7c5b1c7
Merge branch 'corymhall/core/ack-warnings' of github.com:corymhall/aw…
rix0rrr 4fb2770
This is not a warning
rix0rrr af14a3f
Merge branch 'main' into corymhall/core/ack-warnings
rix0rrr 696945d
Exclude "__proto__" from fast-check
rix0rrr 6361023
Fix examples
rix0rrr 52eab30
Merge branch 'main' into corymhall/core/ack-warnings
rix0rrr e8d78d6
Merge branch 'main' into corymhall/core/ack-warnings
rix0rrr 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
181 changes: 181 additions & 0 deletions
181
packages/aws-cdk-lib/core/lib/adr/acknowledge-warnings.md
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,181 @@ | ||
# Acknowledge Warnings | ||
|
||
## Status | ||
|
||
accepted | ||
|
||
## Context | ||
|
||
Construct authors can add messages that will be printed at synthesis. It | ||
possible to add three types of warnings: | ||
|
||
- `INFO`: Prints the info on synthesis | ||
- `WARN`: Prints the warning on synthesis. Can also throw an error if the `--strict` | ||
argument is used | ||
- `ERROR`: Throws an error with the message | ||
|
||
Warning messages are typically used for two types of messages: | ||
|
||
1. Things that are errors (and will error on deployment) in some cases, but not all. For example, a warning is | ||
used when > 10 managed policies are added to an IAM Role because that is the | ||
initial limit for AWS accounts. An error is not used because it is possible | ||
to increase the limit. | ||
2. Things that are not errors (and will deploy successfully), but might be | ||
sub-optimal configuration. For example, a warning is used when an Serverless | ||
V2 Aurora cluster is created and no reader instances are created in tiers | ||
0-1. This is a valid configuration, but could cause availability issues in | ||
certain scenarios. | ||
|
||
Users who are developing CDK applications may want to always use the `--strict` | ||
CLI argument to turn all warnings into errors. Currently this is probably not | ||
possible since as soon as one warning is not applicable they can no longer use | ||
`--strict`. Ideally they should be able to `acknowledge` warnings (similar to | ||
what they can do with notices) indicating that the warning is not applicable to | ||
them/they acknowledge the risk. | ||
|
||
```ts | ||
Annotations.of(this).acknowledgeWarning( | ||
'@aws-cdk/aws-iam:maxPoliciesExceeded', | ||
'A limit increase has been submitted', | ||
); | ||
``` | ||
|
||
This would allow acknowledgements to live alongside the code so all developers | ||
on the code base would have the information readily available. This also allows | ||
the acknowledgement to be added at a certain `scope` and apply to all child | ||
constructs. Users would be able to acknowledge certain warnings for the entire | ||
app, or for a specific scope. | ||
|
||
## Constraints | ||
|
||
Warnings are currently added with the `Annotations` API. | ||
|
||
```ts | ||
Annotations.of(scope).addWarning('This is a warning'); | ||
``` | ||
|
||
`Annotations.of(scope)` creates a new instance of `Annotations` every time so | ||
there is no way to keep track of warnings added. For example, doing something | ||
like this would not work because the `Annotations` instance created with | ||
`acknowledgeWarning` would be different than the one created with `addWarning`. | ||
|
||
```ts | ||
Annotations.of(scope).addWarning('This is a warning'); | ||
Annotations.of(scope).acknowledgeWarning('This is a warning'); | ||
``` | ||
|
||
Currently the storage mechanism for `Annotations` is the `Node` metadata. The | ||
warning is added to the node as node metadata which is read by the CLI after | ||
synthesis to print out the messages. This means that Annotations can be added | ||
during `synthesis`. | ||
|
||
Another constraint is that currently you add a warning with only the message. | ||
There is no unique identifier. This means that to add an acknowledgement the | ||
user would need to copy the entire message. | ||
|
||
## Decision | ||
|
||
We will deprecate the `addWarning` method and add a new method `addWarningV2` | ||
|
||
```ts | ||
/** | ||
* @param id the unique identifier for the warning. This can be used to acknowledge the warning | ||
* @param message The warning message. | ||
*/ | ||
public addWarningV2(id: string, message: string): void | ||
``` | ||
|
||
We will add a new method `acknowledgeWarning` that will allow users to | ||
acknowledge a specific warning by `id`. | ||
|
||
```ts | ||
/** | ||
* @param id - the id of the warning message to acknowledge | ||
* @param message optional message to explain the reason for acknowledgement | ||
*/ | ||
public acknowledgeWarning(id: string, message?: string): void | ||
``` | ||
|
||
We will continue to use the node metadata as the storage mechanism and will add | ||
a new metadata type `aws:cdk:acknowledge` to store information on | ||
acknowledgements. | ||
|
||
At synthesis when we collect all of the annotation messages, we will filter out | ||
any messages that have an acknowledgement. | ||
|
||
Storing the acknowledgements in the metadata will also allow us to report on | ||
warnings that were acknowledged by the user (info will be stored in the | ||
assembly). | ||
|
||
## Alternatives | ||
|
||
### Alternative storage mechanism | ||
|
||
One alternative that was considered was to implement some alternative | ||
intermediary storage mechanism. This storage mechanism would allow storing all | ||
warnings and acknowledgements in a special construct that was created once per | ||
app. It would look something like this (pseudo code) | ||
|
||
```ts | ||
class AnnotationManager extends Construct { | ||
private constructor(scope: Construct) { | ||
attachCustomSynthesis(this, { | ||
onSynthesize: () => { | ||
this.warnings.forEach(warning => node.addMetadata(...)) | ||
} | ||
} | ||
} | ||
|
||
public addWarning() { | ||
if (!this.acks.has()) { | ||
this.warnings.set(); | ||
} | ||
} | ||
public ack() { | ||
if (this.warnings.has()) { | ||
this.warnings.delete(); | ||
} | ||
this.acks.add(); | ||
} | ||
} | ||
``` | ||
|
||
The problem with this method is represented by the `attachCustomSynthesis` in | ||
the example. This same applies for if we used `addValidation` or `Aspects`. | ||
Annotations can be added _after_ that which means they would not be added or | ||
acknowledged. | ||
|
||
### Use context and remove metadata | ||
|
||
Another alternative that was considered was to use context to set | ||
acknowledgements. This would look something like this: | ||
|
||
```ts | ||
public acknowledgeWarning(id: string, message?: string) { | ||
this.scope.node.setContext(id, message ?? true); // can't do this today | ||
this.scope.node.removeMetadata(id); // this method does not exist | ||
} | ||
public addWarningV2(id: string, message: string) { | ||
if (this.scope.node.tryGetContext(id) === undefined) { | ||
this.addMessage(...); | ||
} | ||
} | ||
``` | ||
|
||
There are two issues with this alternative. | ||
|
||
1. It is currently not possible to `node.setContext` once children are added. We | ||
would have to first remove that limitation. I think this could lead to a lot | ||
of issues where users have to keep track of _when_ context is added. | ||
2. We would have to implement the ability to `removeMetadata` from a node. This | ||
functionality doesn't make much sense outside of this context (can't find | ||
where anybody has asked for it). It also may require updating the metadata | ||
types since currently there is no unique identifier for a given metadata | ||
entry (other than the message). | ||
|
||
## Consequences | ||
|
||
With the recommended solution the only major consequence is that it requires | ||
updating the `metadata-schema`, but we can do this in a non-breaking way | ||
(addition of new types). The alternatives may also require changes to the schema | ||
as well. |
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.
It changes the schema, and interpreting the schema becomes more complex. I would really really like to avoid having an add list and a scrap list in the same piece of data, that the client hen has to evaluate.
Adding this as a feature to the core seems preferable to me.
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.
@rix0rrr Then do you think the context + remove metadata option is the one to go with?