Subject: RE: Second Example in section 7.2 of netconf-proto

From: "Sharon Chisholm" <[email-masked]>
Date: Thu, 30 Mar 2006 08:14:15 -0500

hi

Did we agree we were adding this clarifying text as a note to the RFC
editor?

Also, another clarifying question. If I have a record with a key and I
send it a replace command, are the non-key fields not included in the
replace snippet deleted or just not modified? I've seen one
implementations that does the latter, and I think based on the following
excerpt it is what is expected, but I wanted to confirm.

"Unlike a <copy-config> operation, which replaces
the entire target configuration, only the configuration
actually present in the config parameter is affected."

<bowler>
<name>Fred</name>
<location>Bedrock</location>
<status>single</status>
</bowler>

+

<bowler operation="replace">
<name>Fred</name>
<status>married</status>
</bowler>

=

<bowler>
<name>Fred</name>
<location>Bedrock</location>
<status>married</status>
</bowler>

Sharon

-----Original Message-----
From: Andy Bierman [mailto:[email-masked]] 
Sent: Thursday, March 09, 2006 9:50 AM
To: Chisholm, Sharon [CAR:ZZ00:EXCH]
Cc: Netconf (E-mail)
Subject: Re: Second Example in section 7.2 of netconf-proto

Sharon Chisholm wrote:
> hi
>
> In section 7.2, the second example indicates it will add an interface,

> but uses the operator of replace. The definition of replace does not 
> actually say that if the entry does not exist, it is created. Should 
> it, or should the operator of create be used instead in this example?
>
> I also wonder with these examples if there is an implicit assumption 
> that the key is name and this somehow defines whether something exists

> or not?

How about some text that says:

"The manager must understand the data model being used.
In these examples, the manager knows a priori that the 'name' element is
used for instance identification to distinguish multiple instances of
the 'interface' element.

<clip>

--
to unsubscribe send a message to [email-masked] with
the word 'unsubscribe' in a single line as the message text body.
archive: <http://ops.ietf.org/lists/netconf/>

---

From: Martin Bjorklund <[email-masked]>
Date: Thu, 30 Mar 2006 18:20:28 +0200 (CEST)

> <location>Bedrock</location>

Ok, I'll share my interpretation.

I think it should delete the non-present part (provided they are
optional of course).  What you're doing above would be the result of a
"merge" operation.

This also hold if you have more levels in your config:

<bowler>
  <name>Fred</name>
  <status>married</status>
  <cars>
    <car>
      <id>ABC-123</id>
      <make>volvo</make>
    </car>
  </cars>
</bowler>

+

  <cars>
    <car>
      <id>DEF-456</id>
      <make>saab</make>
    </car>
  </cars>
</bowler>

=

  <cars>
    <car>
      <id>DEF-456</id>
      <make>saab</make>
    </car>
  </cars>
</bowler>

/martin

---

From: Andy Bierman <[email-masked]>
Date: Thu, 30 Mar 2006 08:43:50 -0800

Martin Bjorklund wrote:

IMO:

If the agent data model has sub-trees that are
not included in the 'replace' subtrees, then they
are not touched.  Only the agent data model subtrees
explicitly included in the replace-subtrees are touched.

At least that's what I meant when I wrote the original text.

Both of the examples below are correct.

In order to remove optional subtrees in the same edit-config,
appropriately placed operation="delete" attributes are needed.

Andy

---

From: Martin Bjorklund <[email-masked]>
Date: Thu, 30 Mar 2006 19:00:49 +0200 (CEST)

> At least that's what I meant when I wrote the original text.

An example:

  <bowler xmlns="urn:foo">
    <name>Fred</name>
    <status>married</status>
    <cars>
      <car>
        <id>ABC-123</id>
        <make>volvo</make>
      </car>
    </cars>
  </bowler>
  <interfaces>
    <interface>
       <name>eth0</name>
       <ip>10.0.0.1</ip>
    </interface>
  </interfaces>
    
+
 
 <bowler operation="replace">
   <name>Fred</name>
   <status>divorced</status>
 </bowler>

= 

  <bowler xmlns="urn:foo">
    <name>Fred</name>
    <status>divorced</status>
  </bowler>
  <interfaces>
    <interface>
       <name>eth0</name>
       <ip>10.0.0.1</ip>
    </interface>
  </interfaces>

I.e. the subtree "interfaces" is left untouched, but the "bowler"
subtree completely replaced.

Is this what you meant?  (that's what I meant anyway...)

/martin

---

From: Andy Bierman <[email-masked]>
Date: Thu, 30 Mar 2006 09:08:59 -0800

>    <status>divorced</status>

To come up the the result that follows,
you need to do:

   <bowler operation="replace">
    <name>Fred</name>
    <status>divorced</status>
    <cars operation="delete"/>
   </bowler>

Otherwise the 'cars' element is untouched.
The 'interfaces' data model (and all the other
sibling subtrees not included in the replace-subtrees)
are not affected whatsoever by an operation="replace".
This is the whole point of using an operation attribute
placed in the root of the subtree to be affected.

Andy

---

From: Martin Bjorklund <[email-masked]>
Date: Thu, 30 Mar 2006 19:20:41 +0200 (CEST)

> Otherwise the 'cars' element is untouched.

If this is the case, how is 'replace' different from 'merge'??

> are not affected whatsoever by an operation="replace".

That means that	in order to actually completely *replace* an entire
subtree (i.e. not the entire config), a manager would have to first
do a get-config to figure out all instances of all objects, then do an
edit-config where all of these instances are marked as delete, and at
the same time add the new instances?

> placed in the root of the subtree to be affected.

I agree that the operation attribute is very useful.

/martin

---

From: Andy Bierman <[email-masked]>
Date: Thu, 30 Mar 2006 09:28:18 -0800

> If this is the case, how is 'replace' different from 'merge'??

Depends on the data model.
What if the data model allowed duplicate entries?
What if some subtrees allow duplicates or have
some additive properties (defined in the object semantics)?
Then merge and replace act very differently.
They don't in your example though.

> the same time add the new instances?

We have copy-config for course-grained clobbering
of config data.  Edit-config is for fine-grained operations,
so yes, you would have to explicitly delete subtrees by
including the root of the subtree in the request.

Andy

---

From: Martin Bjorklund <[email-masked]>
Date: Thu, 30 Mar 2006 19:37:14 +0200 (CEST)

> Then merge and replace act very differently.

So if the datamodel does not allow duplicates, then 'replace' and
'merge' behave the same?

> of config data.  Edit-config is for fine-grained operations,

But copy-config replaces the *entire* configuration, which also means
that you have to have write-access to *all* config data in order to
use copy-config at all.

> including the root of the subtree in the request.

This seems quite complicated...  Maybe an operation
"really-REALLY-replace" would be useful :)

/martin

---

From: Andy Bierman <[email-masked]>
Date: Thu, 30 Mar 2006 10:11:49 -0800

> So if the datamodel does not allow duplicates, then 'replace' and

Yes

> "really-REALLY-replace" would be useful :)

I don't think so.  Clearly the operation attribute
has no affect whatsoever on sibling nodes, so you
can't clobber the entire config just because you
replace something in one subtree.

The issue here is unspecified subtrees under the
node that contains an operation="replace" attribute.
Not sure if the spec is unclear on this topic.
IMO, you should not touch anything not explicitly
mentioned in the replace-subtree.  That is how I
interpret the text.  I can see how there could be
exceptions.

For example, let's say you had a data model that
was essentially a discriminated union.  In this case,
the agent knows the data model semantics, and
knows that if you change the discriminator that
a different sibling in the union will be selected.

(Sorry for the psuedo-C; IMO it's easier to read than XSD.
Real data model is more complicated; this is just a subset
of my RFC 4001 data model):

     struct InetAddr {
       InetAddressType addr-type;
       choice {
         InetAddressIPv4  ipv4-addr;
         InetAddressIPv6  ipv6-addr;
         InetAddressDns   dns-addr;
       }
     }

What if you want to change the IP address on an interface:

   struct Interface {
      IfNameType name;
      InetAddr   addr;
      ...
   }

  <interfaces>
     <interface operation="replace">
       <name>eth0</name>
       <addr>
         <addr-type>ipv4</addr-type>
         <ipv4-addr>192.168.0.1</ipv4-addr>
       </addr>
       <adminStatus>up</adminStatus>
     </interface>
   </interfaces>

+

   <interfaces>
     <interface operation="replace">
       <name>eth0</name>
       <addr>       # operation=replace should really go here
         <addr-type>dns</addr-type>
         <dns-addr>myhost.example.com</dns-addr>
       </addr>
     </interface>
   </interfaces>

=

   <interfaces>
     <interface operation="replace">
       <name>eth0</name>
       <addr>
         <addr-type>dns</addr-type>
         <dns-addr>myhost.example.com</dns-addr>
       </addr>
       <adminStatus>up</adminStatus>
     </interface>
   </interfaces>

AdminStatus is not an optional element.
It must have some value.  Since <addr> contains
a choice, the agent knows to remove <ipv4-addr>
and replace it with <dns-addr>.  (So choices are special.)

I think your interpretation of operation=replace
is cleaner and more strict -- you would return an error here
and not make any changes, because the <adminStatus>
element is not allowed to be missing.  This forces
the manager to put the operation attribute exactly
where it belongs, including everything in the subtree,
or get an error.

My interpretation is more forgiving of sloppy managers,
but would require the operation="delete" if the manager
really did want to delete a subtree.

I don't know which is right or wrong, or if they
are both right (or wrong ;-).

Andy

---

From: Phil Shafer <[email-masked]>
Date: Thu, 30 Mar 2006 14:08:19 -0500

>So if the datamodel does not allow duplicates, then 'replace' and

That's not the way we do it for JUNOS.  A replace operation replaces
the subtree at the level the operation appears where it matches
the given key elements (identifiers).

Thanks,
 Phil

---

From: Martin Bjorklund <[email-masked]>
Date: Fri, 31 Mar 2006 09:11:29 +0200 (CEST)

> > So if the datamodel does not allow duplicates, then 'replace' and

So the only reason for having a separate 'replace' operation is
because it behaves different from merge when the data model allows
duplicates? 

Could you give an example of a data model with duplicates, and how
replace and merge would behave in your interpretation?

> replace something in one subtree.

Suppose you have a subtree 'system' with parameters 'dnsservers',
'ntpservers', 'syslogservers', ...  i.e. parameters which could be
common for many boxes in a network.  Now the manager wants to set all
these to the same value on all his boxes.  With my interpretation,
this can be done with the same edit-config to all boxes.  With your
interpretation, the manager has to query each box, and build a special
edit-config for each one.  Isn't that more complicated than necessary?

To elaborate unless my description isn't clear:

Suppose I want the end result to be:

  <dnsservers>
    <server>
      <host>10.0.0.1</host>
    </server>
  </dnsservers>

(simpler example to save space)

With my interpretation, I would send

  <dnsservers operation="replace">
    <server>
      <host>10.0.0.1</host>
    </server>
  </dnsservers>

to all boxes.

But suppose box A already has:

  <dnsservers>
    <server>
      <host>10.0.0.2</host>
    </server>
  </dnsservers>

with your interpretation (replace == merge) you would have to do:

  <dnsservers operation="replace">
    <server>
      <host>10.0.0.1</host>
    </server>
    <server operation="delete">
      <host>10.0.0.2</host>
    </server>
  </dnsservers>

... if I understand what you're saying correctly.

> and replace it with <dns-addr>.  (So choices are special.)

I wouldn't use replace in this case, I'd use merge.

> really did want to delete a subtree.

I think 'merge' is for the sloppy manager.

> are both right (or wrong ;-).

Isn't it important for interopability that this issue is clear?

/martin