├── helper_scripts ├── bgpdc-clone.sh ├── oob-mgmt-server-provision.sh ├── pre_config.sh ├── config_oob_server.sh ├── config_server_centos.sh ├── config_internet.sh ├── config_server.sh ├── config_oob_switch.sh ├── config_switch.sh └── apply_udev.py ├── hosts ├── ansible.cfg ├── localconfig ├── server01 │ └── etc │ │ └── network │ │ └── interfaces ├── server02 │ └── etc │ │ └── network │ │ └── interfaces ├── server03 │ └── etc │ │ └── network │ │ └── interfaces ├── server04 │ └── etc │ │ └── network │ │ └── interfaces ├── spine01 │ └── etc │ │ ├── network │ │ └── interfaces │ │ ├── quagga │ │ └── Quagga.conf │ │ └── ntp.conf ├── spine02 │ └── etc │ │ ├── network │ │ └── interfaces │ │ ├── quagga │ │ └── Quagga.conf │ │ └── ntp.conf ├── exit01 │ └── etc │ │ ├── quagga │ │ └── Quagga.conf │ │ ├── network │ │ └── interfaces │ │ └── ntp.conf ├── exit02 │ └── etc │ │ ├── quagga │ │ └── Quagga.conf │ │ ├── network │ │ └── interfaces │ │ └── ntp.conf ├── leaf01 │ └── etc │ │ ├── quagga │ │ └── Quagga.conf │ │ ├── network │ │ └── interfaces │ │ └── ntp.conf ├── leaf02 │ └── etc │ │ ├── quagga │ │ └── Quagga.conf │ │ ├── network │ │ └── interfaces │ │ └── ntp.conf ├── leaf03 │ └── etc │ │ ├── quagga │ │ └── Quagga.conf │ │ ├── network │ │ └── interfaces │ │ └── ntp.conf └── leaf04 │ └── etc │ ├── quagga │ └── Quagga.conf │ ├── network │ └── interfaces │ └── ntp.conf ├── reset.yml ├── compute-leaf-vars-l3.yml ├── ntp.yml ├── properties.yml ├── README.md ├── compute-leaf-vars-common.yml ├── conf-net.yml ├── RUNME.yml ├── ospfset.yml ├── hostset.yml ├── compute-leaf-vars.yml ├── library └── nclu.py └── Vagrantfile /helper_scripts/bgpdc-clone.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | sudo su - cumulus -c '\ 3 | git clone https://github.com/oreillymedia/bgp_in_the_data_center.git bgp_conf; \ 4 | ' 5 | -------------------------------------------------------------------------------- /hosts: -------------------------------------------------------------------------------- 1 | leaf01 2 | leaf02 3 | leaf03 4 | leaf04 5 | spine01 6 | spine02 7 | exit01 8 | exit02 9 | 10 | [server] 11 | server01 12 | server02 13 | server03 14 | server04 15 | -------------------------------------------------------------------------------- /ansible.cfg: -------------------------------------------------------------------------------- 1 | [defaults] 2 | ask_sudo_pass=false 3 | inventory = ./hosts 4 | stdout_callback = skippy 5 | [ssh_connection] 6 | ssh_args = -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null 7 | 8 | -------------------------------------------------------------------------------- /helper_scripts/oob-mgmt-server-provision.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | sudo sh -c 'echo "deb http://httpredir.debian.org/debian jessie main" > /etc/apt/sources.list.d/jessie.list' 3 | sudo sh -c 'echo "deb http://ftp.debian.org/debian jessie-backports main" >> /etc/apt/sources.list.d/jessie.list' 4 | sudo sh -c 'echo "deb http://repo3.cumulusnetworks.com/repo Jessie-supplemental upstream" > /etc/apt/sources.list.d/jessie_cl.list' 5 | sudo apt-get update 6 | sudo apt-get install -yq git python-netaddr 7 | sudo apt-get install -yq -t jessie-backports ansible 8 | git clone https://github.com/CumulusNetworks/cldemo-provision-ts.git 9 | -------------------------------------------------------------------------------- /localconfig/server01/etc/network/interfaces: -------------------------------------------------------------------------------- 1 | auto lo 2 | iface lo inet loopback 3 | 4 | 5 | 6 | 7 | auto eth0 8 | iface eth0 inet dhcp 9 | 10 | 11 | # bond config 12 | auto eth1 13 | iface eth1 inet manual 14 | bond-master bond0 15 | # 16 | auto eth2 17 | iface eth2 inet manual 18 | bond-master bond0 19 | # 20 | auto bond0 21 | iface bond0 inet static 22 | bond-slaves eth1 eth2 23 | bond-mode 802.3ad 24 | bond-miimon 100 25 | bond-use-carrier 1 26 | bond-lacp-rate 1 27 | bond-min-links 1 28 | bond-xmit-hash-policy layer3+4 29 | address 10.1.20.1/24 30 | post-up ifenslave bond0 eth1 eth2 31 | post-up ip link set bond0 promisc on 32 | #post-up ip route replace default via 10.1.20.254 dev bond0 33 | # bond config 34 | -------------------------------------------------------------------------------- /localconfig/server02/etc/network/interfaces: -------------------------------------------------------------------------------- 1 | auto lo 2 | iface lo inet loopback 3 | 4 | 5 | 6 | 7 | auto eth0 8 | iface eth0 inet dhcp 9 | 10 | 11 | # bond config 12 | auto eth1 13 | iface eth1 inet manual 14 | bond-master bond0 15 | # 16 | auto eth2 17 | iface eth2 inet manual 18 | bond-master bond0 19 | # 20 | auto bond0 21 | iface bond0 inet static 22 | bond-slaves eth1 eth2 23 | bond-mode 802.3ad 24 | bond-miimon 100 25 | bond-use-carrier 1 26 | bond-lacp-rate 1 27 | bond-min-links 1 28 | bond-xmit-hash-policy layer3+4 29 | address 10.1.20.2/24 30 | post-up ifenslave bond0 eth1 eth2 31 | post-up ip link set bond0 promisc on 32 | #post-up ip route replace default via 10.1.20.254 dev bond0 33 | # bond config 34 | -------------------------------------------------------------------------------- /localconfig/server03/etc/network/interfaces: -------------------------------------------------------------------------------- 1 | auto lo 2 | iface lo inet loopback 3 | 4 | 5 | 6 | 7 | auto eth0 8 | iface eth0 inet dhcp 9 | 10 | 11 | # bond config 12 | auto eth1 13 | iface eth1 inet manual 14 | bond-master bond0 15 | # 16 | auto eth2 17 | iface eth2 inet manual 18 | bond-master bond0 19 | # 20 | auto bond0 21 | iface bond0 inet static 22 | bond-slaves eth1 eth2 23 | bond-mode 802.3ad 24 | bond-miimon 100 25 | bond-use-carrier 1 26 | bond-lacp-rate 1 27 | bond-min-links 1 28 | bond-xmit-hash-policy layer3+4 29 | address 10.3.20.3/24 30 | post-up ifenslave bond0 eth1 eth2 31 | post-up ip link set bond0 promisc on 32 | #post-up ip route replace default via 10.3.20.254 dev bond0 33 | # bond config 34 | -------------------------------------------------------------------------------- /localconfig/server04/etc/network/interfaces: -------------------------------------------------------------------------------- 1 | auto lo 2 | iface lo inet loopback 3 | 4 | 5 | 6 | 7 | auto eth0 8 | iface eth0 inet dhcp 9 | 10 | 11 | # bond config 12 | auto eth1 13 | iface eth1 inet manual 14 | bond-master bond0 15 | # 16 | auto eth2 17 | iface eth2 inet manual 18 | bond-master bond0 19 | # 20 | auto bond0 21 | iface bond0 inet static 22 | bond-slaves eth1 eth2 23 | bond-mode 802.3ad 24 | bond-miimon 100 25 | bond-use-carrier 1 26 | bond-lacp-rate 1 27 | bond-min-links 1 28 | bond-xmit-hash-policy layer3+4 29 | address 10.3.20.4/24 30 | post-up ifenslave bond0 eth1 eth2 31 | post-up ip link set bond0 promisc on 32 | #post-up ip route replace default via 10.3.20.254 dev bond0 33 | # bond config 34 | -------------------------------------------------------------------------------- /localconfig/spine01/etc/network/interfaces: -------------------------------------------------------------------------------- 1 | # This file describes the network interfaces available on your system 2 | # and how to activate them. For more information, see interfaces(5), ifup(8) 3 | # 4 | # Please see /usr/share/doc/python-ifupdown2/examples/ for examples 5 | # 6 | # 7 | 8 | # The loopback network interface 9 | auto lo 10 | iface lo inet loopback 11 | address 10.254.0.30/32 12 | 13 | # The primary network interface 14 | auto eth0 15 | iface eth0 inet dhcp 16 | vrf mgmt 17 | 18 | auto swp1 19 | iface swp1 20 | 21 | auto swp2 22 | iface swp2 23 | 24 | auto swp3 25 | iface swp3 26 | 27 | auto swp4 28 | iface swp4 29 | 30 | auto swp29 31 | iface swp29 32 | 33 | auto swp30 34 | iface swp30 35 | 36 | auto mgmt 37 | iface mgmt 38 | address 127.0.0.1/8 39 | vrf-table auto 40 | -------------------------------------------------------------------------------- /localconfig/spine02/etc/network/interfaces: -------------------------------------------------------------------------------- 1 | # This file describes the network interfaces available on your system 2 | # and how to activate them. For more information, see interfaces(5), ifup(8) 3 | # 4 | # Please see /usr/share/doc/python-ifupdown2/examples/ for examples 5 | # 6 | # 7 | 8 | # The loopback network interface 9 | auto lo 10 | iface lo inet loopback 11 | address 10.254.0.29/32 12 | 13 | # The primary network interface 14 | auto eth0 15 | iface eth0 inet dhcp 16 | vrf mgmt 17 | 18 | auto swp1 19 | iface swp1 20 | 21 | auto swp2 22 | iface swp2 23 | 24 | auto swp3 25 | iface swp3 26 | 27 | auto swp4 28 | iface swp4 29 | 30 | auto swp29 31 | iface swp29 32 | 33 | auto swp30 34 | iface swp30 35 | 36 | auto mgmt 37 | iface mgmt 38 | address 127.0.0.1/8 39 | vrf-table auto 40 | -------------------------------------------------------------------------------- /helper_scripts/pre_config.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | #This file is transferred to a Debian/Ubuntu Host and executed to re-map interfaces 4 | #Extra config COULD be added here but I would recommend against that to keep this file standard. 5 | echo "#################################" 6 | echo " Running Vagrant Preconfig" 7 | echo "#################################" 8 | sudo su 9 | 10 | #Replace existing network interfaces file 11 | echo -e "auto lo" > /etc/network/interfaces 12 | echo -e "iface lo inet loopback\n\n" >> /etc/network/interfaces 13 | 14 | #Add vagrant interface 15 | echo -e "#\n\nauto vagrant" >> /etc/network/interfaces 16 | echo -e "iface vagrant inet dhcp\n\n" >> /etc/network/interfaces 17 | 18 | echo "#################################" 19 | echo " Finished" 20 | echo "#################################" 21 | -------------------------------------------------------------------------------- /localconfig/exit01/etc/quagga/Quagga.conf: -------------------------------------------------------------------------------- 1 | username cumulus nopassword 2 | ! 3 | service integrated-vtysh-config 4 | ! 5 | log file /var/log/quagga/quagga.log 6 | ! 7 | log timestamp precision 6 8 | ! 9 | interface swp51 10 | ipv6 nd ra-interval 10 11 | no ipv6 nd suppress-ra 12 | ! 13 | interface swp52 14 | ipv6 nd ra-interval 10 15 | no ipv6 nd suppress-ra 16 | ! 17 | router bgp 65000 18 | bgp router-id 10.254.0.17 19 | bgp bestpath as-path multipath-relax 20 | bgp bestpath compare-routerid 21 | neighbor fabric peer-group 22 | neighbor fabric remote-as external 23 | neighbor fabric description Internal Fabric Network 24 | neighbor swp51 interface peer-group fabric 25 | neighbor swp52 interface peer-group fabric 26 | ! 27 | address-family ipv4 unicast 28 | network 10.17.20.0/24 29 | network 10.254.0.17/32 30 | exit-address-family 31 | ! 32 | address-family ipv6 unicast 33 | neighbor fabric activate 34 | exit-address-family 35 | ! 36 | line vty 37 | ! 38 | -------------------------------------------------------------------------------- /localconfig/exit02/etc/quagga/Quagga.conf: -------------------------------------------------------------------------------- 1 | username cumulus nopassword 2 | ! 3 | service integrated-vtysh-config 4 | ! 5 | log file /var/log/quagga/quagga.log 6 | ! 7 | log timestamp precision 6 8 | ! 9 | interface swp51 10 | ipv6 nd ra-interval 10 11 | no ipv6 nd suppress-ra 12 | ! 13 | interface swp52 14 | ipv6 nd ra-interval 10 15 | no ipv6 nd suppress-ra 16 | ! 17 | router bgp 65000 18 | bgp router-id 10.254.0.18 19 | bgp bestpath as-path multipath-relax 20 | bgp bestpath compare-routerid 21 | neighbor fabric peer-group 22 | neighbor fabric remote-as external 23 | neighbor fabric description Internal Fabric Network 24 | neighbor swp51 interface peer-group fabric 25 | neighbor swp52 interface peer-group fabric 26 | ! 27 | address-family ipv4 unicast 28 | network 10.17.20.0/24 29 | network 10.254.0.18/32 30 | exit-address-family 31 | ! 32 | address-family ipv6 unicast 33 | neighbor fabric activate 34 | exit-address-family 35 | ! 36 | line vty 37 | ! 38 | -------------------------------------------------------------------------------- /localconfig/leaf01/etc/quagga/Quagga.conf: -------------------------------------------------------------------------------- 1 | username cumulus nopassword 2 | ! 3 | service integrated-vtysh-config 4 | ! 5 | log file /var/log/quagga/quagga.log 6 | ! 7 | log timestamp precision 6 8 | ! 9 | interface swp51 10 | ipv6 nd ra-interval 10 11 | no ipv6 nd suppress-ra 12 | ! 13 | interface swp52 14 | ipv6 nd ra-interval 10 15 | no ipv6 nd suppress-ra 16 | ! 17 | router bgp 64513 18 | bgp router-id 10.254.0.1 19 | bgp bestpath as-path multipath-relax 20 | bgp bestpath compare-routerid 21 | neighbor fabric peer-group 22 | neighbor fabric remote-as external 23 | neighbor fabric description Internal Fabric Network 24 | neighbor swp51 interface peer-group fabric 25 | neighbor swp52 interface peer-group fabric 26 | ! 27 | address-family ipv4 unicast 28 | network 10.1.20.0/24 29 | network 10.254.0.1/32 30 | exit-address-family 31 | ! 32 | address-family ipv6 unicast 33 | neighbor fabric activate 34 | exit-address-family 35 | ! 36 | line vty 37 | ! 38 | -------------------------------------------------------------------------------- /localconfig/leaf02/etc/quagga/Quagga.conf: -------------------------------------------------------------------------------- 1 | username cumulus nopassword 2 | ! 3 | service integrated-vtysh-config 4 | ! 5 | log file /var/log/quagga/quagga.log 6 | ! 7 | log timestamp precision 6 8 | ! 9 | interface swp51 10 | ipv6 nd ra-interval 10 11 | no ipv6 nd suppress-ra 12 | ! 13 | interface swp52 14 | ipv6 nd ra-interval 10 15 | no ipv6 nd suppress-ra 16 | ! 17 | router bgp 64514 18 | bgp router-id 10.254.0.2 19 | bgp bestpath as-path multipath-relax 20 | bgp bestpath compare-routerid 21 | neighbor fabric peer-group 22 | neighbor fabric remote-as external 23 | neighbor fabric description Internal Fabric Network 24 | neighbor swp51 interface peer-group fabric 25 | neighbor swp52 interface peer-group fabric 26 | ! 27 | address-family ipv4 unicast 28 | network 10.1.20.0/24 29 | network 10.254.0.2/32 30 | exit-address-family 31 | ! 32 | address-family ipv6 unicast 33 | neighbor fabric activate 34 | exit-address-family 35 | ! 36 | line vty 37 | ! 38 | -------------------------------------------------------------------------------- /localconfig/leaf03/etc/quagga/Quagga.conf: -------------------------------------------------------------------------------- 1 | username cumulus nopassword 2 | ! 3 | service integrated-vtysh-config 4 | ! 5 | log file /var/log/quagga/quagga.log 6 | ! 7 | log timestamp precision 6 8 | ! 9 | interface swp51 10 | ipv6 nd ra-interval 10 11 | no ipv6 nd suppress-ra 12 | ! 13 | interface swp52 14 | ipv6 nd ra-interval 10 15 | no ipv6 nd suppress-ra 16 | ! 17 | router bgp 64515 18 | bgp router-id 10.254.0.3 19 | bgp bestpath as-path multipath-relax 20 | bgp bestpath compare-routerid 21 | neighbor fabric peer-group 22 | neighbor fabric remote-as external 23 | neighbor fabric description Internal Fabric Network 24 | neighbor swp51 interface peer-group fabric 25 | neighbor swp52 interface peer-group fabric 26 | ! 27 | address-family ipv4 unicast 28 | network 10.3.20.0/24 29 | network 10.254.0.3/32 30 | exit-address-family 31 | ! 32 | address-family ipv6 unicast 33 | neighbor fabric activate 34 | exit-address-family 35 | ! 36 | line vty 37 | ! 38 | -------------------------------------------------------------------------------- /localconfig/leaf04/etc/quagga/Quagga.conf: -------------------------------------------------------------------------------- 1 | username cumulus nopassword 2 | ! 3 | service integrated-vtysh-config 4 | ! 5 | log file /var/log/quagga/quagga.log 6 | ! 7 | log timestamp precision 6 8 | ! 9 | interface swp51 10 | ipv6 nd ra-interval 10 11 | no ipv6 nd suppress-ra 12 | ! 13 | interface swp52 14 | ipv6 nd ra-interval 10 15 | no ipv6 nd suppress-ra 16 | ! 17 | router bgp 64516 18 | bgp router-id 10.254.0.4 19 | bgp bestpath as-path multipath-relax 20 | bgp bestpath compare-routerid 21 | neighbor fabric peer-group 22 | neighbor fabric remote-as external 23 | neighbor fabric description Internal Fabric Network 24 | neighbor swp51 interface peer-group fabric 25 | neighbor swp52 interface peer-group fabric 26 | ! 27 | address-family ipv4 unicast 28 | network 10.3.20.0/24 29 | network 10.254.0.4/32 30 | exit-address-family 31 | ! 32 | address-family ipv6 unicast 33 | neighbor fabric activate 34 | exit-address-family 35 | ! 36 | line vty 37 | ! 38 | -------------------------------------------------------------------------------- /reset.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: '!server*' 3 | tasks: 4 | 5 | - name: Clear out all config 6 | nclu: 7 | commands: del all 8 | 9 | - name: Wipe out quagga log 10 | shell: echo "" > /etc/quagga/Quagga.conf 11 | 12 | - hosts: 'server*' 13 | vars_files: 14 | - properties.yml 15 | any_errors_fatal: true 16 | tasks: 17 | - name: Clean out /etc/network/interfaces file 18 | shell: echo "" > /etc/network/interfaces 19 | 20 | - name: Add basic /etc/network/interfaces file 21 | blockinfile: 22 | dest: /etc/network/interfaces 23 | block: | 24 | # The loopback network interface 25 | auto lo 26 | iface lo inet loopback 27 | 28 | # The primary network interface 29 | auto eth0 30 | iface eth0 inet dhcp 31 | 32 | - name: Reload interfaces 33 | command: /usr/bin/systemd-run --on-active=10 /bin/systemctl reboot 34 | async: 0 35 | poll: 0 36 | 37 | -------------------------------------------------------------------------------- /localconfig/exit01/etc/network/interfaces: -------------------------------------------------------------------------------- 1 | # This file describes the network interfaces available on your system 2 | # and how to activate them. For more information, see interfaces(5), ifup(8) 3 | # 4 | # Please see /usr/share/doc/python-ifupdown2/examples/ for examples 5 | # 6 | # 7 | 8 | # The loopback network interface 9 | auto lo 10 | iface lo inet loopback 11 | address 10.254.0.17/32 12 | 13 | # The primary network interface 14 | auto eth0 15 | iface eth0 inet dhcp 16 | vrf mgmt 17 | 18 | auto swp49 19 | iface swp49 20 | 21 | auto swp50 22 | iface swp50 23 | 24 | auto swp51 25 | iface swp51 26 | 27 | auto swp52 28 | iface swp52 29 | 30 | auto bridge 31 | iface bridge 32 | bridge-ports peerlink 33 | bridge-vlan-aware yes 34 | 35 | auto mgmt 36 | iface mgmt 37 | address 127.0.0.1/8 38 | vrf-table auto 39 | 40 | auto peerlink 41 | iface peerlink 42 | bond-slaves swp49 swp50 43 | 44 | auto peerlink.4094 45 | iface peerlink.4094 46 | address 169.254.1.1/30 47 | clagd-backup-ip 192.168.0.42 vrf mgmt 48 | clagd-peer-ip 169.254.1.2 49 | clagd-priority 1000 50 | clagd-sys-mac 44:38:39:ff:00:17 51 | -------------------------------------------------------------------------------- /localconfig/exit02/etc/network/interfaces: -------------------------------------------------------------------------------- 1 | # This file describes the network interfaces available on your system 2 | # and how to activate them. For more information, see interfaces(5), ifup(8) 3 | # 4 | # Please see /usr/share/doc/python-ifupdown2/examples/ for examples 5 | # 6 | # 7 | 8 | # The loopback network interface 9 | auto lo 10 | iface lo inet loopback 11 | address 10.254.0.18/32 12 | 13 | # The primary network interface 14 | auto eth0 15 | iface eth0 inet dhcp 16 | vrf mgmt 17 | 18 | auto swp49 19 | iface swp49 20 | 21 | auto swp50 22 | iface swp50 23 | 24 | auto swp51 25 | iface swp51 26 | 27 | auto swp52 28 | iface swp52 29 | 30 | auto bridge 31 | iface bridge 32 | bridge-ports peerlink 33 | bridge-vlan-aware yes 34 | 35 | auto mgmt 36 | iface mgmt 37 | address 127.0.0.1/8 38 | vrf-table auto 39 | 40 | auto peerlink 41 | iface peerlink 42 | bond-slaves swp49 swp50 43 | 44 | auto peerlink.4094 45 | iface peerlink.4094 46 | address 169.254.1.2/30 47 | clagd-backup-ip 192.168.0.41 vrf mgmt 48 | clagd-peer-ip 169.254.1.1 49 | clagd-priority 2000 50 | clagd-sys-mac 44:38:39:ff:00:17 51 | -------------------------------------------------------------------------------- /helper_scripts/config_oob_server.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | #This file is transferred to a Debian/Ubuntu Host and executed to re-map interfaces 4 | #Extra config COULD be added here but I would recommend against that to keep this file standard. 5 | echo "#################################" 6 | echo " Running OOB server config" 7 | echo "#################################" 8 | sudo su 9 | 10 | #Replace existing network interfaces file 11 | echo -e "auto lo" > /etc/network/interfaces 12 | echo -e "iface lo inet loopback\n\n" >> /etc/network/interfaces 13 | echo -e "source /etc/network/interfaces.d/*.cfg\n" >> /etc/network/interfaces 14 | 15 | #Add vagrant interface 16 | echo -e "\n\nauto eth0" >> /etc/network/interfaces 17 | echo -e "iface eth0 inet dhcp\n\n" >> /etc/network/interfaces 18 | 19 | ####### Custom Stuff 20 | echo "auto swp1" >> /etc/network/interfaces 21 | echo "iface swp1 inet static" >> /etc/network/interfaces 22 | echo " address 192.168.0.254" >> /etc/network/interfaces 23 | echo " netmask 255.255.255.0" >> /etc/network/interfaces 24 | 25 | echo "cumulus ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/10_cumulus 26 | 27 | 28 | ifup swp1 29 | sed "s/PasswordAuthentication no/PasswordAuthentication yes/" -i /etc/ssh/sshd_config 30 | service ssh restart 31 | 32 | 33 | 34 | echo "#################################" 35 | echo " Finished" 36 | echo "#################################" 37 | -------------------------------------------------------------------------------- /localconfig/spine01/etc/quagga/Quagga.conf: -------------------------------------------------------------------------------- 1 | username cumulus nopassword 2 | ! 3 | service integrated-vtysh-config 4 | ! 5 | log file /var/log/quagga/quagga.log 6 | ! 7 | log timestamp precision 6 8 | ! 9 | interface swp1 10 | ipv6 nd ra-interval 10 11 | no ipv6 nd suppress-ra 12 | ! 13 | interface swp2 14 | ipv6 nd ra-interval 10 15 | no ipv6 nd suppress-ra 16 | ! 17 | interface swp3 18 | ipv6 nd ra-interval 10 19 | no ipv6 nd suppress-ra 20 | ! 21 | interface swp4 22 | ipv6 nd ra-interval 10 23 | no ipv6 nd suppress-ra 24 | ! 25 | interface swp29 26 | ipv6 nd ra-interval 10 27 | no ipv6 nd suppress-ra 28 | ! 29 | interface swp30 30 | ipv6 nd ra-interval 10 31 | no ipv6 nd suppress-ra 32 | ! 33 | router bgp 65500 34 | bgp router-id 10.254.0.30 35 | bgp bestpath as-path multipath-relax 36 | bgp bestpath compare-routerid 37 | neighbor fabric peer-group 38 | neighbor fabric remote-as external 39 | neighbor fabric description Internal Fabric Network 40 | neighbor swp1 interface peer-group fabric 41 | neighbor swp2 interface peer-group fabric 42 | neighbor swp3 interface peer-group fabric 43 | neighbor swp4 interface peer-group fabric 44 | neighbor swp29 interface peer-group fabric 45 | neighbor swp30 interface peer-group fabric 46 | ! 47 | address-family ipv4 unicast 48 | network 10.254.0.30/32 49 | exit-address-family 50 | ! 51 | address-family ipv6 unicast 52 | neighbor fabric activate 53 | exit-address-family 54 | ! 55 | line vty 56 | ! 57 | -------------------------------------------------------------------------------- /localconfig/spine02/etc/quagga/Quagga.conf: -------------------------------------------------------------------------------- 1 | username cumulus nopassword 2 | ! 3 | service integrated-vtysh-config 4 | ! 5 | log file /var/log/quagga/quagga.log 6 | ! 7 | log timestamp precision 6 8 | ! 9 | interface swp1 10 | ipv6 nd ra-interval 10 11 | no ipv6 nd suppress-ra 12 | ! 13 | interface swp2 14 | ipv6 nd ra-interval 10 15 | no ipv6 nd suppress-ra 16 | ! 17 | interface swp3 18 | ipv6 nd ra-interval 10 19 | no ipv6 nd suppress-ra 20 | ! 21 | interface swp4 22 | ipv6 nd ra-interval 10 23 | no ipv6 nd suppress-ra 24 | ! 25 | interface swp29 26 | ipv6 nd ra-interval 10 27 | no ipv6 nd suppress-ra 28 | ! 29 | interface swp30 30 | ipv6 nd ra-interval 10 31 | no ipv6 nd suppress-ra 32 | ! 33 | router bgp 65500 34 | bgp router-id 10.254.0.29 35 | bgp bestpath as-path multipath-relax 36 | bgp bestpath compare-routerid 37 | neighbor fabric peer-group 38 | neighbor fabric remote-as external 39 | neighbor fabric description Internal Fabric Network 40 | neighbor swp1 interface peer-group fabric 41 | neighbor swp2 interface peer-group fabric 42 | neighbor swp3 interface peer-group fabric 43 | neighbor swp4 interface peer-group fabric 44 | neighbor swp29 interface peer-group fabric 45 | neighbor swp30 interface peer-group fabric 46 | ! 47 | address-family ipv4 unicast 48 | network 10.254.0.29/32 49 | exit-address-family 50 | ! 51 | address-family ipv6 unicast 52 | neighbor fabric activate 53 | exit-address-family 54 | ! 55 | line vty 56 | ! 57 | -------------------------------------------------------------------------------- /localconfig/leaf01/etc/network/interfaces: -------------------------------------------------------------------------------- 1 | # This file describes the network interfaces available on your system 2 | # and how to activate them. For more information, see interfaces(5), ifup(8) 3 | # 4 | # Please see /usr/share/doc/python-ifupdown2/examples/ for examples 5 | # 6 | # 7 | 8 | # The loopback network interface 9 | auto lo 10 | iface lo inet loopback 11 | address 10.254.0.1/32 12 | 13 | # The primary network interface 14 | auto eth0 15 | iface eth0 inet dhcp 16 | vrf mgmt 17 | 18 | auto swp1 19 | iface swp1 20 | 21 | auto swp2 22 | iface swp2 23 | 24 | auto swp49 25 | iface swp49 26 | 27 | auto swp50 28 | iface swp50 29 | 30 | auto swp51 31 | iface swp51 32 | 33 | auto swp52 34 | iface swp52 35 | 36 | auto bond-swp1 37 | iface bond-swp1 38 | bond-slaves swp1 39 | bridge-access 20 40 | clag-id 1 41 | 42 | auto bond-swp2 43 | iface bond-swp2 44 | bond-slaves swp2 45 | bridge-access 20 46 | clag-id 2 47 | 48 | auto bridge 49 | iface bridge 50 | bridge-ports bond-swp1 bond-swp2 peerlink 51 | bridge-vids 20 52 | bridge-vlan-aware yes 53 | 54 | auto mgmt 55 | iface mgmt 56 | address 127.0.0.1/8 57 | vrf-table auto 58 | 59 | auto peerlink 60 | iface peerlink 61 | bond-slaves swp49 swp50 62 | 63 | auto peerlink.4094 64 | iface peerlink.4094 65 | address 169.254.1.1/30 66 | clagd-backup-ip 192.168.0.12 vrf mgmt 67 | clagd-peer-ip 169.254.1.2 68 | clagd-priority 1000 69 | clagd-sys-mac 44:38:39:ff:00:01 70 | 71 | auto vlan20 72 | iface vlan20 73 | address 10.1.20.253/24 74 | address-virtual 00:00:5e:00:01:01 10.1.20.254/32 75 | vlan-id 20 76 | vlan-raw-device bridge 77 | -------------------------------------------------------------------------------- /localconfig/leaf02/etc/network/interfaces: -------------------------------------------------------------------------------- 1 | # This file describes the network interfaces available on your system 2 | # and how to activate them. For more information, see interfaces(5), ifup(8) 3 | # 4 | # Please see /usr/share/doc/python-ifupdown2/examples/ for examples 5 | # 6 | # 7 | 8 | # The loopback network interface 9 | auto lo 10 | iface lo inet loopback 11 | address 10.254.0.2/32 12 | 13 | # The primary network interface 14 | auto eth0 15 | iface eth0 inet dhcp 16 | vrf mgmt 17 | 18 | auto swp1 19 | iface swp1 20 | 21 | auto swp2 22 | iface swp2 23 | 24 | auto swp49 25 | iface swp49 26 | 27 | auto swp50 28 | iface swp50 29 | 30 | auto swp51 31 | iface swp51 32 | 33 | auto swp52 34 | iface swp52 35 | 36 | auto bond-swp1 37 | iface bond-swp1 38 | bond-slaves swp1 39 | bridge-access 20 40 | clag-id 1 41 | 42 | auto bond-swp2 43 | iface bond-swp2 44 | bond-slaves swp2 45 | bridge-access 20 46 | clag-id 2 47 | 48 | auto bridge 49 | iface bridge 50 | bridge-ports bond-swp1 bond-swp2 peerlink 51 | bridge-vids 20 52 | bridge-vlan-aware yes 53 | 54 | auto mgmt 55 | iface mgmt 56 | address 127.0.0.1/8 57 | vrf-table auto 58 | 59 | auto peerlink 60 | iface peerlink 61 | bond-slaves swp49 swp50 62 | 63 | auto peerlink.4094 64 | iface peerlink.4094 65 | address 169.254.1.2/30 66 | clagd-backup-ip 192.168.0.11 vrf mgmt 67 | clagd-peer-ip 169.254.1.1 68 | clagd-priority 2000 69 | clagd-sys-mac 44:38:39:ff:00:01 70 | 71 | auto vlan20 72 | iface vlan20 73 | address 10.1.20.252/24 74 | address-virtual 00:00:5e:00:01:01 10.1.20.254/32 75 | vlan-id 20 76 | vlan-raw-device bridge 77 | -------------------------------------------------------------------------------- /localconfig/leaf03/etc/network/interfaces: -------------------------------------------------------------------------------- 1 | # This file describes the network interfaces available on your system 2 | # and how to activate them. For more information, see interfaces(5), ifup(8) 3 | # 4 | # Please see /usr/share/doc/python-ifupdown2/examples/ for examples 5 | # 6 | # 7 | 8 | # The loopback network interface 9 | auto lo 10 | iface lo inet loopback 11 | address 10.254.0.3/32 12 | 13 | # The primary network interface 14 | auto eth0 15 | iface eth0 inet dhcp 16 | vrf mgmt 17 | 18 | auto swp1 19 | iface swp1 20 | 21 | auto swp2 22 | iface swp2 23 | 24 | auto swp49 25 | iface swp49 26 | 27 | auto swp50 28 | iface swp50 29 | 30 | auto swp51 31 | iface swp51 32 | 33 | auto swp52 34 | iface swp52 35 | 36 | auto bond-swp1 37 | iface bond-swp1 38 | bond-slaves swp1 39 | bridge-access 20 40 | clag-id 1 41 | 42 | auto bond-swp2 43 | iface bond-swp2 44 | bond-slaves swp2 45 | bridge-access 20 46 | clag-id 2 47 | 48 | auto bridge 49 | iface bridge 50 | bridge-ports bond-swp1 bond-swp2 peerlink 51 | bridge-vids 20 52 | bridge-vlan-aware yes 53 | 54 | auto mgmt 55 | iface mgmt 56 | address 127.0.0.1/8 57 | vrf-table auto 58 | 59 | auto peerlink 60 | iface peerlink 61 | bond-slaves swp49 swp50 62 | 63 | auto peerlink.4094 64 | iface peerlink.4094 65 | address 169.254.1.1/30 66 | clagd-backup-ip 192.168.0.14 vrf mgmt 67 | clagd-peer-ip 169.254.1.2 68 | clagd-priority 1000 69 | clagd-sys-mac 44:38:39:ff:00:03 70 | 71 | auto vlan20 72 | iface vlan20 73 | address 10.3.20.253/24 74 | address-virtual 00:00:5e:00:01:01 10.3.20.254/32 75 | vlan-id 20 76 | vlan-raw-device bridge 77 | -------------------------------------------------------------------------------- /localconfig/leaf04/etc/network/interfaces: -------------------------------------------------------------------------------- 1 | # This file describes the network interfaces available on your system 2 | # and how to activate them. For more information, see interfaces(5), ifup(8) 3 | # 4 | # Please see /usr/share/doc/python-ifupdown2/examples/ for examples 5 | # 6 | # 7 | 8 | # The loopback network interface 9 | auto lo 10 | iface lo inet loopback 11 | address 10.254.0.4/32 12 | 13 | # The primary network interface 14 | auto eth0 15 | iface eth0 inet dhcp 16 | vrf mgmt 17 | 18 | auto swp1 19 | iface swp1 20 | 21 | auto swp2 22 | iface swp2 23 | 24 | auto swp49 25 | iface swp49 26 | 27 | auto swp50 28 | iface swp50 29 | 30 | auto swp51 31 | iface swp51 32 | 33 | auto swp52 34 | iface swp52 35 | 36 | auto bond-swp1 37 | iface bond-swp1 38 | bond-slaves swp1 39 | bridge-access 20 40 | clag-id 1 41 | 42 | auto bond-swp2 43 | iface bond-swp2 44 | bond-slaves swp2 45 | bridge-access 20 46 | clag-id 2 47 | 48 | auto bridge 49 | iface bridge 50 | bridge-ports bond-swp1 bond-swp2 peerlink 51 | bridge-vids 20 52 | bridge-vlan-aware yes 53 | 54 | auto mgmt 55 | iface mgmt 56 | address 127.0.0.1/8 57 | vrf-table auto 58 | 59 | auto peerlink 60 | iface peerlink 61 | bond-slaves swp49 swp50 62 | 63 | auto peerlink.4094 64 | iface peerlink.4094 65 | address 169.254.1.2/30 66 | clagd-backup-ip 192.168.0.13 vrf mgmt 67 | clagd-peer-ip 169.254.1.1 68 | clagd-priority 2000 69 | clagd-sys-mac 44:38:39:ff:00:03 70 | 71 | auto vlan20 72 | iface vlan20 73 | address 10.3.20.252/24 74 | address-virtual 00:00:5e:00:01:01 10.3.20.254/32 75 | vlan-id 20 76 | vlan-raw-device bridge 77 | -------------------------------------------------------------------------------- /helper_scripts/config_server_centos.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | #This file is transferred to a Debian/Ubuntu Host and executed to re-map interfaces 4 | #Extra config COULD be added here but I would recommend against that to keep this file standard. 5 | echo "#################################" 6 | echo " Running Server Post Config" 7 | echo "#################################" 8 | sudo su 9 | 10 | 11 | 12 | useradd cumulus 13 | CUMULUS_HASH=`python -c 'import crypt; print(crypt.crypt("CumulusLinux!", "\$6\$saltsalt\$").replace("/","\\/"))'` 14 | sed "s/cumulus:!/cumulus:$CUMULUS_HASH/" -i /etc/shadow 15 | mkdir -p /home/cumulus/ 16 | sed "s/PasswordAuthentication no/PasswordAuthentication yes/" -i /etc/ssh/sshd_config 17 | chsh -s /bin/bash cumulus 18 | 19 | ## Convenience code. This is normally done in ZTP. 20 | echo "cumulus ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/10_cumulus 21 | mkdir -p /home/cumulus/.ssh 22 | echo "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCzH+R+UhjVicUtI0daNUcedYhfvgT1dbZXgY33Ibm4MOo+X84Iwuzirm3QFnYf2O3uyZjNyrA6fj9qFE7Ekul4bD6PCstQupXPwfPMjns2M7tkHsKnLYjNxWNql/rCUxoH2B6nPyztcRCass3lIc2clfXkCY9Jtf7kgC2e/dmchywPV5PrFqtlHgZUnyoPyWBH7OjPLVxYwtCJn96sFkrjaG9QDOeoeiNvcGlk4DJp/g9L4f2AaEq69x8+gBTFUqAFsD8ecO941cM8sa1167rsRPx7SK3270Ji5EUF3lZsgpaiIgMhtIB/7QNTkN9ZjQBazxxlNVN6WthF8okb7OSt" >> /home/cumulus/.ssh/authorized_keys 23 | chmod 700 -R /home/cumulus 24 | chown cumulus:cumulus -R /home/cumulus 25 | 26 | systemctl disable NetworkManager.service 27 | systemctl stop NetworkManager.service 28 | 29 | rm /etc/sysconfig/network-scripts/ifcfg-eth0 30 | echo 'DEVICE="mgmt" BOOTPROTO="dhcp" ONBOOT="yes" TYPE="Ethernet" PERSISTENT_DHCLIENT="yes"' > /etc/sysconfig/network-scripts/ifcfg-mgmt 31 | 32 | echo "#################################" 33 | echo " Finished" 34 | echo "#################################" 35 | -------------------------------------------------------------------------------- /helper_scripts/config_internet.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | #This file is transferred to the Cumulus VX and executed to re-map interfaces 4 | #Extra config COULD be added here but I would recommend against that to keep this file standard. 5 | echo "#################################" 6 | echo " Running internet switch config" 7 | echo "#################################" 8 | sudo su 9 | 10 | echo -e "auto swp48" > /etc/network/interfaces 11 | echo -e "iface swp48 inet dhcp\n" >> /etc/network/interfaces 12 | 13 | ####### Custom Stuff 14 | 15 | # Config for OOB Switch 16 | echo -e "auto eth0" >> /etc/network/interfaces 17 | echo -e "iface eth0" >> /etc/network/interfaces 18 | echo -e " address 192.168.0.253/24" >> /etc/network/interfaces 19 | 20 | 21 | # Exit 1 22 | echo -e "auto swp1" >> /etc/network/interfaces 23 | echo -e "iface swp1" >> /etc/network/interfaces 24 | 25 | 26 | # Exit 2 27 | echo -e "auto swp2" >> /etc/network/interfaces 28 | echo -e "iface swp2" >> /etc/network/interfaces 29 | 30 | 31 | ## Convenience code. This is normally done in ZTP. 32 | echo "cumulus ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/10_cumulus 33 | mkdir -p /home/cumulus/.ssh 34 | echo "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCzH+R+UhjVicUtI0daNUcedYhfvgT1dbZXgY33Ibm4MOo+X84Iwuzirm3QFnYf2O3uyZjNyrA6fj9qFE7Ekul4bD6PCstQupXPwfPMjns2M7tkHsKnLYjNxWNql/rCUxoH2B6nPyztcRCass3lIc2clfXkCY9Jtf7kgC2e/dmchywPV5PrFqtlHgZUnyoPyWBH7OjPLVxYwtCJn96sFkrjaG9QDOeoeiNvcGlk4DJp/g9L4f2AaEq69x8+gBTFUqAFsD8ecO941cM8sa1167rsRPx7SK3270Ji5EUF3lZsgpaiIgMhtIB/7QNTkN9ZjQBazxxlNVN6WthF8okb7OSt" >> /home/cumulus/.ssh/authorized_keys 35 | chmod 700 -R /home/cumulus/.ssh 36 | chown cumulus:cumulus -R /home/cumulus/.ssh 37 | echo "This is a fake license" > /etc/cumulus/.license.txt 38 | 39 | 40 | echo "#################################" 41 | echo " Finished " 42 | echo "#################################" 43 | -------------------------------------------------------------------------------- /compute-leaf-vars-l3.yml: -------------------------------------------------------------------------------- 1 | # This is meant to be included in other main playbooks 2 | --- 3 | - name: Identify subnet from which hosts are assigned IPs 4 | set_fact: 5 | host_ip_base: | 6 | {% if (my_node_id|int %2) == 1 %} 7 | {{ server_ip_base + my_node_id|string + '.' + default_vlan|string }} 8 | {%else%} 9 | {{ server_ip_base + (my_node_id|int -1)|string + '.' + default_vlan|string }} 10 | {%endif%} 11 | when: "{{ 'leaf' in group_names and dual_attach_hosts }}" 12 | 13 | - name: Identify subnet from which hosts are assigned IPs 14 | set_fact: 15 | host_ip_base: | 16 | {{ server_ip_base + my_node_id|string + '.' + default_vlan|string }} 17 | when: "{{ 'leaf' in group_names and not dual_attach_hosts }}" 18 | 19 | 20 | - name: Extract low order subnet bits for bridge for dual-attach hosts 21 | set_fact: 22 | my_br_ip: | 23 | {% if (my_node_id|int %2) == 1 %} 24 | {{ host_ip_base.split()[0] + '.253/24' }} 25 | {%else%} 26 | {{ host_ip_base.split()[0] + '.252/24' }} 27 | {%endif%} 28 | when: "{{ 'leaf' in group_names and dual_attach_hosts }}" 29 | tags: 30 | - compute 31 | - ifconfig 32 | - always 33 | 34 | - name: Extract low order subnet bits for bridge for single attach hosts 35 | set_fact: 36 | my_br_ip: | 37 | {{ host_ip_base.split()[0] + '.253/24' }} 38 | when: "{{ 'leaf' in group_names and not dual_attach_hosts }}" 39 | tags: 40 | - compute 41 | - ifconfig 42 | - always 43 | 44 | - name: Compute VRR address 45 | set_fact: 46 | my_br_vrr_ip: | 47 | {{ host_ip_base.split()[0] + '.254/32' }} 48 | when: "{{ 'leaf' in group_names and dual_attach_hosts }}" 49 | tags: 50 | - compute 51 | - ifconfig 52 | - always 53 | 54 | -------------------------------------------------------------------------------- /helper_scripts/config_server.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | #This file is transferred to a Debian/Ubuntu Host and executed to re-map interfaces 4 | #Extra config COULD be added here but I would recommend against that to keep this file standard. 5 | echo "#################################" 6 | echo " Running Server Post Config" 7 | echo "#################################" 8 | sudo su 9 | 10 | 11 | #Replace existing network interfaces file 12 | echo -e "auto lo" > /etc/network/interfaces 13 | echo -e "iface lo inet loopback\n\n" >> /etc/network/interfaces 14 | 15 | #Add vagrant interface 16 | echo -e "\n\nauto eth0" >> /etc/network/interfaces 17 | echo -e "iface eth0 inet dhcp\n\n" >> /etc/network/interfaces 18 | 19 | useradd cumulus 20 | CUMULUS_HASH=`python -c 'import crypt; print(crypt.crypt("CumulusLinux!", "\$6\$saltsalt\$").replace("/","\\/"))'` 21 | sed "s/cumulus:!/cumulus:$CUMULUS_HASH/" -i /etc/shadow 22 | mkdir /home/cumulus/ 23 | sed "s/PasswordAuthentication no/PasswordAuthentication yes/" -i /etc/ssh/sshd_config 24 | chsh -s /bin/bash cumulus 25 | 26 | ## Convenience code. This is normally done in ZTP. 27 | echo "cumulus ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/10_cumulus 28 | mkdir /home/cumulus/.ssh 29 | echo "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCzH+R+UhjVicUtI0daNUcedYhfvgT1dbZXgY33Ibm4MOo+X84Iwuzirm3QFnYf2O3uyZjNyrA6fj9qFE7Ekul4bD6PCstQupXPwfPMjns2M7tkHsKnLYjNxWNql/rCUxoH2B6nPyztcRCass3lIc2clfXkCY9Jtf7kgC2e/dmchywPV5PrFqtlHgZUnyoPyWBH7OjPLVxYwtCJn96sFkrjaG9QDOeoeiNvcGlk4DJp/g9L4f2AaEq69x8+gBTFUqAFsD8ecO941cM8sa1167rsRPx7SK3270Ji5EUF3lZsgpaiIgMhtIB/7QNTkN9ZjQBazxxlNVN6WthF8okb7OSt" >> /home/cumulus/.ssh/authorized_keys 30 | chmod 700 -R /home/cumulus 31 | chown cumulus:cumulus -R /home/cumulus 32 | 33 | # Other stuff 34 | sudo apt-get update -qy 35 | sudo apt-get install lldpd -qy 36 | 37 | 38 | echo "#################################" 39 | echo " Finished" 40 | echo "#################################" 41 | -------------------------------------------------------------------------------- /helper_scripts/config_oob_switch.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | #This file is transferred to the Cumulus VX and executed to re-map interfaces 4 | #Extra config COULD be added here but I would recommend against that to keep this file standard. 5 | echo "#################################" 6 | echo " Running OOB switch config" 7 | echo "#################################" 8 | sudo su 9 | 10 | echo -e "auto eth0" > /etc/network/interfaces 11 | echo -e "iface eth0 inet dhcp\n" >> /etc/network/interfaces 12 | 13 | ####### Custom Stuff 14 | 15 | # Config for OOB Switch 16 | echo -e "% for i in range(1, 16):" >> /etc/network/interfaces 17 | echo -e "auto swp\${i}" >> /etc/network/interfaces 18 | echo -e "iface swp\${i}" >> /etc/network/interfaces 19 | echo -e "% endfor\n" >> /etc/network/interfaces 20 | echo -e "auto bridge" >> /etc/network/interfaces 21 | echo -e "iface bridge" >> /etc/network/interfaces 22 | echo -e "bridge-ports glob swp1-15" >> /etc/network/interfaces 23 | echo -e "address 192.168.0.1/24" >> /etc/network/interfaces 24 | 25 | #echo -e "bridge-stp on" >> /etc/network/interfaces 26 | 27 | ## Convenience code. This is normally done in ZTP. 28 | echo "cumulus ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/10_cumulus 29 | mkdir -p /home/cumulus/.ssh 30 | echo "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCzH+R+UhjVicUtI0daNUcedYhfvgT1dbZXgY33Ibm4MOo+X84Iwuzirm3QFnYf2O3uyZjNyrA6fj9qFE7Ekul4bD6PCstQupXPwfPMjns2M7tkHsKnLYjNxWNql/rCUxoH2B6nPyztcRCass3lIc2clfXkCY9Jtf7kgC2e/dmchywPV5PrFqtlHgZUnyoPyWBH7OjPLVxYwtCJn96sFkrjaG9QDOeoeiNvcGlk4DJp/g9L4f2AaEq69x8+gBTFUqAFsD8ecO941cM8sa1167rsRPx7SK3270Ji5EUF3lZsgpaiIgMhtIB/7QNTkN9ZjQBazxxlNVN6WthF8okb7OSt" >> /home/cumulus/.ssh/authorized_keys 31 | chmod 700 -R /home/cumulus/.ssh 32 | chown cumulus:cumulus -R /home/cumulus/.ssh 33 | echo "This is a fake license" > /etc/cumulus/.license.txt 34 | 35 | ifreload -a 36 | 37 | echo "#################################" 38 | echo " Finished " 39 | echo "#################################" 40 | -------------------------------------------------------------------------------- /ntp.yml: -------------------------------------------------------------------------------- 1 | --- 2 | #Setup the switch time zone (Note this will always report changed if re-run after the dpkg-reconfigure) 3 | #For a list of time zones check: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones 4 | - name: Set time zone /etc/timezone 5 | copy: content="America/Los_Angeles" dest=/etc/timezone 6 | become: true 7 | tags: 8 | - time_setup 9 | - initial_setup 10 | 11 | #Update switch tzdata for the new time zone using dpkg-reconfigure 12 | - name: Update tzdata with new time zone information 13 | command: dpkg-reconfigure -f noninteractive tzdata 14 | become: true 15 | tags: 16 | - time_setup 17 | - initial_setup 18 | 19 | #Configure ntpd 20 | - name: Setup NTP Base Config 21 | blockinfile: 22 | dest: /etc/ntp.conf 23 | create: yes 24 | marker: "#{mark} Base config. ANSIBLE MANAGED BLOCK" 25 | block: | 26 | driftfile /var/lib/ntp/ntp.drift 27 | 28 | restrict default nomodify notrap nopeer noquery 29 | restrict 127.0.0.1 30 | restrict ::1 31 | 32 | interface listen eth0 33 | become: true 34 | tags: 35 | - time_setup 36 | - initial_setup 37 | 38 | #Configure specific time servers by inserting your servers 39 | #after the sample one in the conf file 40 | - name: Setup NTP servers 41 | blockinfile: 42 | dest: /etc/ntp.conf 43 | marker: "#{mark} {{item}}. ANSIBLE MANAGED BLOCK" 44 | block: | 45 | server {{ item }} 46 | become: true 47 | with_items: "{{ ntp_servers }}" 48 | tags: 49 | - time_setup 50 | - initial_setup 51 | 52 | #Restart the NTP service to apply server changes 53 | - name: Restart NTP service 54 | service: name=ntp state=restarted 55 | become: true 56 | tags: 57 | - time_setup 58 | - initial_setup 59 | 60 | - name: Save a local copy for reference 61 | fetch: src=/etc/ntp.conf dest=localconfig 62 | -------------------------------------------------------------------------------- /helper_scripts/config_switch.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | #This file is transferred to the Cumulus VX and executed to re-map interfaces 4 | #Extra config COULD be added here but I would recommend against that to keep this file standard. 5 | echo "#################################" 6 | echo " Running Switch Post Config" 7 | echo "#################################" 8 | sudo su 9 | 10 | echo " adding fake cl-acltool..." 11 | echo -e "#!/bin/bash\nexit 0" > /bin/cl-acltool 12 | chmod 755 /bin/cl-acltool 13 | 14 | cat < /etc/network/interfaces 15 | # This file describes the network interfaces available on your system 16 | # and how to activate them. For more information, see interfaces(5), ifup(8) 17 | # 18 | # Please see /usr/share/doc/python-ifupdown2/examples/ for examples 19 | # 20 | # 21 | 22 | # The loopback network interface 23 | auto lo 24 | iface lo inet loopback 25 | 26 | # The primary network interface 27 | auto eth0 28 | iface eth0 inet dhcp 29 | EOF 30 | 31 | ## Convenience code. This is normally done in ZTP. 32 | echo "cumulus ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/10_cumulus 33 | mkdir -p /home/cumulus/.ssh 34 | echo "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCzH+R+UhjVicUtI0daNUcedYhfvgT1dbZXgY33Ibm4MOo+X84Iwuzirm3QFnYf2O3uyZjNyrA6fj9qFE7Ekul4bD6PCstQupXPwfPMjns2M7tkHsKnLYjNxWNql/rCUxoH2B6nPyztcRCass3lIc2clfXkCY9Jtf7kgC2e/dmchywPV5PrFqtlHgZUnyoPyWBH7OjPLVxYwtCJn96sFkrjaG9QDOeoeiNvcGlk4DJp/g9L4f2AaEq69x8+gBTFUqAFsD8ecO941cM8sa1167rsRPx7SK3270Ji5EUF3lZsgpaiIgMhtIB/7QNTkN9ZjQBazxxlNVN6WthF8okb7OSt" >> /home/cumulus/.ssh/authorized_keys 35 | chmod 700 -R /home/cumulus/.ssh 36 | chown cumulus:cumulus -R /home/cumulus/.ssh 37 | echo "This is a fake license" > /etc/cumulus/.license.txt 38 | 39 | ## Make onie reinstalls work. Note that installing from onie will undo these changes. 40 | mkdir /tmp/foo 41 | mount LABEL=ONIE-BOOT /tmp/foo 42 | sed -i 's/eth0/eth1/g' /tmp/foo/grub/grub.cfg 43 | sed -i 's/eth0/eth1/g' /tmp/foo/onie/grub/grub-extra.cfg 44 | umount /tmp/foo 45 | 46 | 47 | 48 | echo "#################################" 49 | echo " Finished" 50 | echo "#################################" 51 | -------------------------------------------------------------------------------- /localconfig/exit01/etc/ntp.conf: -------------------------------------------------------------------------------- 1 | # /etc/ntp.conf, configuration for ntpd; see ntp.conf(5) for help 2 | 3 | driftfile /var/lib/ntp/ntp.drift 4 | 5 | 6 | # Enable this if you want statistics to be logged. 7 | #statsdir /var/log/ntpstats/ 8 | 9 | statistics loopstats peerstats clockstats 10 | filegen loopstats file loopstats type day enable 11 | filegen peerstats file peerstats type day enable 12 | filegen clockstats file clockstats type day enable 13 | 14 | 15 | # You do need to talk to an NTP server or two (or three). 16 | #server ntp.your-provider.example 17 | 18 | # pool.ntp.org maps to about 1000 low-stratum NTP servers. Your server will 19 | # pick a different set every time it starts up. Please consider joining the 20 | # pool: 21 | server 0.cumulusnetworks.pool.ntp.org iburst 22 | server 1.cumulusnetworks.pool.ntp.org iburst 23 | server 2.cumulusnetworks.pool.ntp.org iburst 24 | server 3.cumulusnetworks.pool.ntp.org iburst 25 | 26 | 27 | # Access control configuration; see /usr/share/doc/ntp-doc/html/accopt.html for 28 | # details. The web page 29 | # might also be helpful. 30 | # 31 | # Note that "restrict" applies to both servers and clients, so a configuration 32 | # that might be intended to block requests from certain clients could also end 33 | # up blocking replies from your own upstream servers. 34 | 35 | # By default, exchange time with everybody, but don't allow configuration. 36 | restrict -4 default kod notrap nomodify nopeer noquery 37 | restrict -6 default kod notrap nomodify nopeer noquery 38 | 39 | # Local users may interrogate the ntp server more closely. 40 | restrict 127.0.0.1 41 | restrict ::1 42 | 43 | # Clients from this (example!) subnet have unlimited access, but only if 44 | # cryptographically authenticated. 45 | #restrict 192.168.123.0 mask 255.255.255.0 notrust 46 | 47 | 48 | # If you want to provide time to your local subnet, change the next line. 49 | # (Again, the address is an example only.) 50 | #broadcast 192.168.123.255 51 | 52 | # If you want to listen to time broadcasts on your local subnet, de-comment the 53 | # next lines. Please do this only if you trust everybody on the network! 54 | #disable auth 55 | #broadcastclient 56 | 57 | # Specify interfaces, don't listen on switch ports 58 | interface listen eth0 59 | 60 | #BEGIN Base config. ANSIBLE MANAGED BLOCK 61 | driftfile /var/lib/ntp/ntp.drift 62 | 63 | restrict default nomodify notrap nopeer noquery 64 | restrict 127.0.0.1 65 | restrict ::1 66 | 67 | interface listen eth0 68 | #END Base config. ANSIBLE MANAGED BLOCK 69 | #BEGIN 192.168.100.254. ANSIBLE MANAGED BLOCK 70 | server 192.168.100.254 71 | #END 192.168.100.254. ANSIBLE MANAGED BLOCK 72 | #BEGIN 192.168.100.253. ANSIBLE MANAGED BLOCK 73 | server 192.168.100.253 74 | #END 192.168.100.253. ANSIBLE MANAGED BLOCK 75 | -------------------------------------------------------------------------------- /localconfig/exit02/etc/ntp.conf: -------------------------------------------------------------------------------- 1 | # /etc/ntp.conf, configuration for ntpd; see ntp.conf(5) for help 2 | 3 | driftfile /var/lib/ntp/ntp.drift 4 | 5 | 6 | # Enable this if you want statistics to be logged. 7 | #statsdir /var/log/ntpstats/ 8 | 9 | statistics loopstats peerstats clockstats 10 | filegen loopstats file loopstats type day enable 11 | filegen peerstats file peerstats type day enable 12 | filegen clockstats file clockstats type day enable 13 | 14 | 15 | # You do need to talk to an NTP server or two (or three). 16 | #server ntp.your-provider.example 17 | 18 | # pool.ntp.org maps to about 1000 low-stratum NTP servers. Your server will 19 | # pick a different set every time it starts up. Please consider joining the 20 | # pool: 21 | server 0.cumulusnetworks.pool.ntp.org iburst 22 | server 1.cumulusnetworks.pool.ntp.org iburst 23 | server 2.cumulusnetworks.pool.ntp.org iburst 24 | server 3.cumulusnetworks.pool.ntp.org iburst 25 | 26 | 27 | # Access control configuration; see /usr/share/doc/ntp-doc/html/accopt.html for 28 | # details. The web page 29 | # might also be helpful. 30 | # 31 | # Note that "restrict" applies to both servers and clients, so a configuration 32 | # that might be intended to block requests from certain clients could also end 33 | # up blocking replies from your own upstream servers. 34 | 35 | # By default, exchange time with everybody, but don't allow configuration. 36 | restrict -4 default kod notrap nomodify nopeer noquery 37 | restrict -6 default kod notrap nomodify nopeer noquery 38 | 39 | # Local users may interrogate the ntp server more closely. 40 | restrict 127.0.0.1 41 | restrict ::1 42 | 43 | # Clients from this (example!) subnet have unlimited access, but only if 44 | # cryptographically authenticated. 45 | #restrict 192.168.123.0 mask 255.255.255.0 notrust 46 | 47 | 48 | # If you want to provide time to your local subnet, change the next line. 49 | # (Again, the address is an example only.) 50 | #broadcast 192.168.123.255 51 | 52 | # If you want to listen to time broadcasts on your local subnet, de-comment the 53 | # next lines. Please do this only if you trust everybody on the network! 54 | #disable auth 55 | #broadcastclient 56 | 57 | # Specify interfaces, don't listen on switch ports 58 | interface listen eth0 59 | 60 | #BEGIN Base config. ANSIBLE MANAGED BLOCK 61 | driftfile /var/lib/ntp/ntp.drift 62 | 63 | restrict default nomodify notrap nopeer noquery 64 | restrict 127.0.0.1 65 | restrict ::1 66 | 67 | interface listen eth0 68 | #END Base config. ANSIBLE MANAGED BLOCK 69 | #BEGIN 192.168.100.254. ANSIBLE MANAGED BLOCK 70 | server 192.168.100.254 71 | #END 192.168.100.254. ANSIBLE MANAGED BLOCK 72 | #BEGIN 192.168.100.253. ANSIBLE MANAGED BLOCK 73 | server 192.168.100.253 74 | #END 192.168.100.253. ANSIBLE MANAGED BLOCK 75 | -------------------------------------------------------------------------------- /localconfig/leaf01/etc/ntp.conf: -------------------------------------------------------------------------------- 1 | # /etc/ntp.conf, configuration for ntpd; see ntp.conf(5) for help 2 | 3 | driftfile /var/lib/ntp/ntp.drift 4 | 5 | 6 | # Enable this if you want statistics to be logged. 7 | #statsdir /var/log/ntpstats/ 8 | 9 | statistics loopstats peerstats clockstats 10 | filegen loopstats file loopstats type day enable 11 | filegen peerstats file peerstats type day enable 12 | filegen clockstats file clockstats type day enable 13 | 14 | 15 | # You do need to talk to an NTP server or two (or three). 16 | #server ntp.your-provider.example 17 | 18 | # pool.ntp.org maps to about 1000 low-stratum NTP servers. Your server will 19 | # pick a different set every time it starts up. Please consider joining the 20 | # pool: 21 | server 0.cumulusnetworks.pool.ntp.org iburst 22 | server 1.cumulusnetworks.pool.ntp.org iburst 23 | server 2.cumulusnetworks.pool.ntp.org iburst 24 | server 3.cumulusnetworks.pool.ntp.org iburst 25 | 26 | 27 | # Access control configuration; see /usr/share/doc/ntp-doc/html/accopt.html for 28 | # details. The web page 29 | # might also be helpful. 30 | # 31 | # Note that "restrict" applies to both servers and clients, so a configuration 32 | # that might be intended to block requests from certain clients could also end 33 | # up blocking replies from your own upstream servers. 34 | 35 | # By default, exchange time with everybody, but don't allow configuration. 36 | restrict -4 default kod notrap nomodify nopeer noquery 37 | restrict -6 default kod notrap nomodify nopeer noquery 38 | 39 | # Local users may interrogate the ntp server more closely. 40 | restrict 127.0.0.1 41 | restrict ::1 42 | 43 | # Clients from this (example!) subnet have unlimited access, but only if 44 | # cryptographically authenticated. 45 | #restrict 192.168.123.0 mask 255.255.255.0 notrust 46 | 47 | 48 | # If you want to provide time to your local subnet, change the next line. 49 | # (Again, the address is an example only.) 50 | #broadcast 192.168.123.255 51 | 52 | # If you want to listen to time broadcasts on your local subnet, de-comment the 53 | # next lines. Please do this only if you trust everybody on the network! 54 | #disable auth 55 | #broadcastclient 56 | 57 | # Specify interfaces, don't listen on switch ports 58 | interface listen eth0 59 | 60 | #BEGIN Base config. ANSIBLE MANAGED BLOCK 61 | driftfile /var/lib/ntp/ntp.drift 62 | 63 | restrict default nomodify notrap nopeer noquery 64 | restrict 127.0.0.1 65 | restrict ::1 66 | 67 | interface listen eth0 68 | #END Base config. ANSIBLE MANAGED BLOCK 69 | #BEGIN 192.168.100.254. ANSIBLE MANAGED BLOCK 70 | server 192.168.100.254 71 | #END 192.168.100.254. ANSIBLE MANAGED BLOCK 72 | #BEGIN 192.168.100.253. ANSIBLE MANAGED BLOCK 73 | server 192.168.100.253 74 | #END 192.168.100.253. ANSIBLE MANAGED BLOCK 75 | -------------------------------------------------------------------------------- /localconfig/leaf02/etc/ntp.conf: -------------------------------------------------------------------------------- 1 | # /etc/ntp.conf, configuration for ntpd; see ntp.conf(5) for help 2 | 3 | driftfile /var/lib/ntp/ntp.drift 4 | 5 | 6 | # Enable this if you want statistics to be logged. 7 | #statsdir /var/log/ntpstats/ 8 | 9 | statistics loopstats peerstats clockstats 10 | filegen loopstats file loopstats type day enable 11 | filegen peerstats file peerstats type day enable 12 | filegen clockstats file clockstats type day enable 13 | 14 | 15 | # You do need to talk to an NTP server or two (or three). 16 | #server ntp.your-provider.example 17 | 18 | # pool.ntp.org maps to about 1000 low-stratum NTP servers. Your server will 19 | # pick a different set every time it starts up. Please consider joining the 20 | # pool: 21 | server 0.cumulusnetworks.pool.ntp.org iburst 22 | server 1.cumulusnetworks.pool.ntp.org iburst 23 | server 2.cumulusnetworks.pool.ntp.org iburst 24 | server 3.cumulusnetworks.pool.ntp.org iburst 25 | 26 | 27 | # Access control configuration; see /usr/share/doc/ntp-doc/html/accopt.html for 28 | # details. The web page 29 | # might also be helpful. 30 | # 31 | # Note that "restrict" applies to both servers and clients, so a configuration 32 | # that might be intended to block requests from certain clients could also end 33 | # up blocking replies from your own upstream servers. 34 | 35 | # By default, exchange time with everybody, but don't allow configuration. 36 | restrict -4 default kod notrap nomodify nopeer noquery 37 | restrict -6 default kod notrap nomodify nopeer noquery 38 | 39 | # Local users may interrogate the ntp server more closely. 40 | restrict 127.0.0.1 41 | restrict ::1 42 | 43 | # Clients from this (example!) subnet have unlimited access, but only if 44 | # cryptographically authenticated. 45 | #restrict 192.168.123.0 mask 255.255.255.0 notrust 46 | 47 | 48 | # If you want to provide time to your local subnet, change the next line. 49 | # (Again, the address is an example only.) 50 | #broadcast 192.168.123.255 51 | 52 | # If you want to listen to time broadcasts on your local subnet, de-comment the 53 | # next lines. Please do this only if you trust everybody on the network! 54 | #disable auth 55 | #broadcastclient 56 | 57 | # Specify interfaces, don't listen on switch ports 58 | interface listen eth0 59 | 60 | #BEGIN Base config. ANSIBLE MANAGED BLOCK 61 | driftfile /var/lib/ntp/ntp.drift 62 | 63 | restrict default nomodify notrap nopeer noquery 64 | restrict 127.0.0.1 65 | restrict ::1 66 | 67 | interface listen eth0 68 | #END Base config. ANSIBLE MANAGED BLOCK 69 | #BEGIN 192.168.100.254. ANSIBLE MANAGED BLOCK 70 | server 192.168.100.254 71 | #END 192.168.100.254. ANSIBLE MANAGED BLOCK 72 | #BEGIN 192.168.100.253. ANSIBLE MANAGED BLOCK 73 | server 192.168.100.253 74 | #END 192.168.100.253. ANSIBLE MANAGED BLOCK 75 | -------------------------------------------------------------------------------- /localconfig/leaf03/etc/ntp.conf: -------------------------------------------------------------------------------- 1 | # /etc/ntp.conf, configuration for ntpd; see ntp.conf(5) for help 2 | 3 | driftfile /var/lib/ntp/ntp.drift 4 | 5 | 6 | # Enable this if you want statistics to be logged. 7 | #statsdir /var/log/ntpstats/ 8 | 9 | statistics loopstats peerstats clockstats 10 | filegen loopstats file loopstats type day enable 11 | filegen peerstats file peerstats type day enable 12 | filegen clockstats file clockstats type day enable 13 | 14 | 15 | # You do need to talk to an NTP server or two (or three). 16 | #server ntp.your-provider.example 17 | 18 | # pool.ntp.org maps to about 1000 low-stratum NTP servers. Your server will 19 | # pick a different set every time it starts up. Please consider joining the 20 | # pool: 21 | server 0.cumulusnetworks.pool.ntp.org iburst 22 | server 1.cumulusnetworks.pool.ntp.org iburst 23 | server 2.cumulusnetworks.pool.ntp.org iburst 24 | server 3.cumulusnetworks.pool.ntp.org iburst 25 | 26 | 27 | # Access control configuration; see /usr/share/doc/ntp-doc/html/accopt.html for 28 | # details. The web page 29 | # might also be helpful. 30 | # 31 | # Note that "restrict" applies to both servers and clients, so a configuration 32 | # that might be intended to block requests from certain clients could also end 33 | # up blocking replies from your own upstream servers. 34 | 35 | # By default, exchange time with everybody, but don't allow configuration. 36 | restrict -4 default kod notrap nomodify nopeer noquery 37 | restrict -6 default kod notrap nomodify nopeer noquery 38 | 39 | # Local users may interrogate the ntp server more closely. 40 | restrict 127.0.0.1 41 | restrict ::1 42 | 43 | # Clients from this (example!) subnet have unlimited access, but only if 44 | # cryptographically authenticated. 45 | #restrict 192.168.123.0 mask 255.255.255.0 notrust 46 | 47 | 48 | # If you want to provide time to your local subnet, change the next line. 49 | # (Again, the address is an example only.) 50 | #broadcast 192.168.123.255 51 | 52 | # If you want to listen to time broadcasts on your local subnet, de-comment the 53 | # next lines. Please do this only if you trust everybody on the network! 54 | #disable auth 55 | #broadcastclient 56 | 57 | # Specify interfaces, don't listen on switch ports 58 | interface listen eth0 59 | 60 | #BEGIN Base config. ANSIBLE MANAGED BLOCK 61 | driftfile /var/lib/ntp/ntp.drift 62 | 63 | restrict default nomodify notrap nopeer noquery 64 | restrict 127.0.0.1 65 | restrict ::1 66 | 67 | interface listen eth0 68 | #END Base config. ANSIBLE MANAGED BLOCK 69 | #BEGIN 192.168.100.254. ANSIBLE MANAGED BLOCK 70 | server 192.168.100.254 71 | #END 192.168.100.254. ANSIBLE MANAGED BLOCK 72 | #BEGIN 192.168.100.253. ANSIBLE MANAGED BLOCK 73 | server 192.168.100.253 74 | #END 192.168.100.253. ANSIBLE MANAGED BLOCK 75 | -------------------------------------------------------------------------------- /localconfig/leaf04/etc/ntp.conf: -------------------------------------------------------------------------------- 1 | # /etc/ntp.conf, configuration for ntpd; see ntp.conf(5) for help 2 | 3 | driftfile /var/lib/ntp/ntp.drift 4 | 5 | 6 | # Enable this if you want statistics to be logged. 7 | #statsdir /var/log/ntpstats/ 8 | 9 | statistics loopstats peerstats clockstats 10 | filegen loopstats file loopstats type day enable 11 | filegen peerstats file peerstats type day enable 12 | filegen clockstats file clockstats type day enable 13 | 14 | 15 | # You do need to talk to an NTP server or two (or three). 16 | #server ntp.your-provider.example 17 | 18 | # pool.ntp.org maps to about 1000 low-stratum NTP servers. Your server will 19 | # pick a different set every time it starts up. Please consider joining the 20 | # pool: 21 | server 0.cumulusnetworks.pool.ntp.org iburst 22 | server 1.cumulusnetworks.pool.ntp.org iburst 23 | server 2.cumulusnetworks.pool.ntp.org iburst 24 | server 3.cumulusnetworks.pool.ntp.org iburst 25 | 26 | 27 | # Access control configuration; see /usr/share/doc/ntp-doc/html/accopt.html for 28 | # details. The web page 29 | # might also be helpful. 30 | # 31 | # Note that "restrict" applies to both servers and clients, so a configuration 32 | # that might be intended to block requests from certain clients could also end 33 | # up blocking replies from your own upstream servers. 34 | 35 | # By default, exchange time with everybody, but don't allow configuration. 36 | restrict -4 default kod notrap nomodify nopeer noquery 37 | restrict -6 default kod notrap nomodify nopeer noquery 38 | 39 | # Local users may interrogate the ntp server more closely. 40 | restrict 127.0.0.1 41 | restrict ::1 42 | 43 | # Clients from this (example!) subnet have unlimited access, but only if 44 | # cryptographically authenticated. 45 | #restrict 192.168.123.0 mask 255.255.255.0 notrust 46 | 47 | 48 | # If you want to provide time to your local subnet, change the next line. 49 | # (Again, the address is an example only.) 50 | #broadcast 192.168.123.255 51 | 52 | # If you want to listen to time broadcasts on your local subnet, de-comment the 53 | # next lines. Please do this only if you trust everybody on the network! 54 | #disable auth 55 | #broadcastclient 56 | 57 | # Specify interfaces, don't listen on switch ports 58 | interface listen eth0 59 | 60 | #BEGIN Base config. ANSIBLE MANAGED BLOCK 61 | driftfile /var/lib/ntp/ntp.drift 62 | 63 | restrict default nomodify notrap nopeer noquery 64 | restrict 127.0.0.1 65 | restrict ::1 66 | 67 | interface listen eth0 68 | #END Base config. ANSIBLE MANAGED BLOCK 69 | #BEGIN 192.168.100.254. ANSIBLE MANAGED BLOCK 70 | server 192.168.100.254 71 | #END 192.168.100.254. ANSIBLE MANAGED BLOCK 72 | #BEGIN 192.168.100.253. ANSIBLE MANAGED BLOCK 73 | server 192.168.100.253 74 | #END 192.168.100.253. ANSIBLE MANAGED BLOCK 75 | -------------------------------------------------------------------------------- /localconfig/spine01/etc/ntp.conf: -------------------------------------------------------------------------------- 1 | # /etc/ntp.conf, configuration for ntpd; see ntp.conf(5) for help 2 | 3 | driftfile /var/lib/ntp/ntp.drift 4 | 5 | 6 | # Enable this if you want statistics to be logged. 7 | #statsdir /var/log/ntpstats/ 8 | 9 | statistics loopstats peerstats clockstats 10 | filegen loopstats file loopstats type day enable 11 | filegen peerstats file peerstats type day enable 12 | filegen clockstats file clockstats type day enable 13 | 14 | 15 | # You do need to talk to an NTP server or two (or three). 16 | #server ntp.your-provider.example 17 | 18 | # pool.ntp.org maps to about 1000 low-stratum NTP servers. Your server will 19 | # pick a different set every time it starts up. Please consider joining the 20 | # pool: 21 | server 0.cumulusnetworks.pool.ntp.org iburst 22 | server 1.cumulusnetworks.pool.ntp.org iburst 23 | server 2.cumulusnetworks.pool.ntp.org iburst 24 | server 3.cumulusnetworks.pool.ntp.org iburst 25 | 26 | 27 | # Access control configuration; see /usr/share/doc/ntp-doc/html/accopt.html for 28 | # details. The web page 29 | # might also be helpful. 30 | # 31 | # Note that "restrict" applies to both servers and clients, so a configuration 32 | # that might be intended to block requests from certain clients could also end 33 | # up blocking replies from your own upstream servers. 34 | 35 | # By default, exchange time with everybody, but don't allow configuration. 36 | restrict -4 default kod notrap nomodify nopeer noquery 37 | restrict -6 default kod notrap nomodify nopeer noquery 38 | 39 | # Local users may interrogate the ntp server more closely. 40 | restrict 127.0.0.1 41 | restrict ::1 42 | 43 | # Clients from this (example!) subnet have unlimited access, but only if 44 | # cryptographically authenticated. 45 | #restrict 192.168.123.0 mask 255.255.255.0 notrust 46 | 47 | 48 | # If you want to provide time to your local subnet, change the next line. 49 | # (Again, the address is an example only.) 50 | #broadcast 192.168.123.255 51 | 52 | # If you want to listen to time broadcasts on your local subnet, de-comment the 53 | # next lines. Please do this only if you trust everybody on the network! 54 | #disable auth 55 | #broadcastclient 56 | 57 | # Specify interfaces, don't listen on switch ports 58 | interface listen eth0 59 | 60 | #BEGIN Base config. ANSIBLE MANAGED BLOCK 61 | driftfile /var/lib/ntp/ntp.drift 62 | 63 | restrict default nomodify notrap nopeer noquery 64 | restrict 127.0.0.1 65 | restrict ::1 66 | 67 | interface listen eth0 68 | #END Base config. ANSIBLE MANAGED BLOCK 69 | #BEGIN 192.168.100.254. ANSIBLE MANAGED BLOCK 70 | server 192.168.100.254 71 | #END 192.168.100.254. ANSIBLE MANAGED BLOCK 72 | #BEGIN 192.168.100.253. ANSIBLE MANAGED BLOCK 73 | server 192.168.100.253 74 | #END 192.168.100.253. ANSIBLE MANAGED BLOCK 75 | -------------------------------------------------------------------------------- /localconfig/spine02/etc/ntp.conf: -------------------------------------------------------------------------------- 1 | # /etc/ntp.conf, configuration for ntpd; see ntp.conf(5) for help 2 | 3 | driftfile /var/lib/ntp/ntp.drift 4 | 5 | 6 | # Enable this if you want statistics to be logged. 7 | #statsdir /var/log/ntpstats/ 8 | 9 | statistics loopstats peerstats clockstats 10 | filegen loopstats file loopstats type day enable 11 | filegen peerstats file peerstats type day enable 12 | filegen clockstats file clockstats type day enable 13 | 14 | 15 | # You do need to talk to an NTP server or two (or three). 16 | #server ntp.your-provider.example 17 | 18 | # pool.ntp.org maps to about 1000 low-stratum NTP servers. Your server will 19 | # pick a different set every time it starts up. Please consider joining the 20 | # pool: 21 | server 0.cumulusnetworks.pool.ntp.org iburst 22 | server 1.cumulusnetworks.pool.ntp.org iburst 23 | server 2.cumulusnetworks.pool.ntp.org iburst 24 | server 3.cumulusnetworks.pool.ntp.org iburst 25 | 26 | 27 | # Access control configuration; see /usr/share/doc/ntp-doc/html/accopt.html for 28 | # details. The web page 29 | # might also be helpful. 30 | # 31 | # Note that "restrict" applies to both servers and clients, so a configuration 32 | # that might be intended to block requests from certain clients could also end 33 | # up blocking replies from your own upstream servers. 34 | 35 | # By default, exchange time with everybody, but don't allow configuration. 36 | restrict -4 default kod notrap nomodify nopeer noquery 37 | restrict -6 default kod notrap nomodify nopeer noquery 38 | 39 | # Local users may interrogate the ntp server more closely. 40 | restrict 127.0.0.1 41 | restrict ::1 42 | 43 | # Clients from this (example!) subnet have unlimited access, but only if 44 | # cryptographically authenticated. 45 | #restrict 192.168.123.0 mask 255.255.255.0 notrust 46 | 47 | 48 | # If you want to provide time to your local subnet, change the next line. 49 | # (Again, the address is an example only.) 50 | #broadcast 192.168.123.255 51 | 52 | # If you want to listen to time broadcasts on your local subnet, de-comment the 53 | # next lines. Please do this only if you trust everybody on the network! 54 | #disable auth 55 | #broadcastclient 56 | 57 | # Specify interfaces, don't listen on switch ports 58 | interface listen eth0 59 | 60 | #BEGIN Base config. ANSIBLE MANAGED BLOCK 61 | driftfile /var/lib/ntp/ntp.drift 62 | 63 | restrict default nomodify notrap nopeer noquery 64 | restrict 127.0.0.1 65 | restrict ::1 66 | 67 | interface listen eth0 68 | #END Base config. ANSIBLE MANAGED BLOCK 69 | #BEGIN 192.168.100.254. ANSIBLE MANAGED BLOCK 70 | server 192.168.100.254 71 | #END 192.168.100.254. ANSIBLE MANAGED BLOCK 72 | #BEGIN 192.168.100.253. ANSIBLE MANAGED BLOCK 73 | server 192.168.100.253 74 | #END 192.168.100.253. ANSIBLE MANAGED BLOCK 75 | -------------------------------------------------------------------------------- /properties.yml: -------------------------------------------------------------------------------- 1 | # Keep the numSpines and spine2leaf_ports consistent 2 | # For example, if num_spines was 3, leaf_to_spine_ports would 3 | # be "swp[1-3]". 4 | num_spines: 2 5 | num_leaves: 4 6 | hosts_per_leaf: 1 7 | 8 | # Keep the num_leaves and spine_to_leaf_ports consistent 9 | # For example, with 4 leaves, spine_to_leaf_ports could be 10 | # "swp[1-4]". The first server port is after the last ISL port 11 | # For dual-attach ports, the number of leaves have to be even 12 | spine_to_leaf_ports: "swp1-4" 13 | spine_to_exit_ports: "swp29-30" 14 | 15 | # Keep the hosts_per_leaf and leaf_to_server_ports consistent 16 | # For example, if you had 2 hosts per leaf, leaf_to_server_ports 17 | # would be "swp[3-4]". The first server port is after the last ISL 18 | # port 19 | leaf_to_spine_ports: "swp51-52" 20 | leaf_to_server_ports: "swp1-2" 21 | exit_to_edge_ports: "swp1" 22 | 23 | ################### Routing Protocol Used ########################### 24 | protocol: 'bgp' 25 | 26 | ################### SVI and Host IP CONFIGURATION ################### 27 | lo_ip_subnet: '10.254.0.0/27' 28 | # The host_ip_base assumes that the lower 3 bytes are free for 29 | # use with server IP address assignment. The second byte represents the rack 30 | # (or leaf) number, the third byte to represent the VLAN used with the server 31 | # and the lowest number in the dotted decimal format is the 32 | # host IP address, with the first IP address reserved for the leaf's 33 | # SVI. For example, the first leaf has the SVI address 10.1.20.1 and 34 | # hosts attached to it have the IP address from 10.1.20.2-10.1.20.254. 35 | # When used with dual-attached hosts, hosts in both racks get the second 36 | # byte from the odd node's rack number. When used with VxLAN, the second 37 | # byte is fixed to 253. 38 | server_ip_base: '10.' 39 | default_vlan: 20 40 | 41 | ###################### EVPN Configuration ########################### 42 | vlans: 100-105 43 | anycast_vtep_subnet: '10.254.0.32/27' 44 | 45 | ################### Dual-Attach Server CONFIGURATION ################ 46 | # Update the clag-peer ports based on how many server ports are there 47 | dual_attach_hosts: true 48 | clag_peer_ports: "swp49-50" 49 | 50 | ###################### NTP Servers ######################### 51 | ntp_servers: 52 | - '192.168.100.254' 53 | - '192.168.100.253' 54 | 55 | ###################### VxLAN CONFIGURATION ######################### 56 | use_vxlan: false 57 | use_lnv: false 58 | 59 | ################### ADVANCED CONFIGURATION ####################### 60 | # Can be ignored by most users. 61 | ################################################################## 62 | # BGP specific configuration. Following draft-lapukhov ebgp model 63 | # here. Spines have a single ASN, each ToR has its own ASN 64 | bgp_spine_asn: 65500 65 | bgp_leaf_asn_base: 64512 66 | bgp_exit_asn: 65000 67 | clag_base_sys_mac: "44:38:39:ff:00:" 68 | 69 | # Troubleshooting server configuration 70 | anycast_ip_redis: "192.168.0.254" 71 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | BGP in the Data Center 2 | ========== 3 | 4 | This is the example code that accompanies BGP in the Data Center by Dinesh G. Dutt (ISBN). 5 | 6 | Click the Download Zip button to the right to download example code. 7 | 8 | Visit the catalog page [here](http://shop.oreilly.com/product/0636920070467.do). 9 | 10 | See an error? Report it [here](http://oreilly.com/catalog/errata.csp?isbn=0636920070467, or simply fork and send us a pull request. 11 | 12 | 13 | Pre-requisites 14 | ---------------- 15 | 16 | To run the software in this repository, you'll need both [Vagrant](https://www.vagrantup.com/) and [Virtualbox](https://www.virtualbox.org/). 17 | If you're merely interested in looking at the configs, then look under the localconfig directory. 18 | 19 | While the book talked about FRRouting as the open source routing suite, because the demo here is based off of Cumulus Linux' 3.3.x release, Quagga is still used. However, the next release of Cumulus Linux will have FRRouting as the default routing suite. That said, the configuration is the same in both cases. 20 | 21 | The Quagga version is based off of a Cumulus Linux branch rather than the publicly available version due to the features such as BGP Unnumbered which are present in FRRouting, but not in the public Quagga version. 22 | 23 | Topology 24 | --------- 25 | ![Cumulus Reference Topology](https://github.com/CumulusNetworks/cldemo-vagrant/raw/master/cldemo_topology.png) 26 | 27 | Quickstart 28 | ------------- 29 | * Install git on your platform if you want to git clone this repository. Else select the download ZIP option from the directory and download the zip file. 30 | * If you're only interested in the configs, look under the localconfig directory. 31 | * If you wish to run this setup please note that running this simulation uses more than 8G of RAM. 32 | * Install [Vagrant](https://releases.hashicorp.com/vagrant/). Use release 1.9.5. 33 | * Install cumulus plugin for vagrant via `vagrant plugin install vagrant-cumulus` 34 | * Install [Ansible](instructions at http://docs.ansible.com/ansible/intro_installation.html) 35 | * If using a zip file, extract the downloaded zip file. If using git, run `git clone git@github.com:oreillymedia/bgp_in_the_data_center.git' 36 | * `cd bgp_in_the_data_center` 37 | * `vagrant up` 38 | * `vagrant ssh oob-mgmt-server` 39 | * `sudo su - cumulus` 40 | * `cd bgp_conf` 41 | * `ansible-playbook -s RUNME.yml` 42 | 43 | 44 | Details 45 | ------------------------ 46 | 47 | This demo will configure a layer 3 BGP network. The demo is downloaded onto the `oob-mgmt-server` under the `cumulus` user. It assumes the network is up and running (via `vagrant up`) but it **has not** yet been configured. The playbook `RUNME.yml` will configure BGP on all spine and leafs as well as configure the hosts. 48 | 49 | 50 | 51 | Resetting The Topology 52 | ------------------------ 53 | If a previous configuration was applied to the reference topology, it can be reset with the `reset.yml` playbook provided. This can be run before configuring netq to ensure a clean starting state. 54 | 55 | ansible-playbook -s reset.yml 56 | -------------------------------------------------------------------------------- /compute-leaf-vars-common.yml: -------------------------------------------------------------------------------- 1 | # This is meant to be included in other main playbooks 2 | --- 3 | - name: Construct CLAG SysMAC 4 | set_fact: 5 | my_clag_sys_mac: | 6 | {% if (my_node_id|int % 2) == 1 %} 7 | {{ "%s%02d"|format(clag_base_sys_mac, (my_node_id|int)) }} 8 | {%else%} 9 | {{ "%s%02d" | format(clag_base_sys_mac, (my_node_id|int - 1)) }} 10 | {%endif%} 11 | when: "{{ 'leaf' in group_names and dual_attach_hosts }}" 12 | tags: 13 | - compute 14 | - leaf 15 | 16 | - name: Construct CLAG Priority 17 | set_fact: 18 | my_clag_prio: | 19 | {% if (my_node_id|int % 2) == 1 %} 20 | primary 21 | {%else%} 22 | secondary 23 | {%endif%} 24 | when: "{{ 'leaf' in group_names and dual_attach_hosts }}" 25 | tags: 26 | - compute 27 | - leaf 28 | 29 | # Backup IP is the peer switch's eth0 address. 30 | # Construct peer switch's name based on my name: 31 | # If I'm leaf01, peer is leaf02; if I'm leaf02, peer is leaf01 32 | # Same applies for spine and exit leaves 33 | - name: Construct CLAG Backup IP for leaves 34 | set_fact: 35 | clag_backup_ip: | 36 | {% if (my_node_id|int % 2) == 1 %} 37 | {{ hostvars[inventory_hostname.split('f')[0] + 'f' + "%02d"|format(inventory_hostname.split('f')[1]|int + 1)]['ansible_eth0']['ipv4']['address'] }} 38 | {% else %} 39 | {{ hostvars[inventory_hostname.split('f')[0] + 'f' + "%02d"|format(inventory_hostname.split('f')[1]|int - 1)]['ansible_eth0']['ipv4']['address'] }} 40 | {% endif %} 41 | when: "{{ 'leaf' in group_names and 'exit' not in group_names }}" 42 | 43 | - name: Construct CLAG Backup IP for exit leaves 44 | set_fact: 45 | clag_backup_ip: | 46 | {% if (my_node_id|int % 2) == 1 %} 47 | {{ hostvars[inventory_hostname.split('t')[0] + 't' + "%02d"|format(inventory_hostname.split('t')[1]|int + 1)]['ansible_eth0']['ipv4']['address'] }} 48 | {% else %} 49 | {{ hostvars[inventory_hostname.split('t')[0] + 't' + "%02d"|format(inventory_hostname.split('t')[1]|int - 1)]['ansible_eth0']['ipv4']['address'] }} 50 | {% endif %} 51 | when: "{{ 'leaf' in group_names and 'exit' in group_names }}" 52 | 53 | 54 | - name: Compute start of server ports 55 | set_fact: 56 | server_port_start: "{{ ((leaf_to_server_ports.split('p'))[1].split('-'))[0]|int }}" 57 | when: "{{ 'leaf' in group_names and dual_attach_hosts }}" 58 | tags: 59 | - compute 60 | - ifconfig 61 | - always 62 | 63 | - name: Compute end of server ports 64 | set_fact: 65 | server_port_end: "{{ (((leaf_to_server_ports.split('p'))[1].split('-'))[-1]|int)+1 }}" 66 | when: "{{ 'leaf' in group_names and 'exit' not in group_names and dual_attach_hosts }}" 67 | tags: 68 | - compute 69 | - ifconfig 70 | - always 71 | 72 | - name: Compute start of exit edge ports 73 | set_fact: 74 | server_port_start: "{{ ((exit_to_edge_ports.split('p'))[1].split('-'))[0]|int }}" 75 | when: "{{ 'exit' in group_names and dual_attach_hosts }}" 76 | tags: 77 | - compute 78 | - ifconfig 79 | - always 80 | 81 | - name: Compute end of exit edge ports 82 | set_fact: 83 | server_port_end: "{{ (((exit_to_edge_ports.split('p'))[1].split('-'))[-1]|int)+1 }}" 84 | when: "{{ 'exit' in group_names and dual_attach_hosts }}" 85 | tags: 86 | - compute 87 | - ifconfig 88 | - always 89 | 90 | -------------------------------------------------------------------------------- /conf-net.yml: -------------------------------------------------------------------------------- 1 | 2 | # This task configures /etc/network/interfaces on ifupdown2. The variables for 3 | # which interfaces are neighbors and networks come from the group_vars/all file. 4 | - name: configure mgmt VRF 5 | shell: sleep 2 && net add vrf mgmt && net commit 6 | ignore_errors: true 7 | async: 1 8 | poll: 0 9 | notify: Wait for ssh to come back up 10 | 11 | - name: configure rest of networking 12 | nclu: 13 | atomic: true 14 | description: "configure all the newtorking" 15 | template: | 16 | 17 | add loopback lo ip address {{ my_ip }}/32 18 | {% if 'leaf' in hostvars[ansible_hostname]['group_names'] %} 19 | add int {{ leaf_to_spine_ports }} 20 | {% if 'exit' not in hostvars[ansible_hostname]['group_names'] %} 21 | add int {{ leaf_to_server_ports }} 22 | {% endif %} 23 | 24 | {% if dual_attach_hosts %} 25 | add int {{ clag_peer_ports }} 26 | 27 | add clag peer sys-mac {{ my_clag_sys_mac|trim }} interface {{ clag_peer_ports }} {{ my_clag_prio|trim }} backup-ip {{ clag_backup_ip|trim }} vrf mgmt 28 | 29 | {% if 'exit' not in hostvars[ansible_hostname]['group_names'] %} 30 | {% for i in range(server_port_start|int, server_port_end|int) %} 31 | add clag port bond bond-swp{{ i }} interface swp{{ i }} clag-id {{ i }} 32 | add bond bond-swp{{ i }} bridge access {{ default_vlan }} 33 | {% endfor %} 34 | 35 | add vlan {{ default_vlan }} ip addr {{ my_br_ip|trim }} 36 | add vlan {{ default_vlan }} ip address-virtual 00:00:5e:00:01:01 {{ my_br_vrr_ip|trim }} 37 | {% endif %} 38 | {% else %} 39 | add vlan {{ default_vlan }} ip addr {{ my_br_ip|trim }} 40 | {% endif %} 41 | {% elif 'spine' in hostvars[ansible_hostname]['group_names'] %} 42 | add int {{ spine_to_leaf_ports }} 43 | {% endif %} 44 | 45 | add bgp autonomous-system {{ my_asn }} 46 | add bgp router-id {{ my_ip|trim }} 47 | add bgp network {{ my_ip|trim }}/32 48 | {% if 'leaf' in hostvars[ansible_hostname]['group_names'] %} 49 | add bgp network {{ my_br_ip|trim }} 50 | {% endif %} 51 | 52 | add bgp bestpath as-path multipath-relax 53 | add bgp bestpath compare-routerid 54 | add bgp neighbor fabric peer-group 55 | add bgp neighbor fabric description Internal Fabric Network 56 | add bgp neighbor fabric remote-as external 57 | add bgp ipv6 unicast neighbor fabric activate 58 | {% if 'leaf' in hostvars[ansible_hostname]['group_names'] %} 59 | add bgp neighbor {{ leaf_to_spine_ports }} peer-group fabric 60 | {% elif 'spine' in hostvars[ansible_hostname]['group_names'] %} 61 | add bgp neighbor {{ spine_to_leaf_ports }} peer-group fabric 62 | add bgp neighbor {{ spine_to_exit_ports }} peer-group fabric 63 | {% endif %} 64 | 65 | - name: Save a local copy of the interfaces for reference 66 | fetch: src=/etc/network/interfaces dest=localconfig 67 | 68 | - name: Save a local copy of the quagga config for reference 69 | fetch: src=/etc/quagga/Quagga.conf dest=localconfig 70 | 71 | - name: Save a local copy of the NTP config for reference 72 | fetch: src=/etc/ntp.conf dest=localconfig 73 | 74 | -------------------------------------------------------------------------------- /RUNME.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: localhost 3 | tasks: 4 | - name: Create a dir for storing rendered configs locally 5 | file: path=localconfig state=directory owner=cumulus 6 | 7 | - hosts: 'leaf*' 8 | any_errors_fatal: true 9 | gather_facts: false 10 | vars_files: 11 | - properties.yml 12 | tasks: 13 | 14 | - name: Get my node ID 15 | set_fact: 16 | my_node_id: "{{ inventory_hostname.split('f')[1]|int }}" 17 | tags: 18 | - compute 19 | - always 20 | 21 | - group_by: key='leaf' 22 | when: "{{ 'leaf' in inventory_hostname }}" 23 | 24 | - name: Get loopback IP for leaves 25 | set_fact: 26 | my_ip: "{{ lo_ip_subnet|ipsubnet(32, (my_node_id|int))|ipaddr('address') }}" 27 | 28 | - name: Get my ASN for leaves 29 | set_fact: 30 | my_asn: "{{ bgp_leaf_asn_base|int + my_node_id|int }}" 31 | tags: 32 | - compute 33 | - routing 34 | 35 | 36 | - hosts: 'spine*' 37 | any_errors_fatal: true 38 | vars_files: 39 | - properties.yml 40 | tasks: 41 | 42 | - name: Get my node ID 43 | set_fact: 44 | my_node_id: "{{ inventory_hostname.split('e')[1]|int }}" 45 | tags: 46 | - compute 47 | - always 48 | 49 | - group_by: key='spine' 50 | when: "{{ 'spine' in inventory_hostname }}" 51 | 52 | - name: Get loopback IP for spines 53 | set_fact: 54 | my_ip: "{{ lo_ip_subnet|ipsubnet(32, -(my_node_id|int)-1)|ipaddr('address') }}" 55 | 56 | - name: Get my ASN for spines 57 | set_fact: 58 | my_asn: "{{ bgp_spine_asn }}" 59 | tags: 60 | - compute 61 | - routing 62 | 63 | - hosts: 'exit*' 64 | any_errors_fatal: true 65 | gather_facts: false 66 | vars_files: 67 | - properties.yml 68 | tasks: 69 | 70 | - name: Get my node ID 71 | set_fact: 72 | my_node_id: "{{ (16 + (inventory_hostname.split('t')[1]|int))|int }}" 73 | tags: 74 | - compute 75 | - always 76 | 77 | - group_by: key='leaf' 78 | when: "{{ 'exit' in inventory_hostname }}" 79 | 80 | - group_by: key='exit' 81 | when: "{{ 'exit' in inventory_hostname }}" 82 | 83 | - name: Get loopback IP for leaves 84 | set_fact: 85 | my_ip: "{{ lo_ip_subnet|ipsubnet(32, (my_node_id|int))|ipaddr('address') }}" 86 | 87 | - name: Get my ASN for exit leaves 88 | set_fact: 89 | my_asn: "{{ bgp_exit_asn }}" 90 | tags: 91 | - compute 92 | - routing 93 | 94 | 95 | - hosts: '!server*' 96 | vars_files: 97 | - properties.yml 98 | any_errors_fatal: true 99 | gather_facts: true 100 | tasks: 101 | 102 | - group_by: key='routers' 103 | when: "{{ 'spine' in inventory_hostname or 'leaf' in inventory_hostname }}" 104 | 105 | - include: ntp.yml 106 | 107 | - include: compute-leaf-vars-common.yml 108 | when: "{{ 'leaf' in group_names }}" 109 | 110 | - include: compute-leaf-vars-l3.yml 111 | when: "{{ 'leaf' in group_names }}" 112 | 113 | - include: conf-net.yml 114 | 115 | - hosts: 'server*' 116 | vars_files: 117 | - properties.yml 118 | tasks: 119 | - include: hostset.yml 120 | 121 | handlers: 122 | - name: Reboot server to bring up bonds 123 | command: /usr/bin/systemd-run --on-active=10 /bin/systemctl reboot 124 | async: 0 125 | poll: 0 126 | tags: 127 | - command 128 | - hosts 129 | - ifconfig 130 | 131 | - name: Wait for ssh to come back up 132 | local_action: wait_for host={{ inventory_hostname }} state=started delay=3 timeout=7 133 | -------------------------------------------------------------------------------- /ospfset.yml: -------------------------------------------------------------------------------- 1 | # This is meant to be included in other main playbooks 2 | --- 3 | - name: Add logging and base config 4 | blockinfile: 5 | dest: /etc/quagga/Quagga.conf 6 | marker: "!{mark} base config ANSIBLE MANAGED BLOCK" 7 | create: yes 8 | block: | 9 | ! 10 | service integrated-vtysh-config 11 | log file /var/log/quagga/quagga.log 12 | log timestamp precision 6 13 | hostname quagga 14 | username cumulus nopassword 15 | password cn321 16 | enable password cn321 17 | ! 18 | ip forwarding 19 | ipv6 forwarding 20 | line vty 21 | ! 22 | tags: routing 23 | 24 | - name: Base OSPF config on spines 25 | blockinfile: 26 | dest: /etc/quagga/Quagga.conf 27 | marker: "!{mark} base ospf config ANSIBLE MANAGED BLOCK" 28 | block: | 29 | ! 30 | router ospf 31 | ospf router-id {{ my_ip }} 32 | passive-interface lo 33 | 34 | when: "{{ 'spine' in group_names }}" 35 | tags: routing 36 | 37 | - name: Base OSPF config on leaves 38 | blockinfile: 39 | dest: /etc/quagga/Quagga.conf 40 | marker: "!{mark} base ospf config ANSIBLE MANAGED BLOCK" 41 | block: | 42 | ! 43 | router ospf 44 | ospf router-id {{ my_ip }} 45 | passive-interface lo 46 | passive-interface bridge.{{ default_vlan }} 47 | 48 | when: "{{ 'leaf' in group_names }}" 49 | tags: routing 50 | 51 | - name: Enable OSPF on all router ports 52 | blockinfile: 53 | dest: /etc/quagga/Quagga.conf 54 | marker: "!{mark} ospf {{ item }} config ANSIBLE MANAGED BLOCK" 55 | block: | 56 | ! 57 | interface {{ item }} 58 | link-detect 59 | ip ospf network point-to-point 60 | ip ospf area 0.0.0.0 61 | 62 | with_items: "{{ ansible_interfaces }}" 63 | when: "{{ ('spine' in group_names and item|match(spine_to_leaf_ports + '$' )) or 64 | ('leaf' in group_names and item|match(leaf_to_spine_ports + '$' )) }}" 65 | tags: routing 66 | 67 | - name: Announce loopback route 68 | blockinfile: 69 | dest: /etc/quagga/Quagga.conf 70 | marker: "!{mark} ospf lo config ANSIBLE MANAGED BLOCK" 71 | block: | 72 | ! 73 | interface lo 74 | link-detect 75 | ip ospf area 0.0.0.0 76 | 77 | tags: routing 78 | 79 | - name: Announce bridge route on leaves 80 | blockinfile: 81 | dest: /etc/quagga/Quagga.conf 82 | marker: "!{mark} ospf bridge.{{ default_vlan }} config ANSIBLE MANAGED BLOCK" 83 | block: | 84 | ! 85 | interface bridge.{{ default_vlan }} 86 | link-detect 87 | ip ospf area 0.0.0.0 88 | 89 | when: "{{ 'leaf' in group_names }}" 90 | tags: routing 91 | 92 | - name: Enable OSPF and Zebra daemons 93 | replace: dest=/etc/quagga/daemons regexp='(ospfd|zebra)=no' replace='\1=yes' backup=yes 94 | sudo: yes 95 | register: result 96 | tags: routing 97 | 98 | - name: Start the service to let the config take effect 99 | service: name=quagga state=restarted 100 | tags: 101 | - routing 102 | - command 103 | 104 | - name: Save a local copy of daemons for reference 105 | fetch: src=/etc/quagga/daemons dest=localconfig 106 | 107 | - name: Save a local copy of config for reference 108 | fetch: src=/etc/quagga/Quagga.conf dest=localconfig 109 | -------------------------------------------------------------------------------- /hostset.yml: -------------------------------------------------------------------------------- 1 | # This is meant for inclusion in other playbooks 2 | --- 3 | - name: Get my node ID 4 | set_fact: 5 | my_node_id: "{{ inventory_hostname.split('server')[1]|int }}" 6 | tags: 7 | - compute 8 | - always 9 | 10 | - name: create a list of node number 11 | set_fact: 12 | mystr: "{{ my_node_id|list }}" 13 | tags: 14 | - compute 15 | - always 16 | 17 | - name: Identify subnet from which hosts are assigned IPs for dual-attach 18 | set_fact: 19 | host_ip_base: | 20 | {% if (mystr[0]|int %2) == 1 %} 21 | {{ server_ip_base + mystr[0] + '.' + default_vlan|string }} 22 | {%else%} 23 | {{ server_ip_base + (mystr[0]|int -1)|string + '.' + default_vlan|string }} 24 | {%endif%} 25 | when: "{{ dual_attach_hosts and not use_vxlan }}" 26 | 27 | - name: Identify subnet from which hosts are assigned IPs for single-attach 28 | set_fact: 29 | host_ip_base: | 30 | {{ server_ip_base + mystr[0] + '.' + default_vlan|string }} 31 | when: "{{ not dual_attach_hosts and not use_vxlan }}" 32 | 33 | - name: Identify subnet from which hosts are assigned IPs for VxLAN 34 | set_fact: 35 | host_ip_base: | 36 | {{ server_ip_base + '253.' + default_vlan|string }} 37 | when: "{{ use_vxlan }}" 38 | 39 | - name: construct my IP 40 | set_fact: 41 | host_ip_addr: | 42 | {{ "%s.%s/24"|format(host_ip_base.split()[0], my_node_id) }} 43 | tags: 44 | - compute 45 | - always 46 | 47 | - name: Construct GW IP for dual attach 48 | set_fact: 49 | my_gw_ip: | 50 | {{ "%s.254"|format(host_ip_base.split()[0]) }} 51 | when: "{{ dual_attach_hosts }}" 52 | 53 | - name: Construct GW IP for single-attach hosts 54 | set_fact: 55 | my_gw_ip: | 56 | {{ "%s.1"|format(host_ip_base.split()[0]) }} 57 | when: "{{ not dual_attach_hosts }}" 58 | 59 | # we're adding all packages now since we flip the default route to inband 60 | # once the bond is up 61 | - name: Add bonding module 62 | command: modprobe -a bonding 63 | when: "{{ dual_attach_hosts }}" 64 | 65 | - name: Configure interface up on singly-attached hosts in VxLAN 66 | blockinfile: 67 | dest: /etc/network/interfaces 68 | block: | 69 | auto {{ item }} 70 | iface {{ item }} inet static 71 | address {{ host_ip_addr|trim }} 72 | #post-up ip route replace default via {{ my_gw_ip | trim }} dev eth1 73 | 74 | when: "{{ (not dual_attach_hosts) and 75 | (item != ansible_default_ipv4.interface) and 76 | (item|match('enp0') or item|match('eth')) }}" 77 | become: true 78 | with_items: "{{ ansible_interfaces }}" 79 | notify: Reload link config 80 | 81 | - name: Configure bonds on each host 82 | blockinfile: 83 | dest: /etc/network/interfaces 84 | marker: "# bond config" 85 | block: | 86 | auto eth1 87 | iface eth1 inet manual 88 | bond-master bond0 89 | # 90 | auto eth2 91 | iface eth2 inet manual 92 | bond-master bond0 93 | # 94 | auto bond0 95 | iface bond0 inet static 96 | bond-slaves eth1 eth2 97 | bond-mode 802.3ad 98 | bond-miimon 100 99 | bond-use-carrier 1 100 | bond-lacp-rate 1 101 | bond-min-links 1 102 | bond-xmit-hash-policy layer3+4 103 | address {{ host_ip_addr|trim }} 104 | post-up ifenslave bond0 eth1 eth2 105 | post-up ip link set bond0 promisc on 106 | #post-up ip route replace default via {{ my_gw_ip | trim }} dev bond0 107 | 108 | become: true 109 | when: "{{ dual_attach_hosts }}" 110 | tags: 111 | - hosts 112 | - ifconfig 113 | notify: Reboot server to bring up bonds 114 | 115 | 116 | - name: Save a local copy of the interfaces for reference 117 | fetch: src=/etc/network/interfaces dest=localconfig 118 | -------------------------------------------------------------------------------- /compute-leaf-vars.yml: -------------------------------------------------------------------------------- 1 | # This is meant to be included in other main playbooks 2 | --- 3 | - name: Construct CLAG SysMAC 4 | set_fact: 5 | my_clag_sys_mac: | 6 | {% if (my_node_id|int % 2) == 1 %} 7 | {{ "%s%02d"|format(clag_base_sys_mac, (my_node_id|int)) }} 8 | {%else%} 9 | {{ "%s%02d" | format(clag_base_sys_mac, (my_node_id|int - 1)) }} 10 | {%endif%} 11 | when: "{{ 'leaf' in group_names and dual_attach_hosts }}" 12 | tags: 13 | - compute 14 | - leaf 15 | 16 | - name: Construct CLAG Priority 17 | set_fact: 18 | my_clag_prio: | 19 | {% if (my_node_id|int % 2) == 1 %} 20 | primary 21 | {%else%} 22 | secondary 23 | {%endif%} 24 | when: "{{ 'leaf' in group_names and dual_attach_hosts }}" 25 | tags: 26 | - compute 27 | - leaf 28 | 29 | # Backup IP is the peer switch's eth0 address. 30 | # Construct peer switch's name based on my name: 31 | # If I'm leaf01, peer is leaf02; if I'm leaf02, peer is leaf01 32 | # Same applies for spine and exit leaves 33 | - name: Construct CLAG Backup IP for leaves 34 | set_fact: 35 | clag_backup_ip: | 36 | {% if (my_node_id|int % 2) == 1 %} 37 | {{ hostvars[inventory_hostname.split('f')[0] + 'f' + "%02d"|format(inventory_hostname.split('f')[1]|int + 1)]['ansible_eth0']['ipv4']['address'] }} 38 | {% else %} 39 | {{ hostvars[inventory_hostname.split('f')[0] + 'f' + "%02d"|format(inventory_hostname.split('f')[1]|int - 1)]['ansible_eth0']['ipv4']['address'] }} 40 | {% endif %} 41 | when: "{{ 'leaf' in group_names and 'exit' not in group_names }}" 42 | 43 | - name: Construct CLAG Backup IP for exit leaves 44 | set_fact: 45 | clag_backup_ip: | 46 | {% if (my_node_id|int % 2) == 1 %} 47 | {{ hostvars[inventory_hostname.split('t')[0] + 't' + "%02d"|format(inventory_hostname.split('t')[1]|int + 1)]['ansible_eth0']['ipv4']['address'] }} 48 | {% else %} 49 | {{ hostvars[inventory_hostname.split('t')[0] + 't' + "%02d"|format(inventory_hostname.split('t')[1]|int - 1)]['ansible_eth0']['ipv4']['address'] }} 50 | {% endif %} 51 | when: "{{ 'leaf' in group_names and 'exit' in group_names }}" 52 | 53 | - name: Identify subnet from which hosts are assigned IPs 54 | set_fact: 55 | host_ip_base: | 56 | {% if (my_node_id|int %2) == 1 %} 57 | {{ server_ip_base + my_node_id|string + '.' + default_vlan|string }} 58 | {%else%} 59 | {{ server_ip_base + (my_node_id|int -1)|string + '.' + default_vlan|string }} 60 | {%endif%} 61 | when: "{{ 'leaf' in group_names and dual_attach_hosts }}" 62 | 63 | - name: Identify subnet from which hosts are assigned IPs 64 | set_fact: 65 | host_ip_base: | 66 | {{ server_ip_base + my_node_id|string + '.' + default_vlan|string }} 67 | when: "{{ 'leaf' in group_names and not dual_attach_hosts }}" 68 | 69 | 70 | - name: Extract low order subnet bits for bridge for dual-attach hosts 71 | set_fact: 72 | my_br_ip: | 73 | {% if (my_node_id|int %2) == 1 %} 74 | {{ host_ip_base.split()[0] + '.253/24' }} 75 | {%else%} 76 | {{ host_ip_base.split()[0] + '.252/24' }} 77 | {%endif%} 78 | when: "{{ 'leaf' in group_names and dual_attach_hosts }}" 79 | tags: 80 | - compute 81 | - ifconfig 82 | - always 83 | 84 | - name: Extract low order subnet bits for bridge for single attach hosts 85 | set_fact: 86 | my_br_ip: | 87 | {{ host_ip_base.split()[0] + '.253/24' }} 88 | when: "{{ 'leaf' in group_names and not dual_attach_hosts }}" 89 | tags: 90 | - compute 91 | - ifconfig 92 | - always 93 | 94 | - name: Compute VRR address 95 | set_fact: 96 | my_br_vrr_ip: | 97 | {{ host_ip_base.split()[0] + '.254/32' }} 98 | when: "{{ 'leaf' in group_names and dual_attach_hosts }}" 99 | tags: 100 | - compute 101 | - ifconfig 102 | - always 103 | 104 | - name: Compute start of server ports 105 | set_fact: 106 | server_port_start: "{{ ((leaf_to_server_ports.split('p'))[1].split('-'))[0]|int }}" 107 | when: "{{ 'leaf' in group_names and dual_attach_hosts }}" 108 | tags: 109 | - compute 110 | - ifconfig 111 | - always 112 | 113 | - name: Compute end of server ports 114 | set_fact: 115 | server_port_end: "{{ (((leaf_to_server_ports.split('p'))[1].split('-'))[-1]|int)+1 }}" 116 | when: "{{ 'leaf' in group_names and 'exit' not in group_names and dual_attach_hosts }}" 117 | tags: 118 | - compute 119 | - ifconfig 120 | - always 121 | 122 | - name: Compute start of exit edge ports 123 | set_fact: 124 | server_port_start: "{{ ((exit_to_edge_ports.split('p'))[1].split('-'))[0]|int }}" 125 | when: "{{ 'exit' in group_names and dual_attach_hosts }}" 126 | tags: 127 | - compute 128 | - ifconfig 129 | - always 130 | 131 | - name: Compute end of exit edge ports 132 | set_fact: 133 | server_port_end: "{{ (((exit_to_edge_ports.split('p'))[1].split('-'))[-1]|int)+1 }}" 134 | when: "{{ 'exit' in group_names and dual_attach_hosts }}" 135 | tags: 136 | - compute 137 | - ifconfig 138 | - always 139 | 140 | - debug: msg="{{ server_port_start, server_port_end }}" 141 | -------------------------------------------------------------------------------- /library/nclu.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | 4 | # (c) 2016-2017, Cumulus Networks 5 | # 6 | # This file is part of Ansible 7 | # Ansible is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # Ansible is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # You should have received a copy of the GNU General Public License 16 | # along with Ansible. If not, see . 17 | 18 | ANSIBLE_METADATA = {'metadata_version': '1.0', 19 | 'status': ['preview'], 20 | 'supported_by': 'community'} 21 | 22 | DOCUMENTATION = ''' 23 | --- 24 | module: nclu 25 | version_added: "2.3" 26 | author: "Cumulus Networks" 27 | short_description: Configure network interfaces using NCLU 28 | description: 29 | - Interface to the Network Command Line Utility, developed to make it easier 30 | to configure operating systems running ifupdown2 and Quagga, such as 31 | Cumulus Linux. Command documentation is available at 32 | U(https://docs.cumulusnetworks.com/display/DOCS/Network+Command+Line+Utility) 33 | options: 34 | commands: 35 | description: 36 | - A list of strings containing the net commands to run. Mutually 37 | exclusive with I(template). 38 | template: 39 | description: 40 | - A single, multi-line string with jinja2 formatting. This string 41 | will be broken by lines, and each line will be run through net. 42 | Mutually exclusive with I(commands). 43 | commit: 44 | description: 45 | - When true, performs a 'net commit' at the end of the block. 46 | Mutually exclusive with I(atomic). 47 | default: false 48 | abort: 49 | description: 50 | - Boolean. When true, perform a 'net abort' before the block. 51 | This cleans out any uncommitted changes in the buffer. 52 | Mutually exclusive with I(atomic). 53 | default: false 54 | atomic: 55 | description: 56 | - When true, equivalent to both I(commit) and I(abort) being true. 57 | Mutually exclusive with I(commit) and I(atomic). 58 | default: false 59 | description: 60 | description: 61 | - Commit description that will be recorded to the commit log if 62 | I(commit) or I(atomic) are true. 63 | default: "Ansible-originated commit" 64 | ''' 65 | 66 | EXAMPLES = ''' 67 | 68 | - name: Add two interfaces without committing any changes 69 | nclu: 70 | commands: 71 | - add int swp1 72 | - add int swp2 73 | 74 | - name: Add 48 interfaces and commit the change. 75 | nclu: 76 | template: | 77 | {% for iface in range(1,49) %} 78 | add int swp{{iface}} 79 | {% endfor %} 80 | commit: true 81 | description: "Ansible - add swps1-48" 82 | 83 | - name: Atomically add an interface 84 | nclu: 85 | commands: 86 | - add int swp1 87 | atomic: true 88 | description: "Ansible - add swp1" 89 | ''' 90 | 91 | RETURN = ''' 92 | changed: 93 | description: whether the interface was changed 94 | returned: changed 95 | type: bool 96 | sample: True 97 | msg: 98 | description: human-readable report of success or failure 99 | returned: always 100 | type: string 101 | sample: "interface bond0 config updated" 102 | ''' 103 | 104 | 105 | def command_helper(module, command, errmsg=None): 106 | """Run a command, catch any nclu errors""" 107 | (_rc, output, _err) = module.run_command("/usr/bin/net %s"%command) 108 | if _rc or 'ERROR' in output or 'ERROR' in _err: 109 | module.fail_json(msg=errmsg or output) 110 | return str(output) 111 | 112 | 113 | def check_pending(module): 114 | """Check the pending diff of the nclu buffer.""" 115 | pending = command_helper(module, "pending", "Error in pending config. You may want to view `net pending` on this target.") 116 | 117 | delimeter1 = "net add/del commands since the last 'net commit'" 118 | color1 = '\x1b[94m' 119 | if delimeter1 in pending: 120 | pending = pending.split(delimeter1)[0] 121 | pending = pending.replace('\x1b[94m', '') 122 | return pending.strip() 123 | 124 | 125 | def run_nclu(module, command_list, command_string, commit, atomic, abort, description): 126 | _changed = False 127 | 128 | commands = [] 129 | if command_list: 130 | commands = command_list 131 | elif command_string: 132 | commands = command_string.splitlines() 133 | 134 | do_commit = False 135 | do_abort = abort 136 | if commit or atomic: 137 | do_commit = True 138 | if atomic: 139 | do_abort = True 140 | 141 | if do_abort: 142 | command_helper(module, "abort") 143 | 144 | # First, look at the staged commands. 145 | before = check_pending(module) 146 | # Run all of the the net commands 147 | output_lines = [] 148 | for line in commands: 149 | output_lines += [command_helper(module, line.strip(), "Failed on line %s"%line)] 150 | output = "\n".join(output_lines) 151 | 152 | # If pending changes changed, report a change. 153 | after = check_pending(module) 154 | if before == after: 155 | _changed = False 156 | else: 157 | _changed = True 158 | 159 | # Do the commit. 160 | if do_commit: 161 | result = command_helper(module, "commit description '%s'"%description) 162 | if "commit ignored" in result: 163 | _changed = False 164 | command_helper(module, "abort") 165 | elif command_helper(module, "show commit last") == "": 166 | _changed = False 167 | 168 | return _changed, output 169 | 170 | 171 | def main(testing=False): 172 | module = AnsibleModule(argument_spec=dict( 173 | commands = dict(required=False, type='list'), 174 | template = dict(required=False, type='str'), 175 | description = dict(required=False, type='str', default="Ansible-originated commit"), 176 | abort = dict(required=False, type='bool', default=False), 177 | commit = dict(required=False, type='bool', default=False), 178 | atomic = dict(required=False, type='bool', default=False)), 179 | mutually_exclusive=[('commands', 'template'), 180 | ('commit', 'atomic'), 181 | ('abort', 'atomic')] 182 | ) 183 | command_list = module.params.get('commands', None) 184 | command_string = module.params.get('template', None) 185 | commit = module.params.get('commit') 186 | atomic = module.params.get('atomic') 187 | abort = module.params.get('abort') 188 | description = module.params.get('description') 189 | 190 | _changed, output = run_nclu(module, command_list, command_string, commit, atomic, abort, description) 191 | if not testing: 192 | module.exit_json(changed=_changed, msg=output) 193 | elif testing: 194 | return {"changed": _changed, "msg": output} 195 | 196 | # import module snippets 197 | from ansible.module_utils.basic import AnsibleModule 198 | if __name__ == '__main__': 199 | main()#!/usr/bin/python 200 | -------------------------------------------------------------------------------- /helper_scripts/apply_udev.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import os 3 | import re 4 | import time 5 | import argparse 6 | import subprocess 7 | 8 | 9 | parser = argparse.ArgumentParser(description='UDEV Remap Script -- Rename interfaces using UDEV Rules') 10 | 11 | parser.add_argument('-v','--verbose', action='store_true', 12 | help='enables verbose logging mode') 13 | parser.add_argument('-a','--add', nargs=2, action='append', 14 | help='Specify a mac address followed by an interface') 15 | parser.add_argument('-d','--delete', action='append', 16 | help='Specify a mac address to be removed from the exising UDEV rules.') 17 | parser.add_argument('-s','--show', action='store_true', 18 | help='Show the existing UDEV Rules.') 19 | parser.add_argument('-nv','--no-vagrant-interface', action='store_true', 20 | help='Using this option will not create a vagrant interface during the application of rules.') 21 | parser.add_argument('-nd','--no-vagrant-default', action='store_true', 22 | help='Using this option will not create a vagrant default route when applying the re-map.') 23 | parser.add_argument('-vm','--vagrant_mapping', action='store_true', 24 | help='Using this option will create the mapping for the vagrant interface that happens automatically during the apply option.') 25 | parser.add_argument("--vagrant-name", default='vagrant', 26 | help='The name of the vagrant interface (default "vagrant")') 27 | parser.add_argument("--apply", action='store_true', 28 | help='Apply the remap as it has been provided.') 29 | 30 | 31 | def is_mac(mac): 32 | if re.match("[0-9a-f]{2}([-:])[0-9a-f]{2}(\\1[0-9a-f]{2}){4}$",mac.lower()): 33 | mac=mac.lower().replace("-",":") 34 | elif re.match("[0-9a-f]{12}$",mac.lower()): 35 | mac=mac.lower() 36 | mac=':'.join(mac[i:i+2] for i in range(0,len(mac),2)) 37 | else: 38 | print " ### ERROR: MAC address --> " + str(mac) + " is not valid." 39 | exit(1) 40 | return mac 41 | 42 | def show_rules(): 43 | #Show Existing Rules 44 | print "#### UDEV Rules (/etc/udev/rules.d/70-persistent-net.rules) ####" 45 | if not os.path.isfile(udev_file): 46 | if verbose: print " >>> No Rules Present or File Does Not Exist <<<" 47 | return 48 | rules=subprocess.check_output(["cat",udev_file]).split('\n') 49 | for line in rules: print line 50 | 51 | def parse_interfaces(): 52 | #Parse Interfaces 53 | output=subprocess.check_output(["ip","link","show"]).split('\n') 54 | 55 | ifindex="" 56 | interface="" 57 | mac="" 58 | index_map={} 59 | 60 | #parse ip link show output for interface, ifindex and MAC 61 | for line in output: 62 | if re.match("^.*LOOPBACK.*$",line): continue #skip loopbacks 63 | elif re.match("^[0-9]+:.*$",line): #look for lines that start with an ifindex 64 | cut_line=line.split() 65 | ifindex=cut_line[0][:-1] 66 | interface=cut_line[1][:-1] 67 | elif re.match("^.*link/ether.*$",line): #look for lines that have link/ether 68 | cut_line=line.split() 69 | mac=cut_line[1] 70 | if verbose: print "interface: " + interface + " index: " + str(ifindex) + " mac: " + mac 71 | index_map[interface]={"index":ifindex,"mac":mac} 72 | 73 | for interface in index_map: 74 | if verbose: print "determining driver for interface: " + interface 75 | success=False 76 | #Method1 77 | try: 78 | ethtool_output=subprocess.check_output(["ethtool","-i",interface]).split('\n') 79 | driver = ethtool_output[0].split(":")[1][1:] 80 | except (subprocess.CalledProcessError, OSError), e: 81 | #Method 2 82 | try: 83 | driver=subprocess.check_output(["basename $(readlink /sys/class/net/"+interface+"/device/driver/module) > /dev/null 2>&1"],shell=True).replace("\n","") 84 | except subprocess.CalledProcessError, e: 85 | try: 86 | driver=subprocess.check_output(["basename $(readlink /sys/class/net/"+interface+"/device/driver) > /dev/null 2>&1"],shell=True).replace("\n","") 87 | except subprocess.CalledProcessError, e: 88 | print " ### ERROR Tried 3 methods to determine device driver. All Failed." 89 | exit(1) 90 | index_map[interface]["driver"]=driver 91 | if verbose: print "interface: " + interface + " driver: " + driver 92 | return index_map 93 | 94 | def delete_rule(mac): 95 | if not os.path.isfile(udev_file): 96 | if verbose: print "WARN: delete of rule not possible, udev file does not exist." 97 | return 98 | #Delete rule with MAC address 99 | if verbose: 100 | print ">>> BEFORE" 101 | show_rules() 102 | remove_rule=subprocess.check_output(["sed -i '/"+mac+"/d' " + udev_file],shell=True).split('\n') 103 | if verbose: 104 | print "<<< AFTER" 105 | show_rules() 106 | 107 | def add_rule(mac,interface): 108 | index_map=parse_interfaces() 109 | print " INFO: Adding UDEV Rule: " + mac + " --> " + interface 110 | mac_found=False 111 | for interface_1 in index_map: 112 | if index_map[interface_1]['mac'] == mac: mac_found = True 113 | if not mac_found: 114 | print " WARNING: this MAC address presently does not belong to any device on the system." 115 | 116 | if verbose: 117 | print "deleting any matching rules to be safe..." 118 | delete_rule(mac) 119 | 120 | with open("/etc/udev/rules.d/70-persistent-net.rules","a") as udev_file: 121 | udev_file.write("""ACTION=="add", SUBSYSTEM=="net", ATTR{address}==\"""" + mac +"\", NAME=\""+interface+"\", SUBSYSTEMS==\"pci\" \n") 122 | if verbose: show_rules() 123 | 124 | def apply_remap(): 125 | global just_vagrant 126 | index_map=parse_interfaces() 127 | if not just_vagrant: 128 | print " INFO: Applying new UDEV Rules..." 129 | drivers={} 130 | lowest_index="" 131 | lowest_index_interface="" 132 | #Determine Driver and lowest index 133 | for interface in index_map: 134 | if lowest_index == "": 135 | lowest_index = index_map[interface]["index"] 136 | lowest_index_interface = interface 137 | elif int(index_map[interface]["index"]) < int(lowest_index): 138 | #Confirm that it is a physical interface and not a logical device 139 | try: 140 | subprocess.check_call(["udevadm info -a -p /sys/class/net/"+interface+""" | grep 'SUBSYSTEMS=="pci"' > /dev/null"""],shell=True) 141 | except subprocess.CalledProcessError, e: 142 | continue 143 | lowest_index = index_map[interface]["index"] 144 | lowest_index_interface = interface 145 | if verbose: 146 | print interface 147 | print " lowest_index: + " + str(lowest_index) + " --> " + str(lowest_index_interface) 148 | print " index: " + index_map[interface]["index"] 149 | print " mac: " + index_map[interface]["mac"] 150 | print " driver: " + index_map[interface]["driver"] 151 | if index_map[interface]["driver"] not in drivers: drivers[index_map[interface]["driver"]]= True 152 | 153 | #Leave tunnel and bridge devices alone 154 | if "tun" in drivers: del drivers["tun"] 155 | if "bridge" in drivers: del drivers["bridge"] 156 | if "vxlan" in drivers: del drivers["vxlan"] 157 | if "bond" in drivers: del drivers["bond"] 158 | 159 | if verbose: 160 | print "lowest_index_interface: " + lowest_index_interface 161 | print "lowest_index: " + str(lowest_index) 162 | print drivers 163 | 164 | global vagrant_name 165 | if use_vagrant_interface: 166 | add_rule(index_map[lowest_index_interface]["mac"], vagrant_name) 167 | print " FYI: "+lowest_index_interface + " will become the vagrant interface" 168 | 169 | if just_vagrant: return 0 170 | for driver in drivers: 171 | dead_drop=subprocess.check_output(["modprobe","-r",driver]) 172 | 173 | 174 | dead_drop=subprocess.check_output(["udevadm","control","--reload-rules"]) 175 | dead_drop=subprocess.check_output(["udevadm","trigger"]) 176 | time.sleep(4) 177 | if use_vagrant_interface: 178 | dead_drop=subprocess.check_output(["ifup vagrant"],shell=True) 179 | time.sleep(1) 180 | if use_vagrant_default: 181 | dead_drop=subprocess.check_output(["ip route delete default dev vagrant"],shell=True) 182 | output=subprocess.check_output(["ip","link","show"]).split('\n') 183 | print "### PRESENT INTERFACES ###" 184 | for line in output: 185 | print line 186 | 187 | def main(): 188 | 189 | global verbose 190 | verbose=False 191 | global udev_file 192 | udev_file="/etc/udev/rules.d/70-persistent-net.rules" 193 | global use_vagrant_interface 194 | use_vagrant_interface=True 195 | global use_vagrant_default 196 | use_vagrant_default=True 197 | add=False 198 | show=False 199 | delete=False 200 | global just_vagrant 201 | just_vagrant=False 202 | global vagrant_name 203 | apply=False 204 | additions=[] 205 | removals=[] 206 | 207 | args = parser.parse_args() 208 | if args.verbose: verbose=args.verbose 209 | if args.add: 210 | add=True 211 | for mac,interface in args.add: additions.append([is_mac(mac),interface]) 212 | if args.delete: 213 | delete=True 214 | for mac in args.delete: removals.append(is_mac(mac)) 215 | if args.show: show=True 216 | if args.no_vagrant_interface: use_vagrant_interface=False 217 | if args.vagrant_mapping: 218 | apply=True 219 | just_vagrant=True 220 | if args.no_vagrant_default: use_vagrant_default=False 221 | if args.apply: apply=True 222 | vagrant_name = args.vagrant_name 223 | 224 | if verbose: 225 | print "Arguments:" 226 | print args 227 | 228 | if show: show_rules() 229 | elif delete == True: 230 | for mac in removals: delete_rule(mac) 231 | elif add == False: apply_remap() 232 | elif add == True: 233 | for mac,interface in additions: add_rule(mac,interface) 234 | 235 | 236 | if __name__ == "__main__": 237 | main() 238 | 239 | exit(0) 240 | -------------------------------------------------------------------------------- /Vagrantfile: -------------------------------------------------------------------------------- 1 | # Created by Topology-Converter v4.5.0 2 | # https://github.com/cumulusnetworks/topology_converter 3 | # using topology data from: topology.dot 4 | # 5 | # NOTE: in order to use this Vagrantfile you will need: 6 | # -Vagrant(v1.8.1+) installed: http://www.vagrantup.com/downloads 7 | # -Cumulus Plugin for Vagrant installed: $ vagrant plugin install vagrant-cumulus 8 | # -the "helper_scripts" directory that comes packaged with topology-converter.py 9 | # -Virtualbox installed: https://www.virtualbox.org/wiki/Downloads 10 | 11 | 12 | 13 | # Check required plugins 14 | #REQUIRED_PLUGINS = %w(vagrant-cumulus) 15 | #exit unless REQUIRED_PLUGINS.all? do |plugin| 16 | # Vagrant.has_plugin?(plugin) || ( 17 | # puts "The #{plugin} plugin is required. Please install it with:" 18 | # puts "$ vagrant plugin install #{plugin}" 19 | # false 20 | # ) 21 | #end 22 | 23 | $script = <<-SCRIPT 24 | if grep -q -i 'cumulus' /etc/lsb-release &> /dev/null; then 25 | echo "### RUNNING CUMULUS EXTRA CONFIG ###" 26 | source /etc/lsb-release 27 | if [[ $DISTRIB_RELEASE =~ ^2.* ]]; then 28 | echo " INFO: Detected a 2.5.x Based Release" 29 | echo " adding fake cl-acltool..." 30 | echo -e "#!/bin/bash\nexit 0" > /bin/cl-acltool 31 | chmod 755 /bin/cl-acltool 32 | 33 | echo " adding fake cl-license..." 34 | cat > /bin/cl-license <<'EOF' 35 | #! /bin/bash 36 | #------------------------------------------------------------------------------- 37 | # 38 | # Copyright 2013 Cumulus Networks, Inc. All rights reserved 39 | # 40 | 41 | URL_RE='^http://.*/.*' 42 | 43 | #Legacy symlink 44 | if echo "$0" | grep -q "cl-license-install$"; then 45 | exec cl-license -i $* 46 | fi 47 | 48 | LIC_DIR="/etc/cumulus" 49 | PERSIST_LIC_DIR="/mnt/persist/etc/cumulus" 50 | 51 | #Print current license, if any. 52 | if [ -z "$1" ]; then 53 | if [ ! -f "$LIC_DIR/.license.txt" ]; then 54 | echo "No license installed!" >&2 55 | exit 20 56 | fi 57 | cat "$LIC_DIR/.license.txt" 58 | exit 0 59 | fi 60 | 61 | #Must be root beyond this point 62 | if (( EUID != 0 )); then 63 | echo "You must have root privileges to run this command." 1>&2 64 | exit 100 65 | fi 66 | 67 | #Delete license 68 | if [ x"$1" == "x-d" ]; then 69 | rm -f "$LIC_DIR/.license.txt" 70 | rm -f "$PERSIST_LIC_DIR/.license.txt" 71 | 72 | echo License file uninstalled. 73 | exit 0 74 | fi 75 | 76 | function usage { 77 | echo "Usage: $0 (-i (license_file | URL) | -d)" >&2 78 | echo " -i Install a license, via stdin, file, or URL." >&2 79 | echo " -d Delete the current installed license." >&2 80 | echo >&2 81 | echo " cl-license prints, installs or deletes a license on this switch." >&2 82 | } 83 | 84 | if [ x"$1" != 'x-i' ]; then 85 | usage 86 | exit 100 87 | fi 88 | shift 89 | if [ ! -f "$1" ]; then 90 | if [ -n "$1" ]; then 91 | if ! echo "$1" | grep -q "$URL_RE"; then 92 | usage 93 | echo "file $1 not found or not readable." >&2 94 | exit 100 95 | fi 96 | fi 97 | fi 98 | 99 | function clean_tmp { 100 | rm $1 101 | } 102 | 103 | if [ -z "$1" ]; then 104 | LIC_FILE=`mktemp lic.XXXXXX` 105 | trap "clean_tmp $LIC_FILE" EXIT 106 | echo "Paste license text here, then hit ctrl-d" >&2 107 | cat >$LIC_FILE 108 | else 109 | if echo "$1" | grep -q "$URL_RE"; then 110 | LIC_FILE=`mktemp lic.XXXXXX` 111 | trap "clean_tmp $LIC_FILE" EXIT 112 | if ! wget "$1" -O $LIC_FILE; then 113 | echo "Couldn't download $1 via HTTP!" >&2 114 | exit 10 115 | fi 116 | else 117 | LIC_FILE="$1" 118 | fi 119 | fi 120 | 121 | /usr/sbin/switchd -lic "$LIC_FILE" 122 | SWITCHD_RETCODE=$? 123 | if [ $SWITCHD_RETCODE -eq 99 ]; then 124 | more /usr/share/cumulus/EULA.txt 125 | echo "I (on behalf of the entity who will be using the software) accept" 126 | read -p "and agree to the EULA (yes/no): " 127 | if [ "$REPLY" != "yes" -a "$REPLY" != "y" ]; then 128 | echo EULA not agreed to, aborting. >&2 129 | exit 2 130 | fi 131 | elif [ $SWITCHD_RETCODE -ne 0 ]; then 132 | echo '******************************' >&2 133 | echo ERROR: License file not valid. >&2 134 | echo ERROR: No license installed. >&2 135 | echo '******************************' >&2 136 | exit 1 137 | fi 138 | 139 | mkdir -p "$LIC_DIR" 140 | cp "$LIC_FILE" "$LIC_DIR/.license.txt" 141 | chmod 644 "$LIC_DIR/.license.txt" 142 | 143 | mkdir -p "$PERSIST_LIC_DIR" 144 | cp "$LIC_FILE" "$PERSIST_LIC_DIR/.license.txt" 145 | chmod 644 "$PERSIST_LIC_DIR/.license.txt" 146 | 147 | echo License file installed. 148 | echo Reboot to enable functionality. 149 | EOF 150 | chmod 755 /bin/cl-license 151 | 152 | echo " Disabling default remap on Cumulus VX..." 153 | mv -v /etc/init.d/rename_eth_swp /etc/init.d/rename_eth_swp.backup 154 | 155 | echo " Replacing fake switchd" 156 | rm -rf /usr/bin/switchd 157 | cat > /usr/sbin/switchd <<'EOF' 158 | #!/bin/bash 159 | PIDFILE=$1 160 | LICENSE_FILE=/etc/cumulus/.license 161 | RC=0 162 | 163 | # Make sure we weren't invoked with "-lic" 164 | if [ "$PIDFILE" == "-lic" ]; then 165 | if [ "$2" != "" ]; then 166 | LICENSE_FILE=$2 167 | fi 168 | if [ ! -e $LICENSE_FILE ]; then 169 | echo "No license file." >&2 170 | RC=1 171 | fi 172 | RC=0 173 | else 174 | tail -f /dev/null & CPID=$! 175 | echo -n $CPID > $PIDFILE 176 | wait $CPID 177 | fi 178 | 179 | exit $RC 180 | EOF 181 | chmod 755 /usr/sbin/switchd 182 | 183 | cat > /etc/init.d/switchd <<'EOF' 184 | #! /bin/bash 185 | ### BEGIN INIT INFO 186 | # Provides: switchd 187 | # Required-Start: 188 | # Required-Stop: 189 | # Should-Start: 190 | # Should-Stop: 191 | # X-Start-Before 192 | # Default-Start: S 193 | # Default-Stop: 194 | # Short-Description: Controls fake switchd process 195 | ### END INIT INFO 196 | 197 | # Author: Kristian Van Der Vliet 198 | # 199 | # Please remove the "Author" lines above and replace them 200 | # with your own name if you copy and modify this script. 201 | 202 | PATH=/sbin:/bin:/usr/bin 203 | 204 | NAME=switchd 205 | SCRIPTNAME=/etc/init.d/$NAME 206 | PIDFILE=/var/run/switchd.pid 207 | 208 | . /lib/init/vars.sh 209 | . /lib/lsb/init-functions 210 | 211 | do_start() { 212 | echo "[ ok ] Starting Cumulus Networks switch chip daemon: switchd" 213 | /usr/sbin/switchd $PIDFILE 2>/dev/null & 214 | } 215 | 216 | do_stop() { 217 | if [ -e $PIDFILE ];then 218 | kill -TERM $(cat $PIDFILE) 219 | rm $PIDFILE 220 | fi 221 | } 222 | 223 | do_status() { 224 | if [ -e $PIDFILE ];then 225 | echo "[ ok ] switchd is running." 226 | else 227 | echo "[FAIL] switchd is not running ... failed!" >&2 228 | exit 3 229 | fi 230 | } 231 | 232 | case "$1" in 233 | start|"") 234 | log_action_begin_msg "Starting switchd" 235 | do_start 236 | log_action_end_msg 0 237 | ;; 238 | stop) 239 | log_action_begin_msg "Stopping switchd" 240 | do_stop 241 | log_action_end_msg 0 242 | ;; 243 | status) 244 | do_status 245 | ;; 246 | restart) 247 | log_action_begin_msg "Re-starting switchd" 248 | do_stop 249 | do_start 250 | log_action_end_msg 0 251 | ;; 252 | reload|force-reload) 253 | echo "Error: argument '$1' not supported" >&2 254 | exit 3 255 | ;; 256 | *) 257 | echo "Usage: $SCRIPTNAME [start|stop|restart|status]" >&2 258 | exit 3 259 | ;; 260 | esac 261 | 262 | : 263 | EOF 264 | chmod 755 /etc/init.d/switchd 265 | reboot 266 | 267 | elif [[ $DISTRIB_RELEASE =~ ^3.* ]]; then 268 | echo " INFO: Detected a 3.x Based Release" 269 | echo " Disabling default remap on Cumulus VX..." 270 | mv -v /etc/hw_init.d/S10rename_eth_swp.sh /etc/S10rename_eth_swp.sh.backup 271 | echo "### Disabling ZTP service..." 272 | systemctl stop ztp.service 273 | ztp -d 2>&1 274 | echo "### Resetting ZTP to work next boot..." 275 | ztp -R 2>&1 276 | echo "### Rebooting Switch to Apply Remap..." 277 | reboot 278 | fi 279 | echo "### DONE ###" 280 | else 281 | reboot 282 | fi 283 | SCRIPT 284 | 285 | Vagrant.configure("2") do |config| 286 | wbid = 1 287 | offset = 0 288 | 289 | config.vm.provider "virtualbox" do |v| 290 | v.gui=false 291 | 292 | end 293 | 294 | 295 | 296 | ##### DEFINE VM for oob-mgmt-server ##### 297 | config.vm.define "oob-mgmt-server", primary: true do |device| 298 | device.vm.hostname = "oob-mgmt-server" 299 | device.vm.box = "CumulusCommunity/cumulus-vx" 300 | 301 | 302 | device.vm.provider "virtualbox" do |v| 303 | v.name = "#{wbid}_oob-mgmt-server" 304 | v.customize ["modifyvm", :id, '--audiocontroller', 'AC97', '--audio', 'Null'] 305 | v.memory = 1*1024 306 | end 307 | device.vm.synced_folder ".", "/vagrant", disabled: true 308 | 309 | # NETWORK INTERFACES 310 | # link for eth1 --> oob-mgmt-switch:swp1 311 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net54", auto_config: false , :mac => "44383900005f" 312 | device.vm.network "forwarded_port", guest: 9000, host: 9002 313 | 314 | 315 | device.vm.provider "virtualbox" do |vbox| 316 | vbox.customize ['modifyvm', :id, '--nicpromisc2', 'allow-all'] 317 | 318 | vbox.customize ["modifyvm", :id, "--nictype1", "virtio"] 319 | vbox.customize ["modifyvm", :id, "--nictype2", "virtio"] 320 | 321 | end 322 | 323 | # Fixes "stdin: is not a tty" and "mesg: ttyname failed : Inappropriate ioctl for device" messages --> https://github.com/mitchellh/vagrant/issues/1673 324 | device.vm.provision :shell , inline: "(grep -q 'mesg n' /root/.profile 2>/dev/null && sed -i '/mesg n/d' /root/.profile 2>/dev/null && echo 'Ignore the previous error, fixing this now...') || true;" 325 | 326 | # Run Any Extra Config 327 | device.vm.provision :shell , path: "./helper_scripts/config_oob_server.sh" 328 | 329 | 330 | extravars = {wbench_hosts: { 331 | exit02: {ip: "192.168.0.42", mac: "a0:00:00:00:00:42"}, 332 | exit01: {ip: "192.168.0.41", mac: "a0:00:00:00:00:41"}, 333 | spine02: {ip: "192.168.0.22", mac: "a0:00:00:00:00:22"}, 334 | spine01: {ip: "192.168.0.21", mac: "a0:00:00:00:00:21"}, 335 | leaf04: {ip: "192.168.0.14", mac: "a0:00:00:00:00:14"}, 336 | leaf02: {ip: "192.168.0.12", mac: "a0:00:00:00:00:12"}, 337 | leaf03: {ip: "192.168.0.13", mac: "a0:00:00:00:00:13"}, 338 | leaf01: {ip: "192.168.0.11", mac: "a0:00:00:00:00:11"}, 339 | edge01: {ip: "192.168.0.51", mac: "a0:00:00:00:00:51"}, 340 | server01: {ip: "192.168.0.31", mac: "a0:00:00:00:00:31"}, 341 | server03: {ip: "192.168.0.33", mac: "a0:00:00:00:00:33"}, 342 | server02: {ip: "192.168.0.32", mac: "a0:00:00:00:00:32"}, 343 | server04: {ip: "192.168.0.34", mac: "a0:00:00:00:00:34"}, 344 | }} 345 | 346 | device.vm.provision :shell , path: "./helper_scripts/oob-mgmt-server-provision.sh" 347 | device.vm.provision :shell , inline: "ansible-playbook cldemo-provision-ts/site.yml --extra-vars '#{extravars.to_json}' --connection=local -i localhost," 348 | device.vm.provision :shell , path: "./helper_scripts/bgpdc-clone.sh" 349 | 350 | end 351 | 352 | ##### DEFINE VM for oob-mgmt-switch ##### 353 | config.vm.define "oob-mgmt-switch" do |device| 354 | device.vm.hostname = "oob-mgmt-switch" 355 | device.vm.box = "CumulusCommunity/cumulus-vx" 356 | device.vm.box_version = ">=3.3.0" 357 | 358 | device.vm.provider "virtualbox" do |v| 359 | v.name = "#{wbid}_oob-mgmt-switch" 360 | v.customize ["modifyvm", :id, '--audiocontroller', 'AC97', '--audio', 'Null'] 361 | v.memory = 256 362 | end 363 | device.vm.synced_folder ".", "/vagrant", disabled: true 364 | 365 | # NETWORK INTERFACES 366 | # link for swp1 --> oob-mgmt-server:eth1 367 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net54", auto_config: false , :mac => "443839000060" 368 | 369 | # link for swp2 --> server01:eth0 370 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net42", auto_config: false , :mac => "44383900004b" 371 | 372 | # link for swp3 --> server02:eth0 373 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net47", auto_config: false , :mac => "443839000054" 374 | 375 | # link for swp4 --> server03:eth0 376 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net3", auto_config: false , :mac => "443839000005" 377 | 378 | # link for swp5 --> server04:eth0 379 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net49", auto_config: false , :mac => "443839000056" 380 | 381 | # link for swp6 --> leaf01:eth0 382 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net20", auto_config: false , :mac => "443839000025" 383 | 384 | # link for swp7 --> leaf02:eth0 385 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net38", auto_config: false , :mac => "443839000045" 386 | 387 | # link for swp8 --> leaf03:eth0 388 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net28", auto_config: false , :mac => "443839000034" 389 | 390 | # link for swp9 --> leaf04:eth0 391 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net34", auto_config: false , :mac => "44383900003e" 392 | 393 | # link for swp10 --> spine01:eth0 394 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net31", auto_config: false , :mac => "443839000039" 395 | 396 | # link for swp11 --> spine02:eth0 397 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net59", auto_config: false , :mac => "443839000069" 398 | 399 | # link for swp12 --> exit01:eth0 400 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net9", auto_config: false , :mac => "443839000010" 401 | 402 | # link for swp13 --> exit02:eth0 403 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net48", auto_config: false , :mac => "443839000055" 404 | 405 | # link for swp14 --> edge01:eth0 406 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net40", auto_config: false , :mac => "443839000048" 407 | 408 | # link for swp15 --> internet:eth0 409 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net35", auto_config: false , :mac => "443839000040" 410 | 411 | 412 | device.vm.provider "virtualbox" do |vbox| 413 | vbox.customize ['modifyvm', :id, '--nicpromisc2', 'allow-all'] 414 | vbox.customize ['modifyvm', :id, '--nicpromisc3', 'allow-all'] 415 | vbox.customize ['modifyvm', :id, '--nicpromisc4', 'allow-all'] 416 | vbox.customize ['modifyvm', :id, '--nicpromisc5', 'allow-all'] 417 | vbox.customize ['modifyvm', :id, '--nicpromisc6', 'allow-all'] 418 | vbox.customize ['modifyvm', :id, '--nicpromisc7', 'allow-all'] 419 | vbox.customize ['modifyvm', :id, '--nicpromisc8', 'allow-all'] 420 | vbox.customize ['modifyvm', :id, '--nicpromisc9', 'allow-all'] 421 | vbox.customize ['modifyvm', :id, '--nicpromisc10', 'allow-all'] 422 | vbox.customize ['modifyvm', :id, '--nicpromisc11', 'allow-all'] 423 | vbox.customize ['modifyvm', :id, '--nicpromisc12', 'allow-all'] 424 | vbox.customize ['modifyvm', :id, '--nicpromisc13', 'allow-all'] 425 | vbox.customize ['modifyvm', :id, '--nicpromisc14', 'allow-all'] 426 | vbox.customize ['modifyvm', :id, '--nicpromisc15', 'allow-all'] 427 | vbox.customize ['modifyvm', :id, '--nicpromisc16', 'allow-all'] 428 | 429 | end 430 | 431 | # Fixes "stdin: is not a tty" and "mesg: ttyname failed : Inappropriate ioctl for device" messages --> https://github.com/mitchellh/vagrant/issues/1673 432 | device.vm.provision :shell , inline: "(grep -q 'mesg n' /root/.profile 2>/dev/null && sed -i '/mesg n/d' /root/.profile 2>/dev/null && echo 'Ignore the previous error, fixing this now...') || true;" 433 | 434 | 435 | 436 | # Run Any Extra Config 437 | device.vm.provision :shell , path: "./helper_scripts/config_oob_switch.sh" 438 | 439 | 440 | 441 | # Apply the interface re-map 442 | device.vm.provision "file", source: "./helper_scripts/apply_udev.py", destination: "/home/vagrant/apply_udev.py" 443 | device.vm.provision :shell , inline: "chmod 755 /home/vagrant/apply_udev.py" 444 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:60 swp1" 445 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:4b swp2" 446 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:54 swp3" 447 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:05 swp4" 448 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:56 swp5" 449 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:25 swp6" 450 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:45 swp7" 451 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:34 swp8" 452 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:3e swp9" 453 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:39 swp10" 454 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:69 swp11" 455 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:10 swp12" 456 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:55 swp13" 457 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:48 swp14" 458 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:40 swp15" 459 | 460 | 461 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -vm -nv" 462 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -s" 463 | device.vm.provision :shell , :inline => $script 464 | 465 | 466 | 467 | end 468 | 469 | ##### DEFINE VM for exit02 ##### 470 | config.vm.define "exit02" do |device| 471 | device.vm.hostname = "exit02" 472 | device.vm.box = "CumulusCommunity/cumulus-vx" 473 | device.vm.box_version = ">=3.3.0" 474 | 475 | device.vm.provider "virtualbox" do |v| 476 | v.name = "#{wbid}_exit02" 477 | v.customize ["modifyvm", :id, '--audiocontroller', 'AC97', '--audio', 'Null'] 478 | v.memory = 512 479 | end 480 | device.vm.synced_folder ".", "/vagrant", disabled: true 481 | 482 | # NETWORK INTERFACES 483 | # link for eth0 --> oob-mgmt-switch:swp13 484 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net48", auto_config: false , :mac => "a00000000042" 485 | 486 | # link for swp1 --> edge01:eth2 487 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net7", auto_config: false , :mac => "44383900000d" 488 | 489 | # link for swp44 --> internet:swp2 490 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net39", auto_config: false , :mac => "443839000047" 491 | 492 | # link for swp45 --> exit02:swp46 493 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net30", auto_config: false , :mac => "443839000037" 494 | 495 | # link for swp46 --> exit02:swp45 496 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net30", auto_config: false , :mac => "443839000038" 497 | 498 | # link for swp47 --> exit02:swp48 499 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net33", auto_config: false , :mac => "44383900003c" 500 | 501 | # link for swp48 --> exit02:swp47 502 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net33", auto_config: false , :mac => "44383900003d" 503 | 504 | # link for swp49 --> exit01:swp49 505 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net24", auto_config: false , :mac => "44383900002d" 506 | 507 | # link for swp50 --> exit01:swp50 508 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net14", auto_config: false , :mac => "44383900001a" 509 | 510 | # link for swp51 --> spine01:swp29 511 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net21", auto_config: false , :mac => "443839000026" 512 | 513 | # link for swp52 --> spine02:swp29 514 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net53", auto_config: false , :mac => "44383900005d" 515 | 516 | 517 | device.vm.provider "virtualbox" do |vbox| 518 | vbox.customize ['modifyvm', :id, '--nicpromisc2', 'allow-all'] 519 | vbox.customize ['modifyvm', :id, '--nicpromisc3', 'allow-all'] 520 | vbox.customize ['modifyvm', :id, '--nicpromisc4', 'allow-all'] 521 | vbox.customize ['modifyvm', :id, '--nicpromisc5', 'allow-all'] 522 | vbox.customize ['modifyvm', :id, '--nicpromisc6', 'allow-all'] 523 | vbox.customize ['modifyvm', :id, '--nicpromisc7', 'allow-all'] 524 | vbox.customize ['modifyvm', :id, '--nicpromisc8', 'allow-all'] 525 | vbox.customize ['modifyvm', :id, '--nicpromisc9', 'allow-all'] 526 | vbox.customize ['modifyvm', :id, '--nicpromisc10', 'allow-all'] 527 | vbox.customize ['modifyvm', :id, '--nicpromisc11', 'allow-all'] 528 | vbox.customize ['modifyvm', :id, '--nicpromisc12', 'allow-all'] 529 | 530 | end 531 | 532 | # Fixes "stdin: is not a tty" and "mesg: ttyname failed : Inappropriate ioctl for device" messages --> https://github.com/mitchellh/vagrant/issues/1673 533 | device.vm.provision :shell , inline: "(grep -q 'mesg n' /root/.profile 2>/dev/null && sed -i '/mesg n/d' /root/.profile 2>/dev/null && echo 'Ignore the previous error, fixing this now...') || true;" 534 | 535 | 536 | 537 | # Run Any Extra Config 538 | device.vm.provision :shell , path: "./helper_scripts/config_switch.sh" 539 | 540 | 541 | 542 | # Apply the interface re-map 543 | device.vm.provision "file", source: "./helper_scripts/apply_udev.py", destination: "/home/vagrant/apply_udev.py" 544 | device.vm.provision :shell , inline: "chmod 755 /home/vagrant/apply_udev.py" 545 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a a0:00:00:00:00:42 eth0" 546 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:0d swp1" 547 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:47 swp44" 548 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:37 swp45" 549 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:38 swp46" 550 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:3c swp47" 551 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:3d swp48" 552 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:2d swp49" 553 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:1a swp50" 554 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:26 swp51" 555 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:5d swp52" 556 | 557 | 558 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -vm " 559 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -s" 560 | device.vm.provision :shell , :inline => $script 561 | 562 | 563 | 564 | end 565 | 566 | ##### DEFINE VM for exit01 ##### 567 | config.vm.define "exit01" do |device| 568 | device.vm.hostname = "exit01" 569 | device.vm.box = "CumulusCommunity/cumulus-vx" 570 | device.vm.box_version = ">=3.3.0" 571 | 572 | device.vm.provider "virtualbox" do |v| 573 | v.name = "#{wbid}_exit01" 574 | v.customize ["modifyvm", :id, '--audiocontroller', 'AC97', '--audio', 'Null'] 575 | v.memory = 512 576 | end 577 | device.vm.synced_folder ".", "/vagrant", disabled: true 578 | 579 | # NETWORK INTERFACES 580 | # link for eth0 --> oob-mgmt-switch:swp12 581 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net9", auto_config: false , :mac => "a00000000041" 582 | 583 | # link for swp1 --> edge01:eth1 584 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net46", auto_config: false , :mac => "443839000053" 585 | 586 | # link for swp44 --> internet:swp1 587 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net5", auto_config: false , :mac => "443839000009" 588 | 589 | # link for swp45 --> exit01:swp46 590 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net43", auto_config: false , :mac => "44383900004c" 591 | 592 | # link for swp46 --> exit01:swp45 593 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net43", auto_config: false , :mac => "44383900004d" 594 | 595 | # link for swp47 --> exit01:swp48 596 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net11", auto_config: false , :mac => "443839000013" 597 | 598 | # link for swp48 --> exit01:swp47 599 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net11", auto_config: false , :mac => "443839000014" 600 | 601 | # link for swp49 --> exit02:swp49 602 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net24", auto_config: false , :mac => "44383900002c" 603 | 604 | # link for swp50 --> exit02:swp50 605 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net14", auto_config: false , :mac => "443839000019" 606 | 607 | # link for swp51 --> spine01:swp30 608 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net6", auto_config: false , :mac => "44383900000a" 609 | 610 | # link for swp52 --> spine02:swp30 611 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net56", auto_config: false , :mac => "443839000063" 612 | 613 | 614 | device.vm.provider "virtualbox" do |vbox| 615 | vbox.customize ['modifyvm', :id, '--nicpromisc2', 'allow-all'] 616 | vbox.customize ['modifyvm', :id, '--nicpromisc3', 'allow-all'] 617 | vbox.customize ['modifyvm', :id, '--nicpromisc4', 'allow-all'] 618 | vbox.customize ['modifyvm', :id, '--nicpromisc5', 'allow-all'] 619 | vbox.customize ['modifyvm', :id, '--nicpromisc6', 'allow-all'] 620 | vbox.customize ['modifyvm', :id, '--nicpromisc7', 'allow-all'] 621 | vbox.customize ['modifyvm', :id, '--nicpromisc8', 'allow-all'] 622 | vbox.customize ['modifyvm', :id, '--nicpromisc9', 'allow-all'] 623 | vbox.customize ['modifyvm', :id, '--nicpromisc10', 'allow-all'] 624 | vbox.customize ['modifyvm', :id, '--nicpromisc11', 'allow-all'] 625 | vbox.customize ['modifyvm', :id, '--nicpromisc12', 'allow-all'] 626 | 627 | end 628 | 629 | # Fixes "stdin: is not a tty" and "mesg: ttyname failed : Inappropriate ioctl for device" messages --> https://github.com/mitchellh/vagrant/issues/1673 630 | device.vm.provision :shell , inline: "(grep -q 'mesg n' /root/.profile 2>/dev/null && sed -i '/mesg n/d' /root/.profile 2>/dev/null && echo 'Ignore the previous error, fixing this now...') || true;" 631 | 632 | 633 | 634 | # Run Any Extra Config 635 | device.vm.provision :shell , path: "./helper_scripts/config_switch.sh" 636 | 637 | 638 | 639 | # Apply the interface re-map 640 | device.vm.provision "file", source: "./helper_scripts/apply_udev.py", destination: "/home/vagrant/apply_udev.py" 641 | device.vm.provision :shell , inline: "chmod 755 /home/vagrant/apply_udev.py" 642 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a a0:00:00:00:00:41 eth0" 643 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:53 swp1" 644 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:09 swp44" 645 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:4c swp45" 646 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:4d swp46" 647 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:13 swp47" 648 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:14 swp48" 649 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:2c swp49" 650 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:19 swp50" 651 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:0a swp51" 652 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:63 swp52" 653 | 654 | 655 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -vm " 656 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -s" 657 | device.vm.provision :shell , :inline => $script 658 | 659 | 660 | 661 | end 662 | 663 | ##### DEFINE VM for spine02 ##### 664 | config.vm.define "spine02" do |device| 665 | device.vm.hostname = "spine02" 666 | device.vm.box = "CumulusCommunity/cumulus-vx" 667 | device.vm.box_version = ">=3.3.0" 668 | 669 | device.vm.provider "virtualbox" do |v| 670 | v.name = "#{wbid}_spine02" 671 | v.customize ["modifyvm", :id, '--audiocontroller', 'AC97', '--audio', 'Null'] 672 | v.memory = 512 673 | end 674 | device.vm.synced_folder ".", "/vagrant", disabled: true 675 | 676 | # NETWORK INTERFACES 677 | # link for eth0 --> oob-mgmt-switch:swp11 678 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net59", auto_config: false , :mac => "a00000000022" 679 | 680 | # link for swp1 --> leaf01:swp52 681 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net23", auto_config: false , :mac => "44383900002b" 682 | 683 | # link for swp2 --> leaf02:swp52 684 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net58", auto_config: false , :mac => "443839000068" 685 | 686 | # link for swp3 --> leaf03:swp52 687 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net17", auto_config: false , :mac => "443839000020" 688 | 689 | # link for swp4 --> leaf04:swp52 690 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net44", auto_config: false , :mac => "44383900004f" 691 | 692 | # link for swp29 --> exit02:swp52 693 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net53", auto_config: false , :mac => "44383900005e" 694 | 695 | # link for swp30 --> exit01:swp52 696 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net56", auto_config: false , :mac => "443839000064" 697 | 698 | # link for swp31 --> spine01:swp31 699 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net45", auto_config: false , :mac => "443839000051" 700 | 701 | # link for swp32 --> spine01:swp32 702 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net36", auto_config: false , :mac => "443839000042" 703 | 704 | 705 | device.vm.provider "virtualbox" do |vbox| 706 | vbox.customize ['modifyvm', :id, '--nicpromisc2', 'allow-all'] 707 | vbox.customize ['modifyvm', :id, '--nicpromisc3', 'allow-all'] 708 | vbox.customize ['modifyvm', :id, '--nicpromisc4', 'allow-all'] 709 | vbox.customize ['modifyvm', :id, '--nicpromisc5', 'allow-all'] 710 | vbox.customize ['modifyvm', :id, '--nicpromisc6', 'allow-all'] 711 | vbox.customize ['modifyvm', :id, '--nicpromisc7', 'allow-all'] 712 | vbox.customize ['modifyvm', :id, '--nicpromisc8', 'allow-all'] 713 | vbox.customize ['modifyvm', :id, '--nicpromisc9', 'allow-all'] 714 | vbox.customize ['modifyvm', :id, '--nicpromisc10', 'allow-all'] 715 | 716 | end 717 | 718 | # Fixes "stdin: is not a tty" and "mesg: ttyname failed : Inappropriate ioctl for device" messages --> https://github.com/mitchellh/vagrant/issues/1673 719 | device.vm.provision :shell , inline: "(grep -q 'mesg n' /root/.profile 2>/dev/null && sed -i '/mesg n/d' /root/.profile 2>/dev/null && echo 'Ignore the previous error, fixing this now...') || true;" 720 | 721 | 722 | 723 | # Run Any Extra Config 724 | device.vm.provision :shell , path: "./helper_scripts/config_switch.sh" 725 | 726 | 727 | 728 | # Apply the interface re-map 729 | device.vm.provision "file", source: "./helper_scripts/apply_udev.py", destination: "/home/vagrant/apply_udev.py" 730 | device.vm.provision :shell , inline: "chmod 755 /home/vagrant/apply_udev.py" 731 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a a0:00:00:00:00:22 eth0" 732 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:2b swp1" 733 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:68 swp2" 734 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:20 swp3" 735 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:4f swp4" 736 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:5e swp29" 737 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:64 swp30" 738 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:51 swp31" 739 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:42 swp32" 740 | 741 | 742 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -vm " 743 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -s" 744 | device.vm.provision :shell , :inline => $script 745 | 746 | 747 | 748 | end 749 | 750 | ##### DEFINE VM for spine01 ##### 751 | config.vm.define "spine01" do |device| 752 | device.vm.hostname = "spine01" 753 | device.vm.box = "CumulusCommunity/cumulus-vx" 754 | device.vm.box_version = ">=3.3.0" 755 | 756 | device.vm.provider "virtualbox" do |v| 757 | v.name = "#{wbid}_spine01" 758 | v.customize ["modifyvm", :id, '--audiocontroller', 'AC97', '--audio', 'Null'] 759 | v.memory = 512 760 | end 761 | device.vm.synced_folder ".", "/vagrant", disabled: true 762 | 763 | # NETWORK INTERFACES 764 | # link for eth0 --> oob-mgmt-switch:swp10 765 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net31", auto_config: false , :mac => "a00000000021" 766 | 767 | # link for swp1 --> leaf01:swp51 768 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net52", auto_config: false , :mac => "44383900005c" 769 | 770 | # link for swp2 --> leaf02:swp51 771 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net25", auto_config: false , :mac => "44383900002f" 772 | 773 | # link for swp3 --> leaf03:swp51 774 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net50", auto_config: false , :mac => "443839000058" 775 | 776 | # link for swp4 --> leaf04:swp51 777 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net37", auto_config: false , :mac => "443839000044" 778 | 779 | # link for swp29 --> exit02:swp51 780 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net21", auto_config: false , :mac => "443839000027" 781 | 782 | # link for swp30 --> exit01:swp51 783 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net6", auto_config: false , :mac => "44383900000b" 784 | 785 | # link for swp31 --> spine02:swp31 786 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net45", auto_config: false , :mac => "443839000050" 787 | 788 | # link for swp32 --> spine02:swp32 789 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net36", auto_config: false , :mac => "443839000041" 790 | 791 | 792 | device.vm.provider "virtualbox" do |vbox| 793 | vbox.customize ['modifyvm', :id, '--nicpromisc2', 'allow-all'] 794 | vbox.customize ['modifyvm', :id, '--nicpromisc3', 'allow-all'] 795 | vbox.customize ['modifyvm', :id, '--nicpromisc4', 'allow-all'] 796 | vbox.customize ['modifyvm', :id, '--nicpromisc5', 'allow-all'] 797 | vbox.customize ['modifyvm', :id, '--nicpromisc6', 'allow-all'] 798 | vbox.customize ['modifyvm', :id, '--nicpromisc7', 'allow-all'] 799 | vbox.customize ['modifyvm', :id, '--nicpromisc8', 'allow-all'] 800 | vbox.customize ['modifyvm', :id, '--nicpromisc9', 'allow-all'] 801 | vbox.customize ['modifyvm', :id, '--nicpromisc10', 'allow-all'] 802 | 803 | end 804 | 805 | # Fixes "stdin: is not a tty" and "mesg: ttyname failed : Inappropriate ioctl for device" messages --> https://github.com/mitchellh/vagrant/issues/1673 806 | device.vm.provision :shell , inline: "(grep -q 'mesg n' /root/.profile 2>/dev/null && sed -i '/mesg n/d' /root/.profile 2>/dev/null && echo 'Ignore the previous error, fixing this now...') || true;" 807 | 808 | 809 | 810 | # Run Any Extra Config 811 | device.vm.provision :shell , path: "./helper_scripts/config_switch.sh" 812 | 813 | 814 | 815 | # Apply the interface re-map 816 | device.vm.provision "file", source: "./helper_scripts/apply_udev.py", destination: "/home/vagrant/apply_udev.py" 817 | device.vm.provision :shell , inline: "chmod 755 /home/vagrant/apply_udev.py" 818 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a a0:00:00:00:00:21 eth0" 819 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:5c swp1" 820 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:2f swp2" 821 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:58 swp3" 822 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:44 swp4" 823 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:27 swp29" 824 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:0b swp30" 825 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:50 swp31" 826 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:41 swp32" 827 | 828 | 829 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -vm " 830 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -s" 831 | device.vm.provision :shell , :inline => $script 832 | 833 | 834 | 835 | end 836 | 837 | ##### DEFINE VM for leaf04 ##### 838 | config.vm.define "leaf04" do |device| 839 | device.vm.hostname = "leaf04" 840 | device.vm.box = "CumulusCommunity/cumulus-vx" 841 | device.vm.box_version = ">=3.3.0" 842 | 843 | device.vm.provider "virtualbox" do |v| 844 | v.name = "#{wbid}_leaf04" 845 | v.customize ["modifyvm", :id, '--audiocontroller', 'AC97', '--audio', 'Null'] 846 | v.memory = 512 847 | end 848 | device.vm.synced_folder ".", "/vagrant", disabled: true 849 | 850 | # NETWORK INTERFACES 851 | # link for eth0 --> oob-mgmt-switch:swp9 852 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net34", auto_config: false , :mac => "a00000000014" 853 | 854 | # link for swp1 --> server03:eth2 855 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net57", auto_config: false , :mac => "443839000066" 856 | 857 | # link for swp2 --> server04:eth2 858 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net27", auto_config: false , :mac => "443839000033" 859 | 860 | # link for swp45 --> leaf04:swp46 861 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net16", auto_config: false , :mac => "44383900001d" 862 | 863 | # link for swp46 --> leaf04:swp45 864 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net16", auto_config: false , :mac => "44383900001e" 865 | 866 | # link for swp47 --> leaf04:swp48 867 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net32", auto_config: false , :mac => "44383900003a" 868 | 869 | # link for swp48 --> leaf04:swp47 870 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net32", auto_config: false , :mac => "44383900003b" 871 | 872 | # link for swp49 --> leaf03:swp49 873 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net29", auto_config: false , :mac => "443839000036" 874 | 875 | # link for swp50 --> leaf03:swp50 876 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net4", auto_config: false , :mac => "443839000007" 877 | 878 | # link for swp51 --> spine01:swp4 879 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net37", auto_config: false , :mac => "443839000043" 880 | 881 | # link for swp52 --> spine02:swp4 882 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net44", auto_config: false , :mac => "44383900004e" 883 | 884 | 885 | device.vm.provider "virtualbox" do |vbox| 886 | vbox.customize ['modifyvm', :id, '--nicpromisc2', 'allow-all'] 887 | vbox.customize ['modifyvm', :id, '--nicpromisc3', 'allow-all'] 888 | vbox.customize ['modifyvm', :id, '--nicpromisc4', 'allow-all'] 889 | vbox.customize ['modifyvm', :id, '--nicpromisc5', 'allow-all'] 890 | vbox.customize ['modifyvm', :id, '--nicpromisc6', 'allow-all'] 891 | vbox.customize ['modifyvm', :id, '--nicpromisc7', 'allow-all'] 892 | vbox.customize ['modifyvm', :id, '--nicpromisc8', 'allow-all'] 893 | vbox.customize ['modifyvm', :id, '--nicpromisc9', 'allow-all'] 894 | vbox.customize ['modifyvm', :id, '--nicpromisc10', 'allow-all'] 895 | vbox.customize ['modifyvm', :id, '--nicpromisc11', 'allow-all'] 896 | vbox.customize ['modifyvm', :id, '--nicpromisc12', 'allow-all'] 897 | 898 | end 899 | 900 | # Fixes "stdin: is not a tty" and "mesg: ttyname failed : Inappropriate ioctl for device" messages --> https://github.com/mitchellh/vagrant/issues/1673 901 | device.vm.provision :shell , inline: "(grep -q 'mesg n' /root/.profile 2>/dev/null && sed -i '/mesg n/d' /root/.profile 2>/dev/null && echo 'Ignore the previous error, fixing this now...') || true;" 902 | 903 | 904 | 905 | # Run Any Extra Config 906 | device.vm.provision :shell , path: "./helper_scripts/config_switch.sh" 907 | 908 | 909 | 910 | # Apply the interface re-map 911 | device.vm.provision "file", source: "./helper_scripts/apply_udev.py", destination: "/home/vagrant/apply_udev.py" 912 | device.vm.provision :shell , inline: "chmod 755 /home/vagrant/apply_udev.py" 913 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a a0:00:00:00:00:14 eth0" 914 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:66 swp1" 915 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:33 swp2" 916 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:1d swp45" 917 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:1e swp46" 918 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:3a swp47" 919 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:3b swp48" 920 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:36 swp49" 921 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:07 swp50" 922 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:43 swp51" 923 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:4e swp52" 924 | 925 | 926 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -vm " 927 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -s" 928 | device.vm.provision :shell , :inline => $script 929 | 930 | 931 | 932 | end 933 | 934 | ##### DEFINE VM for leaf02 ##### 935 | config.vm.define "leaf02" do |device| 936 | device.vm.hostname = "leaf02" 937 | device.vm.box = "CumulusCommunity/cumulus-vx" 938 | device.vm.box_version = ">=3.3.0" 939 | 940 | device.vm.provider "virtualbox" do |v| 941 | v.name = "#{wbid}_leaf02" 942 | v.customize ["modifyvm", :id, '--audiocontroller', 'AC97', '--audio', 'Null'] 943 | v.memory = 512 944 | end 945 | device.vm.synced_folder ".", "/vagrant", disabled: true 946 | 947 | # NETWORK INTERFACES 948 | # link for eth0 --> oob-mgmt-switch:swp7 949 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net38", auto_config: false , :mac => "a00000000012" 950 | 951 | # link for swp1 --> server01:eth2 952 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net13", auto_config: false , :mac => "443839000018" 953 | 954 | # link for swp2 --> server02:eth2 955 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net15", auto_config: false , :mac => "44383900001c" 956 | 957 | # link for swp45 --> leaf02:swp46 958 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net8", auto_config: false , :mac => "44383900000e" 959 | 960 | # link for swp46 --> leaf02:swp45 961 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net8", auto_config: false , :mac => "44383900000f" 962 | 963 | # link for swp47 --> leaf02:swp48 964 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net55", auto_config: false , :mac => "443839000061" 965 | 966 | # link for swp48 --> leaf02:swp47 967 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net55", auto_config: false , :mac => "443839000062" 968 | 969 | # link for swp49 --> leaf01:swp49 970 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net10", auto_config: false , :mac => "443839000012" 971 | 972 | # link for swp50 --> leaf01:swp50 973 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net1", auto_config: false , :mac => "443839000002" 974 | 975 | # link for swp51 --> spine01:swp2 976 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net25", auto_config: false , :mac => "44383900002e" 977 | 978 | # link for swp52 --> spine02:swp2 979 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net58", auto_config: false , :mac => "443839000067" 980 | 981 | 982 | device.vm.provider "virtualbox" do |vbox| 983 | vbox.customize ['modifyvm', :id, '--nicpromisc2', 'allow-all'] 984 | vbox.customize ['modifyvm', :id, '--nicpromisc3', 'allow-all'] 985 | vbox.customize ['modifyvm', :id, '--nicpromisc4', 'allow-all'] 986 | vbox.customize ['modifyvm', :id, '--nicpromisc5', 'allow-all'] 987 | vbox.customize ['modifyvm', :id, '--nicpromisc6', 'allow-all'] 988 | vbox.customize ['modifyvm', :id, '--nicpromisc7', 'allow-all'] 989 | vbox.customize ['modifyvm', :id, '--nicpromisc8', 'allow-all'] 990 | vbox.customize ['modifyvm', :id, '--nicpromisc9', 'allow-all'] 991 | vbox.customize ['modifyvm', :id, '--nicpromisc10', 'allow-all'] 992 | vbox.customize ['modifyvm', :id, '--nicpromisc11', 'allow-all'] 993 | vbox.customize ['modifyvm', :id, '--nicpromisc12', 'allow-all'] 994 | 995 | end 996 | 997 | # Fixes "stdin: is not a tty" and "mesg: ttyname failed : Inappropriate ioctl for device" messages --> https://github.com/mitchellh/vagrant/issues/1673 998 | device.vm.provision :shell , inline: "(grep -q 'mesg n' /root/.profile 2>/dev/null && sed -i '/mesg n/d' /root/.profile 2>/dev/null && echo 'Ignore the previous error, fixing this now...') || true;" 999 | 1000 | 1001 | 1002 | # Run Any Extra Config 1003 | device.vm.provision :shell , path: "./helper_scripts/config_switch.sh" 1004 | 1005 | 1006 | 1007 | # Apply the interface re-map 1008 | device.vm.provision "file", source: "./helper_scripts/apply_udev.py", destination: "/home/vagrant/apply_udev.py" 1009 | device.vm.provision :shell , inline: "chmod 755 /home/vagrant/apply_udev.py" 1010 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a a0:00:00:00:00:12 eth0" 1011 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:18 swp1" 1012 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:1c swp2" 1013 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:0e swp45" 1014 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:0f swp46" 1015 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:61 swp47" 1016 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:62 swp48" 1017 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:12 swp49" 1018 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:02 swp50" 1019 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:2e swp51" 1020 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:67 swp52" 1021 | 1022 | 1023 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -vm " 1024 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -s" 1025 | device.vm.provision :shell , :inline => $script 1026 | 1027 | 1028 | 1029 | end 1030 | 1031 | ##### DEFINE VM for leaf03 ##### 1032 | config.vm.define "leaf03" do |device| 1033 | device.vm.hostname = "leaf03" 1034 | device.vm.box = "CumulusCommunity/cumulus-vx" 1035 | device.vm.box_version = ">=3.3.0" 1036 | 1037 | device.vm.provider "virtualbox" do |v| 1038 | v.name = "#{wbid}_leaf03" 1039 | v.customize ["modifyvm", :id, '--audiocontroller', 'AC97', '--audio', 'Null'] 1040 | v.memory = 512 1041 | end 1042 | device.vm.synced_folder ".", "/vagrant", disabled: true 1043 | 1044 | # NETWORK INTERFACES 1045 | # link for eth0 --> oob-mgmt-switch:swp8 1046 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net28", auto_config: false , :mac => "a00000000013" 1047 | 1048 | # link for swp1 --> server03:eth1 1049 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net22", auto_config: false , :mac => "443839000029" 1050 | 1051 | # link for swp2 --> server04:eth1 1052 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net19", auto_config: false , :mac => "443839000024" 1053 | 1054 | # link for swp45 --> leaf03:swp46 1055 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net26", auto_config: false , :mac => "443839000030" 1056 | 1057 | # link for swp46 --> leaf03:swp45 1058 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net26", auto_config: false , :mac => "443839000031" 1059 | 1060 | # link for swp47 --> leaf03:swp48 1061 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net51", auto_config: false , :mac => "443839000059" 1062 | 1063 | # link for swp48 --> leaf03:swp47 1064 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net51", auto_config: false , :mac => "44383900005a" 1065 | 1066 | # link for swp49 --> leaf04:swp49 1067 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net29", auto_config: false , :mac => "443839000035" 1068 | 1069 | # link for swp50 --> leaf04:swp50 1070 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net4", auto_config: false , :mac => "443839000006" 1071 | 1072 | # link for swp51 --> spine01:swp3 1073 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net50", auto_config: false , :mac => "443839000057" 1074 | 1075 | # link for swp52 --> spine02:swp3 1076 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net17", auto_config: false , :mac => "44383900001f" 1077 | 1078 | 1079 | device.vm.provider "virtualbox" do |vbox| 1080 | vbox.customize ['modifyvm', :id, '--nicpromisc2', 'allow-all'] 1081 | vbox.customize ['modifyvm', :id, '--nicpromisc3', 'allow-all'] 1082 | vbox.customize ['modifyvm', :id, '--nicpromisc4', 'allow-all'] 1083 | vbox.customize ['modifyvm', :id, '--nicpromisc5', 'allow-all'] 1084 | vbox.customize ['modifyvm', :id, '--nicpromisc6', 'allow-all'] 1085 | vbox.customize ['modifyvm', :id, '--nicpromisc7', 'allow-all'] 1086 | vbox.customize ['modifyvm', :id, '--nicpromisc8', 'allow-all'] 1087 | vbox.customize ['modifyvm', :id, '--nicpromisc9', 'allow-all'] 1088 | vbox.customize ['modifyvm', :id, '--nicpromisc10', 'allow-all'] 1089 | vbox.customize ['modifyvm', :id, '--nicpromisc11', 'allow-all'] 1090 | vbox.customize ['modifyvm', :id, '--nicpromisc12', 'allow-all'] 1091 | 1092 | end 1093 | 1094 | # Fixes "stdin: is not a tty" and "mesg: ttyname failed : Inappropriate ioctl for device" messages --> https://github.com/mitchellh/vagrant/issues/1673 1095 | device.vm.provision :shell , inline: "(grep -q 'mesg n' /root/.profile 2>/dev/null && sed -i '/mesg n/d' /root/.profile 2>/dev/null && echo 'Ignore the previous error, fixing this now...') || true;" 1096 | 1097 | 1098 | 1099 | # Run Any Extra Config 1100 | device.vm.provision :shell , path: "./helper_scripts/config_switch.sh" 1101 | 1102 | 1103 | 1104 | # Apply the interface re-map 1105 | device.vm.provision "file", source: "./helper_scripts/apply_udev.py", destination: "/home/vagrant/apply_udev.py" 1106 | device.vm.provision :shell , inline: "chmod 755 /home/vagrant/apply_udev.py" 1107 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a a0:00:00:00:00:13 eth0" 1108 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:29 swp1" 1109 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:24 swp2" 1110 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:30 swp45" 1111 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:31 swp46" 1112 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:59 swp47" 1113 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:5a swp48" 1114 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:35 swp49" 1115 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:06 swp50" 1116 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:57 swp51" 1117 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:1f swp52" 1118 | 1119 | 1120 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -vm " 1121 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -s" 1122 | device.vm.provision :shell , :inline => $script 1123 | 1124 | 1125 | 1126 | end 1127 | 1128 | ##### DEFINE VM for leaf01 ##### 1129 | config.vm.define "leaf01" do |device| 1130 | device.vm.hostname = "leaf01" 1131 | device.vm.box = "CumulusCommunity/cumulus-vx" 1132 | device.vm.box_version = ">=3.3.0" 1133 | 1134 | device.vm.provider "virtualbox" do |v| 1135 | v.name = "#{wbid}_leaf01" 1136 | v.customize ["modifyvm", :id, '--audiocontroller', 'AC97', '--audio', 'Null'] 1137 | v.memory = 512 1138 | end 1139 | device.vm.synced_folder ".", "/vagrant", disabled: true 1140 | 1141 | # NETWORK INTERFACES 1142 | # link for eth0 --> oob-mgmt-switch:swp6 1143 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net20", auto_config: false , :mac => "a00000000011" 1144 | 1145 | # link for swp1 --> server01:eth1 1146 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net2", auto_config: false , :mac => "443839000004" 1147 | 1148 | # link for swp2 --> server02:eth1 1149 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net12", auto_config: false , :mac => "443839000016" 1150 | 1151 | # link for swp45 --> leaf01:swp46 1152 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net18", auto_config: false , :mac => "443839000021" 1153 | 1154 | # link for swp46 --> leaf01:swp45 1155 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net18", auto_config: false , :mac => "443839000022" 1156 | 1157 | # link for swp47 --> leaf01:swp48 1158 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net41", auto_config: false , :mac => "443839000049" 1159 | 1160 | # link for swp48 --> leaf01:swp47 1161 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net41", auto_config: false , :mac => "44383900004a" 1162 | 1163 | # link for swp49 --> leaf02:swp49 1164 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net10", auto_config: false , :mac => "443839000011" 1165 | 1166 | # link for swp50 --> leaf02:swp50 1167 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net1", auto_config: false , :mac => "443839000001" 1168 | 1169 | # link for swp51 --> spine01:swp1 1170 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net52", auto_config: false , :mac => "44383900005b" 1171 | 1172 | # link for swp52 --> spine02:swp1 1173 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net23", auto_config: false , :mac => "44383900002a" 1174 | 1175 | 1176 | device.vm.provider "virtualbox" do |vbox| 1177 | vbox.customize ['modifyvm', :id, '--nicpromisc2', 'allow-all'] 1178 | vbox.customize ['modifyvm', :id, '--nicpromisc3', 'allow-all'] 1179 | vbox.customize ['modifyvm', :id, '--nicpromisc4', 'allow-all'] 1180 | vbox.customize ['modifyvm', :id, '--nicpromisc5', 'allow-all'] 1181 | vbox.customize ['modifyvm', :id, '--nicpromisc6', 'allow-all'] 1182 | vbox.customize ['modifyvm', :id, '--nicpromisc7', 'allow-all'] 1183 | vbox.customize ['modifyvm', :id, '--nicpromisc8', 'allow-all'] 1184 | vbox.customize ['modifyvm', :id, '--nicpromisc9', 'allow-all'] 1185 | vbox.customize ['modifyvm', :id, '--nicpromisc10', 'allow-all'] 1186 | vbox.customize ['modifyvm', :id, '--nicpromisc11', 'allow-all'] 1187 | vbox.customize ['modifyvm', :id, '--nicpromisc12', 'allow-all'] 1188 | 1189 | end 1190 | 1191 | # Fixes "stdin: is not a tty" and "mesg: ttyname failed : Inappropriate ioctl for device" messages --> https://github.com/mitchellh/vagrant/issues/1673 1192 | device.vm.provision :shell , inline: "(grep -q 'mesg n' /root/.profile 2>/dev/null && sed -i '/mesg n/d' /root/.profile 2>/dev/null && echo 'Ignore the previous error, fixing this now...') || true;" 1193 | 1194 | 1195 | 1196 | # Run Any Extra Config 1197 | device.vm.provision :shell , path: "./helper_scripts/config_switch.sh" 1198 | 1199 | 1200 | 1201 | # Apply the interface re-map 1202 | device.vm.provision "file", source: "./helper_scripts/apply_udev.py", destination: "/home/vagrant/apply_udev.py" 1203 | device.vm.provision :shell , inline: "chmod 755 /home/vagrant/apply_udev.py" 1204 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a a0:00:00:00:00:11 eth0" 1205 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:04 swp1" 1206 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:16 swp2" 1207 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:21 swp45" 1208 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:22 swp46" 1209 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:49 swp47" 1210 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:4a swp48" 1211 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:11 swp49" 1212 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:01 swp50" 1213 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:5b swp51" 1214 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:2a swp52" 1215 | 1216 | 1217 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -vm " 1218 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -s" 1219 | device.vm.provision :shell , :inline => $script 1220 | 1221 | 1222 | 1223 | end 1224 | 1225 | ##### DEFINE VM for edge01 ##### 1226 | config.vm.define "edge01" do |device| 1227 | device.vm.hostname = "edge01" 1228 | device.vm.box = "yk0/ubuntu-xenial" 1229 | 1230 | 1231 | device.vm.provider "virtualbox" do |v| 1232 | v.name = "#{wbid}_edge01" 1233 | v.customize ["modifyvm", :id, '--audiocontroller', 'AC97', '--audio', 'Null'] 1234 | v.memory = 512 1235 | end 1236 | device.vm.synced_folder ".", "/vagrant", disabled: true 1237 | 1238 | # NETWORK INTERFACES 1239 | # link for eth0 --> oob-mgmt-switch:swp14 1240 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net40", auto_config: false , :mac => "a00000000051" 1241 | 1242 | # link for eth1 --> exit01:swp1 1243 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net46", auto_config: false , :mac => "443839000052" 1244 | 1245 | # link for eth2 --> exit02:swp1 1246 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net7", auto_config: false , :mac => "44383900000c" 1247 | 1248 | 1249 | device.vm.provider "virtualbox" do |vbox| 1250 | vbox.customize ['modifyvm', :id, '--nicpromisc2', 'allow-all'] 1251 | vbox.customize ['modifyvm', :id, '--nicpromisc3', 'allow-all'] 1252 | vbox.customize ['modifyvm', :id, '--nicpromisc4', 'allow-all'] 1253 | 1254 | end 1255 | 1256 | # Fixes "stdin: is not a tty" and "mesg: ttyname failed : Inappropriate ioctl for device" messages --> https://github.com/mitchellh/vagrant/issues/1673 1257 | device.vm.provision :shell , inline: "(grep -q 'mesg n' /root/.profile 2>/dev/null && sed -i '/mesg n/d' /root/.profile 2>/dev/null && echo 'Ignore the previous error, fixing this now...') || true;" 1258 | 1259 | # Shorten Boot Process - Applies to Ubuntu Only - remove \"Wait for Network\" 1260 | device.vm.provision :shell , inline: "sed -i 's/sleep [0-9]*/sleep 1/' /etc/init/failsafe.conf || true" 1261 | 1262 | # Run Any Extra Config 1263 | device.vm.provision :shell , path: "./helper_scripts/config_server.sh" 1264 | 1265 | 1266 | 1267 | # Apply the interface re-map 1268 | device.vm.provision "file", source: "./helper_scripts/apply_udev.py", destination: "/home/vagrant/apply_udev.py" 1269 | device.vm.provision :shell , inline: "chmod 755 /home/vagrant/apply_udev.py" 1270 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a a0:00:00:00:00:51 eth0" 1271 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:52 eth1" 1272 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:0c eth2" 1273 | 1274 | 1275 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -vm " 1276 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -s" 1277 | device.vm.provision :shell , :inline => $script 1278 | 1279 | 1280 | 1281 | end 1282 | 1283 | ##### DEFINE VM for server01 ##### 1284 | config.vm.define "server01" do |device| 1285 | device.vm.hostname = "server01" 1286 | device.vm.box = "yk0/ubuntu-xenial" 1287 | 1288 | 1289 | device.vm.provider "virtualbox" do |v| 1290 | v.name = "#{wbid}_server01" 1291 | v.customize ["modifyvm", :id, '--audiocontroller', 'AC97', '--audio', 'Null'] 1292 | v.memory = 512 1293 | end 1294 | device.vm.synced_folder ".", "/vagrant", disabled: true 1295 | 1296 | # NETWORK INTERFACES 1297 | # link for eth0 --> oob-mgmt-switch:swp2 1298 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net42", auto_config: false , :mac => "a00000000031" 1299 | 1300 | # link for eth1 --> leaf01:swp1 1301 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net2", auto_config: false , :mac => "443839000003" 1302 | 1303 | # link for eth2 --> leaf02:swp1 1304 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net13", auto_config: false , :mac => "443839000017" 1305 | 1306 | 1307 | device.vm.provider "virtualbox" do |vbox| 1308 | vbox.customize ['modifyvm', :id, '--nicpromisc2', 'allow-all'] 1309 | vbox.customize ['modifyvm', :id, '--nicpromisc3', 'allow-all'] 1310 | vbox.customize ['modifyvm', :id, '--nicpromisc4', 'allow-all'] 1311 | 1312 | end 1313 | 1314 | # Fixes "stdin: is not a tty" and "mesg: ttyname failed : Inappropriate ioctl for device" messages --> https://github.com/mitchellh/vagrant/issues/1673 1315 | device.vm.provision :shell , inline: "(grep -q 'mesg n' /root/.profile 2>/dev/null && sed -i '/mesg n/d' /root/.profile 2>/dev/null && echo 'Ignore the previous error, fixing this now...') || true;" 1316 | 1317 | # Shorten Boot Process - Applies to Ubuntu Only - remove \"Wait for Network\" 1318 | device.vm.provision :shell , inline: "sed -i 's/sleep [0-9]*/sleep 1/' /etc/init/failsafe.conf || true" 1319 | 1320 | # Run Any Extra Config 1321 | device.vm.provision :shell , path: "./helper_scripts/config_server.sh" 1322 | 1323 | 1324 | 1325 | # Apply the interface re-map 1326 | device.vm.provision "file", source: "./helper_scripts/apply_udev.py", destination: "/home/vagrant/apply_udev.py" 1327 | device.vm.provision :shell , inline: "chmod 755 /home/vagrant/apply_udev.py" 1328 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a a0:00:00:00:00:31 eth0" 1329 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:03 eth1" 1330 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:17 eth2" 1331 | 1332 | 1333 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -vm " 1334 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -s" 1335 | device.vm.provision :shell , :inline => $script 1336 | 1337 | 1338 | 1339 | end 1340 | 1341 | ##### DEFINE VM for server03 ##### 1342 | config.vm.define "server03" do |device| 1343 | device.vm.hostname = "server03" 1344 | device.vm.box = "yk0/ubuntu-xenial" 1345 | 1346 | 1347 | device.vm.provider "virtualbox" do |v| 1348 | v.name = "#{wbid}_server03" 1349 | v.customize ["modifyvm", :id, '--audiocontroller', 'AC97', '--audio', 'Null'] 1350 | v.memory = 512 1351 | end 1352 | device.vm.synced_folder ".", "/vagrant", disabled: true 1353 | 1354 | # NETWORK INTERFACES 1355 | # link for eth0 --> oob-mgmt-switch:swp4 1356 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net3", auto_config: false , :mac => "a00000000033" 1357 | 1358 | # link for eth1 --> leaf03:swp1 1359 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net22", auto_config: false , :mac => "443839000028" 1360 | 1361 | # link for eth2 --> leaf04:swp1 1362 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net57", auto_config: false , :mac => "443839000065" 1363 | 1364 | 1365 | device.vm.provider "virtualbox" do |vbox| 1366 | vbox.customize ['modifyvm', :id, '--nicpromisc2', 'allow-all'] 1367 | vbox.customize ['modifyvm', :id, '--nicpromisc3', 'allow-all'] 1368 | vbox.customize ['modifyvm', :id, '--nicpromisc4', 'allow-all'] 1369 | 1370 | end 1371 | 1372 | # Fixes "stdin: is not a tty" and "mesg: ttyname failed : Inappropriate ioctl for device" messages --> https://github.com/mitchellh/vagrant/issues/1673 1373 | device.vm.provision :shell , inline: "(grep -q 'mesg n' /root/.profile 2>/dev/null && sed -i '/mesg n/d' /root/.profile 2>/dev/null && echo 'Ignore the previous error, fixing this now...') || true;" 1374 | 1375 | # Shorten Boot Process - Applies to Ubuntu Only - remove \"Wait for Network\" 1376 | device.vm.provision :shell , inline: "sed -i 's/sleep [0-9]*/sleep 1/' /etc/init/failsafe.conf || true" 1377 | 1378 | # Run Any Extra Config 1379 | device.vm.provision :shell , path: "./helper_scripts/config_server.sh" 1380 | 1381 | 1382 | 1383 | # Apply the interface re-map 1384 | device.vm.provision "file", source: "./helper_scripts/apply_udev.py", destination: "/home/vagrant/apply_udev.py" 1385 | device.vm.provision :shell , inline: "chmod 755 /home/vagrant/apply_udev.py" 1386 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a a0:00:00:00:00:33 eth0" 1387 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:28 eth1" 1388 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:65 eth2" 1389 | 1390 | 1391 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -vm " 1392 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -s" 1393 | device.vm.provision :shell , :inline => $script 1394 | 1395 | 1396 | 1397 | end 1398 | 1399 | ##### DEFINE VM for server02 ##### 1400 | config.vm.define "server02" do |device| 1401 | device.vm.hostname = "server02" 1402 | device.vm.box = "yk0/ubuntu-xenial" 1403 | 1404 | 1405 | device.vm.provider "virtualbox" do |v| 1406 | v.name = "#{wbid}_server02" 1407 | v.customize ["modifyvm", :id, '--audiocontroller', 'AC97', '--audio', 'Null'] 1408 | v.memory = 512 1409 | end 1410 | device.vm.synced_folder ".", "/vagrant", disabled: true 1411 | 1412 | # NETWORK INTERFACES 1413 | # link for eth0 --> oob-mgmt-switch:swp3 1414 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net47", auto_config: false , :mac => "a00000000032" 1415 | 1416 | # link for eth1 --> leaf01:swp2 1417 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net12", auto_config: false , :mac => "443839000015" 1418 | 1419 | # link for eth2 --> leaf02:swp2 1420 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net15", auto_config: false , :mac => "44383900001b" 1421 | 1422 | 1423 | device.vm.provider "virtualbox" do |vbox| 1424 | vbox.customize ['modifyvm', :id, '--nicpromisc2', 'allow-all'] 1425 | vbox.customize ['modifyvm', :id, '--nicpromisc3', 'allow-all'] 1426 | vbox.customize ['modifyvm', :id, '--nicpromisc4', 'allow-all'] 1427 | 1428 | end 1429 | 1430 | # Fixes "stdin: is not a tty" and "mesg: ttyname failed : Inappropriate ioctl for device" messages --> https://github.com/mitchellh/vagrant/issues/1673 1431 | device.vm.provision :shell , inline: "(grep -q 'mesg n' /root/.profile 2>/dev/null && sed -i '/mesg n/d' /root/.profile 2>/dev/null && echo 'Ignore the previous error, fixing this now...') || true;" 1432 | 1433 | # Shorten Boot Process - Applies to Ubuntu Only - remove \"Wait for Network\" 1434 | device.vm.provision :shell , inline: "sed -i 's/sleep [0-9]*/sleep 1/' /etc/init/failsafe.conf || true" 1435 | 1436 | # Run Any Extra Config 1437 | device.vm.provision :shell , path: "./helper_scripts/config_server.sh" 1438 | 1439 | 1440 | 1441 | # Apply the interface re-map 1442 | device.vm.provision "file", source: "./helper_scripts/apply_udev.py", destination: "/home/vagrant/apply_udev.py" 1443 | device.vm.provision :shell , inline: "chmod 755 /home/vagrant/apply_udev.py" 1444 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a a0:00:00:00:00:32 eth0" 1445 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:15 eth1" 1446 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:1b eth2" 1447 | 1448 | 1449 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -vm " 1450 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -s" 1451 | device.vm.provision :shell , :inline => $script 1452 | 1453 | 1454 | 1455 | end 1456 | 1457 | ##### DEFINE VM for server04 ##### 1458 | config.vm.define "server04" do |device| 1459 | device.vm.hostname = "server04" 1460 | device.vm.box = "yk0/ubuntu-xenial" 1461 | 1462 | 1463 | device.vm.provider "virtualbox" do |v| 1464 | v.name = "#{wbid}_server04" 1465 | v.customize ["modifyvm", :id, '--audiocontroller', 'AC97', '--audio', 'Null'] 1466 | v.memory = 512 1467 | end 1468 | device.vm.synced_folder ".", "/vagrant", disabled: true 1469 | 1470 | # NETWORK INTERFACES 1471 | # link for eth0 --> oob-mgmt-switch:swp5 1472 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net49", auto_config: false , :mac => "a00000000034" 1473 | 1474 | # link for eth1 --> leaf03:swp2 1475 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net19", auto_config: false , :mac => "443839000023" 1476 | 1477 | # link for eth2 --> leaf04:swp2 1478 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net27", auto_config: false , :mac => "443839000032" 1479 | 1480 | 1481 | device.vm.provider "virtualbox" do |vbox| 1482 | vbox.customize ['modifyvm', :id, '--nicpromisc2', 'allow-all'] 1483 | vbox.customize ['modifyvm', :id, '--nicpromisc3', 'allow-all'] 1484 | vbox.customize ['modifyvm', :id, '--nicpromisc4', 'allow-all'] 1485 | 1486 | end 1487 | 1488 | # Fixes "stdin: is not a tty" and "mesg: ttyname failed : Inappropriate ioctl for device" messages --> https://github.com/mitchellh/vagrant/issues/1673 1489 | device.vm.provision :shell , inline: "(grep -q 'mesg n' /root/.profile 2>/dev/null && sed -i '/mesg n/d' /root/.profile 2>/dev/null && echo 'Ignore the previous error, fixing this now...') || true;" 1490 | 1491 | # Shorten Boot Process - Applies to Ubuntu Only - remove \"Wait for Network\" 1492 | device.vm.provision :shell , inline: "sed -i 's/sleep [0-9]*/sleep 1/' /etc/init/failsafe.conf || true" 1493 | 1494 | # Run Any Extra Config 1495 | device.vm.provision :shell , path: "./helper_scripts/config_server.sh" 1496 | 1497 | 1498 | 1499 | # Apply the interface re-map 1500 | device.vm.provision "file", source: "./helper_scripts/apply_udev.py", destination: "/home/vagrant/apply_udev.py" 1501 | device.vm.provision :shell , inline: "chmod 755 /home/vagrant/apply_udev.py" 1502 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a a0:00:00:00:00:34 eth0" 1503 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:23 eth1" 1504 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:32 eth2" 1505 | 1506 | 1507 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -vm " 1508 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -s" 1509 | device.vm.provision :shell , :inline => $script 1510 | 1511 | 1512 | 1513 | end 1514 | 1515 | ##### DEFINE VM for internet ##### 1516 | config.vm.define "internet" do |device| 1517 | device.vm.hostname = "internet" 1518 | device.vm.box = "CumulusCommunity/cumulus-vx" 1519 | device.vm.box_version = ">=3.3.0" 1520 | 1521 | device.vm.provider "virtualbox" do |v| 1522 | v.name = "#{wbid}_internet" 1523 | v.customize ["modifyvm", :id, '--audiocontroller', 'AC97', '--audio', 'Null'] 1524 | v.memory = 256 1525 | end 1526 | device.vm.synced_folder ".", "/vagrant", disabled: true 1527 | 1528 | # NETWORK INTERFACES 1529 | # link for eth0 --> oob-mgmt-switch:swp15 1530 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net35", auto_config: false , :mac => "44383900003f" 1531 | 1532 | # link for swp1 --> exit01:swp44 1533 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net5", auto_config: false , :mac => "443839000008" 1534 | 1535 | # link for swp2 --> exit02:swp44 1536 | device.vm.network "private_network", virtualbox__intnet: "#{wbid}_net39", auto_config: false , :mac => "443839000046" 1537 | 1538 | 1539 | device.vm.provider "virtualbox" do |vbox| 1540 | vbox.customize ['modifyvm', :id, '--nicpromisc2', 'allow-all'] 1541 | vbox.customize ['modifyvm', :id, '--nicpromisc3', 'allow-all'] 1542 | vbox.customize ['modifyvm', :id, '--nicpromisc4', 'allow-all'] 1543 | 1544 | vbox.customize ["modifyvm", :id, "--nictype1", "virtio"] 1545 | vbox.customize ["modifyvm", :id, "--nictype2", "virtio"] 1546 | vbox.customize ["modifyvm", :id, "--nictype3", "virtio"] 1547 | vbox.customize ["modifyvm", :id, "--nictype4", "virtio"] 1548 | 1549 | end 1550 | 1551 | # Fixes "stdin: is not a tty" and "mesg: ttyname failed : Inappropriate ioctl for device" messages --> https://github.com/mitchellh/vagrant/issues/1673 1552 | device.vm.provision :shell , inline: "(grep -q 'mesg n' /root/.profile 2>/dev/null && sed -i '/mesg n/d' /root/.profile 2>/dev/null && echo 'Ignore the previous error, fixing this now...') || true;" 1553 | 1554 | 1555 | 1556 | # Run Any Extra Config 1557 | device.vm.provision :shell , path: "./helper_scripts/config_internet.sh" 1558 | 1559 | 1560 | 1561 | # Apply the interface re-map 1562 | device.vm.provision "file", source: "./helper_scripts/apply_udev.py", destination: "/home/vagrant/apply_udev.py" 1563 | device.vm.provision :shell , inline: "chmod 755 /home/vagrant/apply_udev.py" 1564 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:3f eth0" 1565 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:08 swp1" 1566 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -a 44:38:39:00:00:46 swp2" 1567 | 1568 | 1569 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -vm --vagrant-name=swp48" 1570 | device.vm.provision :shell , inline: "/home/vagrant/apply_udev.py -s" 1571 | device.vm.provision :shell , :inline => $script 1572 | 1573 | 1574 | 1575 | end 1576 | 1577 | 1578 | 1579 | end 1580 | --------------------------------------------------------------------------------