Skip to content

Add jsmops (JSM Ops) notifier as Opsgenie migration target#5373

Open
jothimanikrish wants to merge 6 commits into
prometheus:mainfrom
jothimanikrish:feature/jsmops-notifier-integration
Open

Add jsmops (JSM Ops) notifier as Opsgenie migration target#5373
jothimanikrish wants to merge 6 commits into
prometheus:mainfrom
jothimanikrish:feature/jsmops-notifier-integration

Conversation

@jothimanikrish

@jothimanikrish jothimanikrish commented Jul 5, 2026

Copy link
Copy Markdown

Pull Request Checklist

Please check all the applicable boxes.

  • Please list all open issue(s) discussed with maintainers related to this change

    • Fixes #
  • Is this a new Receiver integration?

  • Is this a bugfix?

    • I have added tests that can reproduce the bug which pass with this bugfix applied
  • Is this a new feature?

    • I have added tests that test the new feature's functionality
  • Does this change affect performance?

    • I have provided benchmarks comparison that shows performance is improved or is not degraded

    • I have added new benchmarks if required or requested by maintainers

  • Is this a breaking change?

    • My changes do not break the existing cluster messages

    • My changes do not break the existing api

  • I have added/updated the required documentation

  • I have signed-off my commits

  • I will follow best practices for contributing to this project

Which user-facing changes does this PR introduce?

[FEATURE] Add `jsmops` (Jira Service Management Operations) receiver as the migration target for the deprecated `opsgenie` receiver. Authentication is delegated to `http_config` (Basic Auth); a per-receiver `cloud_id` is required.

@jothimanikrish jothimanikrish requested a review from a team as a code owner July 5, 2026 09:10
Implement a new notify/jsmops/ package targeting the Jira Service Management
Operations REST API. This is the supported migration path for the deprecated
Opsgenie notifier (EOL April 2027).

Key differences from opsgenie:
- Auth delegated to http_config (no api_key fields)
- Required cloud_id per receiver config
- URLs built via APIURL.JoinPath(cloudID, "v1", "alerts", ...)
- Update requests use PATCH (per JSM Ops OpenAPI spec)

Includes:
- Full notifier implementation with create/close/update lifecycle
- Config schema, global defaults, per-receiver defaulting
- Integration registration in config/receiver
- Default templates (jsmops.default.message/description/source)
- Comprehensive test suite mirroring opsgenie patterns
- Documentation in docs/configuration.md and CHANGELOG.md

Signed-off-by: jothimanikrish <jothimanikrish@hotmail.com>
@jothimanikrish jothimanikrish force-pushed the feature/jsmops-notifier-integration branch from 35db0b9 to 4c8cf0f Compare July 5, 2026 09:11
@coderabbitai

coderabbitai Bot commented Jul 5, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This PR adds a JSM Ops notifier with configuration parsing, responder validation, API URL inheritance, alert create/close/update requests, default templates, documentation, changelog coverage, and tests.

Changes

JSM Ops receiver integration

Layer / File(s) Summary
JSMOpsConfig schema and validation
notify/jsmops/config.go, notify/jsmops/config_test.go
Defines JSM Ops configuration and responder types, defaults, YAML validation, and responder validation tests.
JSM Ops notifier implementation
notify/jsmops/jsmops.go, notify/jsmops/jsmops_test.go
Implements notifier construction, retry handling, create/close/update requests, responder expansion, payload rendering, and behavior tests.
Global and receiver configuration wiring
config/config.go, config/config_test.go, config/receiver/receiver.go, config/testdata/conf.jsmops-default-apiurl.yml
Adds JSM Ops configuration fields, API URL inheritance and normalization, HTTP path resolution, receiver integration construction, and configuration tests.
Default templates and documentation
template/default.tmpl, docs/configuration.md, CHANGELOG.md
Adds JSM Ops notification templates, documents configuration and migration details, and records the unreleased change.

Estimated code review effort: 3 (Moderate) | ~30 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Alertmanager
  participant ReceiverConfig
  participant JSMOpsNotifier
  participant JSMOpsAPI
  Alertmanager->>ReceiverConfig: load jsmops_configs
  ReceiverConfig->>JSMOpsNotifier: build notifier
  Alertmanager->>JSMOpsNotifier: Notify alerts
  JSMOpsNotifier->>JSMOpsAPI: create, close, or update alert
  JSMOpsAPI-->>JSMOpsNotifier: HTTP response
  JSMOpsNotifier-->>Alertmanager: retry decision and error
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 44.44% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly summarizes the main change: adding the JSM Ops notifier as the Opsgenie migration target.
Description check ✅ Passed The description matches the required checklist and release-notes section, with the main user-facing change clearly stated.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
notify/jsmops/config_test.go (1)

29-40: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Add assertion that responder Type is normalized after parsing.

This case exercises mixed-case types ("scheDule", "teams", "USER") but only checks require.NoError. It doesn't assert that the parsed config actually stores the lowercased value, which is why the range-copy bug in notify/jsmops/config.go (see review comment there) went unnoticed.

require.NoError(t, err)
require.Equal(t, "schedule", cfg.Responders[0].Type)
require.Equal(t, "teams", cfg.Responders[1].Type)
require.Equal(t, "user", cfg.Responders[2].Type)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@notify/jsmops/config_test.go` around lines 29 - 40, The “valid configuration”
test only checks that parsing succeeds, so it misses whether responder types are
actually normalized. In config_test.go, update the test that exercises
mixed-case responder types to assert the parsed cfg.Responders entries have
lowercased Type values after parsing, using the cfg.Responders slice and its
Type field to verify schedule, teams, and user normalization.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@notify/jsmops/config.go`:
- Around line 80-95: The responder type normalization in the jsmOps config
validation is only applied to the loop copy, so mixed-case types are not
persisted back into the config. Update the responder validation logic in the
c.Responders loop to iterate by index and assign the lowercased value back into
c.Responders[i].Type after the ContainsTemplating check, while preserving the
existing validation using jsmopsTypeMatcher and jsmopsValidTypesRe.

In `@notify/jsmops/jsmops.go`:
- Around line 182-210: The responder filtering in jsmOps message creation is too
weak because it only skips fully empty jsmOpsCreateMessageResponder values,
allowing identifier-less responders through when only Type is populated. Update
the responder-building loop in the JSM Ops message creation logic to reject
responders that do not have at least one valid identifier field (ID, Name, or
Username) after templating, while still preserving the special teams-to-team
expansion path. Keep the check close to the existing responder construction so
malformed responders are filtered before appending to responders.

---

Nitpick comments:
In `@notify/jsmops/config_test.go`:
- Around line 29-40: The “valid configuration” test only checks that parsing
succeeds, so it misses whether responder types are actually normalized. In
config_test.go, update the test that exercises mixed-case responder types to
assert the parsed cfg.Responders entries have lowercased Type values after
parsing, using the cfg.Responders slice and its Type field to verify schedule,
teams, and user normalization.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 4db83b0a-d437-41d5-b861-7e9675fbb245

📥 Commits

Reviewing files that changed from the base of the PR and between bb956c9 and 4c8cf0f.

📒 Files selected for processing (11)
  • CHANGELOG.md
  • config/config.go
  • config/config_test.go
  • config/receiver/receiver.go
  • config/testdata/conf.jsmops-default-apiurl.yml
  • docs/configuration.md
  • notify/jsmops/config.go
  • notify/jsmops/config_test.go
  • notify/jsmops/jsmops.go
  • notify/jsmops/jsmops_test.go
  • template/default.tmpl

Comment thread notify/jsmops/config.go Outdated
Comment thread notify/jsmops/jsmops.go
jothimanikrish and others added 2 commits July 5, 2026 14:30
- Iterate responders by index so strings.ToLower persists the
  normalized type back into the config struct. Previously the
  range-copy meant mixed-case types like "Teams" passed validation
  but failed the == "teams" check at notification time.

- Add a post-templating guard that skips responders whose identifier
  fields (ID, Name, Username) all evaluated to empty strings,
  preventing type-only responders from reaching the API.

Signed-off-by: jothimanikrish <jothimanikrish@hotmail.com>
@TheMeier

Copy link
Copy Markdown
Contributor

Context: Atlassian is officially retiring Opsgenie and folding its on-call and alerting features directly into Jira Service Management (JSM) Premium and Enterprise tiers. Opsgenie reaches its full end-of-support on April 5, 2027
https://www.atlassian.com/software/opsgenie/migrationhttps://www.atlassian.com/software/opsgenie/migration

However I wonder if JSM Ops only provides the opsgenie compatible API or if there other options, maybe even usable with the webhook notifier . Eg this https://developer.atlassian.com/cloud/jira/service-desk-ops/rest/v2/api-group-alerts/#api-api-cloudid-v1-alerts-post ?

@siavashs siavashs requested a review from SoloJacobs July 10, 2026 14:39
jothimanikrish and others added 3 commits July 12, 2026 13:26
The JSM Ops REST API supports basic auth and OAuth 2.0 authorization
code grants (3LO). Alertmanager's oauth2 http_config implements the
client credentials grant, which this API does not support, so remove
the claim that oauth2 works and document basic_auth (Atlassian account
email + API token) as the only working method, including the one-year
maximum API token lifetime.

Signed-off-by: jothimanikrish <jothimanikrish@hotmail.com>
The update_alerts message PATCH request was appended without
WithContext(ctx), unlike the create, close, and description requests,
so it would not be cancelled with the notification context.

Signed-off-by: jothimanikrish <jothimanikrish@hotmail.com>
@jothimanikrish

Copy link
Copy Markdown
Author

Thanks for raising this. JSM Ops actually exposes two API surfaces:

An Opsgenie-compatible integration API (https://api.atlassian.com/jsm/ops/integration/) — this is what JSM's built-in "Prometheus" integration uses, and the existing opsgenie receiver already works against it by just overriding api_url (confirmed in #4244, and why #3949 was closed).

The documented customer REST API (the one you linked) — officially versioned, authenticated with basic auth (account email + API token). This PR targets this one.

The webhook receiver could only cover alert creation: closing requires a POST to a different path (/alerts/{id}/close) and updates use PATCH, while the webhook posts firing and resolved to a single URL — so the create/close/update lifecycle can't be expressed with it.

For additional context: my own production setup currently runs the existing opsgenie receiver against https://api.atlassian.com/jsm/ops/integration/ (with the API key from JSM's Prometheus integration), and it works fine — so the URL-swap path from #4244 is confirmed working.

If required, I'm happy to rework this into a docs-only change documenting the api_url override as the supported migration path.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants