Skip to content

Commit

Permalink
Expose instance status
Browse files Browse the repository at this point in the history
  • Loading branch information
RebeccaMahany committed Dec 4, 2024
1 parent a898928 commit 0e13da8
Show file tree
Hide file tree
Showing 11 changed files with 103 additions and 8 deletions.
1 change: 1 addition & 0 deletions cmd/launcher/launcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,7 @@ func runLauncher(ctx context.Context, cancel func(), multiSlogger, systemMultiSl
osqueryruntime.WithAugeasLensFunction(augeas.InstallLenses),
)
runGroup.Add("osqueryRunner", osqueryRunner.Run, osqueryRunner.Interrupt)
k.SetInstanceQuerier(osqueryRunner)

versionInfo := version.Version()
k.SystemSlogger().Log(ctx, slog.LevelInfo,
Expand Down
16 changes: 14 additions & 2 deletions ee/agent/knapsack/knapsack.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ type knapsack struct {

slogger, systemSlogger *multislogger.MultiSlogger

querier types.InstanceQuerier

// This struct is a work in progress, and will be iteratively added to as needs arise.
// Some potential future additions include:
// Querier
}

func New(stores map[storage.Store]types.KVStore, flags types.Flags, db *bbolt.DB, slogger, systemSlogger *multislogger.MultiSlogger) *knapsack {
Expand Down Expand Up @@ -87,6 +87,18 @@ func (k *knapsack) AddSlogHandler(handler ...slog.Handler) {
k.systemSlogger.AddHandler(handler...)
}

// Osquery instance querier
func (k *knapsack) SetInstanceQuerier(q types.InstanceQuerier) {
k.querier = q
}

func (k *knapsack) InstanceStatuses() map[string]types.InstanceStatus {
if k.querier == nil {
return nil
}
return k.querier.InstanceStatuses()
}

// BboltDB interface methods
func (k *knapsack) BboltDB() *bbolt.DB {
return k.db
Expand Down
2 changes: 2 additions & 0 deletions ee/agent/types/knapsack.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ type Knapsack interface {
BboltDB
Flags
Slogger
InstanceQuerier
SetInstanceQuerier(q InstanceQuerier)
// LatestOsquerydPath finds the path to the latest osqueryd binary, after accounting for updates.
LatestOsquerydPath(ctx context.Context) string
// ReadEnrollSecret returns the enroll secret value, checking in various locations.
Expand Down
25 changes: 25 additions & 0 deletions ee/agent/types/mocks/knapsack.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions ee/agent/types/querier.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package types

type InstanceStatus string

const (
InstanceStatusNotStarted InstanceStatus = "not_started"
InstanceStatusHealthy InstanceStatus = "healthy"
InstanceStatusUnhealthy InstanceStatus = "unhealthy"
)

// InstanceQuerier is implemented by pkg/osquery/runtime/runner.go
type InstanceQuerier interface {
InstanceStatuses() map[string]InstanceStatus
}
16 changes: 11 additions & 5 deletions ee/debug/checkups/osquery.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,11 @@ import (
)

type osqueryCheckup struct {
k types.Knapsack
status Status
executionTimes map[string]any // maps command to how long it took to run, in ms
summary string
k types.Knapsack
status Status
executionTimes map[string]any // maps command to how long it took to run, in ms
instanceStatuses map[string]types.InstanceStatus
summary string
}

func (o *osqueryCheckup) Name() string {
Expand All @@ -40,6 +41,8 @@ func (o *osqueryCheckup) Run(ctx context.Context, extraWriter io.Writer) error {
return fmt.Errorf("running launcher interactive: %w", err)
}

o.instanceStatuses = o.k.InstanceStatuses()

return nil
}

Expand Down Expand Up @@ -102,5 +105,8 @@ func (o *osqueryCheckup) Summary() string {
}

func (o *osqueryCheckup) Data() any {
return o.executionTimes
return map[string]any{
"execution_time": o.executionTimes,
"instance_statuses": o.instanceStatuses,
}
}
3 changes: 3 additions & 0 deletions ee/localserver/request-id.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"time"

"github.com/kolide/kit/ulid"
"github.com/kolide/launcher/ee/agent/types"
"github.com/kolide/launcher/pkg/traces"
)

Expand All @@ -30,6 +31,7 @@ type (

status struct {
EnrollmentStatus string
InstanceStatuses map[string]types.InstanceStatus
}
)

Expand Down Expand Up @@ -82,6 +84,7 @@ func (ls *localServer) requestIdHandlerFunc(w http.ResponseWriter, r *http.Reque
Origin: r.Header.Get("Origin"),
Status: status{
EnrollmentStatus: string(enrollmentStatus),
InstanceStatuses: ls.knapsack.InstanceStatuses(),
},
}
response.identifiers = ls.identifiers
Expand Down
1 change: 1 addition & 0 deletions ee/localserver/request-id_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ func Test_localServer_requestIdHandler(t *testing.T) {
mockKnapsack.On("ConfigStore").Return(storageci.NewStore(t, multislogger.NewNopLogger(), storage.ConfigStore.String()))
mockKnapsack.On("KolideServerURL").Return("localhost")
mockKnapsack.On("CurrentEnrollmentStatus").Return(types.Enrolled, nil)
mockKnapsack.On("InstanceStatuses").Return(map[string]types.InstanceStatus{"default": types.InstanceStatusHealthy})

var logBytes bytes.Buffer
slogger := slog.New(slog.NewJSONHandler(&logBytes, &slog.HandlerOptions{
Expand Down
23 changes: 23 additions & 0 deletions pkg/osquery/runtime/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -315,3 +315,26 @@ func (r *Runner) Healthy() error {

return nil
}

func (r *Runner) InstanceStatuses() map[string]types.InstanceStatus {
r.instanceLock.Lock()
defer r.instanceLock.Unlock()

instanceStatuses := make(map[string]types.InstanceStatus)
for _, registrationId := range r.registrationIds {
instance, ok := r.instances[registrationId]
if !ok {
instanceStatuses[registrationId] = types.InstanceStatusNotStarted
continue
}

if err := instance.Healthy(); err != nil {
instanceStatuses[registrationId] = types.InstanceStatusUnhealthy
continue
}

instanceStatuses[registrationId] = types.InstanceStatusHealthy
}

return instanceStatuses
}
2 changes: 1 addition & 1 deletion pkg/osquery/runtime/runtime_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,6 @@ func platformArgs() []string {
return nil
}

func isExitOk(err error) bool {
func isExitOk(_ error) bool {
return false
}
8 changes: 8 additions & 0 deletions pkg/osquery/runtime/runtime_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"github.com/kolide/launcher/ee/agent/storage"
storageci "github.com/kolide/launcher/ee/agent/storage/ci"
"github.com/kolide/launcher/ee/agent/storage/inmemory"
"github.com/kolide/launcher/ee/agent/types"
typesMocks "github.com/kolide/launcher/ee/agent/types/mocks"
kolidelog "github.com/kolide/launcher/ee/log/osquerylogs"
"github.com/kolide/launcher/pkg/backoff"
Expand Down Expand Up @@ -389,6 +390,13 @@ func TestMultipleInstances(t *testing.T) {
require.NotEmpty(t, runner.instances[extraRegistrationId].stats.StartTime, "start time should be added to secondary instance stats on start up")
require.NotEmpty(t, runner.instances[extraRegistrationId].stats.ConnectTime, "connect time should be added to secondary instance stats on start up")

// Confirm instance statuses are reported correctly
instanceStatuses := runner.InstanceStatuses()
require.Contains(t, instanceStatuses, defaultRegistrationId)
require.Equal(t, instanceStatuses[defaultRegistrationId], types.InstanceStatusHealthy)
require.Contains(t, instanceStatuses, extraRegistrationId)
require.Equal(t, instanceStatuses[extraRegistrationId], types.InstanceStatusHealthy)

waitShutdown(t, runner, logBytes)

// Confirm both instances exited
Expand Down

0 comments on commit 0e13da8

Please sign in to comment.