How to skip validating NETCONF <edit-config>'s when writing to the candidate

To skip validating the configuration when writing to the NETCONF candidate datastore you use the <test-option>set</test-option> with your <edit-config>.

Here we use the $CONFD_DIR/examples.confd/validate/c_dependency example and slightly modify the commands that comes with the example. We also change the confd.conf to write through the candidate instead of writing directly to the running datastore.

As in the original example we use the netconf-console tool that comes with ConfD.

$ more cmd-set-invalid-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<hello xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <capabilities>
    <capability>urn:ietf:params:netconf:base:1.0</capability>
  </capabilities>
</hello>
]]>]]>
<?xml version="1.0" encoding="UTF-8"?>
<rpc xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="1">
  <edit-config>
    <target>
      <candidate/>
    </target>
    <test-option>set</test-option>
    <config>
      <mtest xmlns="http://tail-f.com/ns/example/mtest"
             xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"
             nc:operation="merge">
        <a_number>7</a_number>
        <b_number>14</b_number>
      </mtest>
    </config>
  </edit-config>
</rpc>
]]>]]>
<?xml version="1.0" encoding="UTF-8"?>
<rpc xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="2">
  <close-session/>
</rpc>
]]>]]>

First we set the above invalid configuration using the netconf-console tool. Note how the validation writing to the candidate datastore is by-passed by setting <test-option>set</test-option> in the <edit-config>

$ netconf-console cmd-set-invalid-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="1">
  <ok/>
</rpc-reply>

If we choose to validate validate the candidate the error is discovered by the validation_a() application.`

$ netconf-console --db=candidate --validate
******* VP1 - validate_a() - Called when a_number or b_number is modified.  Always called with a_number's value
<?xml version="1.0" encoding="UTF-8"?>
<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="1">
  <rpc-error>
    <error-type>application</error-type>
    <error-tag>operation-failed</error-tag>
    <error-severity>error</error-severity>
    <error-path xmlns:mtest="http://tail-f.com/ns/example/mtest">
    /mtest:mtest/mtest:a_number
  </error-path>
    <error-message xml:lang="en">/mtest/a_number: a_number is &lt;= b_number </error-message>
    <error-info>
      <bad-element>a_number</bad-element>
    </error-info>
  </rpc-error>
</rpc-reply>

Same thing if we try to commit the candidate to running. Here the validation phase is performed as part of the transaction copying the candidate to running.
validate_a() discover the error.

$ netconf-console --commit
******* VP1 - validate_a() - Called when a_number or b_number is modified.  Always called with a_number's value
<?xml version="1.0" encoding="UTF-8"?>
<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="1">
  <rpc-error>
    <error-type>application</error-type>
    <error-tag>operation-failed</error-tag>
    <error-severity>error</error-severity>
    <error-path xmlns:mtest="http://tail-f.com/ns/example/mtest">
    /mtest:mtest/mtest:a_number
  </error-path>
    <error-message xml:lang="en">/mtest/a_number: a_number is &lt;= b_number </error-message>
    <error-info>
      <bad-element>a_number</bad-element>
    </error-info>
  </rpc-error>
</rpc-reply>