Skip to content

INTEROP-8979: Add per-rule Slack notifications#274

Closed
amp-rh wants to merge 13 commits into
RedHatQE:mainfrom
amp-rh:interop-8976/token-rotation-alerts
Closed

INTEROP-8979: Add per-rule Slack notifications#274
amp-rh wants to merge 13 commits into
RedHatQE:mainfrom
amp-rh:interop-8976/token-rotation-alerts

Conversation

@amp-rh
Copy link
Copy Markdown
Collaborator

@amp-rh amp-rh commented Apr 7, 2026

Summary

  • Send Slack notifications via $SLACK_WEBHOOK_URL when Jira issues are created, duplicates detected, or success stories filed
  • Uses existing SlackClient.post_webhook() — no new dependencies
  • Notifications are opt-in: no webhook URL means no notifications

Related PRs

Test plan

  • test_post_webhook_success — verifies correct request params
  • test_post_webhook_request_error_does_not_raise — errors are logged, not raised
  • test_notify_slack_posts_when_env_set — posts when $SLACK_WEBHOOK_URL is set
  • test_notify_slack_skips_when_env_not_set — no-op without env var
  • test_notify_slack_does_not_raise_on_failure — swallows exceptions
  • All 222 unit tests passing
  • Pre-commit hooks passing
  • E2E: rehearse slack-webhook-test via INTEROP-8979: Wire Slack webhook into firewatch step openshift/release#78332

Relates: https://issues.redhat.com/browse/INTEROP-8979

🤖 Generated with Claude Code

Jira Cloud cannot programmatically create or rotate API tokens, so
fully automated rotation is not possible with basic auth. Instead,
add tooling for scheduled expiry monitoring with manual rotation:

- check-token-expiry.py: standalone script that reads expires_at from
  Vault and posts Slack alerts at 30/14/7/3/1 days before expiry
- prow-periodic.yaml: reference Prow periodic job config (daily 08:00 UTC)
- docs/vault-schema.md: Vault KV secret schema with new expires_at field
- docs/rotation-runbook.md: step-by-step manual rotation procedure

Relates: https://issues.redhat.com/browse/INTEROP-8976
Made-with: Cursor
@openshift-ci
Copy link
Copy Markdown

openshift-ci Bot commented Apr 7, 2026

Skipping CI for Draft Pull Request.
If you want CI signal for your change, please convert it to an actual PR.
You can still manually trigger a test run with /test all

amp-rh added 3 commits April 8, 2026 11:40
Add optional slack_channel field to firewatch config rules. When set,
firewatch sends a Slack notification after creating a new Jira issue,
updating a duplicate, or filing a success story. Absent or empty value
skips notification. Supports !default to read from env var.

Changes:
- Rule: add _get_slack_channel with !default/$FIREWATCH_DEFAULT_SLACK_CHANNEL
- SlackClient: add post_webhook static method for webhook-based posting
- Configuration: accept slack_bot_token and slack_webhook_url params
- Report: send Slack after issue creation, duplicate comment, success
- CLI: add --slack-bot-token and --slack-webhook-url to report command

Relates: https://issues.redhat.com/browse/INTEROP-8979
Made-with: Cursor
check-token-expiry.py now uses SlackClient.post_webhook() instead of
a local slack_post() function. post_webhook() propagates errors so
callers can decide how to handle failures: the token-expiry script
surfaces them as exit codes while Report._notify_slack() logs and
continues.

Made-with: Cursor
- Add types-requests to mypy pre-commit additional_dependencies
- Fix bare URLs and emphasis-as-heading in rotation-runbook.md and
  vault-schema.md
- Accept ruff-format changes and add mypy type: ignore on dict lookups

Made-with: Cursor
@amp-rh amp-rh changed the title INTEROP-8976: Add Jira API token expiry alerts and rotation runbook INTEROP-8976, INTEROP-8979: Token expiry alerts and per-rule Slack notifications Apr 8, 2026
Findings from staging walkthrough:
- vault kv put destroys 7 undocumented fields (secretsync config,
  account credentials, staging token); switch to vault kv patch
- Document all 10 actual Vault secret fields, not just 3
- Add staging verification step (stage-redhat.atlassian.net)
- Note that API tokens are account-scoped, not instance-scoped
- Specify vault login -method=oidc for authentication
- Include access_token_msi in rotation patch command

Made-with: Cursor
@amp-rh amp-rh marked this pull request as ready for review April 10, 2026 14:52
@amp-rh amp-rh marked this pull request as draft April 10, 2026 14:56
@amp-rh
Copy link
Copy Markdown
Collaborator Author

amp-rh commented Apr 13, 2026

/test all

@amp-rh amp-rh changed the title INTEROP-8976, INTEROP-8979: Token expiry alerts and per-rule Slack notifications INTEROP-8979: Add per-rule Slack notifications Apr 22, 2026
@amp-rh amp-rh force-pushed the interop-8976/token-rotation-alerts branch from ec98beb to 673c3e3 Compare April 23, 2026 19:16
@amp-rh amp-rh marked this pull request as ready for review April 27, 2026 19:31
When SLACK_WEBHOOK_URL is set globally (via CLI or env var), webhook
notifications now fire for all rules, even if the rule does not define
a slack_channel. Previously, _slack_new_issue, _slack_duplicate, and
_slack_success all gated on rule.slack_channel, which meant the global
webhook was silently skipped when rules lacked that field.

Introduces _should_notify_slack() that checks either per-rule
slack_channel OR global slack_webhook_url. Fixes the test CI config
blocker where the webhook never fired because the FIREWATCH_CONFIG
rules did not include slack_channel.
@amp-rh amp-rh force-pushed the interop-8976/token-rotation-alerts branch from 3998e21 to e02af25 Compare April 29, 2026 19:14
…ests

- Document the slack_channel rule field in the configuration guide
- Wire up SLACK_BOT_TOKEN and SLACK_WEBHOOK_URL envvars in Click options
  (previously had default=None, now use envvar= for automatic env pickup)
- Add unit tests for SlackClient.post_webhook() success and failure paths
@amp-rh amp-rh force-pushed the interop-8976/token-rotation-alerts branch from e02af25 to eb6bc77 Compare April 30, 2026 12:37
@amp-rh amp-rh force-pushed the interop-8976/token-rotation-alerts branch from 950b817 to 9100627 Compare April 30, 2026 16:08
amp-rh added 3 commits April 30, 2026 13:16
The rehearsal early-exit path in Report.__init__ skipped all rule
matching and Slack notification, so the webhook never fired during
CI rehearsals even when SLACK_WEBHOOK_URL was set and failures were
detected.

Changes:
- Add _notify_failure_webhooks(): matches failures against rules and
  fires the webhook before the rehearsal exit, without creating Jira
  tickets
- Add slack_user attribute to Rule (parsed from rule config), so rules
  with "slack_user": "user@redhat.com" trigger notifications
- Update _should_notify_slack() to check slack_user in addition to
  slack_channel and slack_webhook_url

TDD: 6 new tests written first (RED), then code added to pass (GREEN).
Logs webhook_url/failure_rules/failures state on entry, warns when
skipping due to missing config, and logs rule match counts per failure.
Without this, the method returned silently, making CI debugging
impossible.
The previous TDD tests called _notify_failure_webhooks directly via
Report.__new__(), bypassing __init__. These new tests exercise the
full Report(config, job) constructor path for rehearsal jobs, proving
the webhook fires before exit(0) when failures exist and
SLACK_WEBHOOK_URL is set.
@amp-rh amp-rh closed this May 5, 2026
@amp-rh
Copy link
Copy Markdown
Collaborator Author

amp-rh commented May 5, 2026

Closing in favor of #277

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