Modify host battery health returned by GET /hosts/:id (#6782)

This commit is contained in:
gillespi314 2022-07-20 21:16:03 -05:00 committed by GitHub
parent cc34585a47
commit 0312454f4c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 34 additions and 11 deletions

View file

@ -0,0 +1,3 @@
- Modified `GET /host/:id` endpoint to calculate battery health based on the cycle count reported by
osquery such that “Normal” corresponds to cycle count < 1000 and “Replacement recommended”
corresponds to cycle count >= 1000.

View file

@ -2132,7 +2132,7 @@ If the scheduled queries haven't run on the host yet, the stats have zero values
"batteries": [
{
"cycle_count": 999,
"health": "Good"
"health": "Normal"
}
]
}
@ -2205,7 +2205,7 @@ Returns the information of the host specified using the `uuid`, `osquery_host_id
"batteries": [
{
"cycle_count": 999,
"health": "Good"
"health": "Normal"
}
]
}

View file

@ -144,7 +144,7 @@ const About = ({
}
return (
<div className="info-grid__block">
<span className="info-grid__header">Battery</span>
<span className="info-grid__header">Battery condition</span>
<span className="info-grid__data">
{aboutData.batteries?.[0]?.health}
</span>

View file

@ -1892,6 +1892,12 @@ func (ds *Datastore) HostIDsByOSVersion(
return ids, nil
}
// ListHostBatteries returns battery information as reported by osquery for the identified host.
//
// Note: Because of a known osquery issue with M1 Macs, we are ignoring the stored `health` value
// in the db and replacing it at the service layer with custom a value determined by the cycle
// count. See https://github.com/fleetdm/fleet/pull/6782#discussion_r926103758.
// TODO: Update once the underlying osquery issue has been resolved.
func (ds *Datastore) ListHostBatteries(ctx context.Context, hid uint) ([]*fleet.HostBattery, error) {
const stmt = `
SELECT

View file

@ -722,6 +722,18 @@ func (svc *Service) getHostDetails(ctx context.Context, host *fleet.Host, opts f
return nil, ctxerr.Wrap(ctx, err, "get batteries for host")
}
// Due to a known osquery issue with M1 Macs, we are ignoring the stored value in the db
// and replacing it at the service layer with custom values determined by the cycle count.
// See https://github.com/fleetdm/fleet/issues/6763.
// TODO: Update once the underlying osquery issue has been resolved.
for _, b := range bats {
if b.CycleCount < 1000 {
b.Health = "Normal"
} else {
b.Health = "Replacement recommended"
}
}
var policies *[]*fleet.HostPolicy
if opts.IncludePolicies {
hp, err := svc.ds.ListPoliciesForHost(ctx, host)

View file

@ -50,10 +50,12 @@ func TestHostDetails(t *testing.T) {
ds.ListPoliciesForHostFunc = func(ctx context.Context, host *fleet.Host) ([]*fleet.HostPolicy, error) {
return nil, nil
}
expectedBats := []*fleet.HostBattery{{HostID: host.ID, SerialNumber: "a"}}
dsBats := []*fleet.HostBattery{{HostID: host.ID, SerialNumber: "a", CycleCount: 999, Health: "Check Battery"}, {HostID: host.ID, SerialNumber: "b", CycleCount: 1001, Health: "Good"}}
ds.ListHostBatteriesFunc = func(ctx context.Context, hostID uint) ([]*fleet.HostBattery, error) {
return expectedBats, nil
return dsBats, nil
}
// Health should be replaced at the service layer with custom values determined by the cycle count. See https://github.com/fleetdm/fleet/issues/6763.
expectedBats := []*fleet.HostBattery{{HostID: host.ID, SerialNumber: "a", CycleCount: 999, Health: "Normal"}, {HostID: host.ID, SerialNumber: "b", CycleCount: 1001, Health: "Replacement recommended"}}
opts := fleet.HostDetailOptions{
IncludeCVEScores: false,

View file

@ -4988,7 +4988,7 @@ func (s *integrationTestSuite) TestGetHostBatteries() {
bats := []*fleet.HostBattery{
{HostID: host.ID, SerialNumber: "a", CycleCount: 1, Health: "Good"},
{HostID: host.ID, SerialNumber: "b", CycleCount: 2, Health: "Poor"},
{HostID: host.ID, SerialNumber: "b", CycleCount: 1002, Health: "Poor"},
}
require.NoError(t, s.ds.ReplaceHostBatteries(context.Background(), host.ID, bats))
@ -4997,8 +4997,8 @@ func (s *integrationTestSuite) TestGetHostBatteries() {
require.Equal(t, host.ID, getHostResp.Host.ID)
// only cycle count and health are returned
require.ElementsMatch(t, []*fleet.HostBattery{
{CycleCount: 1, Health: "Good"},
{CycleCount: 2, Health: "Poor"},
{CycleCount: 1, Health: "Normal"},
{CycleCount: 1002, Health: "Replacement recommended"},
}, *getHostResp.Host.Batteries)
// same for get host by identifier
@ -5006,8 +5006,8 @@ func (s *integrationTestSuite) TestGetHostBatteries() {
require.Equal(t, host.ID, getHostResp.Host.ID)
// only cycle count and health are returned
require.ElementsMatch(t, []*fleet.HostBattery{
{CycleCount: 1, Health: "Good"},
{CycleCount: 2, Health: "Poor"},
{CycleCount: 1, Health: "Normal"},
{CycleCount: 1002, Health: "Replacement recommended"},
}, *getHostResp.Host.Batteries)
}

View file

@ -61,7 +61,7 @@ func (s *integrationTestSuite) TestDeviceAuthenticatedEndpoints() {
require.Equal(t, "http://example.com/logo", getHostResp.OrgLogoURL)
require.Nil(t, getHostResp.Host.Policies)
require.NotNil(t, getHostResp.Host.Batteries)
require.Equal(t, &fleet.HostBattery{CycleCount: 1, Health: "Good"}, (*getHostResp.Host.Batteries)[0])
require.Equal(t, &fleet.HostBattery{CycleCount: 1, Health: "Normal"}, (*getHostResp.Host.Batteries)[0])
hostDevResp := getHostResp.Host
// make request for same host on the host details API endpoint, responses should match, except for policies