From a5ce53c3feac7e5b8de3f3c68cc6fd312edea8ff Mon Sep 17 00:00:00 2001 From: Manuel Kieweg <mail@manuelkieweg.de> Date: Fri, 25 Sep 2020 13:09:01 +0100 Subject: [PATCH] Controller core --- main.go | 21 ++--- nucleus/controller.go | 82 ++++++++++++------- .../client => nucleus/interfaces}/client.go | 2 +- nucleus/interfaces/database.go | 15 ++++ nucleus/nucleus-core.go | 23 +++--- 5 files changed, 85 insertions(+), 58 deletions(-) rename {restconf/client => nucleus/interfaces}/client.go (71%) create mode 100644 nucleus/interfaces/database.go diff --git a/main.go b/main.go index 3e8e3542a..712ed2f30 100644 --- a/main.go +++ b/main.go @@ -5,29 +5,18 @@ import ( "flag" ) - -// Generate the code out of the yang modules -//go:generate go run $GOPATH/src/github.com/openconfig/ygot/generator/generator.go -path=yang -output_file=yang-processor/gosdnyang.go.go -package_name=gosdnyang -generate_fakeroot -fakeroot_name=device -compress_paths=true -shorten_enum_leaf_names -exclude_modules=ietf-interfaces yang/openconfig-interfaces.yang yang/openconfig-if-ip.yang - -type goSDNConfiguration struct { - cliServerAddr4 *string - cliServerPort4 *int -} - func main() { // register our supported flags - cliServerAddr4 := flag.String("cliServerAddr", "127.0.0.1", "The IPv4 Address of the grpcCLI.") - cliServerPort4 := flag.Int("cliServerPort", 55055, "The port number of the grpcCLI") + cliListenAddr := flag.String("cli-listen-addr", "localhost", "The IP address of the grpcCLI.") + cliListenPort := flag.String("cli-server-port", "55055", "The port number of the grpcCLI") + configFileName := flag.String("config-file", "", "Path to the config file") flag.Parse() - - var myConfiguration = new(goSDNConfiguration) - myConfiguration.cliServerAddr4 = cliServerAddr4 - myConfiguration.cliServerPort4 = cliServerPort4 + cliSocket := *cliListenAddr + *cliListenPort // hand off to cmd for further processing - nucleus.StartUp() + nucleus.StartUp(cliSocket, *configFileName) nucleus.Run() // nothing to see here, please move on! diff --git a/nucleus/controller.go b/nucleus/controller.go index 7181ddc36..88edbeb45 100644 --- a/nucleus/controller.go +++ b/nucleus/controller.go @@ -1,42 +1,68 @@ package nucleus import ( - yangPro "code.fbi.h-da.de/cocsn/yang-modules/generated/tapi" - "fmt" - "github.com/openconfig/ygot/ygot" - "net" + "code.fbi.h-da.de/cocsn/gosdn/nucleus/interfaces" + "encoding/json" + "io/ioutil" + "log" ) -// This is a test function in order to see how to generate JSON encoded openconfig stuff +/* ++-- type controllerConfig struct ++-- type Core struct + +-- client *restconf.Client + +-- db *database.Database + +-- config controllerConfig ++-- func Init(){ + read.config + db.create/attach + if config.client{ + client.init + } + } +*/ -func AssembleJSON() { - // Build my device - d := &yangPro.Device{} +type controllerConfig struct { + CliSocket string `json:"cli_socket"` + DatabaseSocket string `json:"database_socket"` + DatabaseUser string `json:"database_user,omitempty"` + DatabasePassword string `json:"database_password,omitempty"` + DatabaseCrypto bool `json:"database_crypto,omitempty"` + ConfigPath string `json:"config_path"` +} - interfaces, _ := net.Interfaces() - for _, iface := range interfaces { - fmt.Println(iface.Name) - } +type Core struct { + clients []interfaces.Client + database interfaces.Database + config controllerConfig +} - // EmitJSON from the ygot library directly does .Validate() and outputs JSON in - // the specified format. - json, err := ygot.EmitJSON(d, &ygot.EmitJSONConfig{ - Format: ygot.RFC7951, - Indent: " ", - RFC7951Config: &ygot.RFC7951JSONConfig{ - AppendModuleName: true, - }, - }) +func (c Core) Init(socket, filename string) { + if filename == "" { + filename = "gosdn.json" + } + config, err := ioutil.ReadFile(filename) if err != nil { - panic(fmt.Sprintf("JSON demo error: %v", err)) + log.Fatal(err) } - fmt.Println(json) - // and now try to read the data from it... - // Device struct to unmarshal into. - loadd := &yangPro.Device{} - if err := yangPro.Unmarshal([]byte(json), loadd); err != nil { - panic(fmt.Sprintf("Cannot unmarshal JSON: %v", err)) + c.config = controllerConfig{} + if err := json.Unmarshal(config, &c.config); err != nil { + log.Fatal(err) + } + if socket != "localhost:55055" { + c.config.CliSocket = socket } + c.database = interfaces.NewDatabaseClient(c.config.DatabaseSocket, c.config.DatabaseUser, c.config.DatabasePassword, c.config.DatabaseCrypto) +} + +func (c Core) Shutdown() { + config, err := json.Marshal(c.config) + if err != nil { + log.Fatal(err) + } + if err := ioutil.WriteFile("gosdn.json", config, 0644); err != nil { + log.Fatal(err) + } } diff --git a/restconf/client/client.go b/nucleus/interfaces/client.go similarity index 71% rename from restconf/client/client.go rename to nucleus/interfaces/client.go index 31de71aa3..1ada3063f 100644 --- a/restconf/client/client.go +++ b/nucleus/interfaces/client.go @@ -1,4 +1,4 @@ -package restconf +package interfaces type Client interface { GetConfig() string diff --git a/nucleus/interfaces/database.go b/nucleus/interfaces/database.go new file mode 100644 index 000000000..1238e4754 --- /dev/null +++ b/nucleus/interfaces/database.go @@ -0,0 +1,15 @@ +package interfaces + +type Database interface { + DropTables() +} + +type MockDatabase struct { +} + +func (db MockDatabase) DropTables() { +} + +func NewDatabaseClient(uri, username, password string, encrypted bool) Database { + return MockDatabase{} +} diff --git a/nucleus/nucleus-core.go b/nucleus/nucleus-core.go index d07c6e28e..86909fc17 100644 --- a/nucleus/nucleus-core.go +++ b/nucleus/nucleus-core.go @@ -10,14 +10,10 @@ import ( "time" ) -// TODO XXX This has to be moved to some configuration file -const ( - cli_control_port = "localhost:55055" -) - // server is used to implement helloworld.GreeterServer. type server struct { pb.UnimplementedGreeterServer + core *Core } // SayHello implements helloworld.GreeterServer @@ -32,18 +28,17 @@ func (s *server) Shutdown(ctx context.Context, in *pb.ShutdownRequest) (*pb.Shut return &pb.ShutdownReply{Message: "Shutdown " + in.GetName()}, nil } - -func getCLIGoing() { +func getCLIGoing(core *Core) { log.Println("Starting: GetCLIGoing") // Boot-up the control interface for the cli - cliControlListener, err := net.Listen("tcp", cli_control_port) + cliControlListener, err := net.Listen("tcp", core.config.CliSocket) if err != nil { log.Fatalf("failed to listen: %v", err) } cliControlServer := grpc.NewServer() - pb.RegisterGreeterServer(cliControlServer, &server{}) + pb.RegisterGreeterServer(cliControlServer, &server{core: core}) if err := cliControlServer.Serve(cliControlListener); err != nil { log.Fatalf("failed to serve: %v", err) } @@ -56,12 +51,14 @@ func getCLIGoing() { // Next-up: backend database. -func StartUp() { - +func StartUp(socket, filename string) { log.Println("This is the network superintendent...") log.Println("Starting my ducks") + // Init the Core + core := Core{} + core.Init(socket, filename) // Start the GRCP CLI - go getCLIGoing() + go getCLIGoing(&core) log.Println("and ready for take off") } @@ -76,7 +73,7 @@ func Run() { for isRunning { time.Sleep(10 * time.Second) - log.Println(("Still alive...")) + log.Println("Still alive...") } log.Println("Good bye....!") -- GitLab