-
Notifications
You must be signed in to change notification settings - Fork 5.6k
Adding an execution module providing helpers for the NAPALM formulas #48879
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
Ooops! It should be fixed now, sorry! |
a7f0d7f to
ef2c817
Compare
salt/modules/napalm_formula.py
Outdated
| try: | ||
| from salt.utils import traverse_dict_and_list | ||
| except ImportError: | ||
| from salt.utils.data import traverse_dict_and_list |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since this code is going into develop, there is no need to do this try/except, since the function lives in salt.utils.data now. Not only that, there are three problems with this approach:
- Importing a function into the module's global scope will add it to the
__salt__dunder (i.e.__salt__['napalm_formula.traverse_dict_and_list']) - This will also add this function to the docs, which will be confusing.
- Since we have compatibility functions in
salt.utilsfor all the funcs that were moved for 2018.3, the first import will succeed and this will result in deprecation warnings.
Instead, you should simply import salt.utils.data and invoke the function with its full name.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When possible, it would be great to also use __utils__['data.traverse_dict_list']() because then it will allow people to include that data.py file in their salt://_utils/ directory if they are unable to upgrade to the newer version of salt.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doing it @gtmanfred's way will also prevent you from needing to import the module at all.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks guys for reviewing this and your thoughts. As Daniel mentioned, I made these imports having backwards potability in mind; using __utils__ sounds like a better idea, thought it would require backporting loads of util modules.
Re 2: Indeed, I thought about that too, but it seems like Sphinx is smart enough not to pick these functions (no idea why) and they don't appear in the documentation (tested with both Salt and our internal documentation).
Anyway, I will change to use __utils__ as it seems a better tradeoff.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated, though I just wanted to point this out: porting utils.data means it also requires porting utils.dictupdate, utils.stringutils, and utils.yaml (as they are imported there).
This is fine, though when I need, e.g., files.fopen, or args.clean_kwargs, I would also need to port loads of others such as utils.jid, utils.path, utils.platform, utils.data... and here's the catch: salt.utils.args needs salt.utils.data - see https://github.com/saltstack/salt/blob/develop/salt/utils/args.py#L18 (which obviously won't be available). So not only that one basically needs to port almost all the modules under utils/ but also they need to be patched (i.e., replace imports like the one from utils.args from import salt.utils.data to import _utils.data plus updating all the code to use the new import. This sounds like a nightmare to me.
Looking at this vs. 1 & 3 I'm not sure which is the worst...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about the following:
from salt.version import __version_info__
if __version_info__ < (2018, 3):
from salt.utils import traverse_dict_and_list as _traverse_dict_and_list
else:
from salt.utils.data import traverse_dict_and_list as _traverse_dict_and_listOr why not, even simpler:
try:
from salt.utils.data import traverse_dict_and_list as _traverse_dict_and_list
except ImportError:
from salt.utils import traverse_dict_and_list as _traverse_dict_and_listThis way we can ensure that the function won't be exported (note that I flipped the import order to prevent deprecation warning thrown on >= Oxygen, i.e., it will firstly try to use from salt.utils.data).
Does this sound like a better alternative?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This does seem like a better alternative.
try:
from salt.utils.data import traverse_dict_and_list as _traverse_dict_and_list
except ImportError:
from salt.utils import traverse_dict_and_list as _traverse_dict_and_listHowever, I'm not sure why this should be necessary at all in develop.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, the question just comes down to, "How friendly to we want to be for allowing people to backport these modules?"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added 3e9ccdb - please let me know if this is okay for the time being.
89870c7 to
18a350a
Compare
|
I definitely think importing the new method first would be the correct
path. And we should add `__utils__` to the loader for utils in the next
major release.
…On Fri, Aug 3, 2018 at 2:59 AM Mircea Ulinic ***@***.***> wrote:
***@***.**** commented on this pull request.
------------------------------
In salt/modules/napalm_formula.py
<#48879 (comment)>:
> +from __future__ import absolute_import, unicode_literals, print_function
+
+# Import python libs
+import copy
+import logging
+import fnmatch
+
+# Import salt modules
+import salt.utils.napalm
+import salt.ext.six as six
+import salt.utils.dictupdate
+from salt.defaults import DEFAULT_TARGET_DELIM
+try:
+ from salt.utils import traverse_dict_and_list
+except ImportError:
+ from salt.utils.data import traverse_dict_and_list
What about the following:
from salt.version import __version_info__if __version_info__ < (2018, 3):
from salt.utils import traverse_list_and_dict as _traverse_list_and_dictelse:
from salt.utils.data import traverse_list_and_dict as _traverse_list_and_dict
Or why not, even simpler:
try:
from salt.utils.data import traverse_dict_and_list as _traverse_dict_and_listexcept ImportError:
from salt.utils import traverse_dict_and_list as _traverse_dict_and_list
This way we can ensure that the function won't be exported (note that I
flipped the import error to prevent deprecation warning thrown on >=
Oxygen).
Does this sound like a better alternative?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#48879 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AAssoVG3MLl7OtfRvCNaZrJpG7nnyYg2ks5uNAL5gaJpZM4VsDBr>
.
|
18a350a to
3e9ccdb
Compare
What does this PR do?
Some time ago I started preparing some formulas for network configuration management with respect to the OpenConfig standards. The repositories are created, part of the formulas are available, e.g, https://github.com/saltstack-formulas/napalm-ntp-formula
Generally, all these formulas (unfortunately) only generate a text blob that is eventually loaded on the device. Therefore the formulas will 90% be some Jinja template with a considerable size. To shrink this size, and make it more human readable, I thought about having a module, that transforms blocks such as:
Into a more simplified (when reading, at least):
{{ salt.napalm_formula.render_field(subif_cfg.config, 'description') }}With the same rendering result:
Which does all these repetitive checks such as above, which would appear tens of times in a template. Besides, it also add the field name.
This module is generic enough, and it will be used by all the future NAPALM Formulas, e.g., https://github.com/saltstack-formulas/napalm-bgp-formula, https://github.com/saltstack-formulas/napalm-interfaces-formula etc.
Together with this, adding some more little helpers for various manipulation of the OpenConfig-like Python objects.