## Overview `dibble` is a one-stop CLI for seeding a Fleet server with test data — users, teams, policies, reports, labels, scripts, MDM profiles, software, secrets, CAs, and vulns — replacing ~8 ad-hoc seeding tools with a single binary. It makes it easy to: - **Spin up a populated dev/test server in one command** — `dibble all` plants everything with sensible, idempotent defaults. - **Skip the flag-memorization** — running `dibble` with no args launches an interactive wizard that prompts for Fleet URL, API token, theme, and which entities to seed, and offers to save the config to `~/.dibble.yaml`. - **Seed individual entity types** — `dibble users`, `dibble teams`, `dibble policies`, etc., when you only need one slice. - **Get themed, recognizable test data** — pick a theme (hitchhikers, tng, lotr, ghibli, parksrec, …) so seeded names are easy to eyeball in the UI. Hosts are intentionally out of scope — `cmd/osquery-perf` still owns that. `dibble hosts` is a thin convenience wrapper that picks a fleet, fetches its enroll secret, and prints/runs the osquery-perf invocation for you. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Dibble: a CLI tool to seed realistic test data, including an interactive wizard and subcommands for teams/users/software/policies/scripts/reports/profiles/labels/activities/enroll-secrets/hosts/vulns, plus theme-driven “cas” and “ping”. * Theme system: multiple curated themes to generate consistent seeded identities, policies, software, labels, and scripts. * **Chores** * Ignored the built dibble binary and added a Makefile build target to compile the dibble tool. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
50 lines
1.6 KiB
Go
50 lines
1.6 KiB
Go
package seed
|
|
|
|
import (
|
|
"crypto/rand"
|
|
"encoding/hex"
|
|
"fmt"
|
|
)
|
|
|
|
// EnrollSecrets seeds a per-team enroll secret — the credential a fleetd
|
|
// agent presents to join a team. This is distinct from "Fleet secrets" /
|
|
// secret variables, which are template variables substituted into profiles
|
|
// and scripts; those are a separate seeder (not yet implemented).
|
|
//
|
|
// The global enroll secret is left alone because changing it would
|
|
// invalidate any already-enrolled host. Rotate it deliberately, not via seed.
|
|
func EnrollSecrets(c Client, log Logger, teams []Team) Result {
|
|
res := Result{Entity: "enroll-secrets"}
|
|
for _, t := range teams {
|
|
secret := randomEnrollSecret()
|
|
body := map[string]any{
|
|
"secrets": []map[string]string{{"secret": secret}},
|
|
}
|
|
// PATCH replaces the team's enroll-secret list with this one. Find
|
|
// them in the UI under Settings → [team] → Add hosts → Show enroll secret.
|
|
err := c.Patch(fmt.Sprintf("/api/latest/fleet/fleets/%d/secrets", t.ID), body, nil)
|
|
switch {
|
|
case err == nil:
|
|
res.Created++
|
|
// Don't log the secret itself — credentials in logs/shell
|
|
// history are an avoidable leak. Find seeded values in the
|
|
// UI under Settings → [team] → Add hosts → Show enroll secret.
|
|
log.Printf("enroll secret created for team=%s (id=%d)", t.Name, t.ID)
|
|
case IsAlreadyExists(err):
|
|
res.Skipped++
|
|
default:
|
|
res.Errors = append(res.Errors, err)
|
|
}
|
|
}
|
|
return res
|
|
}
|
|
|
|
func randomEnrollSecret() string {
|
|
var b [16]byte
|
|
if _, err := rand.Read(b[:]); err != nil {
|
|
// Vanishingly unlikely; fall back to a fixed-but-clearly-fake value.
|
|
return "dibble-fallback-secret"
|
|
}
|
|
return "dibble-" + hex.EncodeToString(b[:])
|
|
}
|