From 0cffff42c7783b8d1911ab46de917bc2aa433705 Mon Sep 17 00:00:00 2001 From: Zac Bergquist Date: Tue, 1 Oct 2024 16:24:48 -0600 Subject: [PATCH] tsh play --format=text (#46849) For sessions with print events, this command will write the text directly to standard out. This makes it easier to grep for a particular pattern or just dump a session recording to a file for manual analysis. Closes #11694 --- tool/tsh/common/play.go | 23 +++++++++++++++++++++-- tool/tsh/common/tsh.go | 4 ++-- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/tool/tsh/common/play.go b/tool/tsh/common/play.go index 14900ce485871..18b5078fb67ac 100644 --- a/tool/tsh/common/play.go +++ b/tool/tsh/common/play.go @@ -115,9 +115,10 @@ func exportSession(cf *CLIConf) error { } switch format { - case teleport.JSON, teleport.YAML: + case teleport.JSON, teleport.YAML, teleport.Text: default: - return trace.Errorf("Invalid format %s, only json and yaml are supported", format) + // this should be unreachable since kingpin validates the format flag + return trace.BadParameter("Invalid format %s", format) } sid, err := session.ParseID(cf.SessionID) @@ -144,6 +145,8 @@ func exportSession(cf *CLIConf) error { exporter = jsonSessionExporter{} case teleport.YAML: exporter = yamlSessionExporter{} + case teleport.Text: + exporter = textSessionExporter{} } exporter.WriteStart() @@ -233,6 +236,22 @@ func (yamlSessionExporter) WriteEvent(evt apievents.AuditEvent) error { return err } +type textSessionExporter struct{} + +func (textSessionExporter) WriteStart() error { return nil } +func (textSessionExporter) WriteEnd() error { return nil } +func (textSessionExporter) WriteSeparator() error { return nil } + +func (textSessionExporter) WriteEvent(evt apievents.AuditEvent) error { + printEvent, ok := evt.(*apievents.SessionPrint) + if !ok { + return nil + } + + _, err := os.Stdout.Write(printEvent.Data) + return trace.Wrap(err) +} + // exportFile converts the binary protobuf events from the file // identified by path to text (JSON/YAML) and writes the converted // events to standard out. diff --git a/tool/tsh/common/tsh.go b/tool/tsh/common/tsh.go index 500dcab53c79f..79bf18f491934 100644 --- a/tool/tsh/common/tsh.go +++ b/tool/tsh/common/tsh.go @@ -983,8 +983,8 @@ func Run(ctx context.Context, args []string, opts ...CliOption) error { play.Flag("speed", "Playback speed, applicable when streaming SSH or Kubernetes sessions.").Default("1x").EnumVar(&cf.PlaySpeed, "0.5x", "1x", "2x", "4x", "8x") play.Flag("skip-idle-time", "Quickly skip over idle time, applicable when streaming SSH or Kubernetes sessions.").BoolVar(&cf.NoWait) play.Flag("format", defaults.FormatFlagDescription( - teleport.PTY, teleport.JSON, teleport.YAML, - )).Short('f').Default(teleport.PTY).EnumVar(&cf.Format, teleport.PTY, teleport.JSON, teleport.YAML) + teleport.PTY, teleport.JSON, teleport.YAML, teleport.Text, + )).Short('f').Default(teleport.PTY).EnumVar(&cf.Format, teleport.PTY, teleport.JSON, teleport.YAML, teleport.Text) play.Arg("session-id", "ID or path to session file to play").Required().StringVar(&cf.SessionID) // scp