{% macro systemsection(device,root_pw,users,syslog_servers,ntp_servers,tacacs_servers) %} system { host-name {{ device.name }}; {% if tacacs_servers %} authentication-order [ tacplus password ]; {% endif %} root-authentication { encrypted-password "{{ root_pw }}"; ## Client Higher } {% if tacacs_servers %} tacplus-server { {% for server, details in tacacs_servers %} {{ server }} { port 49; secret "{{ details['secret'] }}"; ## SECRET-DATA source-address {{ device.primary_ip4.address.ip }}; } {% endfor %} } {% endif %} 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 users|dictsort %} user {{ user }} { uid 200{{ loop.index }}; class {{ details['role'] }}; {% if details['password'] %} authentication { encrypted-password "{{ details['password'] }}"; ## SECRET-DATA } {% endif %} } {% endfor %} } services { {% if device.role.name in ['Leaf','Spine'] %} ssh; {% else %} ssh { root-login deny; } {% endif %} } syslog { {% for server in syslog_servers %} host {{ server }} { any notice; authorization info; {% if device.role.name in ['Leaf','Spine'] %} match "!(.*DH_SVC_SENDMSG_FAILURE.*|.*UI_.*|.*shmlog: unable to create argtype.*|.*DEBUG: PAM_USER.*|.*DEBUG: PAM_ACTUAL_USER.*|.*SNMPD_AUTH_FAILURE.*|.*/usr/sbin/cron.*|.*jl2tpd.*|.*dfcd.*|.*l2ald.*|.*cc_mic_sfp_is_present.*|.*RMOPD_ICMP_SENDMSG_FAILURE.*|.*acx_vpls_mesh_grp_get_info.*|.*last message repeated.*|.*Refreshing mastership.*|.*hw.chassis.startup_time update.*)"; facility-override local6; {% endif %} } {% endfor %} file interactive-commands { interactive-commands any; } {% if device.role.name in ['Leaf','Spine'] %} file linkupdown { any info; match "LINK_DOWN|LINK_UP"; } file messages { any notice; authorization info; } {% endif %} } {% if ntp_servers|length > 0 %} ntp { {% for server in ntp_servers %} server {{ server }}; {% endfor %} } {% endif %} } {%- endmacro %} {% macro chassissection(device,breakout_ports) %} chassis { {% if device.interfaces.all()|selectattr('type','eq','lag')|list|count > 0 %} aggregated-devices { ethernet { device-count {{ device.interfaces.all()|selectattr('type','eq','lag')|list|count }}; } } {% endif %} {% if breakout_ports %} {% for fpc, fpcdata in 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 %} {% if device.role.name in ['Provider Core'] %} forwarding-options { lpm-profile; } {% endif %} } {%- endmacro %} {% macro interfaceconfig(interface,rack = None) -%} {% if not ('-' in interface.name) or interface.description or interface.lag or interface.ip_addresses.count() or interface.connected_endpoints or interface.mode or interface.tagged_vlans.all() or interface.untagged_vlan %} {{ interface.name }} { {% if interface.description %} description "{{ interface.description }}"; {% endif %} {% if interface.mtu and not interface.lag %} mtu {{ interface.mtu }}; {% endif %} {% if interface.device.role.name in ['Provide Core'] %} flexible-vlan-tagging; native-vlan-id 1; encapsulation flexible-ethernet-services; {% endif %} {% if interface.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.count() > 0 %} unit 0 { {% if (interface.connected_endpoints) and (interface.connected_endpoints[0].device.role.name == 'Provider Core') %} vlan-id 1; {% endif %} family inet { {% if interface.ip_addresses.first().status == 'reserved' %}inactive: {% endif %}address {{ interface.ip_addresses.first().address }}; } } {% endif %} {% if interface.device.role.name in ['Leaf','Spine'] %} {% if interface.mode != '' %} 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; } } {% elif interface.device.role.name in ['Provider Core'] and interface.connected_endpoints %} {% if interface.connected_endpoints[0].device.role.name in ['Provider Edge'] %} {% for vlan in interface.tagged_vlans %} unit {{ vlan.vid }} { encapsulation vlan-vpls; vlan-id {{ vlan.vid }}; } {% endfor %} {% endif %} {% endif %} {% endif %} } {% endif %} {%- endmacro %} {% macro interfacesection(device,vlans) %} interfaces { {% if device.role.name in ['Provider Core'] %} interface-range core-mpls { {% for interface in device.interfaces.filter(cable__isnull=False) %} {% if interface.connected_endpoints and interface.connected_endpoints[0].device.role.name in ['Provider Core'] %} member {{ interface }}; {% endif %} {% endfor %} unit 0 { family inet; family mpls; } } {% endif %} {# 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.filter(name__contains='-')|j2_natsort(attribute="name") %} {{- interfaceconfig(interface) }} {% endfor %} {% for interface in device.interfaces.filter(name__startswith='ae') %} {{ interfaceconfig(interface,device.rack.name[5:]) }} {% endfor %} {% for interface in device.interfaces.filter(name__exact='em0') %} {{ interfaceconfig(interface) }} {% endfor %} {% for interface in device.interfaces.filter(name__startswith='irb') %} {% if loop.first %} irb { {% endif %} unit {{ interface.name[4:] }} { description "{{ interface.description }}"; family inet { {% if interface.ip_addresses.first().status == 'reserved' %}inactive: {% endif %}address {{ interface.ip_addresses.first().address }}; } } {% if loop.last %} } {% endif %} {% endfor %} {% for interface in device.interfaces.filter(name__startswith='lo') %} {{ interfaceconfig(interface) }} {% endfor %} } {%- endmacro %} {% macro snmpsection(device, snmp) %} snmp { {% if device.rack and device.rack.site %} location "{{ device.rack.site.name }} Rack {{ device.rack.name }}"; {% elif device.rack and device.site %} location "{{ device.site.name }} Rack {{ device.rack.name }}"; {% elif device.site %} location "{{ device.site.name }}" {% elif device.rack %} location "{{ device.rack.name }}" {% endif %} contact "{{ snmp['contact'] }}"; community {{ snmp['community'] }} { authorization read-only; {% for client in snmp['clients'] %} {% if loop.first %} clients { {% endif %} {{ client }}; {% if loop.last %} } {% endif %} {% endfor %} } } {%- endmacro %} {% macro forwardingoptionssection(device) %} forwarding-options { hash-key { family inet { layer-4; } family mpls { label-1; label-2; payload { ip { port-data; } } } } family inet { filter { input protect_RE; } } } {%- endmacro %} {% macro routingoptionssection(device, overlay_as = None, gateway = None, routes = None) %} routing-options { {% if device.primary_ip4 %} router-id {{ device.primary_ip4.address.ip }}; {% endif %} {% if overlay_as %} autonomous-system {{ overlay_as }}; {% endif %} {% if gateway or routes %} static { {% if gateway %} route 0.0.0.0/0 next-hop {{ gateway }}; {% endif %} } {% 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.ip }}; {% endfor %} } {%- endmacro %} {% macro bgpoverlaygroup(device) %} group OVERLAY { type internal; local-address {{ device.primary_ip4.address.ip }}; family evpn { signaling; } {% if device.role.name == 'Spine' %} cluster {{ device.primary_ip4.address.ip }}; multipath; {% endif %} bfd-liveness-detection { minimum-interval 350; multiplier 3; session-mode automatic; } {% for interface in device.interfaces.filter(cable__isnull=False) %} neighbor {{ interface.connected_endpoints[0].device.primary_ip4.address.ip }}; {% endfor %} } {%- endmacro %} {% macro bgpunderlaygroup(device) %} group UNDERLAY { type external; hold-time 10; family inet { unicast; } export BGP_LOOPBACK0; local-as {{ device.local_context_data['underlay_as'] }}; multipath { multiple-as; } {% for interface in device.interfaces.filter(cable__isnull=False) %} neighbor {{ interface.connected_endpoints[0].ip_addresses.first().address.ip }} { peer-as {{ interface.connected_endpoints[0].device.local_context_data['underlay_as'] }}; } {% endfor %} } {%- endmacro %} {% macro bgpsection(device,spines) %} {% if device.role.name in ['Spine','Lab-Spine'] %} {% set role='Spine' %} {% set other_role='Leaf' %} {% else %} {% set role='Leaf' %} {% set other_role='Spine' %} {% endif %} {% set name=device.name %} bgp { {{ bgpoverlaygroup(device) }} {% if role == 'Spine' %} {{ bgprrmeshgroup(device,spines) }} {% endif %} {{ bgpunderlaygroup(device) }} log-updown; } {%- endmacro %} {% macro sflowsection(sflow) %} sflow { {% for collector in sflow['collectors'] %} collector {{ collector }}; {% endfor %} {% for interface in sflow['interfaces'] %} interfaces {{ interface }}.0; {% endfor %} } {%- 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.all()|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.all()|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.all()|selectattr('name', 'equalto', 'irb.'+vlan.vid|string)|list|count %} l3-interface irb.{{vlan.vid}}; {% endif %} vxlan { vni {{ vlan.vid }}; } } {% endfor %} } {%- endmacro %}