{% macro systemsection(device,name) %} system { host-name {{ name }}; root-authentication { encrypted-password "{{ device['config_context']['root_pw'] }}"; ## Client Higher } login { class sysadmin { permissions [ admin clear configure control firewall-control interface interface-control network reset rollback routing routing-control snmp snmp-control trace-control view view-configuration ]; } {% for user, details in device['config_context']['users']|dictsort %} user {{ user }} { uid 200{{ loop.index }}; class {{ details['role'] }}; authentication { encrypted-password "{{ details['password'] }}"; ## SECRET-DATA } } {% endfor %} } services { ssh; } syslog { {% for server in device['config_context']['syslog_servers'] %} host {{ server }} { any notice; authorization info; } {% endfor %} file interactive-commands { interactive-commands any; } file linkupdown { any info; match "LINK_DOWN|LINK_UP"; } file messages { any notice; authorization info; } } {% if device['config_context']['ntp_servers']|length > 0 %} ntp { {% for server in device['config_context']['ntp_servers'] %} server {{ server }}; {% endfor %} } {% endif %} } {%- endmacro %} {% macro chassissection(device) %} chassis { aggregated-devices { ethernet { device-count {{ device['interfaces']|selectattr('type','eq','LAG')|list|count }}; } } {% if device['config_context']['breakout_ports'] %} {% for fpc, fpcdata in device['config_context']['breakout_ports'].items() %} fpc {{ fpc }} { {% for pic, picdata in fpcdata.items() %} pic {{ pic }} { {% for port, speed in picdata.items() %} port {{ port }} { channel-speed {{ speed }}; } {% endfor %} } {% endfor %} } {% endfor %} {% endif %} } {%- endmacro %} {% macro interfaceconfig(interface,rack = None) %} {{ interface['name'] }} { {% if interface.get('description') != '' %} description "{{ interface['description'] }}"; {% endif %} {% if interface.get('mtu') and not interface.get('lag') %} mtu {{ interface['mtu'] }}; {% endif %} {% if interface.get('lag') %} ether-options { 802.3ad {{ interface['lag']['name'] }}; } {% endif %} {% if interface['name'].startswith('ae') %} {% if interface['_custom_field_data']['esi_lag'] %} esi { auto-derive { lacp; } all-active; } {% endif %} aggregated-ether-options { lacp { periodic fast; {% if interface['_custom_field_data']['system_id'] %} system-id {{ interface['_custom_field_data']['system_id'] }}; {% elif interface['_custom_field_data']['esi_lag'] %} system-id 00:00:{{ '%02d' % rack|int }}:{% if interface['name'][2:]|int < 99 %}{{ '%02d' % interface['name'][2:]|int }}{% else %}{{ '%02x' % interface['name'][2:]|int }}{% endif %}:00:01; {% endif %} } } {% endif %} {% if interface['ip_addresses']|length > 0 %} unit 0 { family inet { {% if interface['ip_addresses'][0]['status']['name'] == 'Reserved' %}inactive: {% endif %}address {{ interface['ip_addresses'][0]['address'] }}; } } {% endif %} {% if interface.get('mode') is not none %} unit 0 { family ethernet-switching { {% if interface['mode']=='ACCESS' %} interface-mode access; vlan { members {{ interface['untagged_vlan']['vid'] }}; } {% elif interface['mode']=='TAGGED' %} interface-mode trunk; vlan { members [ {% for vlan in interface['tagged_vlans'] %}{{ vlan['vid'] }} {% endfor %}]; } {% elif interface['mode']=='TAGGED_ALL' %} interface-mode trunk; vlan { members [ all ]; } {% endif %} storm-control default; } } {% endif %} } {%- endmacro %} {% macro interfacesection(device,vlans) %} interfaces { {# Physical interfaces should be sorted by FPC/PIC/Port value - that's a challenge to do in Jinja so we cheat for now by putting the xe- interfaces first. This won't work for all devices! #} {% for interface in device['interfaces'] if interface['name'].startswith('xe-') %} {{ interfaceconfig(interface) }} {% endfor %} {% for interface in device['interfaces'] if interface['name'].startswith('et-') %} {{ interfaceconfig(interface) }} {% endfor %} {% for interface in device['interfaces'] if interface['name'].startswith('ae') %} {{ interfaceconfig(interface,device['rack']['name'][5:]) }} {% endfor %} {% for interface in device['interfaces'] if interface['name']=='em0' %} {{ interfaceconfig(interface) }} {% endfor %} {% for interface in device['interfaces'] if interface['name'].startswith('irb') %} {% if loop.first %} irb { {% endif %} unit {{ interface['name'][4:] }} { description "{{ interface['description'] }}"; family inet { {% if interface['ip_addresses'][0]['status']['name'] == 'Reserved' %}inactive: {% endif %}address {{ interface['ip_addresses'][0]['address'] }}; } } {% if loop.last %} } {% endif %} {% endfor %} {% for interface in device['interfaces'] if interface['name'].startswith('lo') %} {{ interfaceconfig(interface) }} {% endfor %} } {%- endmacro %} {% macro snmpsection(rack, config_context) %} snmp { location "Domicilium Datacentre {{ rack['name'] }}"; contact "{{ config_context['snmp']['contact'] }}"; community {{ config_context['snmp']['community'] }} { authorization read-only; {% for client in config_context['snmp']['clients'] %} {% if loop.first %} clients { {% endif %} {{ client }}; {% if loop.last %} } {% endif %} {% endfor %} } } {%- endmacro %} {% macro routingoptionssection(primary_ip4, config_context) %} routing-options { router-id {{ primary_ip4['address'][:-3] }}; autonomous-system {{ config_context['overlay_as'] }}; {% if config_context['gateway'] %} static { route 0.0.0.0/0 next-hop {{ config_context['gateway'] }}; } {% endif %} forwarding-table { export PFE-ECMP; chained-composite-next-hop { ingress { evpn; } } } } {%- endmacro %} {% macro bgprrmeshgroup(device,spines) %} group OVERLAY_RR_MESH { type internal; family evpn { signaling; } bfd-liveness-detection { minimum-interval 350; multiplier 3; session-mode automatic; } {% for dst_switch in spines if dst_switch['primary_ip4']['address'] != device['primary_ip4']['address'] %} neighbor {{ dst_switch['primary_ip4']['address'][:-3] }}; {% endfor %} } {%- endmacro %} {% macro bgpoverlaygroup(device) %} group OVERLAY { type internal; local-address {{ device['primary_ip4']['address'][:-3] }}; family evpn { signaling; } {% if device['device_role']['name'] == 'Spine' %} cluster {{ device['primary_ip4']['address'][:-3] }}; multipath; {% endif %} bfd-liveness-detection { minimum-interval 350; multiplier 3; session-mode automatic; } {% for dst_switch in device['peering_interfaces'] %} neighbor {{ dst_switch['cable_peer_interface']['device']['primary_ip4']['address'][:-3] }}; {% endfor %} } {%- endmacro %} {% macro bgpunderlaygroup(device) %} group UNDERLAY { type external; hold-time 10; family inet { unicast; } export BGP_LOOPBACK0; local-as {{ device['config_context']['underlay_as'] }}; multipath { multiple-as; } {% for dst_switch in device['peering_interfaces'] %} neighbor {{ dst_switch['cable_peer_interface']['ip_addresses'][0]['address'][:-3] }} { peer-as {{ dst_switch['cable_peer_interface']['device']['local_context_data']['underlay_as'] }}; } {% endfor %} } {%- endmacro %} {% macro bgpsection(device,spines) %} {% if device['device_role']['name'] in ['Spine','Lab-Spine'] %} {% set role='Spine' %} {% set other_role='Leaf' %} {% else %} {% set role='Leaf' %} {% set other_role='Spine' %} {% endif %} {% if device['device_role']['name'] == 'Lab-Spine' %} {% set name=device['name'][4:] %} {% else %} {% set name=device['name'] %} {% endif %} bgp { {{ bgpoverlaygroup(device) }} {% if role == 'Spine' %} {{ bgprrmeshgroup(device,spines) }} {% endif %} {{ bgpunderlaygroup(device) }} log-updown; } {%- endmacro %} {% macro sflowsection(device) %} {% if device['config_context']['sflow'] %} sflow { {% for collector in device['config_context']['sflow']['collectors'] %} collector {{ collector }}; {% endfor %} {% for interface in device['config_context']['sflow']['interfaces'] %} interface {{ interface }}; {% endfor %} } {% endif %} {%- endmacro %} {% macro vlanssection(vlans,device) %} vlans { {# This next line selects all of the VLANs which are configured on this device #} {% for vlan in vlans if (device['interfaces']|selectattr('untagged_vlan.vid','equalto',vlan)|list|count or interfaces|map(attribute='tagged_vlans')|sum(start=[])|selectattr('vid','equalto',vlan)|list|count) or device['interfaces']|selectattr('name', 'equalto', 'irb.'+vlan['vid']|string)|list|count %} vl{{ vlan['vid'] }} { {% if vlan['name'] != '' %} description "{{ vlan['name'] }}"; {% endif %} vlan-id {{ vlan['vid'] }}; {% if device['interfaces']|selectattr('name', 'equalto', 'irb.'+vlan['vid']|string)|list|count %} l3-interface irb.{{vlan['vid']}}; {% endif %} vxlan { vni {{ vlan['vid'] }}; } } {% endfor %} } {%- endmacro %}