From 39c5e73a169bd2c6e7a6efb7d361293c44c23cbc Mon Sep 17 00:00:00 2001
From: Malte Bauch <malte.bauch@stud.h-da.de>
Date: Mon, 17 Apr 2023 16:10:21 +0200
Subject: [PATCH] Correctly init the goStruct within the plugins ValidateChange
 method

The nodes along a path of the copied model (which is a copy of the
underlying goStruct of the plugin) within the ValidateChange method of a
plugin were not properly initialized.

This means if a JSON string was provided that contained a node that was
not initialized an error was thrown. But since the
`ytypes.IgnoreExtraFields` option was set, the node was just ignored and
no error was thrown.

This change correctly initializes the node at the given path and removes
the `ytypes.IgnoreExtraFields` option.
---
 .../configs/containerlab-gosdn.toml.example   |  2 --
 .../configs/development-gosdn.toml.example    |  2 --
 plugins/sdk/deviceModel.go                    | 22 +++++++++++++++----
 3 files changed, 18 insertions(+), 8 deletions(-)

diff --git a/controller/configs/containerlab-gosdn.toml.example b/controller/configs/containerlab-gosdn.toml.example
index 22357f144..70744a9d0 100644
--- a/controller/configs/containerlab-gosdn.toml.example
+++ b/controller/configs/containerlab-gosdn.toml.example
@@ -1,6 +1,4 @@
 basepnduuid = "5f20f34b-cbd0-4511-9ddc-c50cf6a3b49d"
-basesouthboundtype = 1
-basesouthbounduuid = "ca29311a-3b17-4385-96f8-515b602a97ac"
 csbi-orchestrator = "clab-gosdn_csbi_arista_base-csbi-orchestrator:55056"
 plugin-registry = "clab-gosdn_csbi_arista_base-plugin-registry:55057"
 help = false
diff --git a/controller/configs/development-gosdn.toml.example b/controller/configs/development-gosdn.toml.example
index 3fb884015..beaf1b2c0 100644
--- a/controller/configs/development-gosdn.toml.example
+++ b/controller/configs/development-gosdn.toml.example
@@ -4,8 +4,6 @@ amqpport = '5672'
 amqpprefix = 'amqp://'
 amqpuser = 'guest'
 basepnduuid = '5f20f34b-cbd0-4511-9ddc-c50cf6a3b49d'
-basesouthboundtype = 1
-basesouthbounduuid = 'ca29311a-3b17-4385-96f8-515b602a97ac'
 cli_pnd = '0455b241-5863-4660-ad15-dfde7617738e'
 cli_sbi = 'a249f2d2-f7da-481d-8a99-b7f11471e0af'
 config = '/home/neil/code/gosdn/controller/configs/development-gosdn.toml'
diff --git a/plugins/sdk/deviceModel.go b/plugins/sdk/deviceModel.go
index 1e920b4e7..2ef5e8c84 100644
--- a/plugins/sdk/deviceModel.go
+++ b/plugins/sdk/deviceModel.go
@@ -197,14 +197,28 @@ func (d *DeviceModel) ValidateChange(operation mnepb.ApiOperation, path *gpb.Pat
 
 	switch operation {
 	case mnepb.ApiOperation_API_OPERATION_UPDATE, mnepb.ApiOperation_API_OPERATION_REPLACE:
-		_, entry, err := ytypes.GetOrCreateNode(d.schema.RootSchema(), modelCopy, path)
+		createdNode, entry, err := ytypes.GetOrCreateNode(d.schema.RootSchema(), modelCopy, path)
 		if err != nil {
 			return nil, err
 		}
 
+		validatedCreatedNode, ok := createdNode.(ygot.ValidatedGoStruct)
+		if !ok {
+			return nil, &customerrs.InvalidTypeAssertionError{
+				Value: createdNode,
+				Type:  (*ygot.ValidatedGoStruct)(nil),
+			}
+		}
+
 		if entry.IsDir() {
-			opts := []ytypes.UnmarshalOpt{&ytypes.IgnoreExtraFields{}}
-			if err := d.generatedUnmarshalFn(value, modelCopy, opts...); err != nil {
+			opts := []ytypes.UnmarshalOpt{
+				// NOTE: I think we should not ignore extra fields if we want
+				// to validate a specific change. The input for a valid change
+				// should be correct to be valid.
+				//
+				//&ytypes.IgnoreExtraFields{}
+			}
+			if err := d.generatedUnmarshalFn(value, validatedCreatedNode, opts...); err != nil {
 				return nil, err
 			}
 		} else if entry.IsLeaf() {
@@ -213,7 +227,7 @@ func (d *DeviceModel) ValidateChange(operation mnepb.ApiOperation, path *gpb.Pat
 				return nil, err
 			}
 			opts := []ytypes.SetNodeOpt{&ytypes.InitMissingElements{}, &ytypes.TolerateJSONInconsistencies{}}
-			if err := ytypes.SetNode(d.schema.RootSchema(), modelCopy, path, typedValue, opts...); err != nil {
+			if err := ytypes.SetNode(d.schema.RootSchema(), validatedCreatedNode, path, typedValue, opts...); err != nil {
 				return nil, err
 			}
 		}
-- 
GitLab