Files
openlan/pkg/access/terminal.go
2022-07-29 23:38:54 +08:00

153 lines
3.0 KiB
Go
Executable File

package access
import (
"fmt"
"github.com/chzyer/readline"
"github.com/luscis/openlan/pkg/libol"
"io"
"strings"
)
type Terminal struct {
Pointer Pointer
Console *readline.Instance
}
func NewTerminal(pointer Pointer) *Terminal {
t := &Terminal{Pointer: pointer}
completer := readline.NewPrefixCompleter(
readline.PcItem("quit"),
readline.PcItem("help"),
readline.PcItem("mode",
readline.PcItem("vi"),
readline.PcItem("emacs"),
),
readline.PcItem("show",
readline.PcItem("config"),
readline.PcItem("network"),
readline.PcItem("record"),
readline.PcItem("statistics"),
),
readline.PcItem("edit",
readline.PcItem("user"),
readline.PcItem("connection"),
),
)
config := &readline.Config{
Prompt: t.Prompt(),
HistoryFile: ".history",
InterruptPrompt: "^C",
EOFPrompt: "quit",
HistorySearchFold: true,
AutoComplete: completer,
}
if l, err := readline.NewEx(config); err == nil {
t.Console = l
}
return t
}
func (t *Terminal) Prompt() string {
user := t.Pointer.User()
alias := t.Pointer.Alias()
tenant := t.Pointer.Tenant()
return fmt.Sprintf("[%s@%s %s]# ", user, alias, tenant)
}
func (t *Terminal) CmdEdit(args string) {
}
func (t *Terminal) CmdShow(args string) {
switch args {
case "record":
v := t.Pointer.Record()
if out, err := libol.Marshal(v, true); err == nil {
fmt.Printf("%s\n", out)
}
case "statistics":
if c := t.Pointer.Client(); c != nil {
v := c.Statistics()
if out, err := libol.Marshal(v, true); err == nil {
fmt.Printf("%s\n", out)
}
}
case "config":
cfg := t.Pointer.Config()
if str, err := libol.Marshal(cfg, true); err == nil {
fmt.Printf("%s\n", str)
}
case "network":
cfg := t.Pointer.Network()
if str, err := libol.Marshal(cfg, true); err == nil {
fmt.Printf("%s\n", str)
}
default:
v := struct {
UUID string
UpTime int64
Device string
Status string
}{
UUID: t.Pointer.UUID(),
UpTime: t.Pointer.UpTime(),
Device: t.Pointer.IfName(),
Status: t.Pointer.Status().String(),
}
if str, err := libol.Marshal(v, true); err == nil {
fmt.Printf("%s\n", str)
}
}
}
func (t *Terminal) Trim(v string) string {
return strings.TrimSpace(v)
}
func (t *Terminal) CmdBye() {
}
func (t *Terminal) CmdMode(args string) {
switch args {
case "vi":
t.Console.SetVimMode(true)
case "emacs":
t.Console.SetVimMode(false)
}
}
func (t *Terminal) Start() {
if t.Console == nil {
return
}
defer t.Console.Close()
for {
line, err := t.Console.Readline()
if err == readline.ErrInterrupt {
if len(line) == 0 {
break
} else {
continue
}
} else if err == io.EOF {
break
}
line = t.Trim(line)
switch {
case strings.HasPrefix(line, "mode "):
t.CmdMode(t.Trim(line[5:]))
case line == "show":
t.CmdShow("")
case line == "quit" || line == "exit":
t.CmdBye()
goto quit
case strings.HasPrefix(line, "show "):
t.CmdShow(t.Trim(line[5:]))
case strings.HasPrefix(line, "edit "):
t.CmdEdit(t.Trim(line[5:]))
}
}
quit:
fmt.Printf("Terminal.Start quit")
}