Skip to content
Snippets Groups Projects
Commit 89fe7798 authored by André Sterba's avatar André Sterba
Browse files

Add topology related northbound services

parent 3bb6f855
No related branches found
No related tags found
5 merge requests!376Add additional example application hostname-checker,!349Northbound refactoring to implement NIB concept for devices,!343Add basic application framework and example application to show interaction between events an NBI,!339Create basic venv-manager for use with arista,!324Provide prototype implementation for topology handling
This commit is part of merge request !343. Comments created here will be created in the context of that merge request.
......@@ -4,6 +4,9 @@ import (
"code.fbi.h-da.de/danet/gosdn/controller/interfaces/networkdomain"
"code.fbi.h-da.de/danet/gosdn/controller/interfaces/rbac"
"code.fbi.h-da.de/danet/gosdn/controller/metrics"
"code.fbi.h-da.de/danet/gosdn/controller/topology"
"code.fbi.h-da.de/danet/gosdn/controller/topology/nodes"
"code.fbi.h-da.de/danet/gosdn/controller/topology/ports"
"github.com/prometheus/client_golang/prometheus"
log "github.com/sirupsen/logrus"
"google.golang.org/grpc/codes"
......@@ -13,32 +16,48 @@ import (
var pndc networkdomain.PndStore
var userService rbac.UserService
var roleService rbac.RoleService
var topologyService topology.Service
var nodeService nodes.Service
var portService ports.Service
// NorthboundInterface is the representation of the
// gRPC services used provided.
type NorthboundInterface struct {
Pnd *pndServer
Core *core
Csbi *csbi
Sbi *sbiServer
Auth *Auth
User *User
Role *Role
Pnd *pndServer
Core *core
Csbi *csbi
Sbi *sbiServer
Auth *Auth
User *User
Role *Role
Topology *Topology
}
// NewNBI receives a PndStore and returns a new gRPC *NorthboundInterface
func NewNBI(pnds networkdomain.PndStore, users rbac.UserService, roles rbac.RoleService) *NorthboundInterface {
func NewNBI(
pnds networkdomain.PndStore,
users rbac.UserService,
roles rbac.RoleService,
topology topology.Service,
node nodes.Service,
port ports.Service,
) *NorthboundInterface {
pndc = pnds
userService = users
roleService = roles
topologyService = topology
nodeService = node
portService = port
return &NorthboundInterface{
Pnd: &pndServer{},
Core: &core{},
Csbi: &csbi{},
Sbi: &sbiServer{},
Auth: &Auth{},
User: &User{},
Role: &Role{},
Pnd: &pndServer{},
Core: &core{},
Csbi: &csbi{},
Sbi: &sbiServer{},
Auth: &Auth{},
User: &User{},
Role: &Role{},
Topology: &Topology{},
}
}
......
package server
import (
"context"
"time"
apb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/topology"
"code.fbi.h-da.de/danet/gosdn/controller/topology"
"code.fbi.h-da.de/danet/gosdn/controller/topology/links"
"code.fbi.h-da.de/danet/gosdn/controller/topology/nodes"
"code.fbi.h-da.de/danet/gosdn/controller/topology/ports"
"github.com/google/uuid"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
)
// Topology holds a topologyService and represents a TopologyServiceServer.
type Topology struct {
apb.UnimplementedTopologyServiceServer
topologyService topology.Service
}
// NewTopologyrServer receives a topologyService and returns a new TopologyServer.
func NewTopologyrServer(service topology.Service) *Topology {
return &Topology{
topologyService: service,
}
}
// AddLink adds a new link to the topology
func (t Topology) AddLink(ctx context.Context, request *apb.AddLinkRequest) (*apb.AddLinkResponse, error) {
sourceNode, sourcePort, err := t.ensureNodeAndPortExists(request.Link.SourceNode, request.Link.SourcePort)
if err != nil {
return nil, status.Errorf(codes.Aborted, "%v", err)
}
targetNode, targetPort, err := t.ensureNodeAndPortExists(request.Link.TargetNode, request.Link.TargetPort)
if err != nil {
return nil, status.Errorf(codes.Aborted, "%v", err)
}
link := links.Link{
ID: uuid.New(),
Name: request.Link.Name,
SourceNode: sourceNode,
SourcePort: sourcePort,
TargetNode: targetNode,
TargetPort: targetPort,
}
err = topologyService.AddLink(link)
if err != nil {
return nil, status.Errorf(codes.Aborted, "%v", err)
}
return &apb.AddLinkResponse{
Timestamp: time.Now().UnixNano(),
Status: apb.Status_STATUS_OK,
}, nil
}
// GetTopology returns the current topology in the form of all links
func (t Topology) GetTopology(ctx context.Context, request *apb.GetTopologyRequest) (*apb.GetTopologyResponse, error) {
topo, err := topologyService.GetAll()
if err != nil {
return nil, status.Errorf(codes.Aborted, "%v", err)
}
topology := &apb.Topology{}
for _, link := range topo {
topology.Links = append(topology.Links, &apb.Link{
Id: link.ID.String(),
Name: link.Name,
SourceNode: &apb.Node{
Id: link.SourceNode.ID.String(),
Name: link.SourceNode.Name,
},
SourcePort: &apb.Port{
Id: link.SourcePort.ID.String(),
},
TargetNode: &apb.Node{
Id: link.TargetNode.ID.String(),
Name: link.TargetNode.Name,
},
TargetPort: &apb.Port{
Id: link.TargetPort.ID.String(),
},
})
}
return &apb.GetTopologyResponse{
Timestamp: time.Now().UnixNano(),
Status: apb.Status_STATUS_OK,
Toplogy: topology,
}, nil
}
func (t Topology) ensureNodeAndPortExists(incomingNode *apb.Node, incomingPort *apb.Port) (nodes.Node, ports.Port, error) {
node, err := nodeService.EnsureExists(
nodes.Node{
ID: getExistingOrCreateNewUUIDFromString(incomingNode.Id),
},
)
if err != nil {
return node, ports.Port{}, status.Errorf(codes.Aborted, "%v", err)
}
port, err := portService.EnsureExists(
ports.Port{
ID: getExistingOrCreateNewUUIDFromString(incomingPort.Id),
},
)
if err != nil {
return nodes.Node{}, port, status.Errorf(codes.Aborted, "%v", err)
}
return node, port, nil
}
func getExistingOrCreateNewUUIDFromString(id string) uuid.UUID {
parsedID, err := uuid.Parse(id)
if err != nil {
return uuid.Nil
}
return parsedID
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment