0

I am trying to write switch port VLAN configuration and it breaks because of the last comma on the output, I am trying get an output as follows
vlan trunk allowed 2600,2610,2620,2630,2640,2650
but getting
vlan trunk allowed 2600,2610,2620,2630,2640,2650,

my code currently looks like this

{% for i in interfaces|default([]) %}
interface {{ i.port }}
    no shutdown
    mtu {{ mtu }}
    description Link_to_{{ i.peer|lower }}
    no routing
    vlan trunk native 1
    vlan trunk allowed {% for vc in vlans_core %}{% if vc.src == inventory_hostname and vc.dst == i.peer %}{{ vc.tag }},{% endif %}{% endfor %}{% for vc in vlans_core %}{% if vc.dst == inventory_hostname and vc.src == i.peer %}{{ vc.tag }},{% endif %}{% endfor %}

{% endfor %}

I tired the join but it only produced errors.

{{ vc.tag|join(", ") }}

I have also tried loop.last but this also didn't work

{% if not loop.last %},{% endif %}

Any help would be appreciated.

programpee
  • 13
  • 3
  • 1
    `I tired the join but it only produced errors.` - `I have also tried loop.last but this also didn't work` => You should consider banning "It's not working" from your vocabulary on Q&A sites like SO, at least when used on its own. [It does not accurately describe your problem](http://idownvotedbecau.se/itsnotworking/) – Zeitounator Jan 06 '22 at 17:29

3 Answers3

0

This is a bit hard to answer without an example datastructure. So I'm not sure the following entirely meets your requirement since I only tested against my own guessed test data and I have no exact expected result to compare to. Think about those points for your next question.

Note also that the solution is ugly and could most probably be improved with a better explanation of your final goal (e.g. "I need to filter out vlan tags based on the following condition: ..."

Here I only give an example following the exact original conditions written down in your example template. The solution is to set a variable at the beginning of your outer loop (on interfaces) where you will store relevant tags to later join them at the needed line.

{% for i in interfaces|default([]) %}
{% set trunk_allowed =
  (
    (
      vlans_core
      | selectattr('src', '==', inventory_hostname)
      | selectattr('dst', '==', i.peer)
    )
    +
    (
      vlans_core
      | selectattr('dst', '==', inventory_hostname)
      | selectattr('src', '==', i.peer)
    )
  )
  | map(attribute='tag')
%}
interface {{ i.port }}
    no shutdown
    mtu {{ mtu }}
    description Link_to_{{ i.peer|lower }}
    no routing
    vlan trunk native 1
    vlan trunk allowed {{ trunk_allowed | join(',') }}

{% endfor %}

I suspect the var definition could be simplified to the following (but I'm not entirely sure, give it a try)

{% set trunk_allowed =
  vlans_core 
  | selectattr('src', 'in', [inventory_hostname, i.peer])
  | selectattr('dst', 'in', [inventory_hostname, i.peer])
  | map(attribute='tag')
%}
Zeitounator
  • 38,476
  • 7
  • 53
  • 66
0

I tried a few and found this has worked, by using the joiner function, which adds string except on the first instance.

{% for i in interfaces|default([]) %}
interface {{ i.port }}
    no shutdown
    mtu {{ mtu }}
    description Link_to_{{ i.peer|lower }}
    no routing
    vlan trunk native 1
    vlan trunk allowed {% set comma = joiner(",") %}{% for vc in inter_core_vlans|default([]) %}
{% if vc.src == inventory_hostname and vc.dst == i.peer %}{{ comma() }}{{ vc.tag }}{% endif %}
{% if vc.dst == inventory_hostname and vc.src == i.peer %}{{ comma() }}{{ vc.tag }}{% endif %}{% endfor %}

{% endfor %}
programpee
  • 13
  • 3
-1

I don't know what this syntax it. But logically you should put a check on length and item being processed(to check if its last item) and then if its not last item then include ,

Below may not be syntax-wise correct but approach wise some hint

vlan trunk allowed {% for vc in vlans_core %}{% if vc.src == inventory_hostname and vc.dst == i.peer %}{{ vc.tag }}{{(i<interfaces.length) ?,:''}}{% endif %}{% endfor %}{% for vc in vlans_core %}{% if vc.dst == inventory_hostname and vc.src == i.peer %}{{ vc.tag }}{{(i<interfaces.length) ?,:''}}{% endif %}{% endfor %}
Prateek
  • 374
  • 3
  • 7