Skip to content

Record per-host ticket policy automation activities - #47203

Merged
juan-fdz-hawa merged 6 commits into
46899-policy-status-page---implement-missing-hosts-activities--allfrom
46899-policy-status-page---implement-missing-hosts-activities--tickets
Jun 12, 2026
Merged

Record per-host ticket policy automation activities#47203
juan-fdz-hawa merged 6 commits into
46899-policy-status-page---implement-missing-hosts-activities--allfrom
46899-policy-status-page---implement-missing-hosts-activities--tickets

Conversation

@juan-fdz-hawa

@juan-fdz-hawa juan-fdz-hawa commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Related issue: Resolves #46899

Added per-host activity log entries when policy ticket automations (Jira or Zendesk) fail after all retries are exhausted or succeed (ticket created).

Checklist for submitter

If some of the following don't apply, delete the relevant line.

  • Changes file added for user-visible changes in changes/, orbit/changes/ or ee/fleetd-chrome/changes.
    See Changes files for more information.

Testing

  • Added/updated automated tests

Summary by CodeRabbit

  • New Features

    • Added per-host activity logging for policy ticket automation outcomes across Jira and Zendesk, capturing both successful ticket creation and automation failures after all retries are exhausted.
  • Improvements

    • Enhanced error reporting for ticket creation failures by capturing and displaying error response details.

@juan-fdz-hawa juan-fdz-hawa changed the title Record per-host ticket policy automation activities Record per-host ticket policy automation activities (tickets) Jun 9, 2026
@juan-fdz-hawa juan-fdz-hawa changed the title Record per-host ticket policy automation activities (tickets) Record per-host ticket policy automation activities Jun 9, 2026
@juan-fdz-hawa juan-fdz-hawa linked an issue Jun 9, 2026 that may be closed by this pull request
@codecov

codecov Bot commented Jun 9, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 71.62162% with 21 lines in your changes missing coverage. Please review.
✅ Project coverage is 67.20%. Comparing base (ffbbb9e) to head (9fe7c93).
⚠️ Report is 1 commits behind head on 46899-policy-status-page---implement-missing-hosts-activities--all.

Files with missing lines Patch % Lines
cmd/fleet/cron.go 0.00% 8 Missing ⚠️
server/worker/jira.go 75.00% 3 Missing and 2 partials ⚠️
server/worker/zendesk.go 75.00% 3 Missing and 2 partials ⚠️
server/worker/worker.go 81.81% 1 Missing and 1 partial ⚠️
cmd/fleet/serve.go 0.00% 1 Missing ⚠️
Additional details and impacted files
@@                                         Coverage Diff                                         @@
##           46899-policy-status-page---implement-missing-hosts-activities--all   #47203   +/-   ##
===================================================================================================
  Coverage                                                               67.20%   67.20%           
===================================================================================================
  Files                                                                    2946     2946           
  Lines                                                                  226504   226571   +67     
  Branches                                                                11683    11683           
===================================================================================================
+ Hits                                                                   152217   152271   +54     
- Misses                                                                  60541    60551   +10     
- Partials                                                                13746    13749    +3     
Flag Coverage Δ
backend 68.80% <71.62%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@juan-fdz-hawa
juan-fdz-hawa marked this pull request as ready for review June 9, 2026 18:16
@juan-fdz-hawa
juan-fdz-hawa requested a review from a team as a code owner June 9, 2026 18:16
@juan-fdz-hawa

Copy link
Copy Markdown
Contributor Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Full review finished.

@coderabbitai

coderabbitai Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

This PR adds per-host activity logging for policy ticket automation outcomes in Jira and Zendesk integrations. The change introduces error response truncation utilities (bounded to 512 KiB at UTF-8 boundaries), two new activity types for failed and queued ticket automations, and a worker final-failure notification hook. Jira issue creation now captures HTTP response bodies on failure. Both Jira and Zendesk workers record activities on success (ticket created) and failure (after retries exhausted), with comprehensive test coverage throughout.

Possibly related PRs

  • fleetdm/fleet#44769: Both PRs modify the same newWorkerIntegrationsSchedule wiring in cmd/fleet/cron.go/cmd/fleet/serve.go, with this PR adding activitySvc dependency for Jira/Zendesk activity recording.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% 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
Title check ✅ Passed The title accurately summarizes the main change - recording activity entries for policy ticket automation outcomes across Jira and Zendesk.
Description check ✅ Passed The description covers the main objective, includes a reference to the linked issue, marks a changes file as added, and confirms automated tests were added.
Linked Issues check ✅ Passed The PR implements activity recording for Jira and Zendesk ticket automation failures and successes with error response capture, directly addressing the requirements in issue #46899.
Out of Scope Changes check ✅ Passed All changes are focused on recording ticket policy automation activities for Jira/Zendesk; no unrelated changes for webhooks, calendar events, or conditional access were introduced.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch 46899-policy-status-page---implement-missing-hosts-activities--tickets

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 and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 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 `@server/service/externalsvc/jira.go`:
- Around line 92-97: Replace the manual io.LimitReader + string conversion for
resp.Response.Body with the truncation utility to ensure UTF-8 safety and a
truncation marker: read up to str.MaxErrorResponseBytes+1 bytes from
resp.Response.Body (still guarding OOM), close the body, then call
str.TruncateErrorResponse on the byte slice and assign the result to respBody;
update the block around resp.Response.Body handling in jira.go (the section that
currently uses io.LimitReader and b := io.ReadAll(...)) to use this
read+str.TruncateErrorResponse flow so multi-byte runes are not cut and
"[truncated]" is appended when appropriate.
🪄 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: Pro

Run ID: 7d573718-ab67-4f0f-a130-3f9e0224bdc3

📥 Commits

Reviewing files that changed from the base of the PR and between ffbbb9e and 412a3d8.

📒 Files selected for processing (15)
  • changes/38670-policy-status-page
  • cmd/fleet/cron.go
  • cmd/fleet/serve.go
  • pkg/str/str.go
  • pkg/str/str_test.go
  • server/fleet/activities.go
  • server/fleet/activities_test.go
  • server/service/externalsvc/jira.go
  • server/service/externalsvc/jira_test.go
  • server/worker/jira.go
  • server/worker/jira_test.go
  • server/worker/worker.go
  • server/worker/worker_test.go
  • server/worker/zendesk.go
  • server/worker/zendesk_test.go

Comment thread server/service/externalsvc/jira.go Outdated

@nulmete nulmete left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Looks great. I have some suggestions below which I don't think are blocking, but worth addressing IMHO. Let me know what you think and I can re-review/approve.

Comment on lines +2032 to +2036
// ActivityTypeRanAutomationTicket is recorded when a failing-policy
// ticket automation (Jira or Zendesk) successfully creates the ticket. It is
// associated with every host the failing-policy job targeted. The Type field is
// "jira" or "zendesk". For Jira, TicketKey holds the issue key (e.g. "ENG-24");
// for Zendesk, TicketID holds the numeric ticket ID.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'm wondering if we really need this comment at all.

is recorded when a failing-policy // ticket automation (Jira or Zendesk) successfully creates the ticket

and

For Jira, TicketKey holds the issue key (e.g. "ENG-24"); // for Zendesk, TicketID holds the numeric ticket ID.

IMHO, for those 2 pieces we should be able to understand this by looking at how and where this struct is used.

The Type field is // "jira" or "zendesk"

nit: any chance that we can use a typed string / enum for this?


I'd say the same applies for the comment above ActivityTypeFailedAutomationTicket.

Comment thread server/worker/jira.go Outdated
func (j *Jira) OnFinalFailure(ctx context.Context, argsJSON json.RawMessage, jobErr string) error {
if j.NewActivitySvc == nil {
return nil
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

is there any case where NewActivitySvc would be nil? Reading serve.go I see that it's always passed. If this is just for tests, could tests be adjusted to have this service injected?

same for the check on L355 below.

Comment thread server/worker/jira.go
Comment on lines +267 to +269
// OnFinalFailure records a failed_automation_ticket host activity once
// the worker has exhausted all retries for a failing-policy job. Vulnerability
// jobs are ignored as they are not host- or policy-scoped.

@nulmete nulmete Jun 11, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Something similar to what I commented on the server/fleet/activities.go file. Perhaps we can drop this comment (if I see where this is called I can understand at first glance that this function runs when job.Retries reached maxRetries).

Re:

Vulnerability jobs are ignored as they are not host- or policy-scoped.

Are those Vulnerability jobs ignored because of the args.FailingPolicy == nil check below? Maybe I'd put the // Vulnerability jobs are ignored as they are not host- or policy-scoped. comment just above that line. (I had to look at jiraArgs and then I understood why.)

Comment thread server/worker/jira_test.go Outdated
Comment on lines +381 to +392
t.Run("nil activity service is a no-op", func(t *testing.T) {
j := &Jira{
FleetURL: "https://fleetdm.com",
Datastore: ds,
Log: slog.New(slog.DiscardHandler),
NewClientFunc: func(opts *externalsvc.JiraOptions) (JiraClient, error) {
return client, nil
},
}

args := json.RawMessage(`{"failing_policy":{"policy_id":5,"policy_name":"p5","hosts":[]}}`)
require.NoError(t, j.Run(license.NewContext(context.Background(), &fleet.LicenseInfo{Tier: fleet.TierFree}), args))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I don't think we'll need this test since we always pass the activity service when serving, correct?

Comment thread server/worker/worker_test.go Outdated
return t.run(ctx, argsJSON)
}

// testJobNotifier is a testJob that also implements FinalFailureNotifier.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

nit: IMO we can drop the comment 😄

Comment thread server/worker/zendesk_test.go Outdated
Comment on lines +119 to +131
t.Run("nil activity service is a no-op", func(t *testing.T) {
z := &Zendesk{
FleetURL: "https://fleetdm.com",
Datastore: ds,
Log: slog.New(slog.DiscardHandler),
NewClientFunc: func(opts *externalsvc.ZendeskOptions) (ZendeskClient, error) {
return client, nil
},
}

args := json.RawMessage(`{"failing_policy":{"policy_id":6,"policy_name":"p6","hosts":[]}}`)
require.NoError(t, z.Run(license.NewContext(context.Background(), &fleet.LicenseInfo{Tier: fleet.TierFree}), args))
})

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

same comment that I made in the jira_test.go file

Comment thread server/worker/zendesk.go Outdated
Comment on lines +270 to +276
// OnFinalFailure records a failed_automation_ticket host activity once
// the worker has exhausted all retries for a failing-policy job. Vulnerability
// jobs are ignored as they are not host- or policy-scoped.
func (z *Zendesk) OnFinalFailure(ctx context.Context, argsJSON json.RawMessage, jobErr string) error {
if z.NewActivitySvc == nil {
return nil
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

same comment that I made in the jira.go file (the comment and the nil checks)

@juan-fdz-hawa

Copy link
Copy Markdown
Contributor Author

Looks great. I have some suggestions below which I don't think are blocking, but worth addressing IMHO. Let me know what you think and I can re-review/approve.

Thanks for reviewing this - While those comments might seem a bit redundant to us, they provide helpful context for AI tools without requiring a deep dive into the implementation details. I’m inclined to keep them unless you see a specific downside?

@nulmete

nulmete commented Jun 11, 2026

Copy link
Copy Markdown
Member

Looks great. I have some suggestions below which I don't think are blocking, but worth addressing IMHO. Let me know what you think and I can re-review/approve.

Thanks for reviewing this - While those comments might seem a bit redundant to us, they provide helpful context for AI tools without requiring a deep dive into the implementation details. I’m inclined to keep them unless you see a specific downside?

No big downsides IMO, maybe:

  • more time for us to read the code since we have to read the comments too
  • we have to maintain the comments at the same time we maintain the code (e.g. if we change the implementation details of some func we also have to update the comment)
    (both manageable by using AI of course, this is personal preference)

// be activated, because the current activity was never truly started —
// activating the next one would break the intended sequential ordering.
//
// See commit 159194acc9d92843bb2de933309f159c84a501aa for the fix.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Oh this was removed by 🤖 - let me add it back

@juan-fdz-hawa
juan-fdz-hawa merged commit bf815c1 into 46899-policy-status-page---implement-missing-hosts-activities--all Jun 12, 2026
37 checks passed
@juan-fdz-hawa
juan-fdz-hawa deleted the 46899-policy-status-page---implement-missing-hosts-activities--tickets branch June 12, 2026 13:10
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.

Policy status page - Implement missing host's activities

3 participants