Skip to content
Snippets Groups Projects

V.0.1.0 Codename Threadbare

Closed Ghost User requested to merge v.0.1.0-codename-threadbare into master
2 files
+ 13
3
Compare changes
  • Side-by-side
  • Inline
Files
2
+ 219
0
package commands
import (
"context"
"time"
pb "code.fbi.h-da.de/cocsn/gosdn/api/proto"
"code.fbi.h-da.de/cocsn/gosdn/cmd/gosdn-tview/app"
"github.com/rivo/tview"
grpc "google.golang.org/grpc"
//Package google.golang.org/grpc/health is needed to make gRPC Health Check work
_ "google.golang.org/grpc/health"
healthpb "google.golang.org/grpc/health/grpc_health_v1"
"google.golang.org/protobuf/types/known/emptypb"
)
const (
defaultName = "gosdn-cli"
)
type command struct {
Name string
Description string
Function func(conn *grpc.ClientConn) string
}
//CommandList contains the specific goSDN gRPC calls
var CommandList = []command{
{"hello", "test connection to controller", goSDNSayHello},
{"testdb", "test all database connections", goSDNTestDB},
{"tapiGetDevices", "creates devices", TAPIGetEdge},
{"tapiGetInterfaces", "creates interfaces", TAPIGetEdgeNode},
{"tapiGetLinks", "creates links between devices", TAPIGetLink},
{"shutdown", "request controller to shutdown", goSDNShutdown},
}
var serviceConfig = `{
"loadBalancingPolicy": "round_robin",
"healthCheckConfig": {
"serviceName": ""
}
}`
//Connect creates a new connection to the gRPC server
func Connect(address string) (*grpc.ClientConn, error) {
options := []grpc.DialOption{
grpc.WithInsecure(),
grpc.WithBlock(),
grpc.WithDefaultServiceConfig(serviceConfig),
grpc.WithTimeout(5 * time.Second),
}
return grpc.Dial(address, options...)
}
//GoSDNLogStream creates a continuous gRPC stream to recieve goSDN logs
func GoSDNLogStream(app *app.App, conn *grpc.ClientConn, tv *tview.TextView) error {
var streamError error
c := pb.NewGrpcCliClient(conn)
stream, err := c.CreateLogStream(context.Background(), &emptypb.Empty{})
if err != nil {
return err
}
go func(stream pb.GrpcCli_CreateLogStreamClient) {
for {
msg, err := stream.Recv()
if err != nil {
streamError = err
go func() {
ticker := time.NewTicker(5 * time.Second)
for range ticker.C {
if err := GoSDNLogStream(app, conn, tv); err == nil {
ticker.Stop()
return
}
}
}()
break
}
response := []byte(msg.Log)
app.QueueUpdateDraw(func() {
tv.Write(response)
})
}
}(stream)
return streamError
}
func goSDNSayHello(conn *grpc.ClientConn) string {
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 {
return err.Error()
}
return r.GetMessage()
}
//WatchHealth continuous gRPC Health Check stream to recieve health changes
func WatchHealth(service string, app *app.App, conn *grpc.ClientConn, tv *tview.TextView) error {
var streamError error
c := healthpb.NewHealthClient(conn)
stream, err := c.Watch(context.Background(), &healthpb.HealthCheckRequest{Service: service})
if err != nil {
app.QueueUpdateDraw(func() {
tv.Clear()
tv.SetText(err.Error())
})
return err
}
go func(stream healthpb.Health_WatchClient) {
for {
msg, err := stream.Recv()
if err != nil {
streamError = err
go func() {
ticker := time.NewTicker(5 * time.Second)
for range ticker.C {
if err := WatchHealth(service, app, conn, tv); err == nil {
ticker.Stop()
return
}
}
}()
break
}
app.QueueUpdateDraw(func() {
tv.Clear()
tv.SetText(msg.GetStatus().String())
})
}
}(stream)
return streamError
}
func goSDNShutdown(conn *grpc.ClientConn) string {
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 {
return err.Error()
}
return r.GetMessage()
}
func goSDNTestDB(conn *grpc.ClientConn) string {
// TODO: fill with code and also see if grpc interface has this stub implemented.
return "not implemented yet"
}
// TAPIGetEdge triggers the GetEdge function of the Ciena
// flavoured TAPI client
func TAPIGetEdge(conn *grpc.ClientConn) string {
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 {
return err.Error()
}
return r.GetMessage()
}
// TAPIGetEdgeNode triggers the GetEdgeNode function of the Ciena
// flavoured TAPI client
func TAPIGetEdgeNode(conn *grpc.ClientConn) string {
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 {
return err.Error()
}
return r.GetMessage()
}
// TAPIGetLink triggers the GetLink function of the Ciena
// flavoured TAPI client
func TAPIGetLink(conn *grpc.ClientConn) string {
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 {
return err.Error()
}
return r.GetMessage()
}
Loading