package main import ( pb "code.fbi.h-da.de/cocsn/gosdn/api/proto" "context" "flag" "fmt" log "github.com/sirupsen/logrus" "google.golang.org/grpc" "os" "time" ) const ( defaultName = "gosdn-cli" ) // Based on the helloworld example of grpc.io -- thx! type cliClientConfig struct { goSDNCLIAddr4 *string goSDNCLIPort4 *int interactive *bool goSDNCommand *string } type commandOptions struct { name string description string command func(conn *grpc.ClientConn) } var commandList = map[string]commandOptions{ "hello": {"hello", "test connection to goSDN controller", goSDNSayHello}, "shutdown": {"shutdown", "request goSDN controller to shutdown", goSDNShutdown}, "testdb": {"testdb", "test all database connections", goSDNTestDB}, "tapigetedge": {"tapigetedge", "get list of edges", TAPIGetEdge}, "tapigetedgenode": {"tapigetedgenode", "get list of edgenodes", TAPIGetEdgeNode}, "tapigetlink": {"tapigetlink", "get list of links", TAPIGetLink}, } /* gosdn-cli allows to mode of operations: - interactive: text GUI to operate goSDN - non-interactive: basic CLI without text GUI */ func main() { // This holds the basic configuration for gosdn-cli var myConfiguration = new(cliClientConfig) myConfiguration.goSDNCLIAddr4 = flag.String("cliServerAddr", "127.0.0.1", "The IPv4 Address of the grpcCLI.") myConfiguration.goSDNCLIPort4 = flag.Int("cliServerPort", 55055, "The port number of the grpcCLI") myConfiguration.interactive = flag.Bool("interactive", false, "interactive: text gui or just not") var printCommandList = flag.Bool("commandlist", false, "interactive: print command list") myConfiguration.goSDNCommand = flag.String("command", "", "-command: <your command> ; show commands with -commandlist") flag.Parse() // Print complete command list and exit if *printCommandList { for _, element := range commandList { fmt.Println(element.name + "\t" + element.description) } os.Exit(0) } log.Info("Starting " + defaultName + " to access the goSDN controller") // Prepare string with socket for connection to the goSDN controller goSDNSocketAddress := fmt.Sprintf("%s:%d", *myConfiguration.goSDNCLIAddr4, *myConfiguration.goSDNCLIPort4) log.Info("Connecting to the goSDN server at: " + goSDNSocketAddress) // Set up a connection to the server. address := "localhost:55055" conn, err := grpc.Dial(address, grpc.WithInsecure(), grpc.WithBlock()) if err != nil { log.Fatal(err) } defer conn.Close() log.Info("Connected to " + conn.Target()) // Check for non-interactive or interactive mode if !*myConfiguration.interactive { log.Info("starting in non-interactive mode") // Lookup command or die _, found := commandList[*myConfiguration.goSDNCommand] if found { // Excecute desired command commandList[*myConfiguration.goSDNCommand].command(conn) } else { // TODO: change once gosdn/errors exist log.Fatal("Your desired command is not available: ", commandList[*myConfiguration.goSDNCommand].name) os.Exit(1) } } else { log.Info("starting in interactive mode -- do not use yet") os.Exit(1) } } func goSDNSayHello(conn *grpc.ClientConn) { c := pb.NewGrpcCliClient(conn) // Contact the server and print out its response. name := defaultName if len(os.Args) > 1 { name = os.Args[1] } 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 if len(os.Args) > 1 { name = os.Args[0] } 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 if len(os.Args) > 1 { name = os.Args[0] } 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 if len(os.Args) > 1 { name = os.Args[0] } 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 if len(os.Args) > 1 { name = os.Args[0] } 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()) }