-
Notifications
You must be signed in to change notification settings - Fork 103
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Generate the enrollment details on launcher startup #2045
base: main
Are you sure you want to change the base?
Changes from all commits
5cb998c
1b258aa
9ac8a8b
ee1a0d8
f0a3c8a
25e9a93
a9b91ab
828f91e
872e0bf
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -62,6 +62,7 @@ import ( | |
"github.com/kolide/launcher/pkg/service" | ||
"github.com/kolide/launcher/pkg/traces" | ||
"github.com/kolide/launcher/pkg/traces/exporter" | ||
"go.opentelemetry.io/otel/trace" | ||
|
||
"go.etcd.io/bbolt" | ||
) | ||
|
@@ -195,6 +196,15 @@ func runLauncher(ctx context.Context, cancel func(), multiSlogger, systemMultiSl | |
flagController := flags.NewFlagController(slogger, stores[storage.AgentFlagsStore], fcOpts...) | ||
k := knapsack.New(stores, flagController, db, multiSlogger, systemMultiSlogger) | ||
|
||
details := getEnrollmentDetails(ctx, k, startupSpan, slogger) | ||
if err := k.SetEnrollmentDetails(details); err != nil { | ||
slogger.Log(ctx, slog.LevelError, | ||
"setting enrollment details", | ||
"err", err, | ||
) | ||
} | ||
startupSpan.AddEvent("enrollment_details_set") | ||
|
||
// Generate a new run ID | ||
newRunID := k.GetRunID() | ||
|
||
|
@@ -638,3 +648,46 @@ func runOsqueryVersionCheckAndAddToKnapsack(ctx context.Context, slogger *slog.L | |
"osqueryd_path", osquerydPath, | ||
) | ||
} | ||
|
||
func getEnrollmentDetails(ctx context.Context, k types.Knapsack, startupSpan trace.Span, slogger *slog.Logger) service.EnrollmentDetails { | ||
details := osquery.GetRuntimeEnrollDetails() | ||
|
||
latestOsquerydPath := k.LatestOsquerydPath(ctx) | ||
if latestOsquerydPath == "" { | ||
slogger.Log(ctx, slog.LevelInfo, | ||
"skipping enrollment osquery details, no osqueryd path, this is probably CI", | ||
) | ||
startupSpan.AddEvent("skipping_enrollment_details") | ||
return details | ||
} | ||
|
||
// Add retry mechanism with backoff | ||
if err := backoff.WaitFor(func() error { | ||
err := osquery.GetOsqEnrollDetails(ctx, latestOsquerydPath, &details) | ||
if err != nil { | ||
slogger.Log(ctx, slog.LevelDebug, | ||
"getOsqEnrollDetails failed in backoff", | ||
"err", err, | ||
) | ||
} | ||
return err | ||
}, 30*time.Second, 5*time.Second); err != nil { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This can delay launcher startup for up to 30 seconds -- I think we probably don't want to do that. Maybe we should call |
||
// Check if details are required via env var | ||
if os.Getenv("LAUNCHER_DEBUG_ENROLL_DETAILS_REQUIRED") == "true" { | ||
slogger.Log(ctx, slog.LevelError, | ||
"enrollment details required but failed to get them", | ||
"err", err, | ||
) | ||
} | ||
Comment on lines
+676
to
+681
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @directionless are we able to rip this out? I don't see it in use anywhere in launcher. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't remember what I was debugging with this. Feel free to remove |
||
|
||
slogger.Log(ctx, slog.LevelError, | ||
"failed to get osq enrollment details with retries, moving on", | ||
"err", err, | ||
) | ||
traces.SetError(startupSpan, fmt.Errorf("query osq enrollment details: %w", err)) | ||
} else { | ||
startupSpan.AddEvent("got_enrollment_details") | ||
} | ||
|
||
return details | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,12 +14,16 @@ import ( | |
"github.com/kolide/launcher/ee/agent/types" | ||
"github.com/kolide/launcher/ee/tuf" | ||
"github.com/kolide/launcher/pkg/log/multislogger" | ||
|
||
"go.etcd.io/bbolt" | ||
) | ||
|
||
// Package-level runID variable | ||
var runID string | ||
|
||
// Package-level enrollmentDetails variable | ||
var enrollmentDetails types.EnrollmentDetails | ||
|
||
// type alias Flags, so that we can embed it inside knapsack, as `flags` and not `Flags` | ||
type flags types.Flags | ||
|
||
|
@@ -239,3 +243,17 @@ func (k *knapsack) CurrentEnrollmentStatus() (types.EnrollmentStatus, error) { | |
|
||
return types.Enrolled, nil | ||
} | ||
|
||
func (k *knapsack) SetEnrollmentDetails(details types.EnrollmentDetails) error { | ||
// Only update if there are actual changes | ||
if details != enrollmentDetails { | ||
k.slogger.Logger.DebugContext(context.Background(), "updating enrollment details") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We prefer to use the
(May need to do |
||
enrollmentDetails = details | ||
return nil | ||
} | ||
return nil | ||
} | ||
|
||
func (k *knapsack) GetEnrollmentDetails() (types.EnrollmentDetails, error) { | ||
return enrollmentDetails, nil | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package types | ||
|
||
type EnrollmentStatus string | ||
|
||
const ( | ||
NoEnrollmentKey EnrollmentStatus = "no_enrollment_key" | ||
Unenrolled EnrollmentStatus = "unenrolled" | ||
Enrolled EnrollmentStatus = "enrolled" | ||
Unknown EnrollmentStatus = "unknown" | ||
) | ||
|
||
// Move EnrollmentDetails from service package to types | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this comment should be updated to describe the struct |
||
type EnrollmentDetails struct { | ||
OSVersion string `json:"os_version"` | ||
OSBuildID string `json:"os_build_id"` | ||
OSPlatform string `json:"os_platform"` | ||
Hostname string `json:"hostname"` | ||
HardwareVendor string `json:"hardware_vendor"` | ||
HardwareModel string `json:"hardware_model"` | ||
HardwareSerial string `json:"hardware_serial"` | ||
OsqueryVersion string `json:"osquery_version"` | ||
LauncherHardwareKey string `json:"launcher_hardware_key"` | ||
LauncherHardwareKeySource string `json:"launcher_hardware_key_source"` | ||
LauncherLocalKey string `json:"launcher_local_key"` | ||
LauncherVersion string `json:"launcher_version"` | ||
OSName string `json:"os_name"` | ||
OSPlatformLike string `json:"os_platform_like"` | ||
GOOS string `json:"goos"` | ||
GOARCH string `json:"goarch"` | ||
HardwareUUID string `json:"hardware_uuid"` | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is better to create a new child span here rather than passing in the startup span -- it will give us better and more specific timing details, and is more consistent with what we do elsewhere. The
ctx
that you're passing in here already has information aboutstartupSpan
, so you can use it to automatically create a child span that hangs offstartupSpan
: