Skip to content

fix(cloudwatch): use PutAlarmMuteRule for mute/unmute with duration window#4621

Merged
TheodoreSpeaks merged 2 commits into
stagingfrom
fix/cw-mute-alarm
May 15, 2026
Merged

fix(cloudwatch): use PutAlarmMuteRule for mute/unmute with duration window#4621
TheodoreSpeaks merged 2 commits into
stagingfrom
fix/cw-mute-alarm

Conversation

@TheodoreSpeaks
Copy link
Copy Markdown
Collaborator

Summary

  • Mute Alarm now creates a CloudWatch alarm mute rule (PutAlarmMuteRule) instead of disabling alarm actions, so mutes auto-expire after a fixed duration
  • Unmute Alarm deletes the rule by name (DeleteAlarmMuteRule)
  • Mute params: muteRuleName, comma-separated alarmNames, durationValue + durationUnit dropdown (minutes/hours/days), optional description, optional startDate (Unix epoch — defaults to now); capped at AWS's 15-day limit
  • Unmute params: just muteRuleName

Type of Change

  • Improvement

Testing

Tested manually. bun run lint and bun run check:api-validation:strict pass.

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

@vercel
Copy link
Copy Markdown

vercel Bot commented May 15, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Skipped Skipped May 15, 2026 10:58pm

Request Review

@cursor
Copy link
Copy Markdown

cursor Bot commented May 15, 2026

PR Summary

Medium Risk
Changes the semantics and API contract of alarm muting from toggling alarm actions to creating/deleting named mute rules with schedules; mistakes could leave alarms muted longer than intended or fail to unmute if rule names don’t match.

Overview
Updates CloudWatch alarm muting to use CloudWatch alarm mute rules instead of enabling/disabling alarm actions. mute-alarm now creates a named rule via PutAlarmMuteRule with a scheduled start (at(...)) and ISO-8601 duration (validated and capped at 15 days), and returns the rule name plus the computed schedule details.

unmute-alarm now deletes the mute rule by muteRuleName via DeleteAlarmMuteRule, and the UI/tool contracts are updated accordingly (new required muteRuleName, new mute-only durationValue/durationUnit and optional description/start date; unmute no longer takes alarm names).

Reviewed by Cursor Bugbot for commit 7974bef. Bugbot is set up for automated code reviews on this repo. Configure here.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented May 15, 2026

Greptile Summary

This PR replaces the previous DisableAlarmActions/EnableAlarmActions approach with CloudWatch's newer PutAlarmMuteRule/DeleteAlarmMuteRule APIs, so mutes now carry an explicit time window and auto-expire rather than requiring a manual re-enable. The changes span the route handlers, Zod contracts, block definition, tool configs, and TypeScript types consistently.

  • Mute route: builds a Schedule.Expression using an at() one-time expression and an ISO-8601 duration, with a 15-day cap enforced in the Zod schema via superRefine.
  • Unmute route: simply deletes the named mute rule, replacing the previous alarm-list-based approach.
  • Block: adds muteRuleName, durationValue, durationUnit, and optional description/startDate inputs; splits the previously shared mute/unmute case into two separate branches.

Confidence Score: 3/5

The mute route has two issues that could prevent mute rules from ever activating: a missing seconds component in the schedule expression and a potential timing conflict when a user-supplied startDate is passed as both the at() trigger and the rule's StartDate field.

The at() expression built by toAtExpression omits the seconds field — AWS docs require at(yyyy-mm-ddThh:mm:ss) — likely causing every mute-rule creation to be rejected by the CloudWatch API. Additionally, when a user provides a startDate, the code sets both Schedule.Expression = at(startDate) and StartDate = startDate to the same instant; because StartDate means the rule only takes effect after that point, the at() trigger may fire before the rule is considered active, silently producing a no-op.

apps/sim/app/api/tools/cloudwatch/mute-alarm/route.ts — both the expression format and the StartDate logic need attention before this is production-safe.

Important Files Changed

Filename Overview
apps/sim/app/api/tools/cloudwatch/mute-alarm/route.ts Rewrites the mute handler to use PutAlarmMuteRuleCommand; the at() expression format omits required seconds and the StartDate field conflicts with the Expression timing.
apps/sim/app/api/tools/cloudwatch/unmute-alarm/route.ts Replaces EnableAlarmActionsCommand with DeleteAlarmMuteRuleCommand keyed by muteRuleName; straightforward and correct.
apps/sim/lib/api/contracts/tools/aws/cloudwatch-mute-alarm.ts Adds Zod schema for new mute-rule params including a superRefine check for the 15-day AWS limit; validation looks solid.
apps/sim/lib/api/contracts/tools/aws/cloudwatch-unmute-alarm.ts Replaces alarmNames array with muteRuleName string; schema is correct.
apps/sim/blocks/blocks/cloudwatch.ts Adds durationValue/durationUnit/muteRuleName inputs and splits mute/unmute case logic; parsing is correct but the 15-day cap is only enforced at the route layer.
apps/sim/tools/cloudwatch/types.ts Adds CloudWatchMuteDurationUnit type and updates Mute/Unmute param/response interfaces; types are accurate.
apps/sim/tools/cloudwatch/mute_alarm.ts Updates ToolConfig to reflect new params (muteRuleName, durationValue, durationUnit, startDate) and outputs; aligns with the new contract.
apps/sim/tools/cloudwatch/unmute_alarm.ts Replaces alarmNames param with muteRuleName and updates description/outputs accordingly; clean change.

Sequence Diagram

sequenceDiagram
    participant Block as CloudWatch Block
    participant Route as /api/tools/cloudwatch/mute-alarm
    participant CW as AWS CloudWatch

    Block->>Route: "POST {muteRuleName, alarmNames, durationValue, durationUnit, startDate?}"
    Route->>Route: Zod validate (incl. 15-day cap)
    Route->>Route: toAtExpression(startDate ?? now) → at(YYYY-MM-DDThh:mm)
    Route->>Route: toIsoDuration(value, unit) → PTxH / PxD / PTxM
    Route->>CW: "PutAlarmMuteRuleCommand {Name, Rule.Schedule, MuteTargets, StartDate?}"
    CW-->>Route: 200 OK
    Route-->>Block: "{success, muteRuleName, alarmNames, expression, duration}"

    Note over Block,Route: Unmute flow
    Block->>Route: "POST {muteRuleName}"
    Route->>CW: "DeleteAlarmMuteRuleCommand {AlarmMuteRuleName}"
    CW-->>Route: 200 OK
    Route-->>Block: "{success, muteRuleName}"
Loading

Reviews (1): Last reviewed commit: "fix(cloudwatch): use PutAlarmMuteRule fo..." | Re-trigger Greptile

Comment thread apps/sim/app/api/tools/cloudwatch/mute-alarm/route.ts
Comment thread apps/sim/app/api/tools/cloudwatch/mute-alarm/route.ts
@TheodoreSpeaks TheodoreSpeaks merged commit c403faf into staging May 15, 2026
14 checks passed
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.

1 participant