hobarton_config_templates/juniper-macros.j2

335 lines
9.4 KiB
Django/Jinja

{% macro systemsection(device,root_pw,users,syslog_servers,ntp_servers) %}
system {
host-name {{ device.hostname }};
root-authentication {
encrypted-password "{{ 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 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 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 ntp_servers|length > 0 %}
ntp {
{% for server in ntp_servers %}
server {{ server }};
{% endfor %}
}
{% endif %}
}
{%- endmacro %}
{% macro chassissection(device,breakout_ports) %}
chassis {
aggregated-devices {
ethernet {
device-count {{ device.interfaces.all()|selectattr('type','eq','lag')|list|count }};
}
}
{% 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 %}
}
{%- endmacro %}
{% macro interfaceconfig(interface,rack = None) %}
{{ interface.name }} {
{% if interface.description != '' %}
description "{{ interface.description }}";
{% endif %}
{% if interface.mtu and not interface.lag %}
mtu {{ interface.mtu }};
{% 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 {
family inet {
{% if interface.ip_addresses.first().status == 'reserved' %}inactive: {% endif %}address {{ interface.ip_addresses.first().address }};
}
}
{% endif %}
{% 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;
}
}
{% 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.filter(name__startswith='xe-') %}
{{ interfaceconfig(interface) }}
{% endfor %}
{% for interface in device.interfaces.filter(name__startswith='et-') %}
{{ 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(rack, snmp) %}
snmp {
location "Domicilium Datacentre {{ rack['name'] }}";
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 routingoptionssection(device, gateway) %}
routing-options {
router-id {{ device.primary_ip4.address.ip }};
autonomous-system {{ device.local_context_data['overlay_as'] }};
{% if gateway %}
static {
route 0.0.0.0/0 next-hop {{ 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.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].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].primary_ip4.address.ip }} {
peer-as {{ interface.connected_endpoints[0].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 %}