[Python API] How to render jinja2 template from within python / retrieve list of variables for the currently executed play&task.

33 views
Skip to first unread message

Cukier

unread,
Jul 1, 2020, 5:09:19 AM7/1/20
to Ansible Development
Recently I've been trying to mess a little with Ansible's Python API (I am well aware it is not recommended, and python API is meant only for internal use, however...).

My goal was to create a function that's able to retrieve data from ansible-playbook, which basically means two things:

1. retrieve the raw data by parsing YAML files,
> the simplest solution, is to let ansible do this, and then pass "{{ vars }}" to the module/plugin (at the level of YAML file)
> a more complicated solution is to use: ansible.vars.manager.VariableManager

2. render the jinja2 template
> because ansible stores them, inside variables, instead of what they evaluate to. 
> that's why I need/want to render jinja2 using ansible's API, at the level of .py file.

Questions:
1. is there any way to retrieve current play & current task from within a .py file from within a 
module/plugin (when a said module/plugin is being executed, just like the code below), so I can pass it to the variables = variable_manager.get_vars(...) 2. is there a better way to do what I am trying to do?

from ansible import context
from ansible.inventory.manager import InventoryManager
from ansible.parsing.dataloader import DataLoader
from ansible.template import Templar
from ansible.vars.manager import VariableManager

def render(template):
   """
   Render jinja2 template using Anisble's API.
   """
   options = context.CLIARGS
   sources = options['inventory']
   loader = DataLoader()
   inventory = InventoryManager(
       loader = loader,
       sources = sources
   )
   variable_manager = VariableManager(
       loader = loader,
        inventory = inventory
   )
   templar = Templar(
       loader = DataLoader(),
       variables = variable_manager.get_vars(...) # <<< HERE
   )
   return templar.template(template)

def filter_render_test(*args, **kwargs):
   return render("{{ foo }}")

class FilterModule(object):
   def filters(self):
       return {
           'render_test': filter_render_test,
       }
and the corresponding playbook:
---
- name: Test jinja2 renderer.
  hosts
: all
  vars
:
 
- foo: "success"
  tasks
:
 
- debug:
      msg
: "{{ '' | render_test }}"
...

Reply all
Reply to author
Forward
0 new messages