In a NETCONF <edit-config>, why might a cleanup job use operation="remove" rather than "delete", and what does default-operation none add?
answer
- strict versus tolerant pairs
- what happens when the node is absent
- added in NETCONF 1.1
- ancestors that only point the way
basics
~20 sdelete fails with data-missing when the node is absent; remove deletes it if present and is ignored otherwise, so a retried cleanup stays quiet. default-operation none stops the request's ancestors being merged; they only locate the target.
solid answer
~40 sRFC 6241 gives `<edit-config>` two ways to delete. `delete` removes the node only if it exists and otherwise returns an `<rpc-error>` with error-tag `data-missing`; `remove` deletes it if present and is silently ignored if not. A cleanup job that may run twice, or that converges a device whose state it does not know, wants `remove`; a job that should notice when the node is already gone wants `delete`. `remove` was added in RFC 6241, so a server built only to RFC 4741 does not know it. `<default-operation>none</default-operation>` makes the elements around the target act only as a path: they are neither merged nor created. RFC 6241 notes this stops a delete from unintentionally creating its own parent hierarchy, and if an ancestor is missing the server returns `data-missing` instead.
code
xml · 16 lines<edit-config xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
<target><candidate/></target>
<default-operation>none</default-operation>
<config xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
<top xmlns="http://example.com/schema/1.2/config">
<protocols><ospf><area>
<name>0.0.0.0</name>
<interfaces>
<interface xc:operation="remove">
<name>192.0.2.4</name>
</interface>
</interfaces>
</area></ospf></protocols>
</top>
</config>
</edit-config>go deeper
Recall that delete and remove both delete, and that the difference is what happens when the data is not there.
Explain the table: delete errors with data-missing on absent data, remove ignores it, create errors with data-exists on present data. Say where remove came from.
Choose by intent: remove for idempotent convergence, delete to detect drift, none to stop ancestors being created, and know that a missing ancestor still fails under none.
Discuss how strict and tolerant operations encode a pipeline's assumptions about device state, and where you want failures surfaced versus absorbed.
## Two pairs: strict and tolerant RFC 6241, which obsoletes RFC 4741, defines five values for the `operation` attribute an element in an `<edit-config>` may carry. Two pairs differ only in what happens when the data's presence is not what the caller expected: | Operation | Node present | Node absent | |---|---|---| | `create` | `<rpc-error>`, error-tag `data-exists` | created | | `merge` | merged | added | | `delete` | deleted | `<rpc-error>`, error-tag `data-missing` | | `remove` | deleted | silently ignored | `create` and `delete` are **strict**: they assert something about the current state and fail when it is wrong. `merge` and `remove` are **tolerant**: they reach the same end state from either starting point. `replace`, the fifth value, makes the sent data the whole node. ## Choosing between delete and remove The choice is a statement about what the job expects to find: - **`remove` for convergence.** A job that drives a device toward an intended state, and may run again after a partial failure, wants a request that succeeds whether or not the node is still there. `remove` gives an idempotent delete. - **`delete` for detection.** A job that believes the node exists, and would treat its absence as drift worth investigating, wants the `data-missing` error. Silently succeeding would hide that someone or something already removed it. - **Server support.** `remove` is new in RFC 6241's version of NETCONF; RFC 4741 had only merge, replace, create and delete. A server built only to the older text does not understand `remove`, so a client talking to one may have to fall back to `delete` and treat `data-missing` as success. ## What default-operation none does Every element in `<config>` without an `operation` attribute takes the request's **`<default-operation>`**, which defaults to `merge`. That matters for the elements **around** the node being deleted: the containers and list entries you must send to say where it lives. Under the default `merge`, those ancestors are themselves merge operations. RFC 6241 notes that `none` "allows operations like delete to avoid unintentionally creating the parent hierarchy of the element to be deleted". With `<default-operation>none</default-operation>`: 1. Elements without an attribute leave the target untouched; they only locate the node. 2. Elements with an attribute, such as `operation="remove"`, are applied as usual. 3. If the request contains data for which the target has no corresponding level, the server returns `data-missing`. Point 3 is easy to miss. Under `none`, `remove` is silent only when the **path down to** the node exists. If a whole parent, say the routing-protocol area the interface belonged to, has already been removed, the request fails on the ancestor even though the leaf operation is tolerant. A convergence job therefore either removes at the highest level it owns, or treats `data-missing` on an ancestor as "already clean". ## A worked request RFC 6241's own example removes one interface from an OSPF area without touching the area's other interfaces. A cleanup job can send the same shape with `remove` in place of `delete`: - `<default-operation>none</default-operation>` at the top of the request; - the area, identified by its `<name>`, and its interface list as **path elements** with no attribute; - the interface entry, identified by its `<name>`, carrying `operation="remove"`. If the interface is configured, it is deleted and the area's other interfaces are unaffected. If it is already gone, the server ignores the operation. If the whole area is gone, `none` produces `data-missing` rather than an empty area being merged into existence. ## Pitfalls - **Two operations on one node.** If a single `<edit-config>` applies several sub-operations to the same conceptual node, RFC 6241 says the result is undefined. Do not, for instance, remove and merge the same entry in one request. - **Errors mid-request.** With the default `stop-on-error`, a `data-missing` on the first of several deletes aborts the rest, so a strict delete in a batch can stop a cleanup halfway. - **create as an assertion.** The strict counterpart for additions: `create` returns `data-exists` when the entry is already there, which stops an allocation job from silently taking over an entry someone else configured. - **Keys are required.** A list entry is identified by all of its keys, even under `none`; YANG 1.1 (RFC 7950, Section 7.8.6) returns `missing-element` when a key is left out.
- Under default-operation none, why can a NETCONF remove still fail with data-missing?Under `none`, elements without an operation attribute only locate the target, and RFC 6241 returns `data-missing` when the request holds data for which the target has no corresponding level. If an ancestor, such as the parent area, no longer exists, the path fails before the tolerant `remove` is reached. The job should remove at the highest level it owns, or treat that error as already clean.
- When is the data-missing error from a strict delete the behaviour you want?When absence means something unexpected happened: an out-of-band change, another automation system or a wrong inventory. A reconciliation job that believes an entry exists should fail loudly so a person looks, rather than reporting success on a device that has drifted from what the job thinks it holds.
saying these in an interview costs you the question
- delete and remove are synonyms; the choice is only style.
- remove returns data-missing when the node is already absent.
- With default-operation none, nothing in the request is applied.
- A delete of a missing node returns <ok> on a compliant server.
- Every NETCONF server accepts remove, whatever specification it implements.