aristanetworks / avd

Arista Validated Designs
https://avd.arista.com
Apache License 2.0
293 stars 211 forks source link

mlag_peer not avaiable for Context for interface_descriptions templates #4428

Closed PieterL75 closed 1 month ago

PieterL75 commented 1 month ago

Issue Summary

I have a mlag_port_channel_interfaces (and a mlag_ethernet_interfaces) template to generate the interface descriptions. But when I use {{ mlag_peer }} I get an error during the build playbook. I have to use {{ switch.mlag_peer }}, but seems to be deprecated in 4.x.x

Why is that variable not workign for the mlag_port_channel_interfaces and mlag_ethernet_interfaces interface_descriptions ?

Which component(s) of AVD impacted

eos_designs

How do you run AVD ?

Ansible CLI (with virtual-env or native python)

Steps to reproduce

Create a template mlag_ethernet_interfaces.j2 with the content
   MLAG:{{ mlag_peer }}:{{ mlag_interface }}

Assign this to the node_type_keys/interface_descriptions/mlag_ethernet_interfaces

run the build.yml

I using v4.10

Relevant log output

<localhost> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /home/avd/.ansible/tmp `"&& mkdir "` echo /home/avd/.ansible/tmp/ansible-tmp-1725460566.787541-1564389-118440501178577 `" && echo ansible-tmp-17
25460566.787541-1564389-118440501178577="` echo /home/avd/.ansible/tmp/ansible-tmp-1725460566.787541-1564389-118440501178577 `" ) && sleep 0'
The full traceback is:
Traceback (most recent call last):
  File "/home/avd/.local/lib/python3.12/site-packages/ansible/template/__init__.py", line 993, in do_template
    res = myenv.concat(rf)
          ^^^^^^^^^^^^^^^^
  File "/home/avd/.local/lib/python3.12/site-packages/ansible/template/native_helpers.py", line 81, in ansible_concat
    return ''.join([to_text(v) for v in nodes])
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<template>", line 14, in root
  File "/home/avd/.local/lib/python3.12/site-packages/ansible/template/__init__.py", line 294, in wrapper
    ret = func(*args, **kwargs)
          ^^^^^^^^^^^^^^^^^^^^^
  File "/home/avd/.local/lib/python3.12/site-packages/ansible/template/__init__.py", line 541, in _ansible_finalize
    return thing if _fail_on_undefined(thing) is not None else ''
                    ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/avd/.local/lib/python3.12/site-packages/ansible/template/__init__.py", line 513, in _fail_on_undefined
    elif is_sequence(data):
         ^^^^^^^^^^^^^^^^^
  File "/home/avd/.local/lib/python3.12/site-packages/ansible/module_utils/common/collections.py", line 93, in is_sequence
    if not include_strings and is_string(seq):
                               ^^^^^^^^^^^^^^
  File "/home/avd/.local/lib/python3.12/site-packages/jinja2/runtime.py", line 857, in _fail_with_undefined_error
    raise self._undefined_exception(self._undefined_message)
jinja2.exceptions.UndefinedError: 'mlag_peer' is undefined

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/avd/.local/lib/python3.12/site-packages/pyavd/_eos_designs/shared_utils/utils.py", line 49, in template_var
    return template_var(template_file, template_vars, self.templar)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/avd/.local/lib/python3.12/site-packages/pyavd/_utils/template_var.py", line 29, in template_var
    return str(template(template_file, template_vars, templar)).strip()
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/avd/.local/lib/python3.12/site-packages/pyavd/_utils/template.py", line 46, in template
    result = templar.template(j2template, convert_data=False, escape_backslashes=False)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/avd/.local/lib/python3.12/site-packages/ansible/template/__init__.py", line 747, in template
    result = self.do_template(
             ^^^^^^^^^^^^^^^^^
  File "/home/avd/.local/lib/python3.12/site-packages/ansible/template/__init__.py", line 1027, in do_template
    raise AnsibleUndefinedVariable(e)
ansible.errors.AnsibleUndefinedVariable: 'mlag_peer' is undefined

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/avd/.ansible/collections/ansible_collections/arista/avd/plugins/action/eos_designs_structured_config.py", line 94, in run
    output = get_structured_config(
             ^^^^^^^^^^^^^^^^^^^^^^
  File "/home/avd/.local/lib/python3.12/site-packages/pyavd/_eos_designs/structured_config/__init__.py", line 78, in get_structured_config
    results = eos_designs_module.render()
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/avd/.local/lib/python3.12/site-packages/pyavd/_eos_designs/structured_config/mlag/__init__.py", line 20, in render
    return super().render()
           ^^^^^^^^^^^^^^^^
  File "/home/avd/.local/lib/python3.12/site-packages/pyavd/_eos_designs/avdfacts.py", line 67, in render
    return {key: getattr(self, key) for key in self.keys() if getattr(self, key) is not None}
                                                              ^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/functools.py", line 995, in __get__
    val = self.func(instance)
          ^^^^^^^^^^^^^^^^^^^
  File "/home/avd/.local/lib/python3.12/site-packages/pyavd/_eos_designs/structured_config/mlag/__init__.py", line 207, in ethernet_interfaces
    "description": self.shared_utils.interface_descriptions.mlag_ethernet_interface(
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/avd/.local/lib/python3.12/site-packages/pyavd/_eos_designs/interface_descriptions/__init__.py", line 127, in mlag_ethernet_interface
    return self.mlag_ethernet_interfaces(mlag_interface=data.peer_interface)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/avd/.local/lib/python3.12/site-packages/pyavd/_eos_designs/interface_descriptions/__init__.py", line 132, in mlag_ethernet_interfaces
    return self._template(template_path, mlag_interface=mlag_interface)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/avd/.local/lib/python3.12/site-packages/pyavd/_eos_designs/interface_descriptions/__init__.py", line 34, in _template
    return self.shared_utils.template_var(template_path, template_vars)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/avd/.local/lib/python3.12/site-packages/pyavd/_eos_designs/shared_utils/utils.py", line 51, in template_var
    raise AristaAvdError(f"Error during templating of template: {template_file}") from e
pyavd._errors.AristaAvdError: Error during templating of template: mlag_ethernet_interfaces.j2
fatal: [beaz1-ix215-pp001-lfs-03.infra.cie.ac -> localhost]: FAILED! => {
    "changed": false,
    "msg": "Error during templating of template: mlag_ethernet_interfaces.j2"
}

Contributing Guide

PieterL75 commented 1 month ago

Additionally, I see that other defined variables are also not usable. I have a 'fact' called 'device_details'. That fact can be used in the connected_endpoints_ethernet_interfaces template, but not in the mlag interface templates

ClausHolbechArista commented 1 month ago

Thank you for reporting this. I can see that the docs mention that mlag_peer should be available, but all our own examples use the deprecated switch.mlag_peer, so this is clearly a bug on our side. We will fix the availability of mlag_peer, but until then you can use the switch.mlag_peer. We have moved on to work on 5.0 now, but I will mark this fix for backporting to a 4.10.2 release.

ClausHolbechArista commented 1 month ago

Additionally, I see that other defined variables are also not usable. I have a 'fact' called 'device_details'. That fact can be used in the connected_endpoints_ethernet_interfaces template, but not in the mlag interface templates

I cannot see any explanation for this difference. Please make sure your fact is scoped to all devices and not only set as fact on a subset of devices.

PieterL75 commented 1 month ago

Thank you for taking this and addressing the bug.

I use 4 interface templates on the devices. The ethernet templates can access that variable, but the mlag templates cannot, all in the same device

ClausHolbechArista commented 1 month ago

Thank you for taking this and addressing the bug.

If you have time I would appreciate if you could test the fix in #4429. Note the comment on that PR with instructions on how to download it.

I use 4 interface templates on the devices. The ethernet templates can access that variable, but the mlag templates cannot, all in the same device

That is really weird. The template code is exactly the same, including how it picks up "hostvars" in the templating context. Could it be some inplace update of the data that garbles is before the mlag template runs?

PieterL75 commented 1 month ago

I figured it out.. I started a new fabric, and that one does not have any connected endpoints defined, hence the ethernet template was never used. Turned out I marked out the vars_global_vars section in my ansible.cfg.. that is working now.

I'll see to get that #4429 tested out and let you know