Skip to content
Snippets Groups Projects
Commit 5304922e authored by Martin Stiemerling's avatar Martin Stiemerling
Browse files

hopefully fixed merge conflict

parents 54f78cb0 d83c2f9f
No related branches found
No related tags found
1 merge request!18Develop
This commit is part of merge request !18. Comments created here will be created in the context of that merge request.
package database
import (
"log"
"github.com/neo4j/neo4j-go-driver/neo4j"
)
//Database
type Database struct {
driver neo4j.Driver
session neo4j.Session
}
//NewDatabaseClient creates a database client
func NewDatabaseClient(uri, username, password string, encrypted bool) Database {
//TODO: defer close()?
// probably pretty nasty since it creates copies
driver := createDriver(uri, username, password, encrypted)
session := createSession(driver)
return Database{
driver: driver,
session: session,
}
}
//createDriver creates a neo4j.Driver instance
func createDriver(uri, username, password string, encrypted bool) neo4j.Driver {
driver, err := neo4j.NewDriver(
uri,
neo4j.BasicAuth(username, password, ""),
func(c *neo4j.Config) {
c.Encrypted = encrypted
},
)
logError("failed creating database Driver", err)
return driver
}
//createSession creates a neo4j.Session
func createSession(driver neo4j.Driver) neo4j.Session {
sessionConfig := neo4j.SessionConfig{AccessMode: neo4j.AccessModeWrite}
session, err := driver.NewSession(sessionConfig)
logError("failed creating database session", err)
return session
}
//StoreNodes stores the given nodes to the database
func (d Database) StoreNodes(json string) {
session := d.session
query :=
`
WITH apoc.convert.fromJsonMap($stringToAdd)
AS value
UNWIND value.data as d
MERGE (device:Device {id: d.object_id})
ON CREATE SET device.nativeName = d.object_data.name[0].value,
device.deviceType = d.object_data.name[1].value,
device.serialNumber = d.object_data.name[2].value,
device.softwareVersion = d.object_data.name[3].value,
device.` + "`operational-state` = d.object_data.`operational-state`"
_, err := session.Run(
query, map[string]interface{}{
"stringToAdd": json,
})
logError("failed storing Nodes into database", err)
log.Printf("successfully added Nodes into database")
}
//StoreNodeEdgePoints stores the given node edge points (interfaces)
func (d Database) StoreNodeEdgePoints(json string) {
session := d.session
queryEdgePoints :=
`
WITH apoc.convert.fromJsonMap($stringToAdd)
AS value
UNWIND value.data as i
MERGE (interface:Interface {id: i.object_id})
ON CREATE SET interface.object_type =i.object_type,
interface.localId = i.object_data.name[0].value,
interface.location = i.object_data.name[1].value,
interface.` + "`containing-node` = i.object_data.`containing-node`"
_, err := session.Run(
queryEdgePoints, map[string]interface{}{
"stringToAdd": json,
})
logError("failed storing NodeEdgePoints into database", err)
setNodeNodeEdgePointsRelation(session)
log.Printf("successfully added NodeEdgePoints into database")
}
func (d Database) StoreConnections(json string){}
//setNodeNodeEdgePointsRelation creates the database relations between "nodes" and "node edge points"
func setNodeNodeEdgePointsRelation(session neo4j.Session) {
query :=
`
MATCH (d:Device), (i:Interface)
WHERE d.id = i.` + "`containing-node`" + `
CREATE (i)-[:BELONGS_TO]->(d)
`
_, err := session.Run(
query, map[string]interface{}{})
logError("failed storing NodeNodeEdgePointsRelation into database", err)
log.Printf("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)
}
}
......@@ -4,20 +4,19 @@ go 1.14
require (
code.fbi.h-da.de/cocsn/swagger/apis v0.0.0-20200924152423-61030cab7b88
code.fbi.h-da.de/cocsn/swagger/apis/ciena v0.0.0-20200922140607-29b1f99d0f68 // indirect
code.fbi.h-da.de/cocsn/yang-modules/generated/ciena v0.0.0-20200922150332-3e03fcde3e37
code.fbi.h-da.de/cocsn/yang-modules/generated/tapi v0.0.0-20200922150332-3e03fcde3e37
github.com/BurntSushi/toml v0.3.1
github.com/go-openapi/runtime v0.19.22
github.com/go-openapi/strfmt v0.19.5
github.com/go-openapi/swag v0.19.9 // indirect
github.com/go-openapi/validate v0.19.11 // indirect
github.com/golang/protobuf v1.4.2
github.com/jessevdk/go-flags v1.4.0 // indirect
github.com/google/go-cmp v0.4.1 // indirect
github.com/mattn/go-sqlite3 v1.14.3
github.com/openconfig/goyang v0.0.0-20200917201611-633eccb6fa97 // indirect
github.com/openconfig/ygot v0.8.7
github.com/rivo/tview v0.0.0-20200915114512-42866ecf6ca6
github.com/neo4j/neo4j-go-driver v1.8.3
golang.org/x/net v0.0.0-20200904194848-62affa334b73 // indirect
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299 // indirect
google.golang.org/genproto v0.0.0-20200519141106-08726f379972 // indirect
google.golang.org/grpc v1.29.1
google.golang.org/protobuf v1.23.0
)
This diff is collapsed.
#example gosdn.toml
CliSocket="localhost:55055"
DatabaseSocket="localhost:7687"
ConfigPath="./gosdn.toml"
\ No newline at end of file
......@@ -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!
......
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/database"
"code.fbi.h-da.de/cocsn/gosdn/nucleus/interfaces"
"github.com/BurntSushi/toml"
"log"
"os"
)
// This is a test function in order to see how to generate JSON encoded openconfig stuff
/*
#example gosdn.toml
CliSocket="localhost:55055"
DatabaseSocket="localhost:7687"
ConfigPath="./gosdn.toml"
*/
func AssembleJSON() {
// Build my device
d := &yangPro.Device{}
type controllerConfig struct {
CliSocket string
DatabaseSocket string
DatabaseUser string
DatabasePassword string
DatabaseCrypto bool
ConfigPath string
}
interfaces, _ := net.Interfaces()
for _, iface := range interfaces {
fmt.Println(iface.Name)
}
type Core struct {
clients []interfaces.Client
database database.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, configfile string) {
if configfile == "" {
configfile = "gosdn.toml"
}
_, err := os.Stat(configfile)
if err != nil {
panic(fmt.Sprintf("JSON demo error: %v", err))
log.Fatal("Config file is missing: ", configfile)
}
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 := toml.DecodeFile(configfile, &c.config); err != nil {
log.Fatal(err)
}
if socket != "localhost:55055" {
c.config.CliSocket = socket
}
if c.config.ConfigPath == "" {
c.config.ConfigPath = configfile
}
c.database = database.NewDatabaseClient(c.config.DatabaseSocket, c.config.DatabaseUser, c.config.DatabasePassword, c.config.DatabaseCrypto)
}
func (c Core) Shutdown() {
f, err := os.Create(c.config.ConfigPath)
if err != nil {
log.Fatal(err)
}
enc := toml.NewEncoder(f)
if err := enc.Encode(c.config); err != nil {
log.Fatal(err)
}
}
package restconf
package interfaces
type Client interface {
GetConfig() string
......
package interfaces
type Database interface {
DropTables()
}
type MockDatabase struct {
}
func (db MockDatabase) DropTables() {
}
func NewMockDatabaseClient(uri, username, password string, encrypted bool) Database {
return MockDatabase{}
}
......@@ -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....!")
......
package ciena
import (
"code.fbi.h-da.de/cocsn/gosdn/database"
"code.fbi.h-da.de/cocsn/gosdn/restconf/util"
apiclient "code.fbi.h-da.de/cocsn/swagger/apis/mcp/client"
"crypto/tls"
......@@ -14,6 +15,7 @@ import (
type MCPClient struct {
transport *httptransport.Runtime
client *apiclient.ServiceTopologyTAPI
database *database.Database
buf *[]byte
}
......@@ -23,7 +25,7 @@ func (c MCPClient) GetConfig() string {
}
//NewMCPClient creates a client
func NewMCPClient(endpoint, username, password string) MCPClient {
func NewMCPClient(endpoint, username, password string, database *database.Database) MCPClient {
// create the transport
transport := httptransport.New(endpoint, "/", nil)
transport.Transport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
......@@ -40,30 +42,31 @@ func NewMCPClient(endpoint, username, password string) MCPClient {
return MCPClient{
transport: transport,
client: client,
database: database,
buf: &buf,
}
}
func (c MCPClient) GetConnections() (error, []byte) {
func (c MCPClient) GetConnections() error {
c.buf = nil
_, err := c.client.TapiConnectivityCore.GetTapiCoreContextConnection(nil)
responseBuffer := *c.buf
c.database.StoreConnections(string(*c.buf))
c.buf = nil
return err, responseBuffer
return err
}
func (c MCPClient) GetNodes() (error, []byte) {
func (c MCPClient) GetNodes() error {
c.buf = nil
_, err := c.client.TapiTopologyCore.GetTapiCoreContextTopologyMcpBaseTopologyNode(nil)
responseBuffer := *c.buf
c.database.StoreNodes(string(*c.buf))
c.buf = nil
return err, responseBuffer
return err
}
func (c MCPClient) GetNodeEdgePoints() (error, []byte) {
func (c MCPClient) GetNodeEdgePoints() error {
c.buf = nil
_, err := c.client.TapiTopologyCore.GetTapiCoreContextTopologyMcpBaseTopologyNodeEdgePoint(nil)
responseBuffer := *c.buf
c.database.StoreNodeEdgePoints(string(*c.buf))
c.buf = nil
return err, responseBuffer
return err
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment