07-16-2019 08:45 AM - edited 07-17-2019 05:15 AM
Hi everyone,
I have to retieve configuration from a device and push it to another device in a python action :
So I used the mappi library in writing mode :
Solved! Go to Solution.
07-17-2019 08:46 AM - edited 07-18-2019 12:10 AM
You can find it documented in the $INSTALL_DIR/doc/api/python/_ncs.maapi.html.
There are no examples for python though. This is the definition:
copy_tree(sock, thandle, frompath, topath) -> None
sock will be handled when calling the function on existing maapi session, thandle is the transaction handler of type int, you can get it from the th attribute of your transaction, frompath and topath will be string values in the format of keypath.
So for these 2 values you either construct a string as in the example I posted previously, or you can get the keypath out of the Node object using _path attribute. E.g.
with ncs.maapi.Maapi() as m: with ncs.maapi.Session(m, 'admin', 'python'): with m.start_write_trans() as t: root = ncs.maagic.get_root(t) port_1 = root.devices.device[_input.device1].config.alu__port['2/3/14'] port_2 = root.devices.device[_input.device2].config.alu__port['2/2/2'] m.copy_tree(t.th, port_1._path, port_2._path) t.apply()
I tried it out and it works, on my machine :)
07-17-2019 01:32 AM
Hi,
the error you got is telling you that the ListElement with key value 2/2/2 that you're referencing, doesn't exist in the CDB.
You could go and create it beforehand with create() method
root.devices.device[_input.device1].config.alu__port[2/2/2].create()
and then you could use it the way you tried without receiving that error because now the resource will exist. But this unfotunately will not copy all the values from port1 to port2 as you might think. You would have to go through all elements on the first interface and apply them to the second E.g. port2.ip = port1.ip etc.
Luckily there is an easier way to copy entire subtree of a Node with the copy_tree() method
with ncs.maapi.Maapi() as m:
with ncs.maapi.Session(m, 'admin', 'python'): with m.start_write_trans() as t: port1 = "/devices/device{{0}}/config/alu:port{{1}}".format(_input.device1, "2/3/14")
port2 = "/devices/device{{0}}/config/alu:port{{1}}".format(_input.device1, "2/2/2") m.copy_tree(t.th, port1, port2) t.apply()
As you see you have to use keypath strings as arguments from where to where you want to copy, so there will be some string manipulation. But there might even be an option to get keypath out of the Node object if necessary :)
Hope it helps!
07-17-2019 01:54 AM
thanks sspehar for your reply.
In fact the key value 2/2/2 exist in the CDB.
I tried the solution that you suggested (the copy_tree() method), but unfortunately when I applied it, any changes had ocuured to the CDB (the configuration of port 2 had not changed).
07-17-2019 02:54 AM
2 things come to my mind, maybe the keypath string is not correct, try printing it out and examine if it's correct, or the transaction wasn't applied E.g. t.apply() ?
07-17-2019 03:22 AM
The transaction is applied, I will verify the keypath string.
07-17-2019 04:40 AM
Two things that I see in your code snippets:
1. You mention "device 2", but your code seems to point to "device 1" in both to and from line.
2. The IDs that you're using for the ports. I imagine those need to be strings. In your code, it seems to me that they might be numbers (1/1/1 [=1?], should be '1/1/1'). Might it be that this makes your code try and copy the data to another path than the one you expect?
07-17-2019 05:14 AM - edited 07-17-2019 05:24 AM
Thanks yfherzoa for your reply,
My code respect this two things that you mentioned, sorry for the error in the post.
Yes exactly i want to copy data from one path (device1) to another path (device2)
07-17-2019 06:59 AM
In the documentation, I foundd that the source path of copy_tree() method should be formatted, Do you have any example to do this ?
Documentation bellow :
int maapi_copy_tree(int sock, int thandle, const char *from, const char *tofmt, ...);
This function copies the entire configuration tree rooted at from to tofmt. List entries are created accordingly. If the destination already exists, from is copied on top of the destination. This function is typically used inside actions where we for example could use maapi_copy_tree() to copy a template configuration into a new list entry. The from path must be pre-formatted, e.g. using confd_format_keypath(), whereas the destination path is formatted by this function.
07-17-2019 08:46 AM - edited 07-18-2019 12:10 AM
You can find it documented in the $INSTALL_DIR/doc/api/python/_ncs.maapi.html.
There are no examples for python though. This is the definition:
copy_tree(sock, thandle, frompath, topath) -> None
sock will be handled when calling the function on existing maapi session, thandle is the transaction handler of type int, you can get it from the th attribute of your transaction, frompath and topath will be string values in the format of keypath.
So for these 2 values you either construct a string as in the example I posted previously, or you can get the keypath out of the Node object using _path attribute. E.g.
with ncs.maapi.Maapi() as m: with ncs.maapi.Session(m, 'admin', 'python'): with m.start_write_trans() as t: root = ncs.maagic.get_root(t) port_1 = root.devices.device[_input.device1].config.alu__port['2/3/14'] port_2 = root.devices.device[_input.device2].config.alu__port['2/2/2'] m.copy_tree(t.th, port_1._path, port_2._path) t.apply()
I tried it out and it works, on my machine :)
07-17-2019 09:08 AM
Thanks for your reply
I got the following error when testing the same example :
Error: badly formatted or nonexistent path (8): Data model mismatch
03-22-2020 10:40 PM - edited 03-23-2020 12:53 AM
@sspehar I liked the easy way of coping but my second XPath does not exist due to its new entry. do I need to call the following code before XPath
root.devices.device[_input.device1].config.alu__port[2/2/2].create()
code:
with ncs.maapi.Maapi() as m: with ncs.maapi.Session(m, tctx.username, tctx.context): with m.start_write_trans() as t: root = ncs.maagic.get_root(t) root.devices.device[each_vlan.neighbor_name].config.junos__configuration.protocols.l2circuit.neighbor[target_device_ipv4].create() neighbor1 = "/devices/device{{0}}/config/junos:configuration/protocols/l2circuit/neighbor{{1}}".format(each_vlan.neighbor_name, source_device_ipv4) neighbor2 = "/devices/device{{0}}/config/junos:configuration/protocols/l2circuit/neighbor{{1}}".format(each_vlan.neighbor_name, target_device_ipv4) m.copy_tree(t.th, neighbor1, neighbor2) t.apply()
In my case it's
root.devices.device[each_vlan.neighbor_name].config.junos__configuration.protocols.l2circuit.neighbor[target_device_ipv4].create()
I am getting key error on neighbor2
KeyError: '{10.0.0.1} not in /ncs:devices/device{juniper-pe20}/config/junos:configuration/protocols/l2circuit/neighbor'
To test I have given existing neigbor2 key then, error on create
AttributeError: 'ListElement' object has no attribute 'create'
When I commented on create part of the existing neighbor2 then error on badly formated or nonexisting path
<ERROR> 23-Mar-2020::10:14:57.876 vpws-migration ncs-dp-15537-vpws-migration:main-1-th-28744: - badly formatted or nonexistent path (8): <ERROR> 23-Mar-2020::10:14:57.877 vpws-migration ncs-dp-15537-vpws-migration:main-1-th-28744: - Traceback (most recent call last): File "/opt/ncs/ncs-5.3.0.1/src/ncs/pyapi/ncs/application.py", line 401, in wrapper pl = fn(self, tctx, root, service, proplist) File "/var/opt/ncs/state/packages-in-use/1/vpws-migration/python/vpws_migration/main.py", line 88, in cb_create m.copy_tree(t.th, neighbor1, neighbor2) File "/opt/ncs/ncs-5.3.0.1/src/ncs/pyapi/ncs/maapi.py", line 273, in proxy return real(self2.msock, *args, **kwargs) _ncs.error.Error: badly formatted or nonexistent path (8):
03-23-2020 01:00 AM
You need to run create on the list, rather than on the list element and provide the element key(s) as create() args.
new_entry = my_list.create(new_entry_key)
Discover and save your favorite ideas. Come back to expert answers, step-by-step guides, recent topics, and more.
New here? Get started with these tips. How to use Community New member guide