Skip to content

Commit

Permalink
WIP: refactor template functions
Browse files Browse the repository at this point in the history
  • Loading branch information
ipspace committed Jul 5, 2023
1 parent b490a07 commit 31ede2d
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 14 deletions.
2 changes: 1 addition & 1 deletion netsim/augment/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

from box import Box
from .. import common
from ..utils.templates import get_moddir
from ..utils.files import get_moddir
from .. import data

def load_plugin_from_path(path: str, plugin: str) -> typing.Optional[object]:
Expand Down
1 change: 0 additions & 1 deletion netsim/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
from .utils.log import MissingValue, IncorrectAttr, IncorrectValue, IncorrectType, FatalError, ErrorAbort
from .utils.log import fatal, error, exit_on_error, set_logging_flags, set_flag, print_verbose, debug_active
from .utils.strings import extra_data_printout,format_structured_dict,print_structured_dict
from .utils.templates import template,write_template

AF_LIST = ['ipv4','ipv6']
BGP_SESSIONS = ['ibgp','ebgp']
Expand Down
8 changes: 7 additions & 1 deletion netsim/outputs/ansible.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from . import _TopologyOutput,check_writeable
from ..augment import nodes
from ..augment import devices
from ..utils import templates

forwarded_port_name = { 'ssh': 'ansible_port', }

Expand Down Expand Up @@ -194,7 +195,12 @@ def ansible_config(config_file: typing.Union[str,None] = 'ansible.cfg', inventor
inventory_file = 'hosts.yml'

with open(config_file,"w") as output:
output.write(common.template('ansible.cfg.j2',{ 'inventory': inventory_file or 'hosts.yml' },'templates','ansible'))
cfg_text = templates.template(
j2_file='ansible.cfg.j2',
data={'inventory': inventory_file or 'hosts.yml'},
path='templates',
user_template_path='ansible')
output.write(cfg_text)
output.close()
if not common.QUIET:
print("Created Ansible configuration file: %s" % config_file)
Expand Down
2 changes: 1 addition & 1 deletion netsim/outputs/tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ def create_tool_config(tool: str, topology: Box) -> None:
elif 'template' in config:
template = config.template
config_text = templates.template(
j2=config.template,
j2_file=config.template,
data=topo_data,
path=f'tools/{tool}',
user_template_path=f'tools/{tool}')
Expand Down
50 changes: 40 additions & 10 deletions netsim/utils/templates.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

from jinja2 import Environment, PackageLoader, FileSystemLoader, StrictUndefined, make_logging_undefined

from .log import debug_active
from .log import debug_active,fatal
from .files import get_moddir

ansible_filter_map: dict = {}
Expand All @@ -17,23 +17,53 @@ def add_ansible_filters(ENV: Environment) -> None:
for k,v in ansible_filter_map.items():
ENV.filters[k] = v

def template(j2: str , data: typing.Dict, path: str, user_template_path: typing.Optional[str] = None) -> str:
"""
Render a Jinja2 template
Template parameters:
* j2_file -- the name of the Jinja2 file
* j2_text -- the template text (potentially from a topology setting)
Path parameters:
* template_path -- fully specified template path, overrides any other combo
* path -- relative path to search in package directory or current/absolute directory
* user_template_path -- subdirectory of user directories to search (current, home)
"""

def template(
j2_file: typing.Optional[str],
data: typing.Dict,
path: typing.Optional[str] = None,
user_template_path: typing.Optional[str] = None,
template_path: typing.Optional[list] = None,
j2_text: typing.Optional[str] = None) -> str:

global ansible_filter_map
load_ansible_filters()

if path [0] in ('.','/'): # Absolute path or path relative to current directory?
template_path = [ path ]
else: # Path relative to netsim module, add module path to it
template_path = [ str(get_moddir() / path) ]
if not user_template_path is None:
template_path = [ './' + user_template_path, os.path.expanduser('~/.netlab/'+user_template_path) ] + template_path
if template_path is None:
template_path = []
if path is not None:
if path [0] in ('.','/'): # Absolute path or path relative to current directory?
template_path = [ path ]
else: # Path relative to netsim module, add module path to it
template_path = [ str(get_moddir() / path) ]
if not user_template_path is None:
template_path = [ './' + user_template_path, os.path.expanduser('~/.netlab/'+user_template_path) ] + template_path
if debug_active('template'):
print(f"TEMPLATE PATH for {j2}: {template_path}")
print(f"TEMPLATE PATH for {j2_file or 'text'}: {template_path}")
ENV = Environment(loader=FileSystemLoader(template_path), \
trim_blocks=True,lstrip_blocks=True, \
undefined=make_logging_undefined(base=StrictUndefined))
add_ansible_filters(ENV)
template = ENV.get_template(j2)
if j2_file is not None:
template = ENV.get_template(j2_file)
elif j2_text is not None:
template = ENV.from_string(j2_text)
else:
fatal('Internal error: Call to template function with missing J2 file and J2 text, aborting')
return ""

return template.render(**data)

#
Expand Down

0 comments on commit 31ede2d

Please sign in to comment.