@@ -121,85 +121,14 @@ func (t *ncTarget) Set(ctx context.Context, req *sdcpb.SetDataRequest) (*sdcpb.S
121121 if ! t .connected {
122122 return nil , fmt .Errorf ("not connected" )
123123 }
124- xcbCfg := & netconf.XMLConfigBuilderOpts {
125- HonorNamespace : t .sbiConfig .IncludeNS ,
126- OperationWithNamespace : t .sbiConfig .OperationWithNamespace ,
127- UseOperationRemove : t .sbiConfig .UseOperationRemove ,
128- }
129- xmlCBDelete := netconf .NewXMLConfigBuilder (t .schemaClient , t .schema , xcbCfg )
130-
131- // iterate over the delete array
132- for _ , p := range req .GetDelete () {
133- xmlCBDelete .Delete (ctx , p )
134- }
135-
136- // iterate over the replace array
137- // ATTENTION: This is not implemented intentionally, since it is expected,
138- // that the datastore will only come up with deletes and updates.
139- // actual replaces will be resolved to deletes and updates by the datastore
140- // also replaces would only really make sense with jsonIETF encoding, where
141- // an entire branch is replaces, on single values this is covered via an
142- // update.
143- //
144- // for _, r := range req.Replace {
145- // }
146- //
147-
148- xmlCBAdd := netconf .NewXMLConfigBuilder (t .schemaClient , t .schema , xcbCfg )
149-
150- // iterate over the update array
151- for _ , u := range req .Update {
152- xmlCBAdd .AddValue (ctx , u .Path , u .Value )
124+ switch t .sbiConfig .CommitDatastore {
125+ case "running" :
126+ return t .setRunning (ctx , req )
127+ case "candidate" :
128+ return t .setCandidate (ctx , req )
153129 }
154-
155- // first apply the deletes before the adds
156- for _ , xml := range []* netconf.XMLConfigBuilder {xmlCBDelete , xmlCBAdd } {
157- // finally retrieve the xml config as string
158- xdoc , err := xml .GetDoc ()
159- if err != nil {
160- return nil , err
161- }
162-
163- // if there was no data in the xml document, continue
164- if len (xdoc ) == 0 {
165- continue
166- }
167-
168- log .Debugf ("datastore %s XML:\n %s\n " , t .name , xdoc )
169-
170- // edit the config
171- _ , err = t .driver .EditConfig ("candidate" , xdoc )
172- if err != nil {
173- log .Errorf ("datastore %s failed edit-config: %v" , t .name , err )
174- if strings .Contains (err .Error (), "EOF" ) {
175- t .Close ()
176- t .connected = false
177- go t .reconnect ()
178- return nil , err
179- }
180- err2 := t .driver .Discard ()
181- if err != nil {
182- // log failed discard
183- log .Errorf ("failed with %v while discarding pending changes after error %v" , err2 , err )
184- }
185- return nil , err
186- }
187-
188- }
189- log .Infof ("datastore %s: committing changes on target" , t .name )
190- // commit the config
191- err := t .driver .Commit ()
192- if err != nil {
193- if strings .Contains (err .Error (), "EOF" ) {
194- t .Close ()
195- t .connected = false
196- go t .reconnect ()
197- }
198- return nil , err
199- }
200- return & sdcpb.SetDataResponse {
201- Timestamp : time .Now ().UnixNano (),
202- }, nil
130+ // should not get here if the config validation happened.
131+ return nil , fmt .Errorf ("unknown commit-datastore: %s" , t .sbiConfig .CommitDatastore )
203132}
204133
205134func (t * ncTarget ) Status () string {
@@ -326,3 +255,122 @@ func (t *ncTarget) reconnect() {
326255 return
327256 }
328257}
258+
259+ func (t * ncTarget ) setRunning (ctx context.Context , req * sdcpb.SetDataRequest ) (* sdcpb.SetDataResponse , error ) {
260+ xcbCfg := & netconf.XMLConfigBuilderOpts {
261+ HonorNamespace : t .sbiConfig .IncludeNS ,
262+ OperationWithNamespace : t .sbiConfig .OperationWithNamespace ,
263+ UseOperationRemove : t .sbiConfig .UseOperationRemove ,
264+ }
265+
266+ xmlBuilder := netconf .NewXMLConfigBuilder (t .schemaClient , t .schema , xcbCfg )
267+
268+ // iterate over the update array
269+ for _ , u := range req .GetUpdate () {
270+ xmlBuilder .AddValue (ctx , u .Path , u .Value )
271+ }
272+ // iterate over the delete array
273+ for _ , p := range req .GetDelete () {
274+ xmlBuilder .Delete (ctx , p )
275+ }
276+
277+ xdoc , err := xmlBuilder .GetDoc ()
278+ if err != nil {
279+ return nil , err
280+ }
281+
282+ // if there was no data in the xml document, return
283+ if len (xdoc ) == 0 {
284+ return & sdcpb.SetDataResponse {
285+ Timestamp : time .Now ().UnixNano (),
286+ }, nil
287+ }
288+
289+ log .Debugf ("datastore %s XML:\n %s\n " , t .name , xdoc )
290+
291+ // edit the config
292+ _ , err = t .driver .EditConfig ("running" , xdoc )
293+ if err != nil {
294+ log .Errorf ("datastore %s failed edit-config: %v" , t .name , err )
295+ if strings .Contains (err .Error (), "EOF" ) {
296+ t .Close ()
297+ t .connected = false
298+ go t .reconnect ()
299+ return nil , err
300+ }
301+ return nil , err
302+ }
303+ return & sdcpb.SetDataResponse {
304+ Timestamp : time .Now ().UnixNano (),
305+ }, nil
306+ }
307+
308+ func (t * ncTarget ) setCandidate (ctx context.Context , req * sdcpb.SetDataRequest ) (* sdcpb.SetDataResponse , error ) {
309+ xcbCfg := & netconf.XMLConfigBuilderOpts {
310+ HonorNamespace : t .sbiConfig .IncludeNS ,
311+ OperationWithNamespace : t .sbiConfig .OperationWithNamespace ,
312+ UseOperationRemove : t .sbiConfig .UseOperationRemove ,
313+ }
314+ xmlCBDelete := netconf .NewXMLConfigBuilder (t .schemaClient , t .schema , xcbCfg )
315+
316+ // iterate over the delete array
317+ for _ , p := range req .GetDelete () {
318+ xmlCBDelete .Delete (ctx , p )
319+ }
320+
321+ xmlCBAdd := netconf .NewXMLConfigBuilder (t .schemaClient , t .schema , xcbCfg )
322+
323+ // iterate over the update array
324+ for _ , u := range req .Update {
325+ xmlCBAdd .AddValue (ctx , u .Path , u .Value )
326+ }
327+
328+ // first apply the deletes before the adds
329+ for _ , xml := range []* netconf.XMLConfigBuilder {xmlCBDelete , xmlCBAdd } {
330+ // finally retrieve the xml config as string
331+ xdoc , err := xml .GetDoc ()
332+ if err != nil {
333+ return nil , err
334+ }
335+
336+ // if there was no data in the xml document, continue
337+ if len (xdoc ) == 0 {
338+ continue
339+ }
340+
341+ log .Debugf ("datastore %s XML:\n %s\n " , t .name , xdoc )
342+
343+ // edit the config
344+ _ , err = t .driver .EditConfig ("candidate" , xdoc )
345+ if err != nil {
346+ log .Errorf ("datastore %s failed edit-config: %v" , t .name , err )
347+ if strings .Contains (err .Error (), "EOF" ) {
348+ t .Close ()
349+ t .connected = false
350+ go t .reconnect ()
351+ return nil , err
352+ }
353+ err2 := t .driver .Discard ()
354+ if err != nil {
355+ // log failed discard
356+ log .Errorf ("failed with %v while discarding pending changes after error %v" , err2 , err )
357+ }
358+ return nil , err
359+ }
360+
361+ }
362+ log .Infof ("datastore %s: committing changes on target" , t .name )
363+ // commit the config
364+ err := t .driver .Commit ()
365+ if err != nil {
366+ if strings .Contains (err .Error (), "EOF" ) {
367+ t .Close ()
368+ t .connected = false
369+ go t .reconnect ()
370+ }
371+ return nil , err
372+ }
373+ return & sdcpb.SetDataResponse {
374+ Timestamp : time .Now ().UnixNano (),
375+ }, nil
376+ }
0 commit comments