Closed dbarrosop closed 6 years ago
@ubaumann @mirceaulinic @ktbyers thoughts?
With this approach we could address the 'more verbose logging' issue as well: https://github.com/napalm-automation/napalm-base/issues/272 https://github.com/napalm-automation/napalm-base/issues/273
I will look deeper in the code asap
My findings so far:
recoder
function)...
File "/home/ubaumann/napalm-base/napalm_base/recorder.py", line 57, in __init__
self.device = cls(*args, **kwargs)
File "/home/ubaumann/.virtualenvs/napalm_base/lib/python2.7/site-packages/netmiko/ssh_dispatcher.py", line 131, in ConnectHandler
return ConnectionClass(*args, **kwargs)
File "/home/ubaumann/.virtualenvs/napalm_base/lib/python2.7/site-packages/netmiko/base_connection.py", line 150, in __init__
self.establish_connection()
File "/home/ubaumann/.virtualenvs/napalm_base/lib/python2.7/site-packages/netmiko/base_connection.py", line 506, in establish_connection
raise NetMikoTimeoutException(msg)
netmiko.ssh_exception.NetMikoTimeoutException: Connection to device timed-out: cisco_ios 127.0.0.1:123
With the files and the count number, the order of commands can't be changed. So, every workflow needs a separate record. I would like to have a more flexible way. For example creating a YAML file with the function name and the arguments, so the the recording can be reused. I know the file could get big.
send_command:
- 'show version': 'asdfasdfasdfasdf'
- 'show interface': 'asdfasdfasdfasdf'
enable: ''
Advantages from my point of view:
pickle.dumps
Recordings make it easy to test against different OS versions
With the files and the count number, the order of commands can't be changed. So, every workflow needs a separate record. I would like to have a more flexible way. For example creating a YAML file with the function name and the arguments, so the the recording can be reused. I know the file could get big.
Yes, I believe this is way, way, beyond the goals of NAPALM - as @dbarrosop likes to say everytime, "napalm is a library, it's not a tool.", so this implementation, from any perspective, I believe it doesn't really fit into this definition.
We should not create the real object in 'replay' mode
I agree. That's certainly an easy bug to fix.
With the files and the count number, the order of commands can't be changed
That's the point. This is a recorder/replayer.
I kinda like the idea, but if I'd compare the benefits vs. complexity + risks and environment exposure, I find there's not much real value added.
Complexity, less than what we have today. Benefits of having this between each driver and the underlying class (netmiko, pyeapi, etc):
An alternative to the "pass" behavior would be to call the class directly without the wrapper so the default behavior wouldn't change at all. So on the drivers we would have:
if self.recorder_mode == "pass":
self.device = pyeapi.client.Node(connection, enablepwd=self.enablepwd)
else:
self.device = napalm_base.recorder.Recorder(pyeapi.client.Node,
recorder_options=self.recorder_options,
connection=connection,
enablepwd=self.enablepwd)
Or something like that
My take:
sh hardware internal errors module 1 \| diff \| i crc
IMHO unless this introduced an unnecessary amount of work and future burden I see it as clear net positive.
@itdependsnetworks Can you elaborate on this statement?
Can use the cli to backup commands not in data model. e.g. have a requirement to log: sh hardware internal errors module 1 \| diff \| i crc
I think we should use probably use JSON or YAML to save data instead of pickle.
I like the general idea.
I'm simply highlighting he fact that that command will never be part of any standard getters. It would be nice to have a standard way to say the raw response no matter what you were running
I think we should use probably use JSON or YAML to save data instead of pickle.
Problem with YAML/JSON is that it becomes a problem when the method returns pythons objects. For example, a method might return None
or True
, an Exception
or even a custom object, and those don't translate well to structured data. But I will do some tests and see what happens.
If we use Pickle, then we won't be able to accept data from anyone we don't trust...as they could totally mess us over (like embed system calls inside the pickle file) and we wouldn't be able to easily inspect what was sent to us beforehand.
Booleans and None are not really a problem (objects including Exceptions are a problem).
Does it break how you were planning on using it? I was thinking of it as more of capturing data that could be added to unit tests (as opposed to replacing mocked devices).
>>> a = None
>>> import json
>>> json.dumps(a)
'null'
>>> b = True
>>> json.dumps(a)
'null'
>>> json.dumps(b)
'true'
>>> print json.loads(json.dumps(a))
None
>>> print json.loads(json.dumps(b))
True
then we won't be able to accept data from anyone we don't trust
As discussed via other channels. I think you are right and I will look into that. The main issue is that not all calls might return structured but some "bare" object like a string or an Exception but that can be treated.
mirceaulinic raised the concern that the recorder might break things if a method changes how things are retrieved
That is very much correct so we will do two things:
Regarding the metadata, now it adds a metadata.yaml
file with the following contents:
(napalm) ➜ napalm-base git:(recorder) ✗ cat test_recorder/metadata.yaml
date: 2017-08-16 19:57:11.194889
napalm_version:
- napalm-ansible==0.7.0
- napalm-base==0.24.3
- napalm-eos==0.6.0
- napalm-fortios==0.4.0
- napalm-ios==0.7.0
- napalm-iosxr==0.5.4
- napalm-junos==0.12.0
- napalm-nxos==0.6.0
- napalm-panos==0.4.0
- napalm-pluribus==0.5.1
- napalm-ros==0.2.2
- napalm-vyos==0.1.3
- napalm==1.2.0
@ktbyers @mirceaulinic latest update replaces pickle with Camel
, which builds on top of pyyaml
to provide a safe mechanism to serialize/deserialize custom objects.
I tried pyyaml pickle-like behavior but it turns out is as unsafe as pickle
itself and also not very reliable as it fails to understand how the constructor of the classes work.
I recommend reading this if you have the time/energy:
https://eev.ee/blog/2015/10/15/dont-use-pickle-use-camel/
If you are happy with this I will remove all the testing stuff I added and merge. Then I will quickly integrate it with the napalm
cli tool so users can start recording with it.
@dbarrosop - you may have missed my review.
I disagree on using an obscure library that gained less interest than naplam (i.e. https://github.com/eevee/camel has exactly 7 followers), rather than a very well known and widely adopted msgpack (also very well know for its speed).
Also, it's very bizzare that the sole resource I was able to find about this camel is the blog post you pointed out... written by its maintainer and one of the 4 contributors.
I disagree on using an obscure library that gained less interest than naplam (i.e. https://github.com/eevee/camel has exactly 7 followers)
Are we measuring now usefulness by number of followers? Doesn't make much sense IMHO.
rather than a very well known and widely adopted msgpack (also very well know for its speed
I can write myself what camel does as it's just a framework on top of pyyaml, which seems unnecessary to write as someone else did it already, but as I mentioned in the other comment, msgpack
is way overkill and doesn't do exactly what we want.
As discussed in slack, will rewrite without dependencies.
This PR introduces a class that can sit between the driver and the underlying library (pyeapi, netmiko, pyez, etc. see napalm-automation/napalm-eos/pull/173).
The "middleware" has three modes:
pass
. Does nothing. TheRecorder
will just proxy the calls to the underlying library.record
. The interactions between the driver and the underlying library are proxied and recorded.replay
. The interactions between the driver and the underlying library are interrupted. Instead, theRecorder
will pickle a previous recording and replay it.Example, in the following snippet we are running the same code three times testing all modes. Note that in the "replay" mode at the end I set wrong data to prove that there is no connection with the real device.
TODO: