Added host_count_updated_at to policy API responses. (#15767)

Added `host_count_updated_at` to policy API responses.
#15323 

# Checklist for submitter

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

<!-- Note that API documentation changes are now addressed by the
product design team. -->

- [x] Changes file added for user-visible changes in `changes/` or
`orbit/changes/`.
See [Changes
files](https://fleetdm.com/docs/contributing/committing-changes#changes-files)
for more information.
- [x] Added/updated tests
- [x] Manual QA for all new/changed functionality
This commit is contained in:
Victor Lyuboslavsky
2023-12-27 15:24:27 -06:00
committed by GitHub
parent 289eb271a6
commit 6725da2ad0
6 changed files with 25 additions and 1 deletions
@@ -0,0 +1 @@
Added `host_count_updated_at` to policy API responses.
@@ -37,6 +37,7 @@ func Up_20231215122713(tx *sql.Tx) error {
WHERE p.team_id IS NULL
GROUP BY p.id, t.id
ON DUPLICATE KEY UPDATE
updated_at = NOW(),
passing_host_count = VALUES(passing_host_count),
failing_host_count = VALUES(failing_host_count);
`
@@ -53,6 +54,7 @@ func Up_20231215122713(tx *sql.Tx) error {
LEFT JOIN policy_membership pm ON p.id = pm.policy_id
GROUP BY p.id
ON DUPLICATE KEY UPDATE
updated_at = NOW(),
passing_host_count = VALUES(passing_host_count),
failing_host_count = VALUES(failing_host_count);
`
+7
View File
@@ -62,6 +62,7 @@ func (ds *Datastore) PolicyByName(ctx context.Context, name string) (*fleet.Poli
fmt.Sprint(`SELECT `+policyCols+`,
COALESCE(u.name, '<deleted>') AS author_name,
COALESCE(u.email, '') AS author_email,
ps.updated_at as host_count_updated_at,
COALESCE(ps.passing_host_count, 0) as passing_host_count,
COALESCE(ps.failing_host_count, 0) as failing_host_count
FROM policies p
@@ -93,6 +94,7 @@ func policyDB(ctx context.Context, q sqlx.QueryerContext, id uint, teamID *uint)
SELECT %s,
COALESCE(u.name, '<deleted>') AS author_name,
COALESCE(u.email, '') AS author_email,
ps.updated_at as host_count_updated_at,
COALESCE(ps.passing_host_count, 0) as passing_host_count,
COALESCE(ps.failing_host_count, 0) as failing_host_count
FROM policies p
@@ -312,6 +314,7 @@ func listPoliciesDB(ctx context.Context, q sqlx.QueryerContext, teamID *uint, op
SELECT ` + policyCols + `,
COALESCE(u.name, '<deleted>') AS author_name,
COALESCE(u.email, '') AS author_email,
ps.updated_at as host_count_updated_at,
COALESCE(ps.passing_host_count, 0) AS passing_host_count,
COALESCE(ps.failing_host_count, 0) AS failing_host_count
FROM policies p
@@ -348,6 +351,7 @@ func getInheritedPoliciesForTeam(ctx context.Context, q sqlx.QueryerContext, Tea
` + policyCols + `,
COALESCE(u.name, '<deleted>') AS author_name,
COALESCE(u.email, '') AS author_email,
ps.updated_at as host_count_updated_at,
COALESCE(ps.passing_host_count, 0) as passing_host_count,
COALESCE(ps.failing_host_count, 0) as failing_host_count
FROM policies p
@@ -400,6 +404,7 @@ func (ds *Datastore) PoliciesByID(ctx context.Context, ids []uint) (map[uint]*fl
sql := `SELECT ` + policyCols + `,
COALESCE(u.name, '<deleted>') AS author_name,
COALESCE(u.email, '') AS author_email,
ps.updated_at as host_count_updated_at,
COALESCE(ps.passing_host_count, 0) as passing_host_count,
COALESCE(ps.failing_host_count, 0) as failing_host_count
FROM policies p
@@ -1150,6 +1155,7 @@ func (ds *Datastore) UpdateHostPolicyCounts(ctx context.Context) error {
WHERE p.team_id IS NULL
GROUP BY p.id, t.id
ON DUPLICATE KEY UPDATE
updated_at = NOW(),
passing_host_count = VALUES(passing_host_count),
failing_host_count = VALUES(failing_host_count);
`)
@@ -1169,6 +1175,7 @@ func (ds *Datastore) UpdateHostPolicyCounts(ctx context.Context) error {
LEFT JOIN policy_membership pm ON p.id = pm.policy_id
GROUP BY p.id
ON DUPLICATE KEY UPDATE
updated_at = NOW(),
passing_host_count = VALUES(passing_host_count),
failing_host_count = VALUES(failing_host_count);
`)
+10
View File
@@ -2640,8 +2640,11 @@ func testUpdatePolicyHostCounts(t *testing.T, ds *Datastore) {
require.NoError(t, err)
require.Equal(t, uint(0), policy.FailingHostCount)
require.Equal(t, uint(0), policy.PassingHostCount)
assert.Nil(t, policy.HostCountUpdatedAt)
// update policy host counts
now := time.Now().Truncate(time.Second)
later := now.Add(10 * time.Second)
err = ds.UpdateHostPolicyCounts(context.Background())
require.NoError(t, err)
@@ -2650,4 +2653,11 @@ func testUpdatePolicyHostCounts(t *testing.T, ds *Datastore) {
require.NoError(t, err)
require.Equal(t, uint(0), policy.FailingHostCount)
require.Equal(t, uint(8), policy.PassingHostCount)
require.NotNil(t, policy.HostCountUpdatedAt)
assert.True(
t, policy.HostCountUpdatedAt.Compare(now) >= 0, fmt.Sprintf("reference:%v HostCountUpdatedAt:%v", now, *policy.HostCountUpdatedAt),
)
assert.True(
t, policy.HostCountUpdatedAt.Compare(later) < 0, fmt.Sprintf("later:%v HostCountUpdatedAt:%v", later, *policy.HostCountUpdatedAt),
)
}
+3 -1
View File
@@ -3,6 +3,7 @@ package fleet
import (
"errors"
"strings"
"time"
)
// PolicyPayload holds data for policy creation.
@@ -168,7 +169,8 @@ type Policy struct {
// PassingHostCount is the number of hosts this policy passes on.
PassingHostCount uint `json:"passing_host_count" db:"passing_host_count"`
// FailingHostCount is the number of hosts this policy fails on.
FailingHostCount uint `json:"failing_host_count" db:"failing_host_count"`
FailingHostCount uint `json:"failing_host_count" db:"failing_host_count"`
HostCountUpdatedAt *time.Time `json:"host_count_updated_at" db:"host_count_updated_at"`
}
func (p Policy) AuthzType() string {
+2
View File
@@ -123,6 +123,7 @@ func TestTriggerFailingPoliciesWebhookBasic(t *testing.T) {
"updated_at": "0001-01-01T00:00:00Z",
"passing_host_count": 0,
"failing_host_count": 0,
"host_count_updated_at": null,
"critical": true
},
"hosts": [
@@ -307,6 +308,7 @@ func TestTriggerFailingPoliciesWebhookTeam(t *testing.T) {
"updated_at": "0001-01-01T00:00:00Z",
"passing_host_count": 0,
"failing_host_count": 0,
"host_count_updated_at": null,
"critical": false
},
"hosts": [