Skip to content
Snippets Groups Projects
Commit 4e45930f authored by Neil Schark's avatar Neil Schark
Browse files

added basic import of sDN config (with bugs)

parent 26fba277
Branches
No related tags found
1 merge request!404Enable export and import of SDN configuration
Pipeline #124551 failed
......@@ -16,7 +16,7 @@ type NetworkDomain interface {
Destroy() error
AddSbi(s southbound.SouthboundInterface) error
RemoveSbi(uuid.UUID) error
AddNetworkElement(name string, opts *tpb.TransportOption, sid uuid.UUID) (uuid.UUID, error)
AddNetworkElement(name string, opts *tpb.TransportOption, sid uuid.UUID, networkElement uuid.UUID) (uuid.UUID, error)
GetNetworkElement(identifier string) (networkelement.NetworkElement, error)
RemoveNetworkElement(uuid.UUID) error
UpdateNetworkElement(networkelement.NetworkElement, string) error
......
......@@ -6,14 +6,18 @@ import (
"time"
cmpb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/configurationmanagement"
spb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/southbound"
"code.fbi.h-da.de/danet/gosdn/controller/interfaces/networkdomain"
"code.fbi.h-da.de/danet/gosdn/controller/interfaces/networkelement"
"code.fbi.h-da.de/danet/gosdn/controller/interfaces/southbound"
"code.fbi.h-da.de/danet/gosdn/controller/nucleus"
"code.fbi.h-da.de/danet/gosdn/controller/store"
"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"
tpb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/transport"
"github.com/google/uuid"
)
......@@ -30,7 +34,8 @@ type ConfigurationManagementServer struct {
func NewConfigurationManagementServer(
pndStore networkdomain.PndStore,
topologyService topology.Service,
nodeService nodes.Service, portService ports.Service,
nodeService nodes.Service,
portService ports.Service,
) *ConfigurationManagementServer {
return &ConfigurationManagementServer{
pndStore: pndStore,
......@@ -39,8 +44,8 @@ func NewConfigurationManagementServer(
portService: portService}
}
// SDNConfig is used to aprse the SDNConfig into JSON.
type SDNConfig struct {
// sdnConfig is used to parse the sdnConfig into JSON.
type sdnConfig struct {
PndID string `json:"pndID"`
Nodes []nodes.Node `json:"nodes"`
Ports []ports.Port `json:"ports"`
......@@ -49,9 +54,19 @@ type SDNConfig struct {
NetworkElements []networkelement.NetworkElement `json:"networkelements"`
}
// loadedSDNConfig is used to parse the stringified JSON sdnConfig into objects.
type loadedSDNConfig struct {
PndID string `json:"pndID"`
Nodes []nodes.Node `json:"nodes"`
Ports []ports.Port `json:"ports"`
Links []links.Link `json:"links"`
Sbis []southbound.LoadedSbi `json:"sbis"`
NetworkElements []networkelement.LoadedNetworkElement `json:"networkelements"`
}
// ExportSDNConfig returns the SDN configuration.
func (c ConfigurationManagementServer) ExportSDNConfig(ctx context.Context, request *cmpb.ExportSDNConfigRequest) (*cmpb.ExportSDNConfigResponse, error) {
var sdnConfig = SDNConfig{}
var sdnConfig = sdnConfig{}
sdnConfig.PndID = request.Pid
pndUUID := uuid.MustParse(request.Pid)
......@@ -91,7 +106,120 @@ func (c ConfigurationManagementServer) ExportSDNConfig(ctx context.Context, requ
}
// ImportSDNConfig receives an SDN configuration and imports it.
func (s *NetworkElementServer) ImportSDNConfig(ctx context.Context, request *cmpb.ImportSDNConfigRequest) (*cmpb.ImportSDNConfigResponse, error) {
func (c ConfigurationManagementServer) ImportSDNConfig(ctx context.Context, request *cmpb.ImportSDNConfigRequest) (*cmpb.ImportSDNConfigResponse, error) {
var sdnConfig = loadedSDNConfig{}
err := json.Unmarshal([]byte(request.SdnConfigData), &sdnConfig)
if err != nil {
return nil, err
}
//TODO: Clear DB
//Create all elements
pndUUID := uuid.MustParse(request.Pid)
pnd, err := c.pndStore.Get(store.Query{ID: pndUUID})
if err != nil {
return nil, err
}
for _, inputSBI := range sdnConfig.Sbis {
sbi, err := nucleus.NewSBI(inputSBI.Type, uuid.MustParse(inputSBI.ID))
if err != nil {
return nil, err
}
err = pnd.AddSbi(sbi)
if err != nil {
return nil, err
}
}
for _, inputNode := range sdnConfig.Nodes {
node := nodes.Node{
ID: inputNode.ID,
Name: inputNode.Name,
}
_, err = c.nodeService.EnsureExists(node)
if err != nil {
return nil, err
}
}
for _, inputPort := range sdnConfig.Ports {
port := ports.Port{
ID: inputPort.ID,
Name: inputPort.Name,
Configuration: inputPort.Configuration,
}
_, err = c.portService.EnsureExists(port)
if err != nil {
return nil, err
}
}
for _, inputPort := range sdnConfig.Links {
sourceNode, err := c.nodeService.Get(store.Query{ID: inputPort.SourceNode.ID})
if err != nil {
return nil, err
}
targetNode, err := c.nodeService.Get(store.Query{ID: inputPort.TargetNode.ID})
if err != nil {
return nil, err
}
sourcePort, err := c.portService.Get(store.Query{ID: inputPort.SourcePort.ID})
if err != nil {
return nil, err
}
targetPort, err := c.portService.Get(store.Query{ID: inputPort.TargetPort.ID})
if err != nil {
return nil, err
}
link := links.Link{
ID: inputPort.ID,
Name: inputPort.Name,
SourceNode: sourceNode,
TargetNode: targetNode,
SourcePort: sourcePort,
TargetPort: targetPort,
}
err = c.topologyService.AddLink(link)
if err != nil {
return nil, err
}
}
for _, inputNetworkElement := range sdnConfig.NetworkElements {
transportOption := tpb.TransportOption{
Address: inputNetworkElement.TransportAddress,
Username: inputNetworkElement.TransportUsername,
Password: inputNetworkElement.TransportPassword,
TransportOption: &tpb.TransportOption_GnmiTransportOption{
GnmiTransportOption: &tpb.GnmiTransportOption{},
},
Type: spb.Type_TYPE_OPENCONFIG,
}
_, err := pnd.AddNetworkElement(
inputNetworkElement.Name,
&transportOption,
uuid.MustParse(inputNetworkElement.SBI),
uuid.MustParse(inputNetworkElement.ID),
)
if err != nil {
return nil, err
}
networkelement, err := pnd.GetNetworkElement(inputNetworkElement.ID)
if err != nil {
return nil, err
}
err = pnd.UpdateNetworkElement(networkelement, inputNetworkElement.Model)
if err != nil {
return nil, err
}
}
return &cmpb.ImportSDNConfigResponse{
Timestamp: time.Now().UnixNano()}, nil
}
......@@ -36,6 +36,7 @@ func (s *NetworkElementServer) Add(ctx context.Context, request *mnepb.AddNetwor
request.NetworkElement.NetworkElementName,
request.NetworkElement.TransportOption,
sbiID,
uuid.Nil,
)
if err != nil {
return nil, status.Errorf(codes.Aborted, "%v", err)
......
......@@ -497,7 +497,7 @@ func (p PndServer) SetMneList(ctx context.Context, request *ppb.SetMneListReques
log.Error(err)
return nil, status.Errorf(codes.Aborted, "%v", err)
}
mneID, err := pnd.AddNetworkElement(r.MneName, r.TransportOption, sid)
mneID, err := pnd.AddNetworkElement(r.MneName, r.TransportOption, sid, uuid.Nil)
if err != nil {
log.Error(err)
return nil, status.Errorf(codes.Aborted, "%v", err)
......
......@@ -245,8 +245,8 @@ func (pnd *pndImplementation) RemoveSbi(sid uuid.UUID) error {
return pnd.removeSbi(sid)
}
// AddNetworkElement adds a new network element to the PND.
func (pnd *pndImplementation) AddNetworkElement(name string, opt *tpb.TransportOption, sid uuid.UUID) (uuid.UUID, error) {
// AddNetworkElement adds a new network element to the PND. The UUID for the networkElementID is optional and should normally be empty
func (pnd *pndImplementation) AddNetworkElement(name string, opt *tpb.TransportOption, sid uuid.UUID, networkElementID uuid.UUID) (uuid.UUID, error) {
labels := prometheus.Labels{"type": opt.Type.String()}
start := metrics.StartHook(labels, networkElementCreationsTotal)
defer metrics.FinishHook(labels, start, networkElementCreationDurationSecondsTotal, networkElementCreationDurationSeconds)
......@@ -269,7 +269,7 @@ func (pnd *pndImplementation) AddNetworkElement(name string, opt *tpb.TransportO
}
}
mne, err := NewNetworkElement(name, uuid.Nil, opt, sbi, conflict.Metadata{ResourceVersion: 0})
mne, err := NewNetworkElement(name, networkElementID, opt, sbi, conflict.Metadata{ResourceVersion: 0})
if err != nil {
return uuid.Nil, err
}
......
......@@ -120,7 +120,7 @@ func Test_pndImplementation_AddNetworkElement(t *testing.T) {
t.Error(err)
}
_, err := pnd.AddNetworkElement(tt.args.name, tt.args.opts, defaultSbiID)
_, err := pnd.AddNetworkElement(tt.args.name, tt.args.opts, defaultSbiID, uuid.Nil)
if (err != nil) != tt.wantErr {
t.Errorf("AddNetworkElement() error = %v, wantErr %v", err, tt.wantErr)
}
......@@ -469,11 +469,11 @@ func Test_pndImplementation_RemoveSbiWithAssociatedNetworkElements(t *testing.T)
if err := pnd.addSbi(&OpenConfig{id: defaultSbiID}); err != nil {
t.Error(err)
}
_, err = pnd.AddNetworkElement("associatedNetworkElement", opts, tt.args.id)
_, err = pnd.AddNetworkElement("associatedNetworkElement", opts, tt.args.id, uuid.Nil)
if err != nil {
t.Error(err)
}
_, err = pnd.AddNetworkElement("associatedNetworkElement2", opts, tt.args.id)
_, err = pnd.AddNetworkElement("associatedNetworkElement2", opts, tt.args.id, uuid.Nil)
if err != nil {
t.Error(err)
}
......@@ -482,7 +482,7 @@ func Test_pndImplementation_RemoveSbiWithAssociatedNetworkElements(t *testing.T)
if err := pnd.addSbi(&OpenConfig{id: newID}); err != nil {
t.Error(err)
}
_, err := pnd.AddNetworkElement("associatedNetworkElement2", opts, newID)
_, err := pnd.AddNetworkElement("associatedNetworkElement2", opts, newID, uuid.Nil)
if err != nil {
t.Error(err)
}
......@@ -780,7 +780,7 @@ func Test_pndImplementation_ChangeMNE(t *testing.T) {
if err := pnd.addSbi(&OpenConfig{id: defaultSbiID}); err != nil {
t.Error(err)
}
_, err := pnd.AddNetworkElement("testnetworkElement", opts, defaultSbiID)
_, err := pnd.AddNetworkElement("testnetworkElement", opts, defaultSbiID, uuid.Nil)
if err != nil {
t.Error(err)
return
......
......@@ -186,7 +186,7 @@ func TestGnmi_SetValidIntegration(t *testing.T) {
t.Error(err)
return
}
_, err = pnd.AddNetworkElement("test", opt, sbi.ID())
_, err = pnd.AddNetworkElement("test", opt, sbi.ID(), uuid.Nil)
if err != nil {
t.Error(err)
return
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment