diff --git a/database/database.go b/database/database.go index 3333d55299136190301cb9447343e6c3bae1f2e4..c923ab8aa9d4b70b4b0c61e150dcce8a6b97c4b1 100644 --- a/database/database.go +++ b/database/database.go @@ -1,8 +1,7 @@ package database import ( - "log" - + "code.fbi.h-da.de/cocsn/gosdn/log" "github.com/neo4j/neo4j-go-driver/neo4j" ) @@ -74,7 +73,7 @@ func (d Database) StoreNodes(json string) { logError("failed storing Nodes into database", err) - log.Printf("successfully added Nodes into database") + log.Info("successfully added Nodes into database") } //StoreNodeEdgePoints stores the given node edge points (interfaces) @@ -101,7 +100,7 @@ func (d Database) StoreNodeEdgePoints(json string) { setNodeNodeEdgePointsRelation(session) - log.Printf("successfully added NodeEdgePoints into database") + log.Info("successfully added NodeEdgePoints into database") } @@ -121,12 +120,12 @@ func setNodeNodeEdgePointsRelation(session neo4j.Session) { logError("failed storing NodeNodeEdgePointsRelation into database", err) - log.Printf("successfully stored NodeNodeEdgePointsRelation into database") + log.Info("successfully stored NodeNodeEdgePointsRelation into database") } //logError logs error with custom and error message func logError(message string, err error) { if err != nil { - log.Fatalf("%v: %v", message, err) + log.Info("%v: %v", message, err) } } diff --git a/go.sum b/go.sum index 25e2ba2f05db5283ae6133749b18fdab08d10d2c..1e8b1b3fb4eb989895297976c1fdf45cb6ab3a18 100644 --- a/go.sum +++ b/go.sum @@ -311,6 +311,7 @@ golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBn golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190531172133-b3315ee88b7d/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190617190820-da514acc4774 h1:CQVOmarCBFzTx0kbOU0ru54Cvot8SdSrNYjZPhQl+gk= golang.org/x/tools v0.0.0-20190617190820-da514acc4774/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= diff --git a/gosdn.toml b/gosdn.toml index 3c16579ad09332844408a17188184d921a51e0fa..09b7c2adc12684b41dab4da8f68163684ea667b9 100644 --- a/gosdn.toml +++ b/gosdn.toml @@ -1,4 +1,4 @@ #example gosdn.toml -CliSocket="localhost:55055" -DatabaseSocket="localhost:7687" -ConfigPath="./gosdn.toml" \ No newline at end of file +CliSocket = "localhost:55055" +DatabaseSocket = "bolt://localhost:7687" +ConfigPath = "./gosdn.toml" \ No newline at end of file diff --git a/log/logger.go b/log/logger.go new file mode 100644 index 0000000000000000000000000000000000000000..ab258d8b731c5b8692ee8afe37b9c18012b712b2 --- /dev/null +++ b/log/logger.go @@ -0,0 +1,98 @@ +package log + +import ( + "fmt" + "io" + "os" + "sync" + "time" +) + +var logger *Logger +var once sync.Once + +// Logger is a wrapper for log.Logger and provides +// methods to enable and disable logging. +type Logger struct { + Out io.Writer + Loglevel Level + lock sync.Mutex +} + +func get() *Logger { + once.Do(func() { + logger = &Logger{ + Out: os.Stdout, + Loglevel: INFO, + lock: sync.Mutex{}, + } + }) + return logger +} + +func Loglevel(level Level) { + l := get() + l.lock.Lock() + defer l.lock.Unlock() + l.Loglevel = level +} + +func Output(out io.Writer) { + l := get() + l.lock.Lock() + defer l.lock.Unlock() + l.Out = out +} + +func Debug(args ...interface{}) { + log(DEBUG, args) +} + +func Info(args ...interface{}) { + log(INFO, args) +} + +func Warn(args ...interface{}) { + log(WARNING, args) +} + +func Error(args ...interface{}) { + log(ERROR, args) +} + +func Fatal(args ...interface{}) { + log(FATAL, args) +} + +func Panic(args ...interface{}) { + log(PANIC, args) +} + +func log(level Level, args ...interface{}) { + l := get() + l.lock.Lock() + defer l.lock.Unlock() + if level <= l.Loglevel { + msg := fmt.Sprint(args...) + logMessage := time.Now().Format(time.RFC3339) + "\t" + prefix(level) + "\t" + msg + "\n" + l.Out.Write([]byte(logMessage)) + } +} + +func prefix(level Level) string { + switch level { + case PANIC: + return "PANIC" + case FATAL: + return "FATAL" + case ERROR: + return "ERROR" + case WARNING: + return "WARNING" + case INFO: + return "INFO" + case DEBUG: + return "DEBUG" + } + return "" +} diff --git a/log/loglevel.go b/log/loglevel.go new file mode 100644 index 0000000000000000000000000000000000000000..64a259cb408139a4a1089b5a0f6714244035bf9e --- /dev/null +++ b/log/loglevel.go @@ -0,0 +1,12 @@ +package log + +type Level uint8 + +const ( + PANIC Level = iota + FATAL + ERROR + WARNING + INFO + DEBUG +) diff --git a/main.go b/main.go index 712ed2f3098c261ea2acc8f10c11535f6c4bf498..b04ddc031a21f6fa6c8d2a0ed4b9d438643f8dcb 100644 --- a/main.go +++ b/main.go @@ -1,6 +1,7 @@ package main import ( + "code.fbi.h-da.de/cocsn/gosdn/log" "code.fbi.h-da.de/cocsn/gosdn/nucleus" "flag" ) @@ -13,10 +14,12 @@ func main() { configFileName := flag.String("config-file", "", "Path to the config file") flag.Parse() - cliSocket := *cliListenAddr + *cliListenPort + cliSocket := *cliListenAddr + ":" + *cliListenPort + log.Loglevel(log.DEBUG) // hand off to cmd for further processing nucleus.StartUp(cliSocket, *configFileName) + log.Info("Startup completed") nucleus.Run() // nothing to see here, please move on! diff --git a/nucleus/controller.go b/nucleus/controller.go index 306e268999363e12c8169388f1d8656d47aef22e..2b4cdb19219dc74bf77a48d02f3363df09d2ead3 100644 --- a/nucleus/controller.go +++ b/nucleus/controller.go @@ -2,19 +2,13 @@ package nucleus import ( "code.fbi.h-da.de/cocsn/gosdn/database" + "code.fbi.h-da.de/cocsn/gosdn/log" "code.fbi.h-da.de/cocsn/gosdn/nucleus/interfaces" + "code.fbi.h-da.de/cocsn/gosdn/restconf/client/ciena" "github.com/BurntSushi/toml" - "log" "os" ) -/* -#example gosdn.toml -CliSocket="localhost:55055" -DatabaseSocket="localhost:7687" -ConfigPath="./gosdn.toml" -*/ - type controllerConfig struct { CliSocket string DatabaseSocket string @@ -25,12 +19,13 @@ type controllerConfig struct { } type Core struct { - clients []interfaces.Client + //Assert type with clients[key].(*MCPClient) + clients map[string]interfaces.Client database database.Database config controllerConfig } -func (c Core) Init(socket, configfile string) { +func (c *Core) Init(socket, configfile string) { if configfile == "" { configfile = "gosdn.toml" } @@ -50,10 +45,17 @@ func (c Core) Init(socket, configfile string) { c.config.ConfigPath = configfile } + c.AttachDatabase() + + //TODO: Create client config/CLI adapter + c.clients["ciena-mcp"] = ciena.NewMCPClient( "141.100.70.170", "", "", &c.database) +} + +func (c *Core) AttachDatabase() { c.database = database.NewDatabaseClient(c.config.DatabaseSocket, c.config.DatabaseUser, c.config.DatabasePassword, c.config.DatabaseCrypto) } -func (c Core) Shutdown() { +func (c *Core) Shutdown() { f, err := os.Create(c.config.ConfigPath) if err != nil { log.Fatal(err) diff --git a/nucleus/interfaces/database.go b/nucleus/interfaces/database.go deleted file mode 100644 index cab171004639e17d538222b1e6cc0eff021aa653..0000000000000000000000000000000000000000 --- a/nucleus/interfaces/database.go +++ /dev/null @@ -1,15 +0,0 @@ -package interfaces - -type Database interface { - DropTables() -} - -type MockDatabase struct { -} - -func (db MockDatabase) DropTables() { -} - -func NewMockDatabaseClient(uri, username, password string, encrypted bool) Database { - return MockDatabase{} -} diff --git a/nucleus/nucleus-core.go b/nucleus/nucleus-core.go index 86909fc176a70773bc11a9693e67cfff62480929..5df7e06e4bc636360acab367cb2edfd82702e4ce 100644 --- a/nucleus/nucleus-core.go +++ b/nucleus/nucleus-core.go @@ -2,10 +2,12 @@ package nucleus import ( pb "code.fbi.h-da.de/cocsn/gosdn/cliInterface" + "code.fbi.h-da.de/cocsn/gosdn/database" + "code.fbi.h-da.de/cocsn/gosdn/log" + "code.fbi.h-da.de/cocsn/gosdn/nucleus/interfaces" "context" _ "github.com/mattn/go-sqlite3" "google.golang.org/grpc" - "log" "net" "time" ) @@ -18,31 +20,31 @@ type server struct { // SayHello implements helloworld.GreeterServer func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) { - log.Printf("Received: %v", in.GetName()) + log.Debug("Received: %v", in.GetName()) return &pb.HelloReply{Message: "Hello " + in.GetName()}, nil } func (s *server) Shutdown(ctx context.Context, in *pb.ShutdownRequest) (*pb.ShutdownReply, error) { - log.Printf("Received: %v", in.GetName()) + log.Debug("Received: %v", in.GetName()) isRunning = false return &pb.ShutdownReply{Message: "Shutdown " + in.GetName()}, nil } func getCLIGoing(core *Core) { - log.Println("Starting: GetCLIGoing") + log.Info("Starting: GetCLIGoing") // Boot-up the control interface for the cli cliControlListener, err := net.Listen("tcp", core.config.CliSocket) if err != nil { - log.Fatalf("failed to listen: %v", err) + log.Fatal("failed to listen: %v", err) } cliControlServer := grpc.NewServer() pb.RegisterGreeterServer(cliControlServer, &server{core: core}) if err := cliControlServer.Serve(cliControlListener); err != nil { - log.Fatalf("failed to serve: %v", err) + log.Fatal("failed to serve: %v", err) } - log.Println("Started: GetCLIGoing") + log.Info("Started: GetCLIGoing") } /* @@ -52,14 +54,17 @@ func getCLIGoing(core *Core) { // Next-up: backend database. func StartUp(socket, filename string) { - log.Println("This is the network superintendent...") - log.Println("Starting my ducks") + log.Info("This is the network superintendent...") + log.Info("Starting my ducks") // Init the Core - core := Core{} + core := Core{ + clients: make(map[string]interfaces.Client, 0), + database: database.Database{}, + } core.Init(socket, filename) // Start the GRCP CLI go getCLIGoing(&core) - log.Println("and ready for take off") + log.Info("and ready for take off") } @@ -73,8 +78,8 @@ func Run() { for isRunning { time.Sleep(10 * time.Second) - log.Println("Still alive...") + log.Debug("Still alive...") } - log.Println("Good bye....!") + log.Info("Good bye....!") } diff --git a/restconf/client/ciena/client.go b/restconf/client/ciena/client.go index 4da3f5b80aa99a7176113fff6d6e228939a77990..3624c2d75bf608c02f36ad23ff0d4b677c9233fc 100644 --- a/restconf/client/ciena/client.go +++ b/restconf/client/ciena/client.go @@ -47,7 +47,7 @@ func NewMCPClient(endpoint, username, password string, database *database.Databa } } -func (c MCPClient) GetConnections() error { +func (c *MCPClient) GetConnections() error { c.buf = nil _, err := c.client.TapiConnectivityCore.GetTapiCoreContextConnection(nil) c.database.StoreConnections(string(*c.buf)) @@ -55,7 +55,7 @@ func (c MCPClient) GetConnections() error { return err } -func (c MCPClient) GetNodes() error { +func (c *MCPClient) GetNodes() error { c.buf = nil _, err := c.client.TapiTopologyCore.GetTapiCoreContextTopologyMcpBaseTopologyNode(nil) c.database.StoreNodes(string(*c.buf)) @@ -63,7 +63,7 @@ func (c MCPClient) GetNodes() error { return err } -func (c MCPClient) GetNodeEdgePoints() error { +func (c *MCPClient) GetNodeEdgePoints() error { c.buf = nil _, err := c.client.TapiTopologyCore.GetTapiCoreContextTopologyMcpBaseTopologyNodeEdgePoint(nil) c.database.StoreNodeEdgePoints(string(*c.buf))