Skip to content

Commit c0b8942

Browse files
gmulocVibhu-gslab
andauthored
Fix(plugins): Make ansible global_vars work for ansible-core>=2.19 (#6619)
Co-authored-by: Vibhu-gslab <109593615+Vibhu-gslab@users.noreply.github.com>
1 parent 72aed3c commit c0b8942

4 files changed

Lines changed: 63 additions & 0 deletions

File tree

ansible_collections/arista/avd/plugins/vars/global_vars.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,9 +93,39 @@
9393
from ansible.plugins.vars import BaseVarsPlugin
9494
from ansible.utils.vars import combine_vars
9595

96+
from ansible_collections.arista.avd.plugins.plugin_utils.utils import ANSIBLE_ABOVE_2_19
97+
98+
if ANSIBLE_ABOVE_2_19:
99+
from ansible.template import trust_as_template
100+
96101
FOUND: list = []
97102

98103

104+
def _mark_strings_as_trusted(data: Any) -> Any:
105+
"""
106+
Recursively mark all strings in a data structure as trusted templates.
107+
108+
This is required for ansible-core >= 2.19 where the template trust model was inverted.
109+
Only strings marked as trusted can be rendered as Jinja2 templates.
110+
111+
Should only be called when ANSIBLE_ABOVE_2_19 is True.
112+
113+
Args:
114+
data: The data structure to process (can be dict, list, str, or any other type)
115+
116+
Returns:
117+
The same data structure with all strings marked as trusted templates
118+
"""
119+
if isinstance(data, str):
120+
return trust_as_template(data)
121+
if isinstance(data, dict):
122+
return {key: _mark_strings_as_trusted(value) for key, value in data.items()}
123+
if isinstance(data, list):
124+
return [_mark_strings_as_trusted(item) for item in data]
125+
126+
return data
127+
128+
99129
class VarsModule(BaseVarsPlugin):
100130
def find_variable_source(self, path: str, loader: object) -> list:
101131
"""Return the source files from which to load data, if the path is a directory - lookup vars file inside."""
@@ -144,8 +174,13 @@ def get_vars(self, loader: object, path: str, entities: Any, _cache: bool = True
144174
continue
145175

146176
for found_path in FOUND:
177+
# Load the file. In ansible-core < 2.19, unsafe=True allows Jinja2 templates to be rendered.
178+
# In ansible-core >= 2.19, we need to explicitly mark strings as trusted templates.
147179
new_data = loader.load_from_file(found_path, cache=True, unsafe=True)
148180
if new_data:
181+
if ANSIBLE_ABOVE_2_19:
182+
# Mark all strings in the loaded data as trusted templates for ansible-core >= 2.19
183+
new_data = _mark_strings_as_trusted(new_data)
149184
variables = combine_vars(variables, new_data)
150185

151186
return variables

ansible_collections/arista/avd/tests/integration/targets/vars_global_vars/global_vars.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,15 @@ overwritten_by_zz_global_vars_01: GLOBAL_VALUE
77
overwritten_by_zz_global_vars_02: GLOBAL_VALUE
88
not_overwritten_by_zz_global_vars_03: GLOBAL_VALUE
99
not_overwritten: GLOBAL_VALUE
10+
11+
# Test inline Jinja2 templating
12+
base_value: "BASE"
13+
jinja_template_simple: "{{ base_value }}_RENDERED"
14+
jinja_template_filter: "{{ base_value | lower }}_filtered"
15+
cleartext_password: "{{ vault.users.cvpadmin.password | default(lookup('ansible.builtin.env', 'CVP_PASSWORD'), true) }}"
16+
cleartext_password_2: "{{ lookup('ansible.builtin.env', 'CVP_PASSWORD') }}"
17+
18+
vault:
19+
users:
20+
cvpadmin:
21+
password: "vaulted_password"

ansible_collections/arista/avd/tests/integration/targets/vars_global_vars/playbook.yml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
---
2+
23
- name: Testing All
34
hosts: all
45
tasks:
6+
- name: Print Ansible version
7+
ansible.builtin.debug:
8+
msg: "Ansible version: {{ ansible_version.full }}"
9+
510
- name: Verify Global Variables
611
ansible.builtin.assert:
712
that:
@@ -11,6 +16,16 @@
1116
- not_overwritten_by_zz_global_vars_03 == 'GLOBAL_VALUE'
1217
- overwritten_by_group_all == 'ALL_VALUE'
1318

19+
- name: Verify Jinja2 Template Rendering
20+
ansible.builtin.assert:
21+
that:
22+
- base_value == 'BASE'
23+
- jinja_template_simple == 'BASE_RENDERED'
24+
- jinja_template_filter == 'base_filtered'
25+
- cleartext_password == 'vaulted_password'
26+
- cleartext_password_2 == 'env_password'
27+
fail_msg: "Jinja2 templates in global_vars are not being rendered correctly"
28+
1429
- name: Testing leaf1
1530
hosts: leaf1
1631
tasks:

ansible_collections/arista/avd/tests/integration/targets/vars_global_vars/runme.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
set -eux
44

5+
export CVP_PASSWORD="env_password"
56
# Testing with ansible.cfg
67
export ANSIBLE_CONFIG=./ansible.cfg
78
ansible-playbook -i hosts.yml playbook.yml

0 commit comments

Comments
 (0)