Skip to content
Snippets Groups Projects
Commit 59397667 authored by Manuel Kieweg's avatar Manuel Kieweg
Browse files

Merge branch '15-need-common-configuration-storage' into 'develop'

Resolve "Need common configuration storage"

See merge request cocsn/gosdn!24
parents 505aacd5 16609c6b
No related branches found
No related tags found
2 merge requests!24Resolve "Need common configuration storage",!18Develop
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,19 +4,16 @@ go 1.14 ...@@ -4,19 +4,16 @@ go 1.14
require ( require (
code.fbi.h-da.de/cocsn/swagger/apis v0.0.0-20200924152423-61030cab7b88 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 github.com/BurntSushi/toml v0.3.1
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/go-openapi/runtime v0.19.22 github.com/go-openapi/runtime v0.19.22
github.com/go-openapi/strfmt v0.19.5 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/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/mattn/go-sqlite3 v1.14.3
github.com/openconfig/goyang v0.0.0-20200917201611-633eccb6fa97 // indirect github.com/neo4j/neo4j-go-driver v1.8.3
github.com/openconfig/ygot v0.8.7
golang.org/x/net v0.0.0-20200904194848-62affa334b73 // indirect 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/grpc v1.29.1
google.golang.org/protobuf v1.23.0 google.golang.org/protobuf v1.23.0
) )
This diff is collapsed.
package nucleus package nucleus
import ( import (
"code.fbi.h-da.de/cocsn/gosdn/database"
"code.fbi.h-da.de/cocsn/gosdn/nucleus/interfaces" "code.fbi.h-da.de/cocsn/gosdn/nucleus/interfaces"
"encoding/json" "github.com/BurntSushi/toml"
"io/ioutil"
"log" "log"
"os"
) )
/* /*
+-- type controllerConfig struct #example gosdn.toml
+-- type Core struct CliSocket="localhost:55055"
+-- client *restconf.Client DatabaseSocket="localhost:7687"
+-- db *database.Database ConfigPath="./gosdn.toml"
+-- config controllerConfig
+-- func Init(){
read.config
db.create/attach
if config.client{
client.init
}
}
*/ */
type controllerConfig struct { type controllerConfig struct {
CliSocket string `json:"cli_socket"` CliSocket string
DatabaseSocket string `json:"database_socket"` DatabaseSocket string
DatabaseUser string `json:"database_user,omitempty"` DatabaseUser string
DatabasePassword string `json:"database_password,omitempty"` DatabasePassword string
DatabaseCrypto bool `json:"database_crypto,omitempty"` DatabaseCrypto bool
ConfigPath string `json:"config_path"` ConfigPath string
} }
type Core struct { type Core struct {
clients []interfaces.Client clients []interfaces.Client
database interfaces.Database database database.Database
config controllerConfig config controllerConfig
} }
func (c Core) Init(socket, filename string) { func (c Core) Init(socket, configfile string) {
if filename == "" { if configfile == "" {
filename = "gosdn.json" configfile = "gosdn.toml"
} }
config, err := ioutil.ReadFile(filename) _, err := os.Stat(configfile)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal("Config file is missing: ", configfile)
} }
c.config = controllerConfig{} c.config = controllerConfig{}
if err := json.Unmarshal(config, &c.config); err != nil { if _, err := toml.DecodeFile(configfile, &c.config); err != nil {
log.Fatal(err) log.Fatal(err)
} }
if socket != "localhost:55055" { if socket != "localhost:55055" {
c.config.CliSocket = socket c.config.CliSocket = socket
} }
if c.config.ConfigPath == "" {
c.config.ConfigPath = configfile
}
c.database = interfaces.NewDatabaseClient(c.config.DatabaseSocket, c.config.DatabaseUser, c.config.DatabasePassword, c.config.DatabaseCrypto) c.database = database.NewDatabaseClient(c.config.DatabaseSocket, c.config.DatabaseUser, c.config.DatabasePassword, c.config.DatabaseCrypto)
} }
func (c Core) Shutdown() { func (c Core) Shutdown() {
config, err := json.Marshal(c.config) f, err := os.Create(c.config.ConfigPath)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
if err := ioutil.WriteFile("gosdn.json", config, 0644); err != nil { enc := toml.NewEncoder(f)
if err := enc.Encode(c.config); err != nil {
log.Fatal(err) log.Fatal(err)
} }
} }
...@@ -10,6 +10,6 @@ type MockDatabase struct { ...@@ -10,6 +10,6 @@ type MockDatabase struct {
func (db MockDatabase) DropTables() { func (db MockDatabase) DropTables() {
} }
func NewDatabaseClient(uri, username, password string, encrypted bool) Database { func NewMockDatabaseClient(uri, username, password string, encrypted bool) Database {
return MockDatabase{} return MockDatabase{}
} }
package ciena package ciena
import ( import (
"code.fbi.h-da.de/cocsn/gosdn/database"
"code.fbi.h-da.de/cocsn/gosdn/restconf/util" "code.fbi.h-da.de/cocsn/gosdn/restconf/util"
apiclient "code.fbi.h-da.de/cocsn/swagger/apis/mcp/client" apiclient "code.fbi.h-da.de/cocsn/swagger/apis/mcp/client"
"crypto/tls" "crypto/tls"
...@@ -14,6 +15,7 @@ import ( ...@@ -14,6 +15,7 @@ import (
type MCPClient struct { type MCPClient struct {
transport *httptransport.Runtime transport *httptransport.Runtime
client *apiclient.ServiceTopologyTAPI client *apiclient.ServiceTopologyTAPI
database *database.Database
buf *[]byte buf *[]byte
} }
...@@ -23,7 +25,7 @@ func (c MCPClient) GetConfig() string { ...@@ -23,7 +25,7 @@ func (c MCPClient) GetConfig() string {
} }
//NewMCPClient creates a client //NewMCPClient creates a client
func NewMCPClient(endpoint, username, password string) MCPClient { func NewMCPClient(endpoint, username, password string, database *database.Database) MCPClient {
// create the transport // create the transport
transport := httptransport.New(endpoint, "/", nil) transport := httptransport.New(endpoint, "/", nil)
transport.Transport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: true} transport.Transport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
...@@ -40,30 +42,31 @@ func NewMCPClient(endpoint, username, password string) MCPClient { ...@@ -40,30 +42,31 @@ func NewMCPClient(endpoint, username, password string) MCPClient {
return MCPClient{ return MCPClient{
transport: transport, transport: transport,
client: client, client: client,
database: database,
buf: &buf, buf: &buf,
} }
} }
func (c MCPClient) GetConnections() (error, []byte) { func (c MCPClient) GetConnections() error {
c.buf = nil c.buf = nil
_, err := c.client.TapiConnectivityCore.GetTapiCoreContextConnection(nil) _, err := c.client.TapiConnectivityCore.GetTapiCoreContextConnection(nil)
responseBuffer := *c.buf c.database.StoreConnections(string(*c.buf))
c.buf = nil c.buf = nil
return err, responseBuffer return err
} }
func (c MCPClient) GetNodes() (error, []byte) { func (c MCPClient) GetNodes() error {
c.buf = nil c.buf = nil
_, err := c.client.TapiTopologyCore.GetTapiCoreContextTopologyMcpBaseTopologyNode(nil) _, err := c.client.TapiTopologyCore.GetTapiCoreContextTopologyMcpBaseTopologyNode(nil)
responseBuffer := *c.buf c.database.StoreNodes(string(*c.buf))
c.buf = nil c.buf = nil
return err, responseBuffer return err
} }
func (c MCPClient) GetNodeEdgePoints() (error, []byte) { func (c MCPClient) GetNodeEdgePoints() error {
c.buf = nil c.buf = nil
_, err := c.client.TapiTopologyCore.GetTapiCoreContextTopologyMcpBaseTopologyNodeEdgePoint(nil) _, err := c.client.TapiTopologyCore.GetTapiCoreContextTopologyMcpBaseTopologyNodeEdgePoint(nil)
responseBuffer := *c.buf c.database.StoreNodeEdgePoints(string(*c.buf))
c.buf = nil 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