Compare commits

...

50 Commits
main ... netbox

Author SHA1 Message Date
Daniel Ankers 02b05dd0f1 Roll back last whitespace fix 2024-07-05 15:10:31 +01:00
Daniel Ankers 30fe75a9ed Fix(?) whitespace 2024-07-05 15:05:34 +01:00
Daniel Ankers d589158826 Fix(?) whitespace 2024-07-05 14:59:26 +01:00
Daniel Ankers 2a22e2d507 Fix(?) whitespace 2024-07-05 14:53:29 +01:00
Daniel Ankers 23024dfdf2 Fix(?) whitespace 2024-07-05 14:34:00 +01:00
Daniel Ankers 0d82de4f5b Fix(?) whitespace 2024-07-05 14:32:08 +01:00
Daniel Ankers aa03cc7fca Fix errors 2024-07-05 14:22:57 +01:00
Daniel Ankers a4b99e8297 Fix errors 2024-07-05 14:07:20 +01:00
Daniel Ankers eb2b3ab255 Fix errors 2024-07-05 13:59:02 +01:00
Daniel Ankers 8fc40e6c19 Don't put interfaces with no settings into the configuration 2024-07-05 13:49:44 +01:00
Daniel Ankers a89fea37a9 Fix typo 2024-07-05 12:06:30 +01:00
Daniel Ankers d24db4deb2 More natsort work 2024-07-05 12:03:49 +01:00
Daniel Ankers 8f663cff8f More natsort work 2024-07-04 16:32:40 +01:00
Daniel Ankers 9d03162886 Fix natural sorting 2024-07-04 15:53:44 +01:00
Daniel Ankers 9a33973452 Fix natural sorting 2024-07-04 15:48:16 +01:00
Daniel Ankers 73895d1e5d Sort interface names - requires using 'natsort' module and configuring custom Jinja2 filter 2024-07-04 15:40:30 +01:00
Daniel Ankers 1392e221c7 Fix bug 2024-07-04 15:07:57 +01:00
Daniel Ankers bb7a882a46 Cope better with no primary IP4 2024-07-04 14:58:03 +01:00
Daniel Ankers 2617f6bdfe Cope better with no rack information 2024-07-04 14:56:24 +01:00
Daniel Ankers ee0620612b Change link_peers to connected_endpoints; fix bug in snmpsection 2024-07-04 14:50:57 +01:00
Daniel Ankers 3bd19cd510 Fix logic bug 2024-07-04 14:20:02 +01:00
Daniel Ankers 3809e48b77 Fix logic bug 2024-07-04 14:17:53 +01:00
Daniel Ankers f53e744e32 Fix typo 2024-07-04 14:16:20 +01:00
Daniel Ankers 3afc609244 Jinja2 uses 'and', not '&&' 2024-07-04 14:12:50 +01:00
Daniel Ankers d669ba6e43 WIP changes for VPLS Core 2024-07-04 13:46:17 +01:00
Daniel Ankers 561e4edf38 Add namespace to tags 2024-07-03 16:45:07 +01:00
Dan Ankers 604dc68a6e WIP changes 2024-06-29 14:55:30 +01:00
Dan Ankers 64c62977bc Fix hostname 2024-06-29 13:56:43 +01:00
Dan Ankers 7f54dc2961 Fix device role 2024-06-29 13:52:57 +01:00
Dan Ankers e2f58ebd8f Fix device role 2024-06-29 13:49:20 +01:00
Dan Ankers d771421e93 Missing endif 2024-06-29 13:42:19 +01:00
Dan Ankers 0b674b1f6a Support GE interfaces 2024-06-29 13:33:22 +01:00
Dan Ankers 91bf65108f In progress update for non-VXLAN roles 2024-06-29 10:42:13 +01:00
Dan Ankers 8b8733e8f9 Delete old symlinks 2024-06-29 10:23:36 +01:00
Dan Ankers dd25434241 Fix overlay AS 2024-06-28 22:45:01 +01:00
Dan Ankers bbd8b63f31 Fix neighbour addresses for overlay 2024-06-28 21:05:12 +01:00
Dan Ankers d243b4ab05 Correct local context 2024-06-28 20:47:26 +01:00
Dan Ankers b03b646aa2 Correct IP address 2024-06-28 20:45:18 +01:00
Dan Ankers 86b64d6454 Correct IP address 2024-06-28 20:42:16 +01:00
Dan Ankers 6d62bf9c35 More fixes 2024-06-28 20:34:34 +01:00
Dan Ankers 81ff852d89 More fixes 2024-06-28 20:28:24 +01:00
Dan Ankers 95d2d5caec Correct rack 2024-06-28 20:21:40 +01:00
Daniel Ankers d281e6c8a3 Fix queryset use 2024-06-28 17:29:02 +01:00
Daniel Ankers 9e8cd2d385 Fix typos/thinkos 2024-06-28 17:22:31 +01:00
Daniel Ankers 41be232924 Fix typos/thinkos 2024-06-28 17:19:32 +01:00
Daniel Ankers ddf018c4f9 Fix not equals sign 2024-06-28 15:24:56 +01:00
Daniel Ankers c6cab802be More converting from Nautobot GraphQL/JSON to Netbox objects 2024-06-28 15:17:34 +01:00
Daniel Ankers 5114a4fcad Fix some selections which no longer come from GraphQL 2024-06-28 13:13:22 +01:00
Daniel Ankers 7fa90e6df9 Fix error 2024-06-28 11:57:26 +01:00
Daniel Ankers 21b228b71b Changes for Netbox 2024-06-28 09:53:02 +01:00
4 changed files with 204 additions and 105 deletions

View File

@ -1,36 +1,63 @@
{% macro systemsection(device) %} {% macro systemsection(device,root_pw,users,syslog_servers,ntp_servers,tacacs_servers) %}
system { system {
host-name {{ device['hostname'] }}; host-name {{ device.name }};
{% if tacacs_servers %}
authentication-order [ tacplus password ];
{% endif %}
root-authentication { root-authentication {
encrypted-password "{{ device['config_context']['root_pw'] }}"; ## Client Higher 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 { login {
class sysadmin { 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 ]; 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 %} {% for user, details in users|dictsort %}
user {{ user }} { user {{ user }} {
uid 200{{ loop.index }}; uid 200{{ loop.index }};
class {{ details['role'] }}; class {{ details['role'] }};
{% if details['password'] %}
authentication { authentication {
encrypted-password "{{ details['password'] }}"; ## SECRET-DATA encrypted-password "{{ details['password'] }}"; ## SECRET-DATA
} }
{% endif %}
} }
{% endfor %} {% endfor %}
} }
services { services {
{% if device.role.name in ['Leaf','Spine'] %}
ssh; ssh;
{% else %}
ssh {
root-login deny;
}
{% endif %}
} }
syslog { syslog {
{% for server in device['config_context']['syslog_servers'] %} {% for server in syslog_servers %}
host {{ server }} { host {{ server }} {
any notice; any notice;
authorization info; 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 %} {% endfor %}
file interactive-commands { file interactive-commands {
interactive-commands any; interactive-commands any;
} }
{% if device.role.name in ['Leaf','Spine'] %}
file linkupdown { file linkupdown {
any info; any info;
match "LINK_DOWN|LINK_UP"; match "LINK_DOWN|LINK_UP";
@ -39,10 +66,11 @@ system {
any notice; any notice;
authorization info; authorization info;
} }
{% endif %}
} }
{% if device['config_context']['ntp_servers']|length > 0 %} {% if ntp_servers|length > 0 %}
ntp { ntp {
{% for server in device['config_context']['ntp_servers'] %} {% for server in ntp_servers %}
server {{ server }}; server {{ server }};
{% endfor %} {% endfor %}
} }
@ -51,15 +79,17 @@ system {
{%- endmacro %} {%- endmacro %}
{% macro chassissection(device) %} {% macro chassissection(device,breakout_ports) %}
chassis { chassis {
{% if device.interfaces.all()|selectattr('type','eq','lag')|list|count > 0 %}
aggregated-devices { aggregated-devices {
ethernet { ethernet {
device-count {{ device['interfaces']|selectattr('type','eq','LAG')|list|count }}; device-count {{ device.interfaces.all()|selectattr('type','eq','lag')|list|count }};
} }
} }
{% if device['config_context']['breakout_ports'] %} {% endif %}
{% for fpc, fpcdata in device['config_context']['breakout_ports'].items() %} {% if breakout_ports %}
{% for fpc, fpcdata in breakout_ports.items() %}
fpc {{ fpc }} { fpc {{ fpc }} {
{% for pic, picdata in fpcdata.items() %} {% for pic, picdata in fpcdata.items() %}
pic {{ pic }} { pic {{ pic }} {
@ -73,25 +103,36 @@ chassis {
} }
{% endfor %} {% endfor %}
{% endif %} {% endif %}
{% if device.role.name in ['Provider Core'] %}
forwarding-options {
lpm-profile;
}
{% endif %}
} }
{%- endmacro %} {%- endmacro %}
{% macro interfaceconfig(interface,rack = None) %} {% macro interfaceconfig(interface,rack = None) -%}
{{ interface['name'] }} { {% 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 %}
{% if interface.get('description') != '' %} {{ interface.name }} {
description "{{ interface['description'] }}"; {% if interface.description %}
description "{{ interface.description }}";
{% endif %} {% endif %}
{% if interface.get('mtu') and not interface.get('lag') %} {% if interface.mtu and not interface.lag %}
mtu {{ interface['mtu'] }}; mtu {{ interface.mtu }};
{% endif %} {% endif %}
{% if interface.get('lag') %} {% 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 { ether-options {
802.3ad {{ interface['lag']['name'] }}; 802.3ad {{ interface.lag.name }};
} }
{% endif %} {% endif %}
{% if interface['name'].startswith('ae') %} {% if interface.name.startswith('ae') %}
{% if interface['_custom_field_data']['esi_lag'] %} {% if interface.custom_field_data['esi_lag'] %}
esi { esi {
auto-derive { auto-derive {
lacp; lacp;
@ -102,35 +143,39 @@ chassis {
aggregated-ether-options { aggregated-ether-options {
lacp { lacp {
periodic fast; periodic fast;
{% if interface['_custom_field_data']['system_id'] %} {% if interface.custom_field_data['system_id'] %}
system-id {{ interface['_custom_field_data']['system_id'] }}; system-id {{ interface.custom_field_data['system_id'] }};
{% elif interface['_custom_field_data']['esi_lag'] %} {% 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; 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 %}
} }
} }
{% endif %} {% endif %}
{% if interface['ip_addresses']|length > 0 %} {% if interface.ip_addresses.count() > 0 %}
unit 0 { unit 0 {
{% if (interface.connected_endpoints) and (interface.connected_endpoints[0].device.role.name == 'Provider Core') %}
vlan-id 1;
{% endif %}
family inet { family inet {
{% if interface['ip_addresses'][0]['status']['name'] == 'Reserved' %}inactive: {% endif %}address {{ interface['ip_addresses'][0]['address'] }}; {% if interface.ip_addresses.first().status == 'reserved' %}inactive: {% endif %}address {{ interface.ip_addresses.first().address }};
} }
} }
{% endif %} {% endif %}
{% if interface.get('mode') is not none %} {% if interface.device.role.name in ['Leaf','Spine'] %}
{% if interface.mode != '' %}
unit 0 { unit 0 {
family ethernet-switching { family ethernet-switching {
{% if interface['mode']=='ACCESS' %} {% if interface.mode=='ACCESS' %}
interface-mode access; interface-mode access;
vlan { vlan {
members {{ interface['untagged_vlan']['vid'] }}; members {{ interface.untagged_vlan.vid }};
} }
{% elif interface['mode']=='TAGGED' %} {% elif interface.mode=='TAGGED' %}
interface-mode trunk; interface-mode trunk;
vlan { vlan {
members [ {% for vlan in interface['tagged_vlans'] %}{{ vlan['vid'] }} {% endfor %}]; members [ {% for vlan in interface.tagged_vlans %}{{ vlan.vid }} {% endfor %}];
} }
{% elif interface['mode']=='TAGGED_ALL' %} {% elif interface.mode=='TAGGED_ALL' %}
interface-mode trunk; interface-mode trunk;
vlan { vlan {
members [ all ]; members [ all ];
@ -139,52 +184,81 @@ chassis {
storm-control default; 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 %}
} }
{% endif %}
{%- endmacro %} {%- endmacro %}
{% macro interfacesection(device,vlans) %} {% macro interfacesection(device,vlans) %}
interfaces { 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! #} {# 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-') %} {% 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) }} {{ interfaceconfig(interface) }}
{% endfor %} {% endfor %}
{% for interface in device['interfaces'] if interface['name'].startswith('et-') %} {% for interface in device.interfaces.filter(name__startswith='irb') %}
{{ 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 %} {% if loop.first %}
irb { irb {
{% endif %} {% endif %}
unit {{ interface['name'][4:] }} { unit {{ interface.name[4:] }} {
description "{{ interface['description'] }}"; description "{{ interface.description }}";
family inet { family inet {
{% if interface['ip_addresses'][0]['status']['name'] == 'Reserved' %}inactive: {% endif %}address {{ interface['ip_addresses'][0]['address'] }}; {% if interface.ip_addresses.first().status == 'reserved' %}inactive: {% endif %}address {{ interface.ip_addresses.first().address }};
} }
} }
{% if loop.last %} {% if loop.last %}
} }
{% endif %} {% endif %}
{% endfor %} {% endfor %}
{% for interface in device['interfaces'] if interface['name'].startswith('lo') %} {% for interface in device.interfaces.filter(name__startswith='lo') %}
{{ interfaceconfig(interface) }} {{ interfaceconfig(interface) }}
{% endfor %} {% endfor %}
} }
{%- endmacro %} {%- endmacro %}
{% macro snmpsection(rack, config_context) %} {% macro snmpsection(device, snmp) %}
snmp { snmp {
location "Domicilium Datacentre {{ rack['name'] }}"; {% if device.rack and device.rack.site %}
contact "{{ config_context['snmp']['contact'] }}"; location "{{ device.rack.site.name }} Rack {{ device.rack.name }}";
community {{ config_context['snmp']['community'] }} { {% 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; authorization read-only;
{% for client in config_context['snmp']['clients'] %} {% for client in snmp['clients'] %}
{% if loop.first %} {% if loop.first %}
clients { clients {
{% endif %} {% endif %}
@ -197,13 +271,43 @@ snmp {
} }
{%- endmacro %} {%- endmacro %}
{% macro routingoptionssection(primary_ip4, config_context) %} {% 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 { routing-options {
router-id {{ primary_ip4['address'][:-3] }}; {% if device.primary_ip4 %}
autonomous-system {{ config_context['overlay_as'] }}; router-id {{ device.primary_ip4.address.ip }};
{% if config_context['gateway'] %} {% endif %}
{% if overlay_as %}
autonomous-system {{ overlay_as }};
{% endif %}
{% if gateway or routes %}
static { static {
route 0.0.0.0/0 next-hop {{ config_context['gateway'] }}; {% if gateway %}
route 0.0.0.0/0 next-hop {{ gateway }};
{% endif %}
} }
{% endif %} {% endif %}
forwarding-table { forwarding-table {
@ -229,8 +333,8 @@ routing-options {
multiplier 3; multiplier 3;
session-mode automatic; session-mode automatic;
} }
{% for dst_switch in spines if dst_switch['primary_ip4']['address'] != device['primary_ip4']['address'] %} {% for dst_switch in spines if dst_switch.primary_ip4.address != device.primary_ip4.address %}
neighbor {{ dst_switch['primary_ip4']['address'][:-3] }}; neighbor {{ dst_switch.primary_ip4.address.ip }};
{% endfor %} {% endfor %}
} }
{%- endmacro %} {%- endmacro %}
@ -238,12 +342,12 @@ routing-options {
{% macro bgpoverlaygroup(device) %} {% macro bgpoverlaygroup(device) %}
group OVERLAY { group OVERLAY {
type internal; type internal;
local-address {{ device['primary_ip4']['address'][:-3] }}; local-address {{ device.primary_ip4.address.ip }};
family evpn { family evpn {
signaling; signaling;
} }
{% if device['device_role']['name'] == 'Spine' %} {% if device.role.name == 'Spine' %}
cluster {{ device['primary_ip4']['address'][:-3] }}; cluster {{ device.primary_ip4.address.ip }};
multipath; multipath;
{% endif %} {% endif %}
bfd-liveness-detection { bfd-liveness-detection {
@ -251,8 +355,8 @@ routing-options {
multiplier 3; multiplier 3;
session-mode automatic; session-mode automatic;
} }
{% for dst_switch in device['peering_interfaces'] %} {% for interface in device.interfaces.filter(cable__isnull=False) %}
neighbor {{ dst_switch['cable_peer_interface']['device']['primary_ip4']['address'][:-3] }}; neighbor {{ interface.connected_endpoints[0].device.primary_ip4.address.ip }};
{% endfor %} {% endfor %}
} }
{%- endmacro %} {%- endmacro %}
@ -267,13 +371,13 @@ routing-options {
unicast; unicast;
} }
export BGP_LOOPBACK0; export BGP_LOOPBACK0;
local-as {{ device['config_context']['underlay_as'] }}; local-as {{ device.local_context_data['underlay_as'] }};
multipath { multipath {
multiple-as; multiple-as;
} }
{% for dst_switch in device['peering_interfaces'] %} {% for interface in device.interfaces.filter(cable__isnull=False) %}
neighbor {{ dst_switch['cable_peer_interface']['ip_addresses'][0]['address'][:-3] }} { neighbor {{ interface.connected_endpoints[0].ip_addresses.first().address.ip }} {
peer-as {{ dst_switch['cable_peer_interface']['device']['local_context_data']['underlay_as'] }}; peer-as {{ interface.connected_endpoints[0].device.local_context_data['underlay_as'] }};
} }
{% endfor %} {% endfor %}
} }
@ -282,18 +386,14 @@ routing-options {
{% macro bgpsection(device,spines) %} {% macro bgpsection(device,spines) %}
{% if device['device_role']['name'] in ['Spine','Lab-Spine'] %} {% if device.role.name in ['Spine','Lab-Spine'] %}
{% set role='Spine' %} {% set role='Spine' %}
{% set other_role='Leaf' %} {% set other_role='Leaf' %}
{% else %} {% else %}
{% set role='Leaf' %} {% set role='Leaf' %}
{% set other_role='Spine' %} {% set other_role='Spine' %}
{% endif %} {% endif %}
{% if device['device_role']['name'] == 'Lab-Spine' %} {% set name=device.name %}
{% set name=device['name'][4:] %}
{% else %}
{% set name=device['name'] %}
{% endif %}
bgp { bgp {
{{ bgpoverlaygroup(device) }} {{ bgpoverlaygroup(device) }}
{% if role == 'Spine' %} {% if role == 'Spine' %}
@ -305,34 +405,32 @@ routing-options {
{%- endmacro %} {%- endmacro %}
{% macro sflowsection(device) %} {% macro sflowsection(sflow) %}
{% if device['config_context']['sflow'] %}
sflow { sflow {
{% for collector in device['config_context']['sflow']['collectors'] %} {% for collector in sflow['collectors'] %}
collector {{ collector }}; collector {{ collector }};
{% endfor %} {% endfor %}
{% for interface in device['config_context']['sflow']['interfaces'] %} {% for interface in sflow['interfaces'] %}
interfaces {{ interface }}.0; interfaces {{ interface }}.0;
{% endfor %} {% endfor %}
} }
{% endif %}
{%- endmacro %} {%- endmacro %}
{% macro vlanssection(vlans,device) %} {% macro vlanssection(vlans,device) %}
vlans { vlans {
{# This next line selects all of the VLANs which are configured on this device #} {# 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 %} {% 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'] }} { vl{{ vlan.vid }} {
{% if vlan['name'] != '' %} {% if vlan.name != '' %}
description "{{ vlan['name'] }}"; description "{{ vlan.name }}";
{% endif %} {% endif %}
vlan-id {{ vlan['vid'] }}; vlan-id {{ vlan.vid }};
{% if device['interfaces']|selectattr('name', 'equalto', 'irb.'+vlan['vid']|string)|list|count %} {% if device.interfaces.all()|selectattr('name', 'equalto', 'irb.'+vlan.vid|string)|list|count %}
l3-interface irb.{{vlan['vid']}}; l3-interface irb.{{vlan.vid}};
{% endif %} {% endif %}
vxlan { vxlan {
vni {{ vlan['vid'] }}; vni {{ vlan.vid }};
} }
} }
{% endfor %} {% endfor %}

View File

@ -1,12 +1,11 @@
{% set device=({'hostname':hostname,'device_role':device_role,'primary_ip4':primary_ip4,'rack':rack,'interfaces':interfaces,'peering_interfaces':peering_interfaces,'config_context':config_context}) %}
{% import "juniper-macros.j2" as junos %} {% import "juniper-macros.j2" as junos %}
{{ junos.systemsection(device) }} {{ junos.systemsection(device,root_pw,users,syslog_servers,ntp_servers) }}
{% if device_role['name'] == 'Leaf' %} {% if device.role.name == 'Leaf' %}
{{ junos.chassissection(device) }} {{ junos.chassissection(device,breakout_ports) }}
{% endif %} {% endif %}
{{ junos.interfacesection(device,tenant['vlans']) }} {{ junos.interfacesection(device,ipam.VLAN.objects.filter(tenant=device.tenant)) }}
{{ junos.snmpsection(rack, config_context) }} {{ junos.snmpsection(device, snmp) }}
{% if device_role['name'] == 'Leaf' %} {% if device.role.name == 'Leaf' %}
forwarding-options { forwarding-options {
storm-control-profiles default { storm-control-profiles default {
all; all;
@ -18,7 +17,7 @@ policy-options {
term TERM1 { term TERM1 {
from { from {
protocol direct; protocol direct;
route-filter {{ primary_ip4['address'] }} exact; route-filter {{ device.primary_ip4.address }} exact;
} }
then accept; then accept;
} }
@ -29,28 +28,32 @@ policy-options {
} }
} }
} }
{{ junos.routingoptionssection(primary_ip4, config_context) }} {{ junos.routingoptionssection(device, overlay_as, gateway) }}
protocols { protocols {
{{ junos.bgpsection(device,tenant['spines']) }} {% if device.role.name in ['Leaf','Spine'] %}
{% if device_role['name'] == 'Leaf' %} {{ junos.bgpsection(device,dcim.Device.objects.filter(tenant=device.tenant,role__name='Spine')) }}
{% if device.role.name == 'Leaf' %}
evpn { evpn {
encapsulation vxlan; encapsulation vxlan;
extended-vni-list all; extended-vni-list all;
} }
{% endif %}
{% endif %} {% endif %}
lldp { lldp {
interface all; interface all;
} }
{{ junos.sflowsection(device) }} {% if sflow %}
{{ junos.sflowsection(sflow) }}
{% endif %}
} }
{% if device_role['name'] == 'Leaf' %} {% if device.role.name == 'Leaf' %}
switch-options { switch-options {
vtep-source-interface lo0.0; vtep-source-interface lo0.0;
route-distinguisher {{ primary_ip4['address'][:-3] }}:1; route-distinguisher {{ device.primary_ip4.address.ip }}:1;
vrf-target { vrf-target {
target:64512:1111; target:64512:1111;
auto; auto;
} }
} }
{{ junos.vlanssection(tenant['vlans'], device) }} {{ junos.vlanssection(ipam.VLAN.objects.filter(tenant=device.tenant), device) }}
{% endif %} {% endif %}

View File

@ -1 +0,0 @@
juniper-vxlan.j2

View File

@ -1 +0,0 @@
juniper-vxlan.j2