mirror of
https://github.com/fleetdm/fleet
synced 2026-05-24 09:28:54 +00:00
parent
6133a61fd1
commit
3cd841051b
5 changed files with 79 additions and 39 deletions
|
|
@ -15,7 +15,10 @@ type TargetService interface {
|
|||
// (hosts and label) which match the supplied search query.
|
||||
SearchTargets(ctx context.Context, query string, selectedHostIDs []uint, selectedLabelIDs []uint) (*TargetSearchResults, error)
|
||||
|
||||
CountHostsInTargets(ctx context.Context, hosts []uint, labels []uint) (uint, error)
|
||||
// CountHostsInTargets returns the count of hosts in the selected
|
||||
// targets. The first return uint is the total number of hosts in the
|
||||
// targets. The second return uint is the total online hosts.
|
||||
CountHostsInTargets(ctx context.Context, hostIDs []uint, labelIDs []uint) (uint, uint, error)
|
||||
}
|
||||
|
||||
type TargetType int
|
||||
|
|
@ -18,6 +18,7 @@ type labelResponse struct {
|
|||
kolide.Label
|
||||
DisplayText string `json:"display_text"`
|
||||
Count uint `json:"count"`
|
||||
Online uint `json:"online"`
|
||||
}
|
||||
|
||||
type getLabelResponse struct {
|
||||
|
|
@ -34,7 +35,7 @@ func makeGetLabelEndpoint(svc kolide.Service) endpoint.Endpoint {
|
|||
if err != nil {
|
||||
return getLabelResponse{Err: err}, nil
|
||||
}
|
||||
count, err := svc.CountHostsInTargets(ctx, nil, []uint{label.ID})
|
||||
total, online, err := svc.CountHostsInTargets(ctx, nil, []uint{label.ID})
|
||||
if err != nil {
|
||||
return getLabelResponse{Err: err}, nil
|
||||
}
|
||||
|
|
@ -42,7 +43,8 @@ func makeGetLabelEndpoint(svc kolide.Service) endpoint.Endpoint {
|
|||
Label: labelResponse{
|
||||
*label,
|
||||
label.Name,
|
||||
count,
|
||||
total,
|
||||
online,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
|
@ -73,7 +75,7 @@ func makeListLabelsEndpoint(svc kolide.Service) endpoint.Endpoint {
|
|||
|
||||
resp := listLabelsResponse{}
|
||||
for _, label := range labels {
|
||||
count, err := svc.CountHostsInTargets(ctx, nil, []uint{label.ID})
|
||||
total, online, err := svc.CountHostsInTargets(ctx, nil, []uint{label.ID})
|
||||
if err != nil {
|
||||
return listLabelsResponse{Err: err}, nil
|
||||
}
|
||||
|
|
@ -81,7 +83,8 @@ func makeListLabelsEndpoint(svc kolide.Service) endpoint.Endpoint {
|
|||
labelResponse{
|
||||
*label,
|
||||
label.Name,
|
||||
count,
|
||||
total,
|
||||
online,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
|
@ -111,7 +114,7 @@ func makeCreateLabelEndpoint(svc kolide.Service) endpoint.Endpoint {
|
|||
if err != nil {
|
||||
return createLabelResponse{Err: err}, nil
|
||||
}
|
||||
count, err := svc.CountHostsInTargets(ctx, nil, []uint{label.ID})
|
||||
total, online, err := svc.CountHostsInTargets(ctx, nil, []uint{label.ID})
|
||||
if err != nil {
|
||||
return createLabelResponse{Err: err}, nil
|
||||
}
|
||||
|
|
@ -119,7 +122,8 @@ func makeCreateLabelEndpoint(svc kolide.Service) endpoint.Endpoint {
|
|||
Label: labelResponse{
|
||||
*label,
|
||||
label.Name,
|
||||
count,
|
||||
total,
|
||||
online,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ type labelSearchResult struct {
|
|||
kolide.Label
|
||||
DisplayText string `json:"display_text"`
|
||||
Count uint `json:"count"`
|
||||
Online uint `json:"online"`
|
||||
}
|
||||
|
||||
type targetsData struct {
|
||||
|
|
@ -35,9 +36,10 @@ type targetsData struct {
|
|||
}
|
||||
|
||||
type searchTargetsResponse struct {
|
||||
Targets *targetsData `json:"targets,omitempty"`
|
||||
SelectedTargetsCount uint `json:"selected_targets_count,omitempty"`
|
||||
Err error `json:"error,omitempty"`
|
||||
Targets *targetsData `json:"targets,omitempty"`
|
||||
SelectedTargetsCount uint `json:"selected_targets_count"`
|
||||
SelectedTargetsOnline uint `json:"selected_targets_online"`
|
||||
Err error `json:"error,omitempty"`
|
||||
}
|
||||
|
||||
func (r searchTargetsResponse) error() error { return r.Err }
|
||||
|
|
@ -51,11 +53,6 @@ func makeSearchTargetsEndpoint(svc kolide.Service) endpoint.Endpoint {
|
|||
return searchTargetsResponse{Err: err}, nil
|
||||
}
|
||||
|
||||
count, err := svc.CountHostsInTargets(ctx, req.Selected.Hosts, req.Selected.Labels)
|
||||
if err != nil {
|
||||
return searchTargetsResponse{Err: err}, nil
|
||||
}
|
||||
|
||||
targets := &targetsData{
|
||||
Hosts: []hostSearchResult{},
|
||||
Labels: []labelSearchResult{},
|
||||
|
|
@ -71,7 +68,7 @@ func makeSearchTargetsEndpoint(svc kolide.Service) endpoint.Endpoint {
|
|||
}
|
||||
|
||||
for _, label := range results.Labels {
|
||||
count, err := svc.CountHostsInTargets(ctx, nil, []uint{label.ID})
|
||||
total, online, err := svc.CountHostsInTargets(ctx, nil, []uint{label.ID})
|
||||
if err != nil {
|
||||
return searchTargetsResponse{Err: err}, nil
|
||||
}
|
||||
|
|
@ -79,14 +76,21 @@ func makeSearchTargetsEndpoint(svc kolide.Service) endpoint.Endpoint {
|
|||
labelSearchResult{
|
||||
label,
|
||||
label.Name,
|
||||
count,
|
||||
total,
|
||||
online,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
total, online, err := svc.CountHostsInTargets(ctx, req.Selected.Hosts, req.Selected.Labels)
|
||||
if err != nil {
|
||||
return searchTargetsResponse{Err: err}, nil
|
||||
}
|
||||
|
||||
return searchTargetsResponse{
|
||||
Targets: targets,
|
||||
SelectedTargetsCount: count,
|
||||
Targets: targets,
|
||||
SelectedTargetsCount: total,
|
||||
SelectedTargetsOnline: online,
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,23 +23,30 @@ func (svc service) SearchTargets(ctx context.Context, query string, selectedHost
|
|||
return results, nil
|
||||
}
|
||||
|
||||
func (svc service) CountHostsInTargets(ctx context.Context, hosts []uint, labels []uint) (uint, error) {
|
||||
hostsInLabels, err := svc.ds.ListUniqueHostsInLabels(labels)
|
||||
func (svc service) CountHostsInTargets(ctx context.Context, hostIDs []uint, labelIDs []uint) (uint, uint, error) {
|
||||
hosts, err := svc.ds.ListUniqueHostsInLabels(labelIDs)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
return 0, 0, err
|
||||
}
|
||||
|
||||
for _, id := range hostIDs {
|
||||
h, err := svc.ds.Host(id)
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
hosts = append(hosts, *h)
|
||||
}
|
||||
|
||||
hostLookup := map[uint]bool{}
|
||||
|
||||
online := uint(0)
|
||||
for _, host := range hosts {
|
||||
hostLookup[host] = true
|
||||
}
|
||||
|
||||
for _, host := range hostsInLabels {
|
||||
if !hostLookup[host.ID] {
|
||||
hostLookup[host.ID] = true
|
||||
if svc.HostStatus(ctx, host) == "online" {
|
||||
online++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return uint(len(hostLookup)), nil
|
||||
return uint(len(hostLookup)), online, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/WatchBeam/clock"
|
||||
"github.com/kolide/kolide-ose/server/datastore/inmem"
|
||||
"github.com/kolide/kolide-ose/server/kolide"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
|
@ -47,7 +48,9 @@ func TestCountHostsInTargets(t *testing.T) {
|
|||
ds, err := inmem.New()
|
||||
require.Nil(t, err)
|
||||
|
||||
svc, err := newTestService(ds, nil)
|
||||
mockClock := clock.NewMockClock()
|
||||
|
||||
svc, err := newTestServiceWithClock(ds, nil, mockClock)
|
||||
require.Nil(t, err)
|
||||
|
||||
ctx := context.Background()
|
||||
|
|
@ -59,6 +62,7 @@ func TestCountHostsInTargets(t *testing.T) {
|
|||
UUID: "1",
|
||||
})
|
||||
require.Nil(t, err)
|
||||
require.Nil(t, ds.MarkHostSeen(h1, mockClock.Now()))
|
||||
|
||||
h2, err := ds.NewHost(&kolide.Host{
|
||||
HostName: "bar.local",
|
||||
|
|
@ -67,6 +71,8 @@ func TestCountHostsInTargets(t *testing.T) {
|
|||
UUID: "2",
|
||||
})
|
||||
require.Nil(t, err)
|
||||
// make this host "offline"
|
||||
require.Nil(t, ds.MarkHostSeen(h2, mockClock.Now().Add(-1*time.Hour)))
|
||||
|
||||
h3, err := ds.NewHost(&kolide.Host{
|
||||
HostName: "baz.local",
|
||||
|
|
@ -75,6 +81,7 @@ func TestCountHostsInTargets(t *testing.T) {
|
|||
UUID: "3",
|
||||
})
|
||||
require.Nil(t, err)
|
||||
require.Nil(t, ds.MarkHostSeen(h3, mockClock.Now().Add(-5*time.Minute)))
|
||||
|
||||
h4, err := ds.NewHost(&kolide.Host{
|
||||
HostName: "xxx.local",
|
||||
|
|
@ -83,6 +90,7 @@ func TestCountHostsInTargets(t *testing.T) {
|
|||
UUID: "4",
|
||||
})
|
||||
require.Nil(t, err)
|
||||
require.Nil(t, ds.MarkHostSeen(h4, mockClock.Now()))
|
||||
|
||||
h5, err := ds.NewHost(&kolide.Host{
|
||||
HostName: "yyy.local",
|
||||
|
|
@ -91,6 +99,7 @@ func TestCountHostsInTargets(t *testing.T) {
|
|||
UUID: "5",
|
||||
})
|
||||
require.Nil(t, err)
|
||||
require.Nil(t, ds.MarkHostSeen(h5, mockClock.Now()))
|
||||
|
||||
l1, err := ds.NewLabel(&kolide.Label{
|
||||
Name: "label foo",
|
||||
|
|
@ -118,25 +127,38 @@ func TestCountHostsInTargets(t *testing.T) {
|
|||
assert.Nil(t, err)
|
||||
}
|
||||
|
||||
count, err := svc.CountHostsInTargets(ctx, nil, []uint{l1.ID, l2.ID})
|
||||
total, online, err := svc.CountHostsInTargets(ctx, nil, []uint{l1.ID, l2.ID})
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, uint(5), count)
|
||||
assert.Equal(t, uint(5), total)
|
||||
assert.Equal(t, uint(4), online)
|
||||
|
||||
count, err = svc.CountHostsInTargets(ctx, []uint{h1.ID, h2.ID}, []uint{l1.ID, l2.ID})
|
||||
total, online, err = svc.CountHostsInTargets(ctx, []uint{h1.ID, h2.ID}, []uint{l1.ID, l2.ID})
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, uint(5), count)
|
||||
assert.Equal(t, uint(5), total)
|
||||
assert.Equal(t, uint(4), online)
|
||||
|
||||
count, err = svc.CountHostsInTargets(ctx, []uint{h1.ID, h2.ID}, nil)
|
||||
total, online, err = svc.CountHostsInTargets(ctx, []uint{h1.ID, h2.ID}, nil)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, uint(2), count)
|
||||
assert.Equal(t, uint(2), total)
|
||||
assert.Equal(t, uint(1), online)
|
||||
|
||||
count, err = svc.CountHostsInTargets(ctx, []uint{h1.ID}, []uint{l2.ID})
|
||||
total, online, err = svc.CountHostsInTargets(ctx, []uint{h1.ID}, []uint{l2.ID})
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, uint(4), count)
|
||||
assert.Equal(t, uint(4), total)
|
||||
assert.Equal(t, uint(4), online)
|
||||
|
||||
count, err = svc.CountHostsInTargets(ctx, nil, nil)
|
||||
total, online, err = svc.CountHostsInTargets(ctx, nil, nil)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, uint(0), count)
|
||||
assert.Equal(t, uint(0), total)
|
||||
assert.Equal(t, uint(0), online)
|
||||
|
||||
// Advance clock so all hosts are offline
|
||||
mockClock.AddTime(1 * time.Hour)
|
||||
total, online, err = svc.CountHostsInTargets(ctx, nil, []uint{l1.ID, l2.ID})
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, uint(5), total)
|
||||
assert.Equal(t, uint(0), online)
|
||||
|
||||
}
|
||||
|
||||
func TestSearchWithOmit(t *testing.T) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue