diff --git a/cmd/gosdn-tview/app.go b/cmd/gosdn-tview/app/app.go similarity index 78% rename from cmd/gosdn-tview/app.go rename to cmd/gosdn-tview/app/app.go index 63f429693963ebec249ef10397ba335f8fdbf5ff..e81ececa2e8a4c694ccf888114cd029ec0f32c04 100644 --- a/cmd/gosdn-tview/app.go +++ b/cmd/gosdn-tview/app/app.go @@ -1,4 +1,4 @@ -package main +package app import "github.com/rivo/tview" @@ -16,10 +16,14 @@ func NewApp() *App { return a } -func (a *App) setView(v view) { +func (a *App) SetView(v view) { a.app.SetRoot(v.GetContent(), true) } func (a *App) Run() error { return a.app.Run() } + +func (a *App) Stop() { + a.app.Stop() +} diff --git a/cmd/gosdn-tview/grpc/commands.go b/cmd/gosdn-tview/grpc/commands.go new file mode 100644 index 0000000000000000000000000000000000000000..a5c49e552a6d6d0725ae2a1021ab01b9f06fb506 --- /dev/null +++ b/cmd/gosdn-tview/grpc/commands.go @@ -0,0 +1,130 @@ +package commands + +import ( + pb "code.fbi.h-da.de/cocsn/gosdn/api/proto" + "code.fbi.h-da.de/cocsn/gosdn/log" + "context" + grpc "google.golang.org/grpc" + "time" +) + +type commandType int + +const ( + GoSDN commandType = iota + Database +) + +const ( + defaultName = "gosdn-cli" +) + +type command struct { + Name string + Description string + //CommandType commandType + Function func(conn *grpc.ClientConn) +} + +var CommandList = []command{ + {"hello", "test connection to goSDN controller", goSDNSayHello}, + {"shutdown", "request goSDN controller to shutdown", goSDNShutdown}, + {"testdb", "test all database connections", goSDNTestDB}, + {"tapigetedge", "get list of edges", TAPIGetEdge}, + {"tapigetedgenode", "get list of edgenodes", TAPIGetEdgeNode}, + {"tapigetlink", "get list of links", TAPIGetLink}, +} + +func Connect() *grpc.ClientConn { + address := "localhost:55055" + conn, err := grpc.Dial(address, grpc.WithInsecure(), grpc.WithBlock()) + if err != nil { + log.Fatal(err) + } + log.Info("Connected to " + conn.Target()) + return conn +} + +func goSDNSayHello(conn *grpc.ClientConn) { + c := pb.NewGrpcCliClient(conn) + + // Contact the server and print out its response. + name := defaultName + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + r, err := c.SayHello(ctx, &pb.HelloRequest{Name: name}) + if err != nil { + log.Fatal(err) + } + log.Info("Greeting: ", r.String()) + +} + +func goSDNShutdown(conn *grpc.ClientConn) { + + c := pb.NewGrpcCliClient(conn) + + // Contact the server and print out its response. + name := defaultName + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + r, err := c.Shutdown(ctx, &pb.ShutdownRequest{Name: name}) + if err != nil { + log.Fatal(err) + } + log.Info("Greeting: ", r.GetMessage()) +} + +func goSDNTestDB(conn *grpc.ClientConn) { + // TODO: fill with code and also see if grpc interface has this stub implemented. +} + +// TAPIGetEdge triggers the GetEdge function of the Ciena +// flavoured TAPI client +func TAPIGetEdge(conn *grpc.ClientConn) { + + c := pb.NewGrpcCliClient(conn) + + // Contact the server and print out its response. + name := defaultName + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + r, err := c.TAPIGetEdge(ctx, &pb.TAPIRequest{Name: name}) + if err != nil { + log.Fatal(err) + } + log.Info("TAPIGetEdge said: ", r.GetMessage()) +} + +// TAPIGetEdgeNode triggers the GetEdgeNode function of the Ciena +// flavoured TAPI client +func TAPIGetEdgeNode(conn *grpc.ClientConn) { + c := pb.NewGrpcCliClient(conn) + + // Contact the server and print out its response. + name := defaultName + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + r, err := c.TAPIGetEdgeNode(ctx, &pb.TAPIRequest{Name: name}) + if err != nil { + log.Fatal(err) + } + log.Info("TAPIGetEdgeNode said: ", r.GetMessage()) +} + +// TAPIGetLink triggers the GetLink function of the Ciena +// flavoured TAPI client +func TAPIGetLink(conn *grpc.ClientConn) { + + c := pb.NewGrpcCliClient(conn) + + // Contact the server and print out its response. + name := defaultName + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + r, err := c.TAPIGetLink(ctx, &pb.TAPIRequest{Name: name}) + if err != nil { + log.Fatal(err) + } + log.Info("TAPIGetLink said: ", r.GetMessage()) +} diff --git a/cmd/gosdn-tview/main.go b/cmd/gosdn-tview/main.go index 3c5fb43284cc024007161ff980db5371de518a19..f44ba7ae773dd13513be864e3f1f62461ae42194 100644 --- a/cmd/gosdn-tview/main.go +++ b/cmd/gosdn-tview/main.go @@ -1,9 +1,15 @@ package main -import "code.fbi.h-da.de/cocsn/gosdn/cmd/gosdn-tview/views" +import ( + "code.fbi.h-da.de/cocsn/gosdn/cmd/gosdn-tview/app" + grpc "code.fbi.h-da.de/cocsn/gosdn/cmd/gosdn-tview/grpc" + "code.fbi.h-da.de/cocsn/gosdn/cmd/gosdn-tview/views" +) func main() { - app := NewApp() - app.setView(views.NewMainView()) + conn := grpc.Connect() + app := app.NewApp() + app.SetView(views.NewMainView(app, conn)) app.Run() + app.Stop() } diff --git a/cmd/gosdn-tview/views/commandsListView.go b/cmd/gosdn-tview/views/commandsListView.go index 31c18ff658d70802810cb7a50e0f465dda207eb0..989fd09755928be1eae2a6aae585e1646c5edc12 100644 --- a/cmd/gosdn-tview/views/commandsListView.go +++ b/cmd/gosdn-tview/views/commandsListView.go @@ -1,37 +1,43 @@ package views import ( + "code.fbi.h-da.de/cocsn/gosdn/cmd/gosdn-tview/app" + commands "code.fbi.h-da.de/cocsn/gosdn/cmd/gosdn-tview/grpc" "github.com/gdamore/tcell" "github.com/rivo/tview" + "google.golang.org/grpc" ) type CommandListView struct { - rootNode *tview.TreeNode - commandsTree *tview.TreeView + commandsList *tview.List } -func NewCommandListView(rootTitle string) *CommandListView { +func NewCommandListView() *CommandListView { v := &CommandListView{ - rootNode: tview.NewTreeNode(rootTitle), - commandsTree: tview.NewTreeView(), + commandsList: tview.NewList(), } - v.commandsTree. - SetRoot(v.rootNode). - SetTitle("Commands"). + v.commandsList. SetBorder(true). - SetBorderColor(tcell.ColorSteelBlue) + SetBorderColor(tcell.ColorSteelBlue). + SetTitle("Commands") return v } func (c *CommandListView) GetContent() tview.Primitive { - return c.commandsTree + return c.commandsList } -func (v *CommandListView) GetCommands(path string) { - //TODO: change to use commandlist -} +func (v *CommandListView) GetCommands(app *app.App, conn *grpc.ClientConn) { + for i, command := range commands.CommandList { + f := command.Function + v.commandsList. + AddItem(command.Name, command.Description, rune('a'+i), func() { + f(conn) + }) + } -func (v *CommandListView) SelectedFunc() { - //TODO: call GRPC calls for the selected item + v.commandsList.AddItem("quit", "closes the application", 'q', func() { + app.Stop() + }) } diff --git a/cmd/gosdn-tview/views/mainView.go b/cmd/gosdn-tview/views/mainView.go index a543399062c8b06ed6eb6e0bb683b918d7950477..1e86860c685a10164d5ca7b4148f4c45c6714912 100644 --- a/cmd/gosdn-tview/views/mainView.go +++ b/cmd/gosdn-tview/views/mainView.go @@ -1,6 +1,10 @@ package views -import "github.com/rivo/tview" +import ( + "code.fbi.h-da.de/cocsn/gosdn/cmd/gosdn-tview/app" + "github.com/rivo/tview" + "google.golang.org/grpc" +) type MainView struct { pages *tview.Pages @@ -9,14 +13,14 @@ type MainView struct { resultAndInputView *ResultAndInputView } -func NewMainView() *MainView { +func NewMainView(app *app.App, conn *grpc.ClientConn) *MainView { v := &MainView{ pages: tview.NewPages(), mainFlexBox: createFlexBox(tview.FlexColumn), - commandsListView: NewCommandListView(""), + commandsListView: NewCommandListView(), resultAndInputView: NewResultAndInputView(), } - v.commandsListView.GetCommands("../") + v.commandsListView.GetCommands(app, conn) commandsFlexBox := createFlexBox(tview.FlexRow) commandsFlexBox.AddItem(v.commandsListView.GetContent(), 0, 40, true)