Repository navigation
feat(#1273): the CloudWatch Logs tagging trio, and the ARN it takes - #1281
Merged
Merged
Conversation
TagResource was not mis-validating its resourceArn — it was absent, along with UntagResource and ListTagsForResource, so the request was refused as an unknown action. The trio therefore arrives with the rule the issue was filed for: the operations take the unsuffixed log-group ARN and refuse the IAM-policy form with the trailing ":*". Substrate hands a caller the refused form itself. DescribeLogGroups reports both ARNs and the suffixed one travels under the shorter member name `arn`, so reaching for it is the natural mistake — and a fake that accepts any ARN keeps a tagging path green offline and then fails on every log group of a live deploy. The rule applies to the read as well as the two writes, because a convergence path reads before it writes: a ListTagsForResource that accepted the suffixed form would report a group untagged rather than naming the ARN to send. ValidationException / Invalid resourceArn is observed rather than published — no page for the three lists a ValidationException at all — but what is published supports refusing: resourceArn carries Pattern [\w+=/:,.@-], a class with no "*" in it, so the suffixed form violates the request model before any resource is resolved. Only the code and message text come from observation. CreateLogGroup's inline tags are now persisted and read back; they were decoded and discarded, which is the half of the convergence path that looked like it worked. The account and Region come from the ARN and never from the caller's context (#826), which is why the three handlers are the only ones in the plugin that take no request context at all. Closes #1273. Refs #1274.
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
This file contains hidden or 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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
TagResourcewas not mis-validating itsresourceArn— it was absent, along withUntagResourceandListTagsForResource, so a request was refused as an unknown action rather thanaccepted with the wrong ARN. That is the correction #1274's audit made to the issue as filed, and it
is why the trio arrives together with the rule: a rule on an unroutable operation is untestable, and
an operation without the rule is the fake that caused the report.
The rule
The three operations take the unsuffixed log-group ARN and refuse the IAM-policy form:
The trap is that substrate hands a caller the refused form itself:
DescribeLogGroupsreports both,and the suffixed one travels under the shorter member name
arn. Reaching for it is the naturalmistake — it is also the ARN an IAM policy wants — and a hand-written fake that accepts any ARN keeps
a tagging path green offline and then fails on every group of a live deploy.
The rule is applied to the read as well as to the two writes, because a convergence path reads
before it writes: a
ListTagsForResourcethat accepted the suffixed form would report a groupuntagged rather than naming the ARN to send. A
:log-stream:suffix is refused the same way.Provenance
ValidationException/Invalid resourceArnis observed real-AWS behavior (us-west-2, by thereporter), not published: the pages for all three operations list
InvalidParameterException/400,ResourceNotFoundException/400 andServiceUnavailableException/500, plusTooManyTagsException/400on
TagResource, and none lists aValidationExceptionat all.What is published supports refusing —
resourceArncarries Pattern[\w+=/:,.@-]*, acharacter class with no
*in it, so the suffixed form violates the request model before anyresource is resolved. Only the code and the message text come from observation.
What else lands
CreateLogGroup's inlinetagsare persisted and read back byListTagsForResource. Theywere decoded and discarded, so a group created with tags inline reported none — the half of the
convergence path that looked like it worked.
tagsis a string-to-string map on both the request and the response, not the{key, value}array most services use; an untagged group answers
{"tags":{}}rather than omitting the member,so a caller comparing maps never has to tell nil from empty. Getting this shape wrong is the Logs: DescribeLogGroups/DescribeLogStreams/GetLogEvents return PascalCase members, so an SDK parses every field to null #528
failure mode for this service: a JSON-1.1 member that does not match the model parses to nothing
rather than erroring.
TagResource, against the merged set — a one-tag requestagainst a group holding fifty is refused, while the request alone is within bounds.
destination:ARN answersResourceNotFoundException. It is the other type all three pagespublish as taggable, and substrate models no destinations, so the ARN names a taggable type and a
resource that cannot exist here: the resource is missing, not the ARN wrong.
handlers are the only ones in the plugin that take no
*RequestContextat all, so there is nocaller's account in scope for a later edit to reach for.
Deliberately not here
CreateLogGroupdoes not enforce the tag ceiling. Its page publishes no error code forexceeding the
tagsmap maximum andTooManyTagsExceptionis published onTagResourcealone, sorefusing would mean inventing a code (ec2: an invalid block device mapping is accepted instead of refused with InvalidBlockDeviceMapping #671). The asymmetry is pinned by a test and documented
rather than smoothed over.
resolveARNhas nologsarm; adding one needs a resource-type filter, an ARN builder and theEverTaggedreportingrule the wire-bookkeeping ratchet is shrinking. Filed as a follow-up on foray adoption: 10 missing operations + 5 behaviours (checked against origin/main @ 57ab1d0) #1274 rather than folded in,
and stated in
docs/services.mdso it is not read as an oversight.Also pinned, not changed
DescribeLogGroupsfilterslogGroupNamePrefixas a prefix, so a caller checking existence thatway reads
/aws/lambda/foray-gatewayas existing when only/aws/lambda/foray-gateway-v2does. Thatis faithful, and the issue's closing note asked for it to stay; there is now a test so a well-meaning
edit cannot turn it into an exact match and hide the trap instead of modelling it.
Verification
make lint— 0 issues.make test(race,-count=1) — green.make docs-reference-check docs-versions version-check discarded-unmarshal-check wire-bookkeeping-check— green, with the ratchet still at 330: the newTagsmember is not abookkeeping field and the record deliberately carries no
EverTagged.changed statement, including both
storeLogGroupfailure paths, reached through an injectedfailing store.
Closes #1273. Refs #1274.