Skip to content
Snippets Groups Projects
Commit ca37afb6 authored by nimrod's avatar nimrod
Browse files

Small refactor and cleanup.

- Change the `run` filter to be a function. Usage should be nicer now:
  `{{ run(['id', '-u'])['stdout'] }}`. Keep the filter for a few
releases to avoid breakage.
- A few filters were missing from the README, add the documentation.
parent 58970d36
No related branches found
No related tags found
No related merge requests found
Pipeline #2043 passed
......@@ -81,6 +81,8 @@ Jinja filters
The following Jinja filters were added:
- :code:`combine`: Merges 2 dictionaries with the 2nd overriding the 1st.
Returns the result.
- :code:`to_yaml`: Convert to yaml (requires the :code:`yaml` package
specifier).
- :code:`from_yaml`: Convert from yaml (requires the :code:`yaml` package
......@@ -94,8 +96,8 @@ The following Jinja filters were added:
- :code:`jmespath`: Queries data using the `JMESPath <http://jmespath.org/>`_
query language (requires the :code:`jmespath` package specifier).
- :code:`run`: Runs a command and returns the stdout, stderr and returncode
using `run
<https://docs.python.org/3.6/library/subprocess.html?highlight=popen#subprocess.run>`_.
using run_. This filter is replaced with the :code:`run` function and will
be removed in the 0.10 release.
- :code:`ipaddress`: Returns an IPAddress object from the netaddr_ library
(requires the :code:`netaddr` package specifier).
- :code:`ipnetwork`: Returns an IPNetwork object from the netaddr_ library
......@@ -104,10 +106,21 @@ The following Jinja filters were added:
(requires the :code:`netaddr` package specifier).
- :code:`ipglob`: Returns an IPGlob object from the netaddr_ library (requires
the :code:`netaddr` package specifier).
- :code:`ipset`: Returns an IPSet object from the netaddr_ library (requires
the :code:`netaddr` package specifier).
Example usage can be seen in :code:`tests` and for specific filters in the
docstrings in :code:`template/filters.py`.
Jinja functions
---------------
- :code:`run`: Runs a command and returns the stdout, stderr and returncode
using run_. This function replaces the :code:`run` filter.
Example usage can be seen in :code:`tests` and for specific filters in the
docstrings in :code:`template/functions.py`.
Testing
-------
......@@ -152,3 +165,4 @@ at: https://git.shore.co.il/nimrod/.
.. _netaddr: https://netaddr.readthedocs.io/
.. _Pipenv: https://docs.pipenv.org
.. _run: https://docs.python.org/3.6/library/subprocess.html?highlight=popen#subprocess.run
......@@ -13,6 +13,7 @@ from os import environ
import sys
import argparse
import template.filters
import template.functions
# I ignore import errors here and fail on them later in the main function so
# the module can be imported by the setup.py with jinja missing so the
......@@ -31,9 +32,18 @@ def render(template_string):
env = Environment(autoescape=True)
# Add all functions in template.filters as Jinja filters.
# pylint: disable=invalid-name
for tf in filter(lambda x: not x.startswith("_"), dir(template.filters)):
for tf in filter(
lambda x: callable(getattr(template.filters, x))
and not x.startswith("_"),
dir(template.filters),
):
env.filters[tf] = getattr(template.filters, tf)
t = env.from_string(template_string)
functions = {
x: getattr(template.functions, x)
for x in dir(template.functions)
if callable(getattr(template.functions, x)) and not x.startswith("_")
}
t = env.from_string(template_string, globals=functions)
return t.render(environ)
......
......@@ -10,6 +10,8 @@ from __future__ import (
unicode_literals,
) # pylint: disable=duplicate-code
from template.functions import run # noqa: F401 pylint: disable=unused-import
def to_yaml(value):
r"""
......@@ -145,36 +147,6 @@ def jmespath(value, query):
return jp.search(query, value)
def run(*argv, **kwargs):
"""
Runs a command and returns the stdout, stderr and returncode
using `run
<https://docs.python.org/3.5/library/subprocess.html?highlight=popen#subprocess.run>`_.
>>> run('ls')["returncode"] == 0
True
>>> 'SHELL' not in run('echo $SHELL', shell=True)['stdout']
True
>>> run(['ls', 'foo'])['returncode'] > 0
True
"""
import sys
if sys.version_info[0] < 3: # nosec
import subprocess32 as subprocess
else:
import subprocess # nosemgrep: rules.bandit.B40
defaults = {"stdout": subprocess.PIPE, "stderr": subprocess.PIPE}
defaults.update(kwargs)
proc = subprocess.run( # nosec, pylint: disable=subprocess-run-check
*argv, **defaults
).__dict__
if "text" not in kwargs or kwargs["text"]:
proc["stdout"] = proc["stdout"].decode()
proc["stderr"] = proc["stderr"].decode()
return proc
def ipaddress(addr, version=None, flags=0):
"""
Returns an IPAddress object from the netaddr library.
......
#!/usr/bin/env python
"""Filters for the template CLI."""
# pylint: disable=import-error, import-outside-toplevel
from __future__ import (
absolute_import,
division,
print_function,
unicode_literals,
) # pylint: disable=duplicate-code
def run(*argv, **kwargs):
"""
Runs a command and returns the stdout, stderr and returncode
using `run
<https://docs.python.org/3.5/library/subprocess.html?highlight=popen#subprocess.run>`_.
>>> run('ls')["returncode"] == 0
True
>>> 'SHELL' not in run('echo $SHELL', shell=True)['stdout']
True
>>> run(['ls', 'foo'])['returncode'] > 0
True
"""
import sys
if sys.version_info[0] < 3: # nosec
import subprocess32 as subprocess
else:
import subprocess # nosemgrep: rules.bandit.B40
defaults = {"stdout": subprocess.PIPE, "stderr": subprocess.PIPE}
defaults.update(kwargs)
proc = subprocess.run( # nosec, pylint: disable=subprocess-run-check
*argv, **defaults
).__dict__
if "text" not in kwargs or kwargs["text"]:
proc["stdout"] = proc["stdout"].decode()
proc["stderr"] = proc["stderr"].decode()
return proc
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment