diff --git a/changes/29795-deleted-policies-still-showing b/changes/29795-deleted-policies-still-showing new file mode 100644 index 0000000000..64b35388ce --- /dev/null +++ b/changes/29795-deleted-policies-still-showing @@ -0,0 +1 @@ +* Refactored the way failing policies are computed on Host end-point to avoid discrepancies due to read replica delays and async computation. \ No newline at end of file diff --git a/server/service/hosts.go b/server/service/hosts.go index a6045d481e..199f1236ae 100644 --- a/server/service/hosts.go +++ b/server/service/hosts.go @@ -1215,14 +1215,24 @@ func (svc *Service) getHostDetails(ctx context.Context, host *fleet.Host, opts f if err != nil { return nil, ctxerr.Wrap(ctx, err, "get policies for host") } - if hp == nil { hp = []*fleet.HostPolicy{} } - policies = &hp } + // Calculate the number of failing policies for the host based on the returned policies to + // avoid discrepancies due to read replica delay. + var failingPolicies uint64 + if policies != nil { + for _, p := range *policies { + if p != nil && p.Response == "fail" { + failingPolicies++ + } + } + } + host.HostIssues.FailingPoliciesCount = failingPolicies + // If Fleet MDM is enabled and configured, we want to include MDM profiles, // disk encryption status, and macOS setup details for non-linux hosts. ac, err := svc.ds.AppConfig(ctx) diff --git a/server/service/integration_core_test.go b/server/service/integration_core_test.go index ae98fa2fa2..62ba1ba503 100644 --- a/server/service/integration_core_test.go +++ b/server/service/integration_core_test.go @@ -2970,11 +2970,11 @@ func (s *integrationTestSuite) TestHostDetailsUpdatesStaleHostIssues() { hosts := s.createHosts(t, "linux") host := hosts[0] - stalePolicyCount, staleIssuesCount, freshPolicyCount, freshIssueCount := uint64(50), uint64(500), uint64(0), uint64(0) + staleIssuesCount, freshIssueCount := uint64(500), uint64(0) // create host_issues for it with stale data mysql.ExecAdhocSQL(t, s.ds, func(q sqlx.ExtContext) error { _, err := q.ExecContext(ctx, - `INSERT INTO host_issues (host_id, failing_policies_count, total_issues_count) VALUES (?, ?, ?)`, host.ID, stalePolicyCount, staleIssuesCount) + `INSERT INTO host_issues (host_id, total_issues_count) VALUES (?, ?)`, host.ID, staleIssuesCount) return err }) @@ -2982,7 +2982,6 @@ func (s *integrationTestSuite) TestHostDetailsUpdatesStaleHostIssues() { hostResp := getHostResponse{} s.DoJSON("GET", fmt.Sprintf("/api/v1/fleet/hosts/%d", host.ID), nil, http.StatusOK, &hostResp) - require.Equal(t, hostResp.Host.HostIssues.FailingPoliciesCount, stalePolicyCount) require.Equal(t, hostResp.Host.HostIssues.TotalIssuesCount, staleIssuesCount) // set updated_at to longer than minute ago @@ -2993,7 +2992,6 @@ func (s *integrationTestSuite) TestHostDetailsUpdatesStaleHostIssues() { }) // hit endpoint: should have been updated this time s.DoJSON("GET", fmt.Sprintf("/api/v1/fleet/hosts/%d", host.ID), nil, http.StatusOK, &hostResp) - require.Equal(t, hostResp.Host.HostIssues.FailingPoliciesCount, freshPolicyCount) require.Equal(t, hostResp.Host.HostIssues.TotalIssuesCount, freshIssueCount) }