diff --git a/ansible/config_sonic_basedon_testbed.yml b/ansible/config_sonic_basedon_testbed.yml new file mode 100644 index 00000000000..94ff94e8b80 --- /dev/null +++ b/ansible/config_sonic_basedon_testbed.yml @@ -0,0 +1,98 @@ +# This Playbook run time generate matching configuration file for SONiC switch(Minigraph) based on a specific testbed topology specified in testbed.csv +# When user call testbed-cli to deploy a testbed topology, use this playbook to generate matching SONiC minigraph file and deploy it into SONiC switch under test. +# Or when you know your topology name, you may use this playbook alone to generate a minigraph matching your topology name without deploy it. +# +# VM Topologies are defined inside of vars/ directory in files vars/topo_{{ topology_name}}.yml +# Every topology should have a name to distinct one topology from another on the server +# Every topology contains a ptf container which will be used as placeholder for the injected interfaces from VMs, or direct connections to PTF host +# VMs inventory file is also required to have all VMs ready for generating the minigraph file +# VMs inventory is in file 'veos' +# +# Template files for generating minigraph.xml are defined in template/topo directory +# +# To generate and deploy minigraph for SONiC switch matching the VM topology please use following command +# ansible-playbook -i lab config_sonic_basedon_testbed.yml -l sonic_dut_name -e vm_base=VM0300 -e topo=t0 [-e deploy=true] +# +# Parameters +# -l str-msn2700-01 - the sonic_dut_name you are going to generate minigraph for +# -e vm_base=VM0300 - the VM name which is used to as base to calculate VM name for this set +# -e topo=t0 - the name of topology to generate minigraph file +# -e deploy=True - if deploy the newly generated minigraph to the targent DUT, default is false if not defined +# +# After minigraph.xml is generated, the playbook will replace the original minigraph file under ansible/minigraph/ with the newly generated minigraph file for the SONiC device. +# The playbook will based on deploy=True or False to deside if load the SONiC device with new minigraph or not. +# If deploy=true, the playbook will reboot the SONiC switch after change to new minigraph to make it take effect +# +#################################################################################################################################################################################### + +- hosts: sonic + gather_facts: yes + tasks: + - fail: msg="need to provide topology type and vm base like topo=t0 and vm_base=VM100" + when: (topo is not defined) or (vm_base is not defined) + + - fail: msg="need hwsku, interface speed, netmask and interface prefix/postfix defined to generate configuration file" + when: (hwsku is not defined) or (iface_speed is not defined) or (mgmt_subnet_mask_length is not defined) + + - set_fact: + VM_topo: "{% if 'ptf' in topo %}False{% else %}True{% endif %}" + remote_dut: "{{ ansible_ssh_host }}" + template_name: "{{ 't1' if topo=='ptf32' else topo }}" + + - testbed_vm_info: base_vm="{{ vm_base }}" topo="{{ topo }}" + connection: local + when: VM_topo + + - name: find interface name mapping + port_alias: hwsku="{{ hwsku }}" + connection: local + + - debug: var=port_alias + + - name: save original minigraph file (if original file does not exist, then ignore errors) + shell: mv minigraph/{{ inventory_hostname }}.xml minigraph/{{ inventory_hostname }}.xml.orig + connection: local + ignore_errors: true + + - name: create minigraph file in minigraph folder + become: true + template: src=templates/topo/{{ template_name }}.j2 + dest=minigraph/{{ inventory_hostname}}.xml + connection: local + + - block: + - name: saved original minigraph file (if original file may don't exist, then ignore errors) + shell: mv /etc/sonic/minigraph.xml /etc/sonic/minigraph.xml.orig + become: true + ignore_errors: true + + - name: create minigraph file for SONiC device + template: src=templates/topo/{{ template_name }}.j2 + dest=/etc/sonic/minigraph.xml + become: true + + - name: disable automatic minigraph update if we are deploying new minigraph into SONiC + lineinfile: + name: /etc/sonic/updategraph.conf + regexp: '^enabled=' + line: 'enabled=false' + become: true + + # reload the device and wait it to come back + - name: Reboot is required for minigraph change + shell: sleep 2 && shutdown -r now "Ansible Create new configuration Minigraph file, triggered reboot." + async: 1 + poll: 0 + become: true + ignore_errors: true + + - name: waiting for switch to come back + local_action: + wait_for host={{ remote_dut }} + port=22 + state=started + delay=30 + timeout=300 + become: false + changed_when: false + when: deploy is defined and deploy|bool == true diff --git a/ansible/group_vars/lab/lab.yml b/ansible/group_vars/lab/lab.yml index 2cafa9d4b04..4b33f607cad 100644 --- a/ansible/group_vars/lab/lab.yml +++ b/ansible/group_vars/lab/lab.yml @@ -1,15 +1,34 @@ --- -#starlab (str) group variables -# file: group_vars/str.yml +#testlab (lab) group variables +# file: group_vars/lab.yml # ntp variables ntp_servers: ['10.0.0.1', '10.0.0.2'] # syslog variables syslog_servers: ['10.0.0.5', '10.0.0.6'] -# + # dns variables dns_servers: ['10.0.0.5', '10.0.0.6'] + +# forced_mgmt_routes +forced_mgmt_routes: ['10.0.0.100/31', '10.250.0.8', '10.255.0.0/28'] + +# ErspanDestinationIpv4 +erspan_dest: ['10.0.0.7'] + +radius_servers: [] + +tacacs_servers: ['10.0.0.9', '10.0.0.8'] + +# tacacs grous +tacacs_group: 'testlab' + +# snmp servers +snmp_servers: ['10.0.0.9'] + +# dhcp replay servers +dhcp_servers: ['10.0.0.1'] # # snmp variables snmp_rocommunity: public diff --git a/ansible/lab b/ansible/lab index f5803e3a7b9..056a2168dc7 100644 --- a/ansible/lab +++ b/ansible/lab @@ -1,14 +1,19 @@ -[sonic_latest] -str-msn2700-01 ansible_host=10.251.0.188 sonic_version=v2 +[sonic_mlnx_40] +str-msn2700-01 ansible_host=10.251.0.188 + +[sonic_mlnx_40:vars] +hwsku="ACS-MSN2700" +iface_speed='40000' +mgmt_subnet_mask_length="24" [sonic:children] -sonic_latest +sonic_mlnx_40 [ptf] ptf_ptf1 ansible_host=10.255.0.188 ansible_ssh_user=root ansible_ssh_pass=root ptf_vms1-1 ansible_host=10.255.0.178 ansible_ssh_user=root ansible_ssh_pass=root -[str:children] +[lab:children] sonic fanout diff --git a/ansible/library/port_alias.py b/ansible/library/port_alias.py new file mode 100644 index 00000000000..18d9020a7e0 --- /dev/null +++ b/ansible/library/port_alias.py @@ -0,0 +1,88 @@ +#!/usr/bin/env python + +import re +import os +import traceback +import subprocess +from operator import itemgetter +from itertools import groupby +from collections import defaultdict + +DOCUMENTATION = ''' +module: port_alias.py +Ansible_version_added: 2.0.0.2 +short_description: Find SONiC device port alias mapping if there is alias mapping +Description: + Minigraph file is using SONiC deivce alias to describe the interface name, it's vendor and and hardware platform dependent + This module is used to find the correct port_config.ini for the hwsku and return Ansible ansible_facts.port_alias + The definition of this mapping is specified in http://github.com/azure/sonic-buildimage/device + You should build docker-sonic-mgmt from sonic-buildimage and run Ansible from sonic-mgmt docker container + Input: + hwsku + + Return Ansible_facts: + port_alias: SONiC interface name or SONiC interface alias if alias is available + +''' + +EXAMPLES = ''' + - name: get hardware interface name + port_alias: hwsku='ACS-MSN2700' +''' + +### TODO: we could eventually use sonic config package to replace this port_alias module later ############### +### Here are the expectation of files of device port_config.ini located, in case changed please modify it here +FILE_PATH = '/usr/share/sonic/device' +PORTMAP_FILE = 'port_config.ini' + +class SonicPortAliasMap(): + """ + Retrieve SONiC device interface port alias mapping + + """ + def __init__(self, hwsku): + self.filename = '' + self.hwsku = hwsku + self.portmap = [] + return + + def findfile(self): + for (rootdir, dirnames, filenames) in os.walk(FILE_PATH): + if self.hwsku in rootdir and len(dirnames) == 0 and PORTMAP_FILE in filenames: + self.filename = rootdir+'/'+PORTMAP_FILE + + def get_portmap(self): + self.findfile() + if self.filename == '': + raise Exception("Something wrong when trying to find the portmap file, either the hwsku is not available or file location is not correct") + with open(self.filename) as f: + lines = f.readlines() + for line in lines: + if 'Ethernet' in line: + mapping = line.split() + if len(mapping) < 3: + self.portmap.append(mapping[0]) + else: + self.portmap.append(mapping[2]) + return + +def main(): + module = AnsibleModule( + argument_spec=dict( + hwsku=dict(required=True, type='str') + ), + supports_check_mode=False + ) + m_args = module.params + try: + allmap = SonicPortAliasMap(m_args['hwsku']) + allmap.get_portmap() + module.exit_json(ansible_facts={'port_alias': allmap.portmap}) + except (IOError, OSError): + module.fail_json(msg=allmap.portmap) + except Exception: + module.fail_json(msg=allmap.portmap) + +from ansible.module_utils.basic import * +if __name__ == "__main__": + main() diff --git a/ansible/library/testbed_vm_info.py b/ansible/library/testbed_vm_info.py new file mode 100644 index 00000000000..c60c7c7069d --- /dev/null +++ b/ansible/library/testbed_vm_info.py @@ -0,0 +1,105 @@ +#!/usr/bin/env python + +import re +import yaml +import os +import traceback +import subprocess +import ipaddr as ipaddress +from operator import itemgetter +from itertools import groupby +from collections import defaultdict + +DOCUMENTATION = ''' +module: testbed_vm_info.py +Ansible_version_added: 2.0.0.2 +short_description: Gather all related VMs info +Description: + When deploy testbed topology with VM connected to SONiC, gather neighbor VMs info for generating SONiC minigraph file + options: + base_vm: base vm name defined in testbed.csv for the deployed topology; required: True + topo: topology name defined in testbed.csv for the deployed topology; required: True + +Ansible_facts: + 'neighbor_eosvm_mgmt': all VM hosts management IPs + 'topoall': topology information + +''' + +EXAMPLES = ''' + - name: gather vm information + testbed_vm_info: base_vm='VM0100' topo='t1' +''' + +### Here are the assumption/expectation of files to gather VM informations, if the file location or name changes, please modify it here +TOPO_PATH = 'vars/' +VM_INV_FILE = 'veos' + + +class TestbedVMFacts(): + """ + Retrieve testbed VMs management information that for a specified toplogy defined in testbed.csv + + """ + + def __init__(self, toponame, vmbase): + self.topofile = TOPO_PATH+'topo_'+toponame +'.yml' + self.start_index = int(re.findall('VM(\d+)', vmbase)[0]) + self.vmhosts = {} + return + + + def get_neighbor_eos(self): + eos = {} + with open(self.topofile) as f: + vm_topology = yaml.load(f) + self.topoall = vm_topology + for vm in vm_topology['topology']['VMs']: + vm_index = int(vm_topology['topology']['VMs'][vm]['vm_offset'])+self.start_index + eos[vm] = vm_index + return eos + + + def gather_veos_vms(self): + vms = {} + with open(VM_INV_FILE) as f: + lines = f.readlines() + for line in lines: + if 'VM' in line and 'ansible_host' in line: + items = line.split() + vms[items[0]] = items[1].split('=')[1] + return vms + +def main(): + module = AnsibleModule( + argument_spec=dict( + base_vm=dict(required=True, type='str'), + topo=dict(required=True, type='str'), + ), + supports_check_mode=False + ) + m_args = module.params + topo_type = m_args['topo'] + if 'ptf' in topo_type: + module.exit_json(ansible_facts={'neighbor_eosvm_mgmt': {}}) + try: + vmsall = TestbedVMFacts(m_args['topo'], m_args['base_vm']) + neighbor_eos = vmsall.get_neighbor_eos() + vm_inv = vmsall.gather_veos_vms() + for eos in neighbor_eos: + vmname = 'VM'+format(neighbor_eos[eos], '04d') + if vmname in vm_inv: + vmsall.vmhosts[eos] = vm_inv[vmname] + else: + err_msg = "cannot find the vm " + vmname + " in VM inventory file, please make sure you have enough VMs for the topology you are using" + module.fail_json(msg=err_msg) + module.exit_json(ansible_facts={'neighbor_eosvm_mgmt':vmsall.vmhosts, 'topoall': vmsall.topoall}) + except (IOError, OSError): + module.fail_json(msg="Can not find file "+vmsall.topofile+" or "+VM_INV_FILE) + except Exception as e: + module.fail_json(msg=traceback.format_exc()) + +from ansible.module_utils.basic import * +if __name__ == "__main__": + main() + diff --git a/ansible/templates/topo/dev_metadata.j2 b/ansible/templates/topo/dev_metadata.j2 new file mode 100644 index 00000000000..6ac28e8bb28 --- /dev/null +++ b/ansible/templates/topo/dev_metadata.j2 @@ -0,0 +1,101 @@ + + + true + +{% for index in range(32) %} +{% set sonic_if_name='Ethernet'+((index*4)|string) %} + + DeviceInterface + + true + true + 1 + {{ port_alias[index] }} + + false + 0 + 0 + {{ iface_speed }} + +{% endfor %} + + true + 0 + {{ hwsku }} + + + + +{% set syslog_servers_str=';'.join(syslog_servers) %} +{% set dhcp_servers_str=';'.join(dhcp_servers) %} +{% set forced_mgmt_routes_str = ';'.join(forced_mgmt_routes) %} +{% set ntp_servers_str = ';'.join(ntp_servers) %} +{% set snmp_servers_str = ';'.join(snmp_servers) %} +{% set tacacs_servers_str = ';'.join(tacacs_servers) %} +{% set radius_servers_str = ';'.join(radius_servers) %} +{% set erspan_dest_str = ';'.join(erspan_dest) %} + + + {{ ansible_hostname }} + + + DhcpResources + + {{ dhcp_servers_str }} + + + NTPResources + + {{ ntp_servers_str }} + + + DeploymentId + + 1 + + + QosProfile + + Profile0 + + + RadiusResources + + {{ radius_servers_str }} + + + SnmpResources + + {{ snmp_servers_str }} + + + SyslogResources + + {{ syslog_servers_str }} + + + TacacsGroup + + {{ tacacs_group }} + + + TacacsServer + + {{ tacacs_servers_str }} + + + ForcedMgmtRoutes + + {{ forced_mgmt_routes_str }} + + + ErspanDestinationIpv4 + + {{ erspan_dest_str }} + + + + + + + diff --git a/ansible/templates/topo/t0.j2 b/ansible/templates/topo/t0.j2 new file mode 100644 index 00000000000..c918c14e818 --- /dev/null +++ b/ansible/templates/topo/t0.j2 @@ -0,0 +1,197 @@ + + + + +{% for index in range(4) %} + + false + {{ inventory_hostname }} + 10.0.0.{{ 56 + index*2 }} + ARISTA0{{ index+1 }}T1 + 10.0.0.{{ 56 + index*2 +1 }} + 1 + 10 + 3 + + + {{ inventory_hostname }} + FC00::{{ ('%0x' % (113 + index*4)) | upper }} + ARISTA0{{ index+1 }}T1 + FC00::{{ ('%0x' % (113 + index*4 +1)) | upper }} + 1 + 10 + 3 + +{% endfor %} + + + + 65100 + {{ inventory_hostname }} + +{% for index in range(4) %} + +
10.0.0.{{ 57 + index*2 }}
+ + + +
+{% endfor %} + + BGPPeer +
10.1.0.32
+ + + + BGPSLBPassive + 10.255.0.0/27 +
+ + BGPPeer +
10.1.0.32
+ + + + BGPVac + 192.168.0.0/27 +
+
+ +
+{% for index in range(4) %} + + 64600 + ARISTA0{{ index+1 }}T1 + + +{% endfor %} +
+
+ + + + + + HostIP + Loopback0 + + 10.1.0.32/32 + + 10.1.0.32/32 + + + HostIP1 + Loopback0 + + FC00:1::32/128 + + FC00:1::32/128 + + + + + HostIP + eth0 + + {{ ansible_host }}/{{ mgmt_subnet_mask_length }} + + {{ ansible_host }}/{{ mgmt_subnet_mask_length }} + + + + + + + {{ inventory_hostname }} + +{% for index in range(4) %} + + PortChannel0{{ index+1 }} + {{ port_alias[28+index] }} + + +{% endfor %} + + + + Vlan1000 + {{ port_alias[1] }};{{ port_alias[2] }};{{ port_alias[3] }};{{ port_alias[4] }};{{ port_alias[5] }};{{ port_alias[6] }};{{ port_alias[7] }};{{ port_alias[8] }};{{ port_alias[9] }};{{ port_alias[10] }};{{ port_alias[11] }};{{ port_alias[12] }};{{ port_alias[13] }};{{ port_alias[14] }};{{ port_alias[15] }};{{ port_alias[16] }};{{ port_alias[17] }};{{ port_alias[18] }};{{ port_alias[19] }};{{ port_alias[20] }};{{ port_alias[21] }};{{ port_alias[22] }};{{ port_alias[23] }};{{ port_alias[24] }} + False + 0.0.0.0/0 + + 1000 + 1000 + 192.168.0.0/27 + + + +{% for index in range(4) %} + + + PortChannel0{{ index +1 }} + 10.0.0.{{ 56 + index*2 }}/31 + + + + PortChannel0{{ index +1 }} + FC00::{{ ('%0x' % (113+index*4)) | upper }}/126 + +{% endfor %} + + + Vlan1000 + 192.168.0.1/27 + + + + + + + + + + +{% for index in range(4) %} + + DeviceInterfaceLink + ARISTA0{{ index+1 }}T1 + Ethernet1 + {{ inventory_hostname }} + {{ port_alias[28+index] }} + +{% endfor %} + + + + {{ inventory_hostname }} + {{ hwsku }} + + {{ ansible_host }} + + +{% if VM_topo %} +{% for dev in neighbor_eosvm_mgmt %} +{% if 'T1' in dev %} +{% set dev_type = 'LeafRouter' %} +{% elif 'T2' in dev %} +{% set dev_type = 'SpineRouter' %} +{% elif 'T0' in dev %} +{% set dev_type = 'TorRouter' %} +{% else %} +{% set dev_ytpe = 'Unknown' %} +{% endif %} + + "{{ dev }}" + + {{ neighbor_eosvm_mgmt[dev] }} + + Arista-VM + +{% endfor %} +{% endif %} + + +{% include 'dev_metadata.j2' %} + {{ inventory_hostname }} + {{ hwsku }} +
diff --git a/ansible/templates/topo/t1-lag.j2 b/ansible/templates/topo/t1-lag.j2 new file mode 100644 index 00000000000..b1dc804a40f --- /dev/null +++ b/ansible/templates/topo/t1-lag.j2 @@ -0,0 +1,227 @@ + + + + +{% for index in range(16) %} + + ARISTA{{ '%02d' % (index + 1) }}T0 + 10.0.0.{{ (32 + index * 2 + 1) }} + {{ inventory_hostname }} + 10.0.0.{{ (32 + index * 2) }} + 1 + 10 + 3 + + + ARISTA{{ '%02d' % (index + 1) }}T0 + FC00::{{ ('%0x' % (65+index*4+1)) | upper }} + {{ inventory_hostname }} + FC00::{{ ('%0x' % (65+index*4)) | upper}} + 1 + 10 + 3 + +{% if (index%2)==0 %} + + {{ inventory_hostname }} + 10.0.0.{{ (index*2) }} + ARISTA{{ '%02d' % (index+1) }}T2 + 10.0.0.{{ (index*2+1) }} + 1 + 10 + 3 + + + {{ inventory_hostname }} + FC00::{{ ('%0x' % (index*4 +1)) | upper }} + ARISTA{{ '%02d' % (index+1) }}T2 + FC00::{{ ('%0x' % (index*4+2)) | upper }} + 1 + 10 + 3 + +{% endif %} +{% endfor %} + + + + 65100 + {{ inventory_hostname }} + +{% for ip in range(16) %} + +
10.0.0.{{ ip*2+33 }}
+ + +
+{% if (ip%2)==0 %} + +
10.0.0.{{ ip*2+1 }}
+ + +
+{% endif %} +{% endfor %} +
+ +
+{% for i in range(1,17,1) %} + + 640{{ '%02d' % i }} + ARISTA{{ '%02d' % i }}T0 + + +{% if (i%2)==1 %} + + 65200 + ARISTA{{ '%02d' % i }}T2 + + +{% endif %} +{% endfor %} +
+
+ + + + + + HostIP + Loopback0 + + 10.1.0.32/32 + + 10.1.0.32/32 + + + HostIP1 + Loopback0 + + FC00:1::32/128 + + FC00:1::32/128 + + + + + HostIP + eth0 + + {{ ansible_host }}/{{ mgmt_subnet_mask_length }} + + {{ ansible_host }}/{{ mgmt_subnet_mask_length }} + + + + + + {{ inventory_hostname }} + +{% for index in range(8) %} + + PortChannelInterface + PortChannel{{ index*8 }} + {{ port_alias[index*2] }};{{ port_alias[index*2+1] }} + + +{% endfor %} + + + +{% for index in range(8) %} + + IPInterface + + PortChannel{{ index*8 }} + 10.0.0.{{ index*4 }}/31 + + + IPInterface + + PortChannel{{ index*8 }} + FC00::{{ ('%0x' % (index*8+1)) | upper }}/126 + +{% endfor %} +{% for index in range(16) %} + + IPInterface + + {{ port_alias[16+index] }} + 10.0.0.{{ 32+index*2 }}/31 + + + IPInterface + + {{ port_alias[16+index] }} + FC00::{{ ('%0x' % (64+index*4 +1)) | upper }}/126 + +{% endfor %} + + + + + + + + + +{% for index in range(0,16,2) %} + + DeviceInterfaceLink + {{ inventory_hostname }} + {{ port_alias[index] }} + ARISTA{{ '%02d' % (index+1) }}T2 + Ethernet1 + + + DeviceInterfaceLink + {{ inventory_hostname }} + {{ port_alias[index+1] }} + ARISTA{{ '%02d' % (index+1) }}T2 + Ethernet2 + +{% endfor %} +{% for index in range(16) %} + + DeviceInterfaceLink + {{ inventory_hostname }} + {{ port_alias[16+index] }} + ARISTA{{ '%02d' % (index+1) }}T0 + Ethernet1 + +{% endfor %} + + + + {{ inventory_hostname }} + {{ hwsku }} + + {{ ansible_host }} + + +{% if VM_topo %} +{% for dev in neighbor_eosvm_mgmt.keys()|sort %} +{% if 'T1' in dev %} +{% set dev_type = 'LeafRouter' %} +{% elif 'T2' in dev %} +{% set dev_type = 'SpineRouter' %} +{% elif 'T0' in dev %} +{% set dev_type = 'ToRRouter' %} +{% else %} +{% set dev_type = 'Unknown' %} +{% endif %} + + "{{ dev }}" + Arista-VM + + {{ neighbor_eosvm_mgmt[dev] }} + + +{% endfor %} +{% endif %} + + +{% include 'dev_metadata.j2' %} + {{ inventory_hostname }} + {{ hwsku }} +
diff --git a/ansible/templates/topo/t1.j2 b/ansible/templates/topo/t1.j2 new file mode 100644 index 00000000000..79c427fe9aa --- /dev/null +++ b/ansible/templates/topo/t1.j2 @@ -0,0 +1,189 @@ + + + + +{% for index in range(16) %} + + ARISTA{{ '%02d' % (index + 1) }}T0 + 10.0.0.{{ (32 + index * 2 + 1) }} + {{ inventory_hostname }} + 10.0.0.{{ (32 + index * 2) }} + 1 + 10 + 3 + + + ARISTA{{ '%02d' % (index + 1) }}T0 + FC00::{{ ('%0x' % (65+index*4+1)) | upper }} + {{ inventory_hostname }} + FC00::{{ ('%0x' % (65+index*4)) | upper}} + 1 + 10 + 3 + + + {{ inventory_hostname }} + 10.0.0.{{ (index*2) }} + ARISTA{{ '%02d' % (index+1) }}T2 + 10.0.0.{{ (index*2+1) }} + 1 + 10 + 3 + + + {{ inventory_hostname }} + FC00::{{ ('%0x' % (index*4 +1)) | upper }} + ARISTA{{ '%02d' % (index+1) }}T2 + FC00::{{ ('%0x' % (index*4+2)) | upper }} + 1 + 10 + 3 + +{% endfor %} + + + + 65100 + {{ inventory_hostname }} + +{% for ip in range(1,32,2) %} + +
10.0.0.{{ 32+ip }}
+ + +
+ +
10.0.0.{{ ip }}
+ + +
+{% endfor %} +
+ +
+{% for i in range(1,17,1) %} + + 640{{ '%02d' % i }} + ARISTA{{ '%02d' % i }}T0 + + + + 65200 + ARISTA{{ '%02d' % i }}T2 + + +{% endfor %} +
+
+ + + + + + HostIP + Loopback0 + + 10.1.0.32/32 + + 10.1.0.32/32 + + + HostIP1 + Loopback0 + + FC00:1::32/128 + + FC00:1::32/128 + + + + + HostIP + eth0 + + {{ ansible_host }}/{{ mgmt_subnet_mask_length }} + + {{ ansible_host }}/{{ mgmt_subnet_mask_length }} + + + + + + {{ inventory_hostname }} + + + +{% for index in range(32) %} + + + {{ port_alias[index] }} + 10.0.0.{{ index*2 }}/31 + + + + {{ port_alias[index] }} + FC00::{{ ('%0x' % (index*4 +1)) | upper }}/126 + +{% endfor %} + + + + + + + + + +{% for index in range(16) %} + + DeviceInterfaceLink + {{ inventory_hostname }} + {{ port_alias[index] }} + ARISTA{{ '%02d' % (index+1) }}T2 + Ethernet1 + +{% endfor %} +{% for index in range(16) %} + + DeviceInterfaceLink + {{ inventory_hostname }} + {{ port_alias[16+index] }} + ARISTA{{ '%02d' % (index+1) }}T0 + Ethernet1 + +{% endfor %} + + + + {{ inventory_hostname }} + {{ hwsku }} + + {{ ansible_host }} + + +{% if VM_topo %} +{% for dev in neighbor_eosvm_mgmt.keys()|sort %} +{% if 'T1' in dev %} +{% set dev_type = 'LeafRouter' %} +{% elif 'T2' in dev %} +{% set dev_type = 'SpineRouter' %} +{% elif 'T0' in dev %} +{% set dev_type = 'ToRRouter' %} +{% else %} +{% set dev_type = 'Unknown' %} +{% endif %} + + "{{ dev }}" + Arista-VM + + {{ neighbor_eosvm_mgmt[dev] }} + + +{% endfor %} +{% endif %} + + +{% include 'dev_metadata.j2' %} + {{ inventory_hostname }} + {{ hwsku }} +
diff --git a/ansible/templates/topo/updategraph.conf b/ansible/templates/topo/updategraph.conf new file mode 100644 index 00000000000..cd74f82777b --- /dev/null +++ b/ansible/templates/topo/updategraph.conf @@ -0,0 +1 @@ +enable=false diff --git a/ansible/veos b/ansible/veos index 4f1df47615f..01cd5458981 100644 --- a/ansible/veos +++ b/ansible/veos @@ -13,6 +13,34 @@ VM0100 ansible_host=10.250.0.2 VM0101 ansible_host=10.250.0.3 VM0102 ansible_host=10.250.0.4 VM0103 ansible_host=10.250.0.5 +VM0104 ansible_host=10.250.0.6 +VM0105 ansible_host=10.250.0.7 +VM0106 ansible_host=10.250.0.8 +VM0107 ansible_host=10.250.0.9 +VM0108 ansible_host=10.250.0.10 +VM0109 ansible_host=10.250.0.11 +VM0110 ansible_host=10.250.0.12 +VM0111 ansible_host=10.250.0.13 +VM0112 ansible_host=10.250.0.14 +VM0113 ansible_host=10.250.0.15 +VM0114 ansible_host=10.250.0.16 +VM0115 ansible_host=10.250.0.17 +VM0116 ansible_host=10.250.0.18 +VM0117 ansible_host=10.250.0.19 +VM0118 ansible_host=10.250.0.20 +VM0119 ansible_host=10.250.0.21 +VM0120 ansible_host=10.250.0.22 +VM0121 ansible_host=10.250.0.23 +VM0122 ansible_host=10.250.0.24 +VM0123 ansible_host=10.250.0.25 +VM0124 ansible_host=10.250.0.26 +VM0125 ansible_host=10.250.0.27 +VM0126 ansible_host=10.250.0.28 +VM0127 ansible_host=10.250.0.29 +VM0128 ansible_host=10.250.0.30 +VM0129 ansible_host=10.250.0.31 +VM0130 ansible_host=10.250.0.32 +VM0131 ansible_host=10.250.0.33 [vms_2] VM0200 ansible_host=10.250.0.51