Skip to content
Snippets Groups Projects
Commit 38b0222a authored by S.H.'s avatar S.H.
Browse files

Remove old topology definition that is now redundant because of sdnconfig

parent 620a3bb1
No related branches found
No related tags found
No related merge requests found
Pipeline #268062 failed
...@@ -223,7 +223,7 @@ func (r *RtdtManager) ApplyChanges(twinName string) error { ...@@ -223,7 +223,7 @@ func (r *RtdtManager) ApplyChanges(twinName string) error {
// Performance benchmarks of realnet // Performance benchmarks of realnet
func (r *RtdtManager) RunBenchmark0() error { func (r *RtdtManager) RunBenchmark0() error {
var mneid string var mneid string
for _, node := range r.realnet.GetTopology().Nodes { for _, node := range r.realnet.GetSdnConfig().Nodes {
if strings.HasPrefix(node.Name, "gnmi-target-switch0") { if strings.HasPrefix(node.Name, "gnmi-target-switch0") {
mneid = node.ID mneid = node.ID
} }
...@@ -434,7 +434,7 @@ func (r *RtdtManager) updateMNECallback(event *event.Event) { ...@@ -434,7 +434,7 @@ func (r *RtdtManager) updateMNECallback(event *event.Event) {
err = twin.SetGnmiPath(path, value, twinEntityID, false) err = twin.SetGnmiPath(path, value, twinEntityID, false)
if err != nil { if err != nil {
fmt.Println("Callback failed:", err) fmt.Println("Callback failed:", err)
return return
} }
} }
} }
......
package rtdt_topology
import (
"fmt"
"regexp"
"strings"
topoPb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/topology"
clabconfig "code.fbi.h-da.de/danet/gosdn/applications/rtdt-manager/clab-config"
rtdt_auth "code.fbi.h-da.de/danet/gosdn/applications/rtdt-manager/rtdt-auth"
"code.fbi.h-da.de/danet/gosdn/applications/rtdt-manager/util"
"code.fbi.h-da.de/danet/gosdn/models/generated/openconfig"
)
// Struct definitions were taken from:
// "code.fbi.h-da.de/danet/gosdn/applications/venv-manager/topology/port.go"
// "code.fbi.h-da.de/danet/gosdn/applications/venv-manager/topology/link.go"
// "code.fbi.h-da.de/danet/gosdn/applications/venv-manager/topology/node.go"
// commit: 0264b698286b6cbb965d743078c681f8af55edf6
type Link struct {
ID string
Name string
SourceNode *Node
TargetNode *Node
SourcePort *Port
TargetPort *Port
}
type Port struct {
ID string
Name string
}
type Node struct {
ID string
Name string
Kind string
Image string
MgmtIpv4 string
YangData openconfig.Device
}
type Topology struct {
Links []*Link
Ports []*Port
Nodes []*Node
}
func NewTopology() *Topology {
return &Topology{}
}
func (t *Topology) GetNodeByUUID(UUID string) *Node {
for _, node := range t.Nodes {
if node.ID == UUID {
return node
}
}
return nil
}
func (t *Topology) GetNodeByName(name string) *Node {
for _, node := range t.Nodes {
if node.Name == name {
return node
}
}
return nil
}
func (t *Topology) GetPortByUUID(UUID string) *Port {
for _, port := range t.Ports {
if port.ID == UUID {
return port
}
}
return nil
}
func (t *Topology) GetLinkByUUID(UUID string) *Link {
for _, link := range t.Links {
if link.ID == UUID {
return link
}
}
return nil
}
// Source for function: "code.fbi.h-da.de/danet/gosdn/applications/venv-manager/link.go"
// commit: 0264b698286b6cbb965d743078c681f8af55edf6
// GetLinkAsSliceOfStrings returns the link as a slice of strings for yaml representation.
func (l *Link) GetLinkAsSliceOfStrings() [2]string {
return [2]string{l.SourceNode.Name + ":" + l.SourcePort.Name, l.TargetNode.Name + ":" + l.TargetPort.Name}
}
// Source for function: "code.fbi.h-da.de/danet/gosdn/applications/venv-manager/node.go"
// commit: 0264b698286b6cbb965d743078c681f8af55edf6
// FillAllFields fills all remaining fields of object with data from YangData.
func (n *Node) FillAllFields(containerRegistryURL string) {
// Works if linux and our gnmi target is used.
softwareVersion := n.YangData.System.State.SoftwareVersion
if softwareVersion != nil {
// Checks if software version is in compatible format.
result, _ := regexp.MatchString(`^([A-Za-z0-9\.\/])*:([A-Za-z0-9\.])*`, *softwareVersion)
if result {
n.Kind = "linux"
n.Image = containerRegistryURL + *softwareVersion
return
}
n.Kind = "couldn't detect kind"
n.Image = "couldn't detect image"
return
}
// Specific to arista
regex := regexp.MustCompile(`[0-9]+\.[0-9]+\.[0-9][A-Z]`)
dockerTag := string(regex.FindAll([]byte(*n.YangData.Lldp.Config.SystemDescription), 1)[0])
// If it's not linux with our gnmi target and not arista, we don't support it.
if len(dockerTag) == 0 {
n.Kind = "couldn't detect kind"
n.Image = "couldn't detect image"
return
}
n.Kind = "ceos"
n.Image = containerRegistryURL + n.Kind + ":" + dockerTag
}
// Based on the given auth and a pnd, get a topology from the DB store
func (t *Topology) RetrieveTopology(pnd string, auth *rtdt_auth.RtdtAuth) error {
conn := auth.GetConn()
ctx := auth.CreateContextWithAuthorization()
topoService := topoPb.NewTopologyServiceClient(conn)
topoResponse, err := topoService.GetTopology(ctx, &topoPb.GetTopologyRequest{Timestamp: util.Now()})
if err != nil {
return fmt.Errorf("Couldn't retrieve topology from DB: %v\n", err)
}
sourceTopo := topoResponse.GetToplogy()
targetTopo := NewTopology()
for _, link := range sourceTopo.Links {
var n0 Node
var n1 Node
if targetTopo.GetNodeByUUID(link.SourceNode.Id) == nil {
snode := link.SourceNode
n0 = Node{
ID: snode.Id,
Name: snode.Name,
Kind: "todo",
Image: "todo", // How to do this?
MgmtIpv4: "todo",
}
// n0.FillAllFields(containerRegistryURL) // TODO get this later
t.Nodes = append(t.Nodes, &n0)
}
if targetTopo.GetNodeByUUID(link.TargetNode.Id) == nil {
tnode := link.TargetNode
n1 = Node{
ID: tnode.Id,
Name: tnode.Name,
Kind: "todo",
Image: "todo", // How to do this?
MgmtIpv4: "todo",
}
//n1.FillAllFields(v.containerRegistryURL)
t.Nodes = append(t.Nodes, &n1)
}
if targetTopo.GetLinkByUUID(link.Id) == nil {
var p0 Port
var p1 Port
if targetTopo.GetPortByUUID(link.SourcePort.Id) == nil {
p0 = Port{
Name: link.SourcePort.Name,
ID: link.SourcePort.Id,
}
}
if targetTopo.GetPortByUUID(link.SourcePort.Id) == nil {
p1 = Port{
Name: link.TargetPort.Name,
ID: link.TargetPort.Id,
}
}
var newLink = Link{
ID: link.Id,
Name: link.Name,
SourceNode: &n0,
TargetNode: &n1,
SourcePort: &p0,
TargetPort: &p1,
}
t.Links = append(t.Links, &newLink)
}
}
return nil
}
func (t *Topology) ToYAML() *clabconfig.ClabConfig {
var yamlMgmt clabconfig.Mgmt
var yamlNodes map[string]clabconfig.Node
var yamlLinks []clabconfig.Link
// First get topology information, meaning gnmi-targets and hosts
for _, n := range t.Nodes {
// TODO This is very ugly, for now just fill in missing data based on name of node
var cmd string
var binds []string
var ports []string
var env map[string]string
var startupDelay int
switch {
case strings.Contains(n.Name, "gnmi-target"):
cmd = "start --ca_file /etc/gnmi-target/ssl/ca.crt --cert /etc/gnmi-target/ssl/certs/gnmi-target-selfsigned.crt --key /etc/gnmi-target/ssl/private/gnmi-target-selfsigned.key"
binds = []string{"../../../artifacts/ssl/gnmi-target", "/etc/gnmi-target/ssl"}
startupDelay = 5
case strings.Contains(n.Name, "gosdn"):
cmd = "--config /app/configs/containerlab-gosdn.toml"
binds = []string{"../../../artifacts/ssl/gosdn", "/app/ssl"}
}
node := clabconfig.Node{
Kind: n.Kind,
Image: n.Image,
Ports: ports,
Cmd: cmd,
MgmtIPv4: n.MgmtIpv4,
Env: env,
Binds: binds,
StartupDelay: startupDelay,
Group: "",
}
yamlNodes[n.Name] = node
}
// Now: Get configuration for environment (controller, rabbitmq, mongodb) somehow..
return &clabconfig.ClabConfig{
Name: "",
Mgmt: yamlMgmt,
Topology: clabconfig.Topology{
Nodes: yamlNodes,
Links: yamlLinks,
},
}
}
// Converter functions to convert between this and topoPb version of topology
func (n *Node) Convert() *topoPb.Node {
return &topoPb.Node{
Id: n.ID,
Name: n.Name,
}
}
func (p *Port) Convert() *topoPb.Port {
return &topoPb.Port{
Id: p.ID,
Name: p.Name,
}
}
func (l *Link) Convert() *topoPb.Link {
return &topoPb.Link{
Id: l.ID,
Name: l.Name,
SourceNode: l.SourceNode.Convert(),
SourcePort: l.SourcePort.Convert(),
TargetNode: l.TargetNode.Convert(),
TargetPort: l.TargetPort.Convert(),
}
}
...@@ -19,12 +19,9 @@ import ( ...@@ -19,12 +19,9 @@ import (
clabconfig "code.fbi.h-da.de/danet/gosdn/applications/rtdt-manager/clab-config" clabconfig "code.fbi.h-da.de/danet/gosdn/applications/rtdt-manager/clab-config"
"code.fbi.h-da.de/danet/gosdn/applications/rtdt-manager/gosdnutil" "code.fbi.h-da.de/danet/gosdn/applications/rtdt-manager/gosdnutil"
rtdt_auth "code.fbi.h-da.de/danet/gosdn/applications/rtdt-manager/rtdt-auth" rtdt_auth "code.fbi.h-da.de/danet/gosdn/applications/rtdt-manager/rtdt-auth"
rtdt_topology "code.fbi.h-da.de/danet/gosdn/applications/rtdt-manager/rtdt-topology"
"code.fbi.h-da.de/danet/gosdn/applications/rtdt-manager/sdnconfig" "code.fbi.h-da.de/danet/gosdn/applications/rtdt-manager/sdnconfig"
"code.fbi.h-da.de/danet/gosdn/applications/rtdt-manager/util" "code.fbi.h-da.de/danet/gosdn/applications/rtdt-manager/util"
gnmitargetygot "code.fbi.h-da.de/danet/gosdn/applications/rtdt-manager/yang" gnmitargetygot "code.fbi.h-da.de/danet/gosdn/applications/rtdt-manager/yang"
yangparser "code.fbi.h-da.de/danet/gosdn/applications/venv-manager/yang-parser"
"code.fbi.h-da.de/danet/gosdn/models/generated/openconfig"
uuid "github.com/google/uuid" uuid "github.com/google/uuid"
gnmi "github.com/openconfig/gnmi/proto/gnmi" gnmi "github.com/openconfig/gnmi/proto/gnmi"
"github.com/openconfig/ygot/ygot" "github.com/openconfig/ygot/ygot"
...@@ -40,8 +37,7 @@ type VEnv struct { ...@@ -40,8 +37,7 @@ type VEnv struct {
pnd *pnd.PrincipalNetworkDomain pnd *pnd.PrincipalNetworkDomain
clabData *clabconfig.ClabConfig // Represents yaml file that was used to deploy clabData *clabconfig.ClabConfig // Represents yaml file that was used to deploy
sdnConfig *sdnconfig.SdnConfig // Represents json config file for configuration grpc interface sdnConfig *sdnconfig.SdnConfig // Represents json config file for configuration grpc interface
topology *rtdt_topology.Topology clabFilename string // This is the name of the yaml file clabData is based on
clabFilename string // This is the name of the yaml file clabData is based on
StopChan <-chan struct{} StopChan <-chan struct{}
waitGroup *sync.WaitGroup waitGroup *sync.WaitGroup
containerRegistryURL string containerRegistryURL string
...@@ -119,7 +115,6 @@ func NewVEnv(name, clabFilename, user, pass string, wg *sync.WaitGroup, sdnConfi ...@@ -119,7 +115,6 @@ func NewVEnv(name, clabFilename, user, pass string, wg *sync.WaitGroup, sdnConfi
clabData: clabData, clabData: clabData,
clabFilename: clabFilename, clabFilename: clabFilename,
waitGroup: wg, waitGroup: wg,
topology: nil, // set this later
sdnConfig: sdnConfig, sdnConfig: sdnConfig,
containerRegistryURL: "registry.code.fbi.h-da.de/danet/gnmi-target/debian:interface-enabled-test", // TODO: Could let user choose containerRegistryURL: "registry.code.fbi.h-da.de/danet/gnmi-target/debian:interface-enabled-test", // TODO: Could let user choose
} }
...@@ -178,7 +173,7 @@ func (v *VEnv) CreateDevices() error { ...@@ -178,7 +173,7 @@ func (v *VEnv) CreateDevices() error {
// Source: "code.fbi.h-da.de/danet/gosdn/applications/venv-manager/venv-manager/venv-manager.go" // Source: "code.fbi.h-da.de/danet/gosdn/applications/venv-manager/venv-manager/venv-manager.go"
// commit: 0264b698286b6cbb965d743078c681f8af55edf6 // commit: 0264b698286b6cbb965d743078c681f8af55edf6
func (v *VEnv) loadNetworkElementModelPathsIntoGosdn(ctx context.Context, conn *grpc.ClientConn, nodes *[]*rtdt_topology.Node) error { func (v *VEnv) loadNetworkElementModelPathsIntoGosdn(ctx context.Context, conn *grpc.ClientConn, nodes *[]*sdnconfig.Node) error {
networkElementService := networkelement.NewNetworkElementServiceClient(conn) networkElementService := networkelement.NewNetworkElementServiceClient(conn)
paths := [2]string{"/lldp/config/system-description", "/system/state/"} paths := [2]string{"/lldp/config/system-description", "/system/state/"}
...@@ -193,106 +188,10 @@ func (v *VEnv) loadNetworkElementModelPathsIntoGosdn(ctx context.Context, conn * ...@@ -193,106 +188,10 @@ func (v *VEnv) loadNetworkElementModelPathsIntoGosdn(ctx context.Context, conn *
return nil return nil
} }
// Based on getAndAddMoreData() in: "code.fbi.h-da.de/danet/gosdn/applications/venv-manager/venv-manager/venv-manager.go"
// commit: 0264b698286b6cbb965d743078c681f8af55edf6
// What this does: Load yang paths into topo, then iterate over
// nodes and fill data in
func (v *VEnv) ConstructTopology() error {
if v.clabData == nil {
return fmt.Errorf("Error: Trying to construct topology without containerlab file being loaded first")
}
// Either fill topology from clabData or from database?
ctx := v.auth.CreateContextWithAuthorization()
conn := v.conn
var path = "/"
var ygotPath *gnmi.Path
// Create 'root' path to be able to load the whole model from the store.
var err error
ygotPath, err = ygot.StringToPath(path, ygot.StructuredPath)
if err != nil {
return err
}
// just to load model data into goSDN to guaranteed have new data available for get request
err = v.loadNetworkElementModelPathsIntoGosdn(ctx, conn, &v.topology.Nodes)
if err != nil {
return err
}
networkElementService := networkelement.NewNetworkElementServiceClient(conn)
for iterator, node := range v.topology.Nodes {
getNetworkElementResponse, _ := networkElementService.Get(ctx, &networkelement.GetRequest{Mneid: node.ID})
if err != nil {
return err
}
var marshalledYangData openconfig.Device
err = yangparser.Unmarshal([]byte(getNetworkElementResponse.Mne.Model), ygotPath, &marshalledYangData)
if err != nil {
return err
}
mgmntAddress := strings.Split(getNetworkElementResponse.Mne.TransportAddress, ":")
v.topology.Nodes[iterator].MgmtIpv4 = mgmntAddress[0]
v.topology.Nodes[iterator].YangData = marshalledYangData
v.topology.Nodes[iterator].FillAllFields(v.containerRegistryURL)
}
return nil
}
// Create rtdt_topology.Topology from clabconfig.Topology
func (v *VEnv) DeriveTopologyFromClabData() error {
if v.clabData == nil {
return fmt.Errorf("Can't derive topology without clabData\n")
}
v.topology = &rtdt_topology.Topology{}
var topoNodes []*rtdt_topology.Node
// Get all the nodes from clab structure
for nodeName, node := range v.clabData.Topology.Nodes {
topoNode := rtdt_topology.Node{
ID: uuid.NewString(),
Name: nodeName,
Kind: node.Kind,
Image: node.Image,
MgmtIpv4: node.MgmtIPv4,
}
topoNodes = append(topoNodes, &topoNode)
}
v.topology.Nodes = topoNodes
for _, link := range v.clabData.Topology.Links {
if len(link.Endpoints) != 2 {
return fmt.Errorf("Couldn't parse clabData into topology\n")
}
var topoLink = rtdt_topology.Link{}
// determine Node name and port
node0Full := strings.Split(link.Endpoints[0], ":")
node0Name := node0Full[0]
node0Port := node0Full[1]
node1Full := strings.Split(link.Endpoints[1], ":")
node1Name := node1Full[0]
node1Port := node1Full[1]
// find the node that has right name, add links and ports
topoLink.SourceNode = v.topology.GetNodeByName(node0Name)
topoLink.SourcePort = &rtdt_topology.Port{Name: node0Port, ID: uuid.NewString()}
v.topology.Ports = append(v.topology.Ports, topoLink.SourcePort)
topoLink.TargetNode = v.topology.GetNodeByName(node1Name)
topoLink.TargetPort = &rtdt_topology.Port{Name: node1Port, ID: uuid.NewString()}
v.topology.Ports = append(v.topology.Ports, topoLink.TargetPort)
v.topology.Links = append(v.topology.Links, &topoLink)
v.topology.Nodes = topoNodes
}
return nil
}
func (v *VEnv) ApplyRoutes() error { func (v *VEnv) ApplyRoutes() error {
conn := v.auth.GetConn() conn := v.auth.GetConn()
hostIP := int64(1) hostIP := int64(1)
for _, link := range v.topology.Links { for _, link := range v.sdnConfig.Links {
req := topoPb.AddRoutingTableRequest{ req := topoPb.AddRoutingTableRequest{
Timestamp: util.Now(), Timestamp: util.Now(),
RoutingTable: &topoPb.RoutingTable{ RoutingTable: &topoPb.RoutingTable{
...@@ -508,9 +407,6 @@ func (v VEnv) GetAuth() *rtdt_auth.RtdtAuth { ...@@ -508,9 +407,6 @@ func (v VEnv) GetAuth() *rtdt_auth.RtdtAuth {
func (v *VEnv) GetWaitgroup() *sync.WaitGroup { func (v *VEnv) GetWaitgroup() *sync.WaitGroup {
return v.waitGroup return v.waitGroup
} }
func (v *VEnv) GetTopology() *rtdt_topology.Topology {
return v.topology
}
func (v *VEnv) GetSdnConfig() *sdnconfig.SdnConfig { func (v *VEnv) GetSdnConfig() *sdnconfig.SdnConfig {
return v.sdnConfig return v.sdnConfig
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment