Files
llmgw/internal/cli/audit.go
T

68 lines
2.2 KiB
Go

package cli
import (
"encoding/json"
"fmt"
"net/url"
"strconv"
"github.com/spf13/cobra"
"gitea.mynodes.xyz/ilker/llmgw/internal/store"
)
func newAuditCmd(client func() *ctlClient, asJSON *bool) *cobra.Command {
var (
since, actor, contains string
limit int
detail bool
)
c := &cobra.Command{
Use: "audit",
Short: "Who changed what: every change through the admin API and the administration pages",
Long: "Each change made with `llmgw ctl`, the console, or the pages under /admin —\n" +
"and a person's own keys and password — is recorded: who, when, through\n" +
"what, the fields it was given with anything secret taken out, and how it\n" +
"ended. The newest first.",
Example: " llmgw ctl audit --since 24h\n llmgw ctl audit --actor ilker --contains models\n llmgw ctl audit --contains bob@example.com --detail",
Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, _ []string) error {
q := url.Values{"since": {since}, "limit": {strconv.Itoa(limit)}}
if actor != "" {
q.Set("actor", actor)
}
if contains != "" {
q.Set("contains", contains)
}
var ev []store.AuditEvent
if err := client().get(cmd.Context(), "/api/v1/audit?"+q.Encode(), &ev); err != nil {
return err
}
if *asJSON {
return json.NewEncoder(cmd.OutOrStdout()).Encode(ev)
}
if len(ev) == 0 {
fmt.Fprintln(cmd.OutOrStdout(), "No changes recorded in that time.")
return nil
}
w := tab()
fmt.Fprintln(w, "WHEN (UTC)\tWHO\tVIA\tWHAT\tTARGET\tSTATUS")
for _, e := range ev {
fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\t%d\n", e.At.UTC().Format("2006-01-02 15:04:05"),
e.Actor, e.Source, e.Action, dash(e.Target), e.Status)
if detail && e.Detail != "" && e.Detail != "{}" {
fmt.Fprintf(w, "\t\t\t %s\t\t\n", e.Detail)
}
}
return w.Flush()
},
}
f := c.Flags()
f.StringVar(&since, "since", "7d", "how far back: 90m, 24h, 30d")
f.StringVar(&actor, "actor", "", "only changes by this person")
f.StringVar(&contains, "contains", "", "only changes whose action or target contains this")
f.IntVar(&limit, "limit", 200, "at most this many")
f.BoolVar(&detail, "detail", false, "show the fields each change was given")
return c
}