Configuring /etc/network/interfaces with Mako

Follow

Issue

The /etc/network/interfaces file gets really long and cumbersome. What if multiple ports have similar configurations? Is there a way automate this without having to use something like Ansible or Puppet, or without making a custom Python/bash script?

Solution

Mako templates are supported by ifupdown2 on Cumulus Linux 2.1 and later releases. Template engines are usually used for generating HTML content, but they work great for large network configurations. Mako itself is used in the popular website Reddit, which gets over a billion page views per month, so configuration scalability is not problem. Read the Mako documentation for more information.

Examples

Mako Output
## Note that the "range" ends with '4'
## But will iterate only from 1 to 3
## See Python range() for more details
% for i in range(1, 4): auto swp${i} iface swp${i} % endfor
auto swp1
iface swp1
auto swp2
iface swp2
auto swp3
iface swp3
## Mako code when commented out, should be 
## done using two comments, not one.
## Otherwise incorrect processing may occur
## <%def name="other_defaults()">
## mtu 3000
## </%def>
###
<%def name="interface_defaults()"> mtu 9000 link-speed 10000 link-duplex full link-autoneg off </%def> % for i in range(3,7): auto swp${i} iface swp${i} ${interface_defaults()} % endfor auto default_bridge iface default_bridge bridge_ports glob swp3-6 bridge-stp on
auto swp3
iface swp3

   mtu 9000
   link-speed 10000
   link-duplex full
   link-autoneg off 

auto swp4
iface swp4

   mtu 9000
   link-speed 10000
   link-duplex full
   link-autoneg off 

auto swp5
iface swp5

   mtu 9000
   link-speed 10000
   link-duplex full
   link-autoneg off 

auto swp6
iface swp6

   mtu 9000
   link-speed 10000
   link-duplex full
   link-autoneg off 


auto default_bridge
iface default_bridge
    bridge_ports glob swp3-6
    bridge-stp on


<%
    vlan_range_1 = [200,220,260]
    vlan_range_2 = range(300,305)
    full_vlan_list = vlan_range_1 + vlan_range_2
%>

% for v in full_vlan_list:
auto vlan${v}
iface vlan${v}
        bridge-ports glob swp1-6.${v}
        bridge-stp on
% endfor
auto vlan200
iface vlan200
    bridge-ports glob swp1-6.200
    bridge-stp on
auto vlan220
iface vlan220
    bridge-ports glob swp1-6.220
    bridge-stp on
auto vlan260
iface vlan260
    bridge-ports glob swp1-6.260
    bridge-stp on
auto vlan300
iface vlan300
    bridge-ports glob swp1-6.300
    bridge-stp on
auto vlan301
iface vlan301
    bridge-ports glob swp1-6.301
    bridge-stp on
auto vlan302
iface vlan302
    bridge-ports glob swp1-6.302
    bridge-stp on
auto vlan303
iface vlan303
    bridge-ports glob swp1-6.303
    bridge-stp on
auto vlan304
iface vlan304
    bridge-ports glob swp1-6.304
    bridge-stp on

Layer 3 Configuration Using Mako

The following is a layer 3 configuration created with Mako for ifupdown2:

This requires apt-get install python-ipaddr if not already installed.

Mako Output
iface lo inet loopback

auto eth0
iface eth0 inet dhcp

<%!
from ipaddr import IPAddress
ip = IPAddress('10.1.1.0')
%>

<%def name="incr_ip(ip, count, incr)"> 
<% newip = ip + (count * incr) %> 
  address ${newip}/31
</%def>

% for i in range(1,10):
auto swp${i}
iface swp${i}
${incr_ip(ip, i, 2)}
% endfor

iface lo inet loopback

auto eth0
iface eth0 inet dhcp

auto swp1
iface swp1
    address 10.1.1.2/31

auto swp2
iface swp2
    address 10.1.1.4/31

auto swp3
iface swp3
    address 10.1.1.6/31

auto swp4
iface swp4
    address 10.1.1.8/31

auto swp5
iface swp5
    address 10.1.1.10/31

auto swp6
iface swp6
    address 10.1.1.12/31

auto swp7
iface swp7
    address 10.1.1.14/31

auto swp8
iface swp8
    address 10.1.1.16/31

auto swp9
iface swp9
    address 10.1.1.18/31


<%!
from ipaddr import IPAddress
ip = IPAddress('12.12.12.12')
%>

<%def name="incr_ip(ip, count, incr)">
<% newip = ip + (count * incr) %>
address ${newip}/31
</%def>

% for i in range(1,4):
auto swp${i}
iface swp${i}
% endfor


% for i in range(5,8):
auto vlan${i}
iface vlan${i}
bridge-ports swp1.${i} swp2.${i} swp3.${i}
${incr_ip(ip, i, 2)}
% endfor
auto swp1
iface swp1

auto swp2
iface swp2

auto swp3
iface swp3

auto vlan5
iface vlan5
bridge-ports swp1.5 swp2.5 swp3.5
address 12.12.12.22/31

auto vlan6
iface vlan6
bridge-ports swp1.6 swp2.6 swp3.6
address 12.12.12.24/31

auto vlan7
iface vlan7
bridge-ports swp1.7 swp2.7 swp3.7
address 12.12.12.26/31

Notes

To correctly comment Mako code, make sure to comment out the code twice (using two hash marks — ##). Otherwise, you may see the following error when running ifquery on an interface:

cumulus@switch:~$ ifquery swp1
error: /etc/network/interfaces: failed to render template (Undefined). Continue without template rendering ...
auto swp1
iface swp1 inet static
address 10.1.2.2
netmask 255.255.255.252
down ip addr flush dev swp1

See Also

Have more questions? Submit a request

Comments

  • Avatar
    Harrison Duong

    Sean,

    I'm looking for an easy way to define a bridge with a bunch of 4x10g ports. Here is the manual setup:

    auto br0
    iface br0 inet static
    bridge-ports glob swp1s0-3 glob swp2s0-3 glob swp3s0-3 glob swp4s0-3 glob swp5s0-3 glob swp6s0-3 glob swp7s0-3 glob swp8s0-3
    bridge-stp on

    Do you have any scripts that would make defining this easier?

  • Avatar
    Sean Cavanaugh

    Hey Harrison,

    For this particular example I would just use a very simple regex. Like this

    auto br0
    iface br0
    bridge-ports regex swp[1-4]s[0-3]
    bridge-stp on

    I just tried it out and it seemes to get your desired result:
    root@leaf1:~# brctl show
    bridge name bridge id STP enabled interfaces
    br0 8000.7072cfbe2eb3 no swp1s0
    swp1s1
    swp1s2
    swp1s3
    swp2s0
    swp2s1
    swp2s2
    swp2s3
    swp3s0
    swp3s1
    swp3s2
    swp3s3
    swp4s0
    swp4s1
    swp4s2
    swp4s3

  • Avatar
    Emmanuel DECAEN

    Hi,

    I use Mako for simple /etc/network/interfaces configuration like this:

    %for port in range(5, 8):
    auto swp${port}
    iface swp${port}
       bridge-allow-untagged no

    %endfor

    But in Cumulus 3.2.1, it's not compatible with "net show interface" :

    # mako-render /etc/network/interfaces shows
    [...]
    auto swp5
    iface swp5
      bridge-allow-untagged no
    [...]

    # ifreload -a

    # net show interface
    [no entry for swp5, swp6 or swp7]

    # echo "iface swp5' >> /etc/network/interfaces

    # net show interface
    [...]
    UP swp5 10G 1500 Trunk/L2
    [...]

     

    Edited by Emmanuel DECAEN
Powered by Zendesk