From f06a4debff176c9ab7b3335ac28935b06754ceb1 Mon Sep 17 00:00:00 2001
From: Malte Bauch <malte.bauch@stud.h-da.de>
Date: Wed, 22 Nov 2023 11:05:57 +0000
Subject: [PATCH] Resolve "Failed network element creation leads to the return
 of false error messages"

See merge request danet/gosdn!618
---
 .../northbound/server/networkElement.go       | 42 ++++++++-----------
 1 file changed, 18 insertions(+), 24 deletions(-)

diff --git a/controller/northbound/server/networkElement.go b/controller/northbound/server/networkElement.go
index b3104644f..caa807b55 100644
--- a/controller/northbound/server/networkElement.go
+++ b/controller/northbound/server/networkElement.go
@@ -24,6 +24,7 @@ import (
 	aGNMI "code.fbi.h-da.de/danet/gosdn/forks/goarista/gnmi"
 	"github.com/bufbuild/protovalidate-go"
 	"github.com/google/uuid"
+	"github.com/hashicorp/go-multierror"
 	"github.com/openconfig/gnmi/proto/gnmi"
 
 	"github.com/openconfig/ygot/ygot"
@@ -568,8 +569,18 @@ func (n *NetworkElementServer) AddList(ctx context.Context, request *mnepb.AddLi
 	}, nil
 }
 
-func (n *NetworkElementServer) addMne(ctx context.Context, name string, opt *tpb.TransportOption, requestPluginFunc func(uuid.UUID) (plugin.Plugin, error), pluginID uuid.UUID, pndID uuid.UUID, optionalNetworkElementID ...uuid.UUID) (uuid.UUID, error) {
-	var err error
+func (n *NetworkElementServer) addMne(ctx context.Context, name string, opt *tpb.TransportOption, requestPluginFunc func(uuid.UUID) (plugin.Plugin, error), pluginID uuid.UUID, pndID uuid.UUID, optionalNetworkElementID ...uuid.UUID) (mneId uuid.UUID, err error) {
+	var plugin plugin.Plugin
+	var mne networkelement.NetworkElement
+
+	defer func() {
+		if err != nil && plugin != nil {
+			// clean up plugin
+			if pErr := plugin.Remove(); pErr != nil {
+				err = multierror.Append(err, pErr)
+			}
+		}
+	}()
 
 	networkElementID := uuid.Nil
 	if len(optionalNetworkElementID) > 0 {
@@ -580,38 +591,29 @@ func (n *NetworkElementServer) addMne(ctx context.Context, name string, opt *tpb
 		requestPluginFunc = n.pluginService.RequestPlugin
 	}
 
-	plugin, err := requestPluginFunc(pluginID)
+	plugin, err = requestPluginFunc(pluginID)
 	if err != nil {
 		return uuid.Nil, err
 	}
 
-	mne, err := nucleus.NewNetworkElement(name, networkElementID, opt, pndID, plugin, conflict.Metadata{ResourceVersion: 0})
+	mne, err = nucleus.NewNetworkElement(name, networkElementID, opt, pndID, plugin, conflict.Metadata{ResourceVersion: 0})
 	if err != nil {
-		if pluginRmErr := plugin.Remove(); err != nil {
-			return uuid.Nil, pluginRmErr
-		}
 		return uuid.Nil, err
 	}
 
 	if mne.IsTransportValid() {
-		err := n.initialNetworkElementRootPathRequest(ctx, mne, plugin)
+		err = n.initialNetworkElementRootPathRequest(ctx, mne, plugin)
 		if err != nil {
 			return uuid.Nil, err
 		}
 
 		err = n.mneService.Add(mne)
 		if err != nil {
-			if pluginRmErr := plugin.Remove(); err != nil {
-				return uuid.Nil, pluginRmErr
-			}
 			return uuid.Nil, err
 		}
 
 		err = n.pluginService.Add(plugin)
 		if err != nil {
-			if pluginRmErr := plugin.Remove(); err != nil {
-				return uuid.Nil, pluginRmErr
-			}
 			if err := n.mneService.Delete(mne); err != nil {
 				return uuid.Nil, err
 			}
@@ -620,10 +622,8 @@ func (n *NetworkElementServer) addMne(ctx context.Context, name string, opt *tpb
 
 		n.networkElementWatchter.SubscribeToNetworkElement(mne, config.GetGnmiSubscriptionPaths(), nil)
 	} else {
-		if pluginRmErr := plugin.Remove(); err != nil {
-			return uuid.Nil, pluginRmErr
-		}
-		return uuid.Nil, fmt.Errorf("invalid transport data provided")
+		err = fmt.Errorf("invalid transport data provided")
+		return uuid.Nil, err
 	}
 
 	return mne.ID(), nil
@@ -632,17 +632,11 @@ func (n *NetworkElementServer) addMne(ctx context.Context, name string, opt *tpb
 func (n *NetworkElementServer) initialNetworkElementRootPathRequest(ctx context.Context, mne networkelement.NetworkElement, plugin plugin.Plugin) error {
 	resp, err := n.getPath(ctx, mne, "/")
 	if err != nil {
-		if pluginRmErr := plugin.Remove(); err != nil {
-			return pluginRmErr
-		}
 		return err
 	}
 
 	err = mne.ProcessResponse(resp)
 	if err != nil {
-		if pluginRmErr := plugin.Remove(); err != nil {
-			return pluginRmErr
-		}
 		return err
 	}
 	return nil
-- 
GitLab