Subject: [i2rs] comments on draft-atlas-i2rs-architecture-00

From: Andy Bierman <[email-masked]>
Date: Fri, 28 Jun 2013 08:31:43 -0700

Hi,

I really like the simplified approach for the agent.
This is (almost) exactly what I had in mind by "core agent functionality".

* Figure 1:

Since the agent is now simple, all the state-full complexity
is pushed to the client.  There is no "broker" in the architecture
in between the client and the agent.  There is no way to
insert client-B data when client-A removes some conflicting data.

The assumption seems to be that client-B will wait for
a notification that client-A removed its data, and then
it can go ahead and insert its data (assuming client-C doesn't
get there first).  This is not always good enough.

* pg 6:

      The black box behavior
      for interactions between the state that I2RS installs into the
      routing element and the Local Config must be defined.

I agree w/ this requirement -- I have been working on this problem,
and plan to write a draft when we get to the solution phase.
There are several issues wrt/ transactions and deferred validation
that need to be answered.

* sec. 2 Terminology:

I think a term for 'conflict' or 'collision' is needed.
The concept of one client's change colliding with another client
is still vague. The actual conflicts are going to be data-model specific.
Sometimes writing the same 'row' means a collision.  Often it is
more complicated than that -- e.g. another row in the same table
takes precedence over the other client (is that a collision?)

The ability to automatically determine the data model scope of a collision
between clients would be very useful (e.g. YANG extension).

* sec. 5.2 State Storage:

     Meaningful logging is also recommended.

Is this a suggestion to agent developers or a suggestion that the
standard protocol have meaningful monitoring and notifications?

     The I2RS Agent will not attempt to retain or reapply state across
     routing element reboot.

This is good -- it might be data-model specific whether any entries
get saved at all. If they do, then it is a protocol interaction with the
local config that handles the NV storage.

* 5.2.1.  Starting and Ending

I like the simple approach.
The agent supports "start now" and "end now".

* 5.3.  Interactions with Local Config

    As described above, local device configuration is considered to be
    separate from the I2RS data store.

This only works if the actual data is separate from the local config data.
IMO, this is good practice anyway.  Otherwise locking the local
config would affect I2RS data store.

* 6.8.  Multi-Headed Control

   The current recommendation is to
   have a simple priority associated with each I2RS clients, and the
   highest priority change remains in effect.  In the case of priority
   ties, the first client whose attribution is associated with the data
   will keep control

All I2RS clients need to be configured in a proprietary manner
with their priority. The operator needs to be aware of all possible
data model interactions between all clients and pick the priority numbers
that will cause the conflict to be resolved correctly.
IMO this approach is not viable if I2RS clients from different vendors are used,
or the number of clients is significant.

This section suggests that the agent will remember the client identity
for each edit, and not allow any other client to change that data,,
except if they have higher client priority.  This should be explained
more clearly somewhere.

* 6.9.  Transactions
      A) Perform all or none
      B) Perform until error
      C) Perform all

A good agent is always going to do (A).
Asking for 'stop-on-error' or 'continue-on-error' is a really bad idea,
left over from the CLI.  It's OK if an expert is typing commands
and will look at the config after a partial transaction is applied to
see what mess needs to be cleaned up.

A good database is going to use recoverable edits and all-or-nothing
transactions
all the time, and refuse to leave the database in an invalid state
because the client
asked to do this (kind of a security issue, not just operations). A
programmatic API
should always use (A).

Andy

---

From: "Joel M. Halpern" <[email-masked]>
Date: Fri, 28 Jun 2013 11:47:35 -0400

Thank you Andy.  A few comments in line.  The helpful comments which I 
understand have been deleted.

> This is (almost) exactly what I had in mind by "core agent functionality".
Thanks.

> get there first).  This is not always good enough.
Yes, that is the assumption.  Can you elaborate on when that is not good 
enough?

...
> between clients would be very useful (e.g. YANG extension).
Yes, the data model will have to have scope, but even taht will be very 
simplistic.  I.e., if you have a table, with a collection of information 
in each entry in the table, the data model would specify that the entire 
table, a single entry, or an individual field in an entry is the scope 
for collision detection. (I personally expect "entire table" to be a 
very rare case.)
More complex collisions are not expected to be noticed by the system. 
If a client manipulating item A depends upon the value of item B, it 
should register for notifications of changes to B.

...
> see what mess needs to be cleaned up.
That depends very much upon how you assume the client has packaged 
things up into the requests.  There are many ways to design clients, and 
it is not up to the protocol to constrain the client design.  Several 
designs other than CLI have found these alternatives to be useful.

> asked to do this (kind of a security issue, not just operations). A
Yes, the database will always end up in a valid state.  That does not 
mean that one must use all-or-nothing semantics.

> Andy

Yours,
Joel

---

From: Andy Bierman <[email-masked]>
Date: Fri, 28 Jun 2013 09:13:44 -0700

> Yes, that is the assumption.  Can you elaborate on when that is not good

I think the broker functionality should be standardized.
Maybe this is phase 2 or 3, but the configuration rules
needed to integrate multiple clients into the same system
should be part of the standard. I suspect this is more complicated
than an integer priority level, but whatever is needed should
be standardized.

.....
> That depends very much upon how you assume the client has packaged things up
> into the requests.  There are many ways to design clients, and it is not up
> to the protocol to constrain the client design.  Several designs other than
> CLI have found these alternatives to be useful.
>

I've heard the opposite argument too -- it's not up to the agent
to figure out which errors are good vs. bad.  The client should be
smart enough to package its requests in a way that will work.

> Yes, the database will always end up in a valid state.  That does not mean
> that one must use all-or-nothing semantics.
>

This is very implementation-specific.

Some agents do not accept invalid syntax and require
that a well-formed message be received before anything
is processed.  Some agents process on-the-fly and
don't check for this at all.

Some agents check all field validation before processing
the request.  Others do field validation as they go.

So when you say stop on the first error, which error is that?
On many agents, stop-on-error usually means that nothing
was applied, not that all the data preceding the error data was applied.

Andy

---

From: "Joel M. Halpern" <[email-masked]>
Date: Fri, 28 Jun 2013 13:45:01 -0400

My assumption is that the agent will handle"all-or-none" requests very 
differently from the other two cases.  In the all-or-none case, the 
agent needs to build up (with the help of the underlying system) a 
shadow state that has all the changes.  If they all work, it applies 
them.  If not, it leaves the device in the state it was.  (This can be 
implemented also by making a copy, applying changes, and then switching 
to the old copy if that won't work.)  The key is that there may be 
intermediate states that are meaningless or erroneous, but that get 
resolved when everything is in place.

In contrast, with perform all or perform until error the client is 
telling the agent not to worry about interacting dependencies.  The 
agent can simply apply the changes in the message one at a time to the 
system.

The later is muh simpler o implement, and much faster to apply.  That 
efficiency is important for many I2RS cases.  But it clearly does not 
cover everything folks will want to do with I2RS, so we need the former 
as well.

Yours,
Joel

---

From: Nitin Bahadur <[email-masked]>
Date: Fri, 28 Jun 2013 22:55:30 +0000

All-or-none depends on the granularity of the "transaction". Stop-on-error
can be modeled as multiple transactions (where each transaction has a
all-or-none behavior).

Thanks
Nitin Bahadur

On 6/28/13 10:45 AM, "Joel M. Halpern" <[email-masked]> wrote:

>>>things up
>>>mean
>_______________________________________________
>i2rs mailing list
>[email-masked]
>https://www.ietf.org/mailman/listinfo/i2rs
>
>

---

From: Andy Bierman <[email-masked]>
Date: Fri, 28 Jun 2013 16:44:49 -0700

Hi,

I think it will depend on the data model as to what is safe for
a transaction model other than all-or-none.

The validation overhead is very implementation-dependent.

There are different kinds of validation (see RFC 6020, sec. 8 for details).
I made up 3 classifications of database validation wrt/ I2RS (need better terms)

  1) clean:
      * no database nodes outside the patched sub-tree are affected
      * no referential integrity tests (e.g. must-stmt) on the patched tree
      * only patch field validation required (syntax, type, # of instances)

   2) self:
      * no database nodes outside the patched sub-tree are affected
      * there are referential integrity tests on the patched tree
      * also patch field validation required (syntax, type, # of instances)

   3) complex:
      * referential integrity tests for database nodes outside the patched
        sub-tree are affected
      * there may be referential integrity tests on the patched tree
      * also patch field validation required (syntax, type, # of instances)

stop-on-error and continue-on-error transactions are only safe for type (1).
An example of a referential integrity test other than must-stmt might
be a user-ordered list. Only an all-or-none patch on a list of rules to be
processed in order is safe.

I suspect most I2RS data will be type (1) and some will be type (2).

Andy

---

From: Andy Bierman <[email-masked]>
Date: Fri, 28 Jun 2013 18:58:38 -0700

On Fri, Jun 28, 2013 at 10:45 AM, Joel M. Halpern <[email-masked]> wrote:
> differently from the other two cases.  In the all-or-none case, the agent
> needs to build up (with the help of the underlying system) a shadow state
> that has all the changes.  If they all work, it applies them.  If not, it
> leaves the device in the state it was.  (This can be implemented also by
> making a copy, applying changes, and then switching to the old copy if that
> won't work.)  The key is that there may be intermediate states that are
> meaningless or erroneous, but that get resolved when everything is in place.
>
> In contrast, with perform all or perform until error the client is telling
> the agent not to worry about interacting dependencies.  The agent can simply
> apply the changes in the message one at a time to the system.
>
> efficiency is important for many I2RS cases.  But it clearly does not cover
> everything folks will want to do with I2RS, so we need the former as well.
>

I agree there are valid use cases.
There should be a standard transaction model.
In NETCONF, the all-or-none transaction is optional-to-implement,
but there is no defined order to process edits, errors, etc.

I think I2RS transactions should be based on ordered patch lists
(ala JSON Patch) and not arbitrary datastore sub-trees (ala NETCONF).
That will make 'Perform until error' and 'Perform all' more usable
by clients because the implementation steps are easier to define.

Andy