diff --git a/tool/tsh/common/play.go b/tool/tsh/common/play.go index 67614b161bb07..7b560ffc260ae 100644 --- a/tool/tsh/common/play.go +++ b/tool/tsh/common/play.go @@ -113,9 +113,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) @@ -142,6 +143,8 @@ func exportSession(cf *CLIConf) error { exporter = jsonSessionExporter{} case teleport.YAML: exporter = yamlSessionExporter{} + case teleport.Text: + exporter = textSessionExporter{} } exporter.WriteStart() @@ -231,6 +234,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 5466f3bda68a0..13de3b78de8f8 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