From a7d7ea66294b30c3cdd8f32c5ab09655cd4a4877 Mon Sep 17 00:00:00 2001 From: llaoj Date: Sun, 13 Nov 2022 11:14:11 +0800 Subject: [PATCH] 1. introduct operation log feature in README.md 2. add args(json) in operation logs --- README.md | 30 ++++++++++++++++++++++++++++++ server/handlers.go | 1 + webtty/option.go | 8 ++++++++ webtty/webtty.go | 10 +++++++--- 4 files changed, 46 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 39404e8..1c7fbe0 100644 --- a/README.md +++ b/README.md @@ -151,6 +151,36 @@ When you want to create a jailed environment for each client, you can use Docker $ gotty -w docker run -it --rm busybox ``` +## Operation log + +User's input in terminal can be found in logs. for example: + +if you run gotty like this: + +```shell +./gotty -w --permit-arguments ./test.sh +``` + +this is `test.sh`: + +```sh +# !/bin/bash + +echo "Welcome: $4" +kubectl -n $1 exec -it $2 -c $3 -- sh +``` + +visit `http://127.0.0.1:8080/?arg=without-istio&arg=sleep-7b6d569576-57sjq&arg=sleep&arg=21001713` and input your commands in shell, and you will see operation logs in stdout: + +``` +... +2022/11/13 10:48:12 [oplog] lsCR {"arg":["without-istio","sleep-7b6d569576-57sjq","sleep","21001713"]} +2022/11/13 10:48:14 [oplog] pwdCR {"arg":["without-istio","sleep-7b6d569576-57sjq","sleep","21001713"]} +... +``` + +Using the `[oplog]` flag, you can collect and store these logs persistently. All args are in the log, including the userID. + ## Development You can build a binary by simply running `make`. go1.16 is required. diff --git a/server/handlers.go b/server/handlers.go index 3393b22..2439e50 100644 --- a/server/handlers.go +++ b/server/handlers.go @@ -145,6 +145,7 @@ func (server *Server) processWSConn(ctx context.Context, conn *websocket.Conn, h opts := []webtty.Option{ webtty.WithWindowTitle(titleBuf.Bytes()), + webtty.WithArguments(params), } if server.options.PermitWrite { opts = append(opts, webtty.WithPermitWrite()) diff --git a/webtty/option.go b/webtty/option.go index 1618e89..5abc261 100644 --- a/webtty/option.go +++ b/webtty/option.go @@ -41,6 +41,14 @@ func WithWindowTitle(windowTitle []byte) Option { } } +// WithArguments sets the command line arguments that clients send +func WithArguments(arguments map[string][]string) Option { + return func(wt *WebTTY) error { + wt.arguments = arguments + return nil + } +} + // WithReconnect enables reconnection on the master side. func WithReconnect(timeInSeconds int) Option { return func(wt *WebTTY) error { diff --git a/webtty/webtty.go b/webtty/webtty.go index 8532b2b..9c940dc 100644 --- a/webtty/webtty.go +++ b/webtty/webtty.go @@ -4,8 +4,8 @@ import ( "context" "encoding/base64" "encoding/json" - "fmt" "github.com/sorenisanerd/gotty/utils" + "log" "sync" "github.com/pkg/errors" @@ -21,6 +21,7 @@ type WebTTY struct { slave Slave windowTitle []byte + arguments map[string][]string permitWrite bool columns int rows int @@ -188,9 +189,12 @@ func (wt *WebTTY) handleMasterReadEvent(data []byte, line *[]byte) error { } *line = append(*line, decodedBuffer[:n]...) - //fmt.Printf("master read: %v -> %v\n", decodedBuffer[:n], string(decodedBuffer[:n])) if decodedBuffer[n-1] == 13 { - fmt.Printf("master read line: %v\n", utils.FormatOperationLog(line)) + argumentsByte, err := json.Marshal(wt.arguments) + if err != nil { + return errors.Wrapf(err, "failed to marshal arguments map") + } + log.Printf("[oplog] %s %s\n", utils.FormatOperationLog(line), string(argumentsByte)) *line = nil }