fleet/orbit/pkg/table/cryptsetup/table.go
2023-11-01 20:11:35 -06:00

90 lines
2.5 KiB
Go

// based on github.com/kolide/launcher/pkg/osquery/tables
package cryptsetup
import (
"context"
"fmt"
"strings"
"github.com/fleetdm/fleet/v4/orbit/pkg/dataflatten"
"github.com/fleetdm/fleet/v4/orbit/pkg/table/dataflattentable"
"github.com/fleetdm/fleet/v4/orbit/pkg/table/tablehelpers"
"github.com/go-kit/log"
"github.com/go-kit/log/level"
"github.com/osquery/osquery-go/plugin/table"
)
var cryptsetupPaths = []string{
"/usr/sbin/cryptsetup",
"/sbin/cryptsetup",
}
const allowedNameCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-/_"
type Table struct {
logger log.Logger
name string
}
func TablePlugin(logger log.Logger) *table.Plugin {
columns := dataflattentable.Columns(
table.TextColumn("name"),
)
t := &Table{
logger: logger,
name: "cryptsetup_status",
}
return table.NewPlugin(t.name, columns, t.generate)
}
func (t *Table) generate(ctx context.Context, queryContext table.QueryContext) ([]map[string]string, error) {
var results []map[string]string
requestedNames := tablehelpers.GetConstraints(queryContext, "name",
tablehelpers.WithAllowedCharacters(allowedNameCharacters),
tablehelpers.WithLogger(t.logger),
)
if len(requestedNames) == 0 {
return results, fmt.Errorf("The %s table requires that you specify a constraint for name", t.name)
}
for _, name := range requestedNames {
output, err := tablehelpers.Exec(ctx, t.logger, 15, cryptsetupPaths, []string{"--readonly", "status", name}, false)
if err != nil {
level.Debug(t.logger).Log("msg", "Error execing for status", "name", name, "err", err)
continue
}
status, err := parseStatus(output)
if err != nil {
level.Info(t.logger).Log("msg", "Error parsing status", "name", name, "err", err)
continue
}
for _, dataQuery := range tablehelpers.GetConstraints(queryContext, "query", tablehelpers.WithDefaults("*")) {
flatData, err := t.flattenOutput(dataQuery, status)
if err != nil {
level.Info(t.logger).Log("msg", "flatten failed", "err", err)
continue
}
rowData := map[string]string{"name": name}
results = append(results, dataflattentable.ToMap(flatData, dataQuery, rowData)...)
}
}
return results, nil
}
func (t *Table) flattenOutput(dataQuery string, status map[string]interface{}) ([]dataflatten.Row, error) {
flattenOpts := []dataflatten.FlattenOpts{
dataflatten.WithLogger(t.logger),
dataflatten.WithQuery(strings.Split(dataQuery, "/")),
}
return dataflatten.Flatten(status, flattenOpts...)
}