Saturday, November 23, 2024

Testing Traefik's dyn.toml jinja template generation with python.

Thought I'd share the simple python code to dry run the jinja template with variables. I needed to do it for the Traefik proxy dyn.toml. Especially with their change of using multiple Host and PathPrefix conditions, instead of having multiple parameters inside these.

Here is the code:

from jinja2 import Environment, select_autoescape, FileSystemLoader

env = Environment(loader=FileSystemLoader(
searchpath='./'))

context = {
    'fqdn': 'xx1.blocoware.com',
    'http_services': [
{
    'name': 'adiona',
    'priority': '2',
    'path_prefix': '`/prefix1/`, `/prefix2/`',
    'all_fqdn_aliases': 'zz1.blocoware.com,xx1.blocoware.com,yy1.blocoware.com',
    'ip_port': '127.0.0.1:111'
},
{
    'name': 'beacon',
    'priority': '4',
    'path_prefix': '`/prefix2/`',
    'all_fqdn_aliases': 'zz1.blocoware.com,xx1.blocoware.com,yy1.blocoware.com',
    'ip_port': '127.0.0.1:333'
}
]}

template = env.get_template('dyn.toml.j2')

body = template.render(context)

print(body)

And fragment of the dyn.toml.j2 to show the usage of the context:

 [http.routers]
{% for service in http_services %}
  {% set domains = all_fqdn_aliases.split(',') %}
  {% set prefixes = service.path_prefix.split(',') %}
  [http.routers.{{ service.name }}]
    rule = "({% for domain in domains %}Host(`{{ domain }}`){% if not loop.last %} || {% endif %}{% endfor %}) && ({% for prefix in prefixes %}PathPrefix({{ prefix }}){% if not loop.last %} || {% endif %}{% endfor %})"
    entrypoints = ["main", "main-secure"]
    ...

Rendered fragment:

  [http.routers.adiona]
    rule = "(Host(`zz1.blocoware.com`) || Host(`xx1.blocoware.com`) || Host(`yy1.blocoware.com`)) && (PathPrefix(`/prefix1/`) || PathPrefix( `/prefix2/`))"
    entrypoints = ["main", "main-secure"]
    ...
These are my first lines of python code ever, so I'm letting you to cope with the python environment setup. 

Somehow I confirmed to vscode to create this environment in some folder and I had to copy dyn.toml.j2 there, otherwise it could not find it, regardless the searchpath. Run button is fortunately just above the python window :). You'll need to install python extension, but vscode offers that once you create your first python file, cool.

No comments: