sonic-buildimage/src/sonic-config-engine/config_samples.py

176 lines
6.4 KiB
Python
Raw Normal View History

import sys
from collections import defaultdict
from ipaddress import ip_interface
from natsort import natsorted
#TODO: Remove once Python 2 support is removed
if sys.version_info.major == 3:
UNICODE_TYPE = str
else:
UNICODE_TYPE = unicode
def generate_common_config(data):
data['FLEX_COUNTER_TABLE'] = {
'ACL': {
'FLEX_COUNTER_STATUS': 'disable',
'FLEX_COUNTER_DELAY_STATUS': 'true',
'POLL_INTERVAL': '10000'
}
}
return data
# The following config generation methods exits:
# 't1': generate_t1_sample_config,
# 'l2': generate_l2_config,
# 'empty': generate_empty_config,
# 'l1': generate_l1_config,
# 'l3': generate_l3_config
def generate_l1_config(data):
for port in natsorted(data['PORT']):
data['PORT'][port]['admin_status'] = 'up'
data['PORT'][port]['mtu'] = '9100'
return data;
def generate_l3_config(data):
data['LOOPBACK_INTERFACE'] = {"Loopback0": {},
"Loopback0|10.1.0.1/32": {}}
data['BGP_NEIGHBOR'] = {}
data['DEVICE_NEIGHBOR'] = {}
data['INTERFACE'] = {}
for port in natsorted(data['PORT']):
data['PORT'][port]['admin_status'] = 'up'
data['PORT'][port]['mtu'] = '9100'
data['INTERFACE']['{}'.format(port)] = {}
return data;
def generate_t1_sample_config(data):
data['DEVICE_METADATA']['localhost']['hostname'] = 'sonic'
data['DEVICE_METADATA']['localhost']['type'] = 'LeafRouter'
data['DEVICE_METADATA']['localhost']['bgp_asn'] = '65100'
data['LOOPBACK_INTERFACE'] = {"Loopback0|10.1.0.1/32": {}}
data['BGP_NEIGHBOR'] = {}
data['DEVICE_NEIGHBOR'] = {}
data['INTERFACE'] = {}
port_count = 0
total_port_amount = len(data['PORT'])
for port in natsorted(data['PORT']):
data['PORT'][port]['admin_status'] = 'up'
data['PORT'][port]['mtu'] = '9100'
[sonic-utilities] Update submodule; Build and install as a Python 3 wheel (#5926) Submodule updates include the following commits: * src/sonic-utilities 9dc58ea...f9eb739 (18): > Remove unnecessary calls to str.encode() now that the package is Python 3; Fix deprecation warning (#1260) > [generate_dump] Ignoring file/directory not found Errors (#1201) > Fixed porstat rate and util issues (#1140) > fix error: interface counters is mismatch after warm-reboot (#1099) > Remove unnecessary calls to str.decode() now that the package is Python 3 (#1255) > [acl-loader] Make list sorting compliant with Python 3 (#1257) > Replace hard-coded fast-reboot with variable. And some typo corrections (#1254) > [configlet][portconfig] Remove calls to dict.has_key() which is not available in Python 3 (#1247) > Remove unnecessary conversions to list() and calls to dict.keys() (#1243) > Clean up LGTM alerts (#1239) > Add 'requests' as install dependency in setup.py (#1240) > Convert to Python 3 (#1128) > Fix mock SonicV2Connector in python3: use decode_responses mode so caller code will be the same as python2 (#1238) > [tests] Do not trim from PATH if we did not append to it; Clean up/fix shebangs in scripts (#1233) > Updates to bgp config and show commands with BGP_INTERNAL_NEIGHBOR table (#1224) > [cli]: NAT show commands newline issue after migrated to Python3 (#1204) > [doc]: Update Command-Reference.md (#1231) > Added 'import sys' in feature.py file (#1232) * src/sonic-py-swsssdk 9d9f0c6...1664be9 (2): > Fix: no need to decode() after redis client scan, so it will work for both python2 and python3 (#96) > FieldValueMap `contains`(`in`) will also work when migrated to libswsscommon(C++ with SWIG wrapper) (#94) - Also fix Python 3-related issues: - Use integer (floor) division in config_samples.py (sonic-config-engine) - Replace print statement with print function in eeprom.py plugin for x86_64-kvm_x86_64-r0 platform - Update all platform plugins to be compatible with both Python 2 and Python 3 - Remove shebangs from plugins files which are not intended to be executable - Replace tabs with spaces in Python plugin files and fix alignment, because Python 3 is more strict - Remove trailing whitespace from plugins files
2020-11-25 12:28:36 -06:00
local_addr = '10.0.{}.{}'.format(2 * port_count // 256, 2 * port_count % 256)
peer_addr = '10.0.{}.{}'.format(2 * port_count // 256, 2 * port_count % 256 + 1)
peer_name='ARISTA{0:02d}{1}'.format(1+port_count%(total_port_amount // 2), 'T2' if port_count < (total_port_amount // 2) else 'T0')
peer_asn = 65200 if port_count < (total_port_amount // 2) else 64001 + port_count - (total_port_amount // 2)
data['INTERFACE']['{}|{}/31'.format(port, local_addr)] = {}
data['BGP_NEIGHBOR'][peer_addr] = {
'rrclient': 0,
'name': peer_name,
'local_addr': local_addr,
'nhopself': 0,
'holdtime': '180',
'asn': str(peer_asn),
'keepalive': '60'
}
port_count += 1
return data
def generate_empty_config(data):
new_data = {'DEVICE_METADATA': data['DEVICE_METADATA']}
if 'hostname' not in new_data['DEVICE_METADATA']['localhost']:
new_data['DEVICE_METADATA']['localhost']['hostname'] = 'sonic'
if 'type' not in new_data['DEVICE_METADATA']['localhost']:
new_data['DEVICE_METADATA']['localhost']['type'] = 'LeafRouter'
return new_data
def generate_global_dualtor_tables():
data = defaultdict(lambda: defaultdict(dict))
data['LOOPBACK_INTERFACE'] = {
'Loopback2': {},
'Loopback2|3.3.3.3': {}
}
data['MUX_CABLE'] = {}
data['PEER_SWITCH'] = {
"peer_switch_hostname": {
"address_ipv4": "1.1.1.1"
}
}
data['TUNNEL'] = {
"MuxTunnel0": {
"dscp_mode": "uniform",
"dst_ip": "2.2.2.2",
"ecn_mode": "copy_from_outer",
"encap_ecn_mode": "standard",
"ttl_mode": "pipe",
"tunnel_type": "IPINIP"
}
}
return data
def generate_l2_config(data):
# Check if dual ToR configs are needed
if 'is_dualtor' in data and data['is_dualtor']:
is_dualtor = True
data.pop('is_dualtor')
else:
is_dualtor = False
if 'uplinks' in data:
uplinks = data['uplinks']
data.pop('uplinks')
if 'downlinks' in data:
downlinks = data['downlinks']
data.pop('downlinks')
# VLAN initial data
data['VLAN'] = {'Vlan1000': {'vlanid': '1000'}}
data['VLAN_MEMBER'] = {}
if is_dualtor:
data['DEVICE_METADATA']['localhost']['subtype'] = 'DualToR'
data['DEVICE_METADATA']['localhost']['peer_switch'] = 'peer_switch_hostname'
data.update(generate_global_dualtor_tables())
server_ipv4_base = ip_interface(UNICODE_TYPE('192.168.0.1/32'))
server_ipv6_base = ip_interface(UNICODE_TYPE('fc02:1000::1/128'))
server_offset = 1
for port in natsorted(data['PORT']):
if is_dualtor:
# Ports in use should be admin up, unused ports default to admin down
if port in downlinks or port in uplinks:
data['PORT'][port].setdefault('admin_status', 'up')
data['VLAN_MEMBER']['Vlan1000|{}'.format(port)] = {'tagging_mode': 'untagged'}
# Downlinks (connected to mux cable) need a MUX_CABLE entry
# as well as the `mux_cable` field in the PORT table
if port in downlinks:
mux_cable_entry = {
'server_ipv4': str(server_ipv4_base + server_offset),
'server_ipv6': str(server_ipv6_base + server_offset),
'state': 'auto'
}
server_offset += 1
data['MUX_CABLE'][port] = mux_cable_entry
data['PORT'][port]['mux_cable'] = 'true'
else:
data['PORT'][port].setdefault('admin_status', 'up')
data['VLAN_MEMBER']['Vlan1000|{}'.format(port)] = {'tagging_mode': 'untagged'}
return data
_sample_generators = {
't1': generate_t1_sample_config,
'l2': generate_l2_config,
'empty': generate_empty_config,
'l1': generate_l1_config,
'l3': generate_l3_config
}
def get_available_config():
return list(_sample_generators.keys())
def generate_sample_config(data, setting_name):
data = generate_common_config(data)
return _sample_generators[setting_name.lower()](data)