Why might I be getting this error?

I’m trying to do a config replace on a Juniper EX2200 for three config sections: interfaces, protocols rstp, and ethernet-switching-options, which is rendered by a j2 template whose output is stored in host data as fp_config. The config apply section in my function is as follows:

    task.run(task=networking.napalm_configure,
             name="Loading Configuration on the device",
             replace=True,
             configuration=task.host['fp_config'])

I have successfully run this against another switch, but when I try on this EX2200, I’m getting the following error (details redacted for length):

2020-02-12 14:23:27,433 - nornir.core.task -    ERROR -      start() - Host 'jnpr-sw-temp.nec-labs.com': task 'Loading Configuration on the device' failed with traceback:
Traceback (most recent call last):
   [...]
ncclient.operations.rpc.RPCError: error: mgd: Missing mandatory statement: 'root-authentication'
error: commit failed: (missing mandatory statements)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
   [...]
jnpr.junos.exception.RpcError: RpcError(severity: error, bad_element: system, message: error: mgd: Missing mandatory statement: 'root-authentication'
error: commit failed: (missing mandatory statements))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
   [...]
jnpr.junos.exception.CommitError: CommitError(edit_path: [edit], bad_element: system, message: error: mgd: Missing mandatory statement: 'root-authentication'
error: commit failed: (missing mandatory statements))

2020-02-12 14:23:27,433 - nornir.core.task -    ERROR -      start() - Host 'jnpr-sw-temp.nec-labs.com': task 'config_front_ports' failed with traceback:
Traceback (most recent call last):
   [...]
nornir.core.exceptions.NornirSubTaskError: Subtask: <function napalm_configure at 0x106e564d0> (failed)

So I see it’s complaining about root-authentication not being set, but – that does indeed exist on the current config on the switch! Is it because I am using replace=True in networking.napalm_configure and it is trying to replace the entire device config, instead of just the three sections that I want to replace? (I do want to completely replace those three config sections…) If so, is there a way to “roll over” the existing config for those three sections only?

I might add, when I change replace=True to replace=False in the networking.napalm_configure function, I get this traceback, which I assume is due to napalm_configure using a merge strategy on the interfaces, one of which has a different VLAN set:

2020-02-13 09:23:39,537 - nornir.core.task -    ERROR -      start() - Host 'jnpr-sw-temp.nec-labs.com': task 'Loading Configuration on the device' failed with traceback:
Traceback (most recent call last):
   [...]
ncclient.operations.rpc.RPCError: error: Access interface <ge-0/0/0.0> has more than one vlan member: <vl200> and <blackhole>
error: configuration check-out failed

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
   [...]
jnpr.junos.exception.RpcError: RpcError(severity: error, bad_element: None, message: error: Access interface <ge-0/0/0.0> has more than one vlan member: <vl200> and <blackhole>
error: configuration check-out failed)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
   [...]
jnpr.junos.exception.CommitError: CommitError(edit_path: None, bad_element: None, message: error: Access interface <ge-0/0/0.0> has more than one vlan member: <vl200> and <blackhole>
error: configuration check-out failed)

2020-02-13 09:23:39,538 - nornir.core.task -    ERROR -      start() - Host 'jnpr-sw-temp.nec-labs.com': task 'config_front_ports' failed with traceback:
Traceback (most recent call last):
   [...]
nornir.core.exceptions.NornirSubTaskError: Subtask: <function napalm_configure at 0x10b0d34d0> (failed)

(which is why I set replace=True in that function, as I want to completely replace all of the interface config…)

Yes, so NAPALM’s pattern for Junos is:

replace = True (replace the entire configuration)

replace = False (merge operation)

NAPALM doesn’t directly support a replace section operation here.

Probably the easiest solution is to make a custom task in Nornir and then use NAPALM to access the underlying PyEZ driver. Then use the PyEZ driver and the load() method to do the replace section operation.