Repository: napalm-automation/napalm
Pull request #522 (2017-11-15 20:44:19)

base: helpers: Added jinja_filters arg to load_template
This is a bit more of a discussion with working code, but happy to have it merged if it checks out.

In the ios driver I want to implement the set_users template, but I would need to either compute each ssh key's fingerprint, or wrap the text since ios doesn't allow any lines longer than 254. Adding a filter to the base class seemed like the wrong solution, so I came up with this. This way the ios driver could override `base.load_template` and inject the filters specific to the driver. 

coveralls: 
[![Coverage Status](https://coveralls.io/builds/14222470/badge)](https://coveralls.io/builds/14222470)

Coverage increased (+0.004%) to 77.903% when pulling **7754fefafe5cca56b5f1764662925c0dba15ed9e on nickethier:feature/custom_jinja_filters** into **a04c348caef8318b106ce751c66a221a6b7a76d0 on napalm-automation:develop**.

coveralls: 
[![Coverage Status](https://coveralls.io/builds/14239417/badge)](https://coveralls.io/builds/14239417)

Coverage increased (+0.004%) to 77.903% when pulling **cde9c540d542ca9730822710889add733cfa974d on nickethier:feature/custom_jinja_filters** into **a04c348caef8318b106ce751c66a221a6b7a76d0 on napalm-automation:develop**.

coveralls: 
[![Coverage Status](https://coveralls.io/builds/14363477/badge)](https://coveralls.io/builds/14363477)

Coverage increased (+0.004%) to 78.588% when pulling **46bc83254e3cb0c8444142fec249c357da6bd32d on nickethier:feature/custom_jinja_filters** into **584197ed4a8f368ccbc1cb0eb18f14f4ab663f33 on napalm-automation:develop**.

nickethier: Anything else you folks need from me to get this merged? @ktbyers @mirceaulinic 
I've about got a PR ready to make use of this if you'd like to see that first.
coveralls: 
[![Coverage Status](https://coveralls.io/builds/14617043/badge)](https://coveralls.io/builds/14617043)

Coverage increased (+0.003%) to 78.648% when pulling **13fe4c9b9cb57114ee97a710de9972f66f69b065 on nickethier:feature/custom_jinja_filters** into **f4c91209a42328a6e6cc1c9e9ae372c812abfb89 on napalm-automation:develop**.

dbarrosop: LGTM as well :)

Patch:
diff --git a/napalm/base/helpers.py b/napalm/base/helpers.py
index 44682d67..e640f7f6 100644
--- a/napalm/base/helpers.py
+++ b/napalm/base/helpers.py
@@ -7,6 +7,7 @@ from __future__ import unicode_literals
 # std libs
 import os
 import sys
+import itertools
 
 # third party libs
 import jinja2
@@ -36,7 +37,7 @@ _MACFormat.word_fmt = '%.2X'
 # callable helpers
 # ----------------------------------------------------------------------------------------------------------------------
 def load_template(cls, template_name, template_source=None, template_path=None,
-                  openconfig=False, **template_vars):
+                  openconfig=False, jinja_filters={}, **template_vars):
     try:
         search_path = []
         if isinstance(template_source, py23_compat.string_types):
@@ -62,7 +63,9 @@ def load_template(cls, template_name, template_source=None, template_path=None,
             loader = jinja2.FileSystemLoader(search_path)
             environment = jinja2.Environment(loader=loader)
 
-            for filter_name, filter_function in CustomJinjaFilters.filters().items():
+            for filter_name, filter_function in itertools.chain(
+                    CustomJinjaFilters.filters().items(),
+                    jinja_filters.items()):
                 environment.filters[filter_name] = filter_function
 
             template = environment.get_template('{template_name}.j2'.format(


Test patch:
diff --git a/test/base/templates/__custom_jinja_filter_template__.j2 b/test/base/templates/__custom_jinja_filter_template__.j2
new file mode 100644
index 00000000..9cc10cc9
--- /dev/null
+++ b/test/base/templates/__custom_jinja_filter_template__.j2
@@ -0,0 +1,1 @@
+{{foo | foo_to_bar}}
\ No newline at end of file
diff --git a/test/base/test_helpers.py b/test/base/test_helpers.py
index 7c08e9e2..1f9ab15a 100644
--- a/test/base/test_helpers.py
+++ b/test/base/test_helpers.py
@@ -125,6 +125,18 @@ class TestBaseHelpers(unittest.TestCase):
                                                           '_this_still_needs_a_name',
                                                           template_source=template_source,
                                                           **_TEMPLATE_VARS))
+
+        def __foo_to_bar(s):
+            if s == "foo":
+                return "bar"
+            return s
+
+        jinja_filters = {'foo_to_bar': __foo_to_bar}
+
+        self.assertTrue(napalm.base.helpers.load_template(self.network_driver,
+                                                          '__custom_jinja_filter_template__',
+                                                          jinja_filters=jinja_filters,
+                                                          **_TEMPLATE_VARS))
         # MIGRATION mircea
         #  self.assertRaisesRegexp(napalm.base.exceptions.TemplateNotImplemented,
         #                          "path.*napalm-base/test/unit/templates'" +