[ConfigDB] Move all BGP configuration into DB (#861)

- BGP data read from minigraph.py now match DB schema
- BGP templates are updated
- bgpcfgd can now deal with runtime neighbor create/delete
This commit is contained in:
Taoyu Li 2017-08-08 16:23:58 -07:00 committed by GitHub
parent afbf1ee2fb
commit a2fe0212be
18 changed files with 159 additions and 169 deletions

View File

@ -18,7 +18,7 @@ log facility local4
!
! bgp multiple-instance
!
router bgp {{ minigraph_bgp_asn }}
router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }}
bgp log-neighbor-changes
bgp bestpath as-path multipath-relax
{# TODO: use lo[0] for backward compatibility, will revisit the case with multiple lo interfaces #}
@ -46,16 +46,16 @@ router bgp {{ minigraph_bgp_asn }}
{% endfor %}
{% endblock vlan_advertisement %}
{% block bgp_sessions %}
{% for bgp_session in minigraph_bgp %}
{% for neighbor_addr, bgp_session in BGP_NEIGHBOR.iteritems() %}
{% if bgp_session['asn'] != 0 %}
neighbor {{ bgp_session['addr'] }} remote-as {{ bgp_session['asn'] }}
neighbor {{ bgp_session['addr'] }} description {{ bgp_session['name'] }}
neighbor {{ neighbor_addr }} remote-as {{ bgp_session['asn'] }}
neighbor {{ neighbor_addr }} description {{ bgp_session['name'] }}
{% if minigraph_devices[inventory_hostname]['type'] == 'ToRRouter' %}
neighbor {{ bgp_session['addr'] }} allowas-in 1
neighbor {{ neighbor_addr }} allowas-in 1
{% endif %}
{% if bgp_session['addr'] | ipv6 %}
{% if neighbor_addr | ipv6 %}
address-family ipv6
neighbor {{ bgp_session['addr'] }} activate
neighbor {{ neighbor_addr }} activate
maximum-paths 64
exit-address-family
{% endif %}
@ -66,5 +66,5 @@ router bgp {{ minigraph_bgp_asn }}
maximum-paths 64
!
route-map ISOLATE permit 10
set as-path prepend {{ minigraph_bgp_asn }}
set as-path prepend {{ DEVICE_METADATA['localhost']['bgp_asn'] }}
!

View File

@ -8,13 +8,13 @@ exit $?
## vtysh script start from next line, which line number MUST eqaul in 'sed' command above
configure terminal
router bgp {{ minigraph_bgp_asn }}
{% for bgp_session in minigraph_bgp %}
neighbor {{ bgp_session['addr'] }} route-map ISOLATE out
router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }}
{% for neighbor_addr in BGP_NEIGHBOR %}
neighbor {{ neighbor_addr }} route-map ISOLATE out
{% endfor %}
exit
exit
{% for bgp_session in minigraph_bgp %}
clear ip bgp {{ bgp_session['addr'] }} soft out
{% for neighbor_addr in BGP_NEIGHBOR %}
clear ip bgp {{ neighbor_addr }} soft out
{% endfor %}

View File

@ -8,13 +8,13 @@ exit $?
## vtysh script start from next line, which line number MUST eqaul in 'sed' command above
configure terminal
router bgp {{ minigraph_bgp_asn }}
{% for bgp_session in minigraph_bgp %}
no neighbor {{ bgp_session['addr'] }} route-map ISOLATE out
router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }}
{% for neighbor_ip in BGP_NEIGHBOR %}
no neighbor {{ neighbor_ip }} route-map ISOLATE out
{% endfor %}
exit
exit
{% for bgp_session in minigraph_bgp %}
clear ip bgp {{ bgp_session['addr'] }} soft out
{% for neighbor_ip in BGP_NEIGHBOR %}
clear ip bgp {{ neighbor_ip }} soft out
{% endfor %}

View File

@ -1,17 +1,17 @@
[global.config]
as = {{ minigraph_bgp_asn }}
as = {{ DEVICE_METADATA['localhost']['bgp_asn'] }}
router-id = "{{ minigraph_lo_interfaces[0]['addr'] }}"
{% for bgp_session in minigraph_bgp %}
{% for neighbor_addr, bgp_session in BGP_NEIGHBOR.iteritems() %}
{% if bgp_session['asn'] != 0 %}
[[neighbors]]
[neighbors.config]
peer-as = {{ bgp_session['asn'] }}
neighbor-address = "{{ bgp_session['addr'] }}"
neighbor-address = "{{ neighbor_addr }}"
[neighbors.graceful-restart.config]
enabled = true
[[neighbors.afi-safis]]
[neighbors.afi-safis.config]
{% if bgp_session['addr'] | ipv6 %}
{% if neighbor_addr | ipv6 %}
afi-safi-name = "ipv6-unicast"
{% else %}
afi-safi-name = "ipv4-unicast"

View File

@ -2,23 +2,3 @@
echo Not implemented yet
exit
## vtysh only accepts script in stdin, so cannot be directly used in shebang
## Cut the tail of this script and feed vtysh stdin
sed -n -e '9,$p' < "$0" | vtysh "$@"
## Exit with vtysh return code
exit $?
## vtysh script start from next line, which line number MUST eqaul in 'sed' command above
configure terminal
router bgp {{ minigraph_bgp_asn }}
{% for bgp_session in minigraph_bgp %}
neighbor {{ bgp_session['addr'] }} route-map ISOLATE out
{% endfor %}
exit
exit
{% for bgp_session in minigraph_bgp %}
clear ip bgp {{ bgp_session['addr'] }} soft out
{% endfor %}

View File

@ -3,22 +3,3 @@
echo Not implemented yet
exit
## vtysh only accepts script in stdin, so cannot be directly used in shebang
## Cut the tail of this script and feed vtysh stdin
sed -n -e '9,$p' < "$0" | vtysh "$@"
## Exit with vtysh return code
exit $?
## vtysh script start from next line, which line number MUST eqaul in 'sed' command above
configure terminal
router bgp {{ minigraph_bgp_asn }}
{% for bgp_session in minigraph_bgp %}
no neighbor {{ bgp_session['addr'] }} route-map ISOLATE out
{% endfor %}
exit
exit
{% for bgp_session in minigraph_bgp %}
clear ip bgp {{ bgp_session['addr'] }} soft out
{% endfor %}

View File

@ -6,37 +6,60 @@ import subprocess
import syslog
from swsssdk import ConfigDBConnector
# Returns BGP ASN as a string
def _get_bgp_asn_from_minigraph():
# Get BGP ASN from minigraph
proc = subprocess.Popen(
['sonic-cfggen', '-m', '/etc/sonic/minigraph.xml', '-v', 'minigraph_bgp_asn'],
stdout=subprocess.PIPE,
shell=False,
stderr=subprocess.STDOUT)
stdout = proc.communicate()[0]
proc.wait()
return stdout.rstrip('\n')
class BGPConfigDaemon:
def bgp_config(asn, ip, config):
syslog.syslog(syslog.LOG_INFO, '[bgp cfgd] value for {} changed to {}'.format(ip, config))
# Currently dynamic config is supported only for bgp admin status
if config.has_key('admin_status'):
command_mod = 'no ' if config['admin_status'] == 'up' else ''
command = "vtysh -c 'configure terminal' -c 'router bgp {}' -c '{}neighbor {} shutdown'".format(asn, command_mod, ip)
def __init__(self):
self.config_db = ConfigDBConnector()
self.config_db.connect()
self.bgp_asn = self.config_db.get_entry('DEVICE_METADATA', 'localhost')['bgp_asn']
self.bgp_neighbor = self.config_db.get_table('BGP_NEIGHBOR')
def __run_command(self, command):
# print command
p = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE)
stdout = p.communicate()[0]
p.wait()
if p.returncode != 0:
syslog.syslog(syslog.LOG_ERR, '[bgp cfgd] command execution returned {}. Command: "{}", stdout: "{}"'.format(p.returncode, command, stdout))
def main():
sub = ConfigDBConnector()
bgp_asn = _get_bgp_asn_from_minigraph()
handler = lambda table, key, data: bgp_config(bgp_asn, key, data)
sub.subscribe('BGP_NEIGHBOR', handler)
sub.connect()
sub.listen()
def metadata_handler(self, key, data):
if key == 'localhost' and data.has_key('bgp_asn'):
if data['bgp_asn'] != self.bgp_asn:
syslog.syslog(syslog.LOG_INFO, '[bgp cfgd] ASN changed to {} from {}, restart BGP...'.format(data['bgp_asn'], self.bgp_asn))
self.__run_command("supervisorctl restart start.sh")
self.__run_command("service quagga restart")
self.bgp_asn = data['bgp_asn']
main()
def bgp_handler(self, key, data):
syslog.syslog(syslog.LOG_INFO, '[bgp cfgd] value for {} changed to {}'.format(key, data))
if not data:
# Neighbor is deleted
command = "vtysh -c 'configure terminal' -c 'router bgp {}' -c 'no neighbor {}'".format(self.bgp_asn, key)
self.__run_command(command)
self.bgp_neighbor.pop(key)
else:
command = "vtysh -c 'configure terminal' -c 'router bgp {}' -c 'neighbor {} remote-as {}'".format(self.bgp_asn, key, data['asn'])
self.__run_command(command)
if data.has_key('name'):
command = "vtysh -c 'configure terminal' -c 'router bgp {}' -c 'neighbor {} description {}'".format(self.bgp_asn, key, data['name'])
self.__run_command(command)
if data.has_key('admin_status'):
command_mod = 'no ' if data['admin_status'] == 'up' else ''
command = "vtysh -c 'configure terminal' -c 'router bgp {}' -c '{}neighbor {} shutdown'".format(self.bgp_asn, command_mod, key)
self.__run_command(command)
self.bgp_neighbor[key] = data
def start(self):
self.config_db.subscribe('BGP_NEIGHBOR',
lambda table, key, data: self.bgp_handler(key, data))
self.config_db.subscribe('DEVICE_METADATA',
lambda table, key, data: self.metadata_handler(key, data))
self.config_db.listen()
def main():
daemon = BGPConfigDaemon()
daemon.start()
if __name__ == "__main__":
main()

View File

@ -14,7 +14,7 @@ log facility local4
! enable password {# {{ en_passwd }} TODO: param needed #}
{% endblock system_init %}
!
{% if minigraph_bgp_asn is not none %}
{% if DEVICE_METADATA['localhost'].has_key('bgp_asn') %}
{% block bgp_init %}
!
! bgp multiple-instance
@ -23,7 +23,7 @@ route-map FROM_BGP_SPEAKER_V4 permit 10
!
route-map TO_BGP_SPEAKER_V4 deny 10
!
router bgp {{ minigraph_bgp_asn }}
router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }}
bgp log-neighbor-changes
bgp bestpath as-path multipath-relax
{# Advertise graceful restart capability for ToR #}
@ -50,24 +50,24 @@ router bgp {{ minigraph_bgp_asn }}
{% endfor %}
{% endblock vlan_advertisement %}
{% block bgp_sessions %}
{% for bgp_session in minigraph_bgp %}
{% for neighbor_addr, bgp_session in BGP_NEIGHBOR.iteritems() %}
{% if bgp_session['asn'] != 0 %}
neighbor {{ bgp_session['addr'] }} remote-as {{ bgp_session['asn'] }}
neighbor {{ bgp_session['addr'] }} description {{ bgp_session['name'] }}
{% if bgp_admin_state and bgp_admin_state.has_key(bgp_session['addr']) and bgp_admin_state[bgp_session['addr']]==False or bgp_admin_state and not bgp_admin_state.has_key(bgp_session['addr']) and bgp_admin_state.has_key('all') and bgp_admin_state['all']==False %}
neighbor {{ bgp_session['addr'] }} shutdown
neighbor {{ neighbor_addr }} remote-as {{ bgp_session['asn'] }}
neighbor {{ neighbor_addr }} description {{ bgp_session['name'] }}
{% if bgp_session.has_key('admin_status') and bgp_session['admin_status'] == 'down' or not bgp_session.has_key('admin_status') and DEVICE_METADATA['localhost'].has_key('default_bgp_status') and DEVICE_METADATA['localhost']['default_bgp_status'] == 'down' %}
neighbor {{ neighbor_addr }} shutdown
{% endif %}
{% if bgp_session['addr'] | ipv4 %}
{% if neighbor_addr | ipv4 %}
{% if minigraph_devices[inventory_hostname]['type'] == 'ToRRouter' %}
neighbor {{ bgp_session['addr'] }} allowas-in 1
neighbor {{ neighbor_addr }} allowas-in 1
{% endif %}
{% endif %}
{% if bgp_session['addr'] | ipv6 %}
{% if neighbor_addr | ipv6 %}
address-family ipv6
{% if minigraph_devices[inventory_hostname]['type'] == 'ToRRouter' %}
neighbor {{ bgp_session['addr'] }} allowas-in 1
neighbor {{ neighbor_addr }} allowas-in 1
{% endif %}
neighbor {{ bgp_session['addr'] }} activate
neighbor {{ neighbor_addr }} activate
maximum-paths 64
exit-address-family
{% endif %}
@ -75,7 +75,7 @@ router bgp {{ minigraph_bgp_asn }}
{% endfor %}
{% endblock bgp_sessions %}
{% block bgp_peers_with_range %}
{% for bgp_peer in minigraph_bgp_peers_with_range %}
{% for bgp_peer in BGP_PEER_RANGE.values() %}
neighbor {{ bgp_peer['name'] }} peer-group
neighbor {{ bgp_peer['name'] }} passive
neighbor {{ bgp_peer['name'] }} remote-as {{deployment_id_asn_map[deployment_id] }}
@ -90,10 +90,10 @@ router bgp {{ minigraph_bgp_asn }}
{% endfor %}
{% endblock bgp_peers_with_range %}
!
{% if minigraph_bgp_asn is not none %}
{% if DEVICE_METADATA['localhost'].has_key('bgp_asn') %}
maximum-paths 64
!
route-map ISOLATE permit 10
set as-path prepend {{ minigraph_bgp_asn }}
set as-path prepend {{ DEVICE_METADATA['localhost']['bgp_asn'] }}
{% endif %}
!

View File

@ -8,13 +8,13 @@ exit $?
## vtysh script start from next line, which line number MUST eqaul in 'sed' command above
configure terminal
router bgp {{ minigraph_bgp_asn }}
{% for bgp_session in minigraph_bgp %}
neighbor {{ bgp_session['addr'] }} route-map ISOLATE out
router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }}
{% for neighbor_addr in BGP_NEIGHBOR %}
neighbor {{ neighbor_addr }} route-map ISOLATE out
{% endfor %}
exit
exit
{% for bgp_session in minigraph_bgp %}
clear ip bgp {{ bgp_session['addr'] }} soft out
{% for neighbor_addr in BGP_NEIGHBOR %}
clear ip bgp {{ neighbor_addr }} soft out
{% endfor %}

View File

@ -3,13 +3,13 @@
mkdir -p /etc/quagga
sonic-cfggen -m -d -y /etc/sonic/deployment_id_asn_map.yml -t /usr/share/sonic/templates/bgpd.conf.j2 > /etc/quagga/bgpd.conf
sonic-cfggen -m /etc/sonic/minigraph.xml -t /usr/share/sonic/templates/zebra.conf.j2 > /etc/quagga/zebra.conf
sonic-cfggen -m -d -t /usr/share/sonic/templates/zebra.conf.j2 > /etc/quagga/zebra.conf
sonic-cfggen -m /etc/sonic/minigraph.xml -t /usr/share/sonic/templates/isolate.j2 > /usr/sbin/bgp-isolate
sonic-cfggen -m -d -t /usr/share/sonic/templates/isolate.j2 > /usr/sbin/bgp-isolate
chown root:root /usr/sbin/bgp-isolate
chmod 0755 /usr/sbin/bgp-isolate
sonic-cfggen -m /etc/sonic/minigraph.xml -t /usr/share/sonic/templates/unisolate.j2 > /usr/sbin/bgp-unisolate
sonic-cfggen -m -d -t /usr/share/sonic/templates/unisolate.j2 > /usr/sbin/bgp-unisolate
chown root:root /usr/sbin/bgp-unisolate
chmod 0755 /usr/sbin/bgp-unisolate

View File

@ -8,13 +8,13 @@ exit $?
## vtysh script start from next line, which line number MUST eqaul in 'sed' command above
configure terminal
router bgp {{ minigraph_bgp_asn }}
{% for bgp_session in minigraph_bgp %}
no neighbor {{ bgp_session['addr'] }} route-map ISOLATE out
router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }}
{% for neighbor_ip in BGP_NEIGHBOR %}
no neighbor {{ neighbor_ip }} route-map ISOLATE out
{% endfor %}
exit
exit
{% for bgp_session in minigraph_bgp %}
clear ip bgp {{ bgp_session['addr'] }} soft out
{% for neighbor_ip in BGP_NEIGHBOR %}
clear ip bgp {{ neighbor_ip }} soft out
{% endfor %}

View File

@ -132,7 +132,7 @@ sudo bash -c "echo dhcp_as_static=true >> $FILESYSTEM_ROOT/etc/sonic/updategraph
sudo bash -c "echo enabled=false > $FILESYSTEM_ROOT/etc/sonic/updategraph.conf"
{% endif %}
{% if shutdown_bgp_on_start == "y" %}
sudo bash -c "echo '{ \"bgp_admin_state\": { \"all\": false } }' >> $FILESYSTEM_ROOT/etc/sonic/config_db.json"
sudo bash -c "echo '{ \"DEVICE_METADATA\": { \"localhost\": { \"default_bgp_status\": \"down\" } } }' >> $FILESYSTEM_ROOT/etc/sonic/init_cfg.json"
{% endif %}
# Copy SNMP configuration files
sudo cp $IMAGE_CONFIGS/snmp/snmp.yml $FILESYSTEM_ROOT/etc/sonic/

View File

@ -35,8 +35,20 @@ if [ -f /host/image-$sonic_version/platform/firsttime ]; then
mv -f /host/old_config/* /etc/sonic/
elif [ -f /host/minigraph.xml ]; then
mv /host/minigraph.xml /etc/sonic/
# Combine information in minigraph and init_cfg.json to form initiate config DB dump file.
# TODO: After moving all information from minigraph to DB, sample config DB dump should be provide
if [ -f /etc/sonic/init_cfg.json ]; then
sonic-cfggen -m -j /etc/sonic/init_cfg.json --print-data > /etc/sonic/config_db.json
else
sonic-cfggen -m --print-data > /etc/sonic/config_db.json
fi
else
cp /usr/share/sonic/device/$platform/minigraph.xml /etc/sonic/
if [ -f /etc/sonic/init_cfg.json ]; then
sonic-cfggen -m -j /etc/sonic/init_cfg.json --print-data > /etc/sonic/config_db.json
else
sonic-cfggen -m --print-data > /etc/sonic/config_db.json
fi
fi
if [ -d /host/image-$sonic_version/platform/$platform ]; then

View File

@ -68,6 +68,13 @@ while true; do
sleep 5
done
echo "Regenerating config DB from minigraph..."
if [ -f /etc/sonic/init_cfg.json ]; then
sonic-cfggen -m -j /etc/sonic/init_cfg.json --print-data > /etc/sonic/config_db.json
else
sonic-cfggen -m --print-data > /etc/sonic/config_db.json
fi
# Mark as disabled after graph is successfully downloaded
sed -i "/enabled=/d" /etc/sonic/updategraph.conf
echo "enabled=false" >> /etc/sonic/updategraph.conf

View File

@ -249,9 +249,9 @@ def parse_dpg(dpg, hname):
def parse_cpg(cpg, hname):
bgp_sessions = []
bgp_sessions = {}
myasn = None
bgp_peers_with_range = []
bgp_peers_with_range = {}
for child in cpg:
tag = child.tag
if tag == str(QName(ns, "PeeringSessions")):
@ -261,17 +261,15 @@ def parse_cpg(cpg, hname):
end_router = session.find(str(QName(ns, "EndRouter"))).text
end_peer = session.find(str(QName(ns, "EndPeer"))).text
if end_router == hname:
bgp_sessions.append({
bgp_sessions[start_peer] = {
'name': start_router,
'addr': start_peer,
'peer_addr': end_peer
})
'local_addr': end_peer
}
else:
bgp_sessions.append({
bgp_sessions[end_peer] = {
'name': end_router,
'addr': end_peer,
'peer_addr': start_peer
})
'local_addr': start_peer
}
elif child.tag == str(QName(ns, "Routers")):
for router in child.findall(str(QName(ns1, "BGPRouterDeclaration"))):
asn = router.find(str(QName(ns1, "ASN"))).text
@ -285,12 +283,13 @@ def parse_cpg(cpg, hname):
name = bgpPeer.find(str(QName(ns1, "Name"))).text
ip_range = bgpPeer.find(str(QName(ns1, "PeersRange"))).text
ip_range_group = ip_range.split(';') if ip_range and ip_range != "" else []
bgp_peers_with_range.append({
bgp_peers_with_range[name] = {
'name': name,
'ip_range': ip_range_group
})
}
else:
for bgp_session in bgp_sessions:
for peer in bgp_sessions:
bgp_session = bgp_sessions[peer]
if hostname == bgp_session['name']:
bgp_session['asn'] = int(asn)
@ -447,9 +446,9 @@ def parse_xml(filename, platform=None, port_config_file=None):
# sorting by lambdas are not easily done without custom filters.
# TODO: add jinja2 filter to accept a lambda to sort a list of dictionaries by attribute.
# TODO: alternatively (preferred), implement class containers for multiple-attribute entries, enabling sort by attr
results['minigraph_bgp'] = sorted(bgp_sessions, key=lambda x: x['addr'])
results['minigraph_bgp_asn'] = bgp_asn
results['minigraph_bgp_peers_with_range'] = bgp_peers_with_range
results['BGP_NEIGHBOR'] = bgp_sessions
results['DEVICE_METADATA'] = {'localhost': { 'bgp_asn': bgp_asn }}
results['BGP_PEER_RANGE'] = bgp_peers_with_range
# TODO: sort does not work properly on all interfaces of varying lengths. Need to sort by integer group(s).
phyport_intfs = []

View File

@ -73,37 +73,25 @@ TODO(taoyl): Current version of config db only supports BGP admin states.
"""
@staticmethod
def db_to_output(db_data):
data_bgp_admin = {}
for table_name, content in db_data.iteritems():
if table_name == 'BGP_NEIGHBOR':
for key, value in content.iteritems():
if value.has_key('admin_status'):
data_bgp_admin[key] = (value['admin_status'] == 'up')
elif table_name == 'DEVICE_METADATA':
if content['localhost'].has_key('bgp_default_status'):
data_bgp_admin['all'] = (content['localhost']['bgp_default_status'] == 'up')
output_data = {'bgp_admin_state': data_bgp_admin} if data_bgp_admin else {}
return output_data
return db_data
@staticmethod
def output_to_db(output_data):
db_data = {}
for key, value in output_data.iteritems():
if key == 'bgp_admin_state':
for neighbor, state in value.iteritems():
if neighbor == 'all':
if not db_data.has_key('DEVICE_METADATA'):
db_data['DEVICE_METADATA'] = {'localhost': {}}
db_data['DEVICE_METADATA']['localhost']['bgp_default_status'] = 'up' if state else 'down'
else:
if not db_data.has_key('BGP_NEIGHBOR'):
db_data['BGP_NEIGHBOR'] = {}
if not db_data['BGP_NEIGHBOR'].has_key(neighbor):
db_data['BGP_NEIGHBOR'][neighbor] = {}
db_data['BGP_NEIGHBOR'][neighbor]['admin_status'] = 'up' if state else 'down'
for table_name in output_data:
if table_name == 'BGP_NEIGHBOR' or table_name == 'BGP_PEER_RANGE' or table_name == 'DEVICE_METADATA':
db_data[table_name] = output_data[table_name]
return db_data
def deep_update(dst, src):
for key, value in src.iteritems():
if isinstance(value, dict):
node = dst.setdefault(key, {})
deep_update(node, value)
else:
dst[key] = value
return dst
def main():
parser=argparse.ArgumentParser(description="Render configuration file from minigraph data and jinja2 template.")
@ -126,7 +114,7 @@ def main():
data = {}
machine_info = get_machine_info()
if machine_info != None:
data.update(machine_info)
deep_update(data, machine_info)
platform_info = get_platform_info(machine_info)
if platform_info != None:
data['platform'] = platform_info
@ -135,34 +123,34 @@ def main():
minigraph = args.minigraph
if data.has_key('platform'):
if args.port_config != None:
data.update(parse_xml(minigraph, data['platform'], args.port_config))
deep_update(data, parse_xml(minigraph, data['platform'], args.port_config))
else:
data.update(parse_xml(minigraph, data['platform']))
deep_update(data, parse_xml(minigraph, data['platform']))
else:
if args.port_config != None:
data.update(parse_xml(minigraph, port_config_file=args.port_config))
deep_update(data, parse_xml(minigraph, port_config_file=args.port_config))
else:
data.update(parse_xml(minigraph))
deep_update(data, parse_xml(minigraph))
if args.device_description != None:
data.update(parse_device_desc_xml(args.device_description))
deep_update(data, parse_device_desc_xml(args.device_description))
for yaml_file in args.yaml:
with open(yaml_file, 'r') as stream:
additional_data = yaml.load(stream)
data.update(additional_data)
deep_update(data, additional_data)
for json_file in args.json:
with open(json_file, 'r') as stream:
data.update(json.load(stream))
deep_update(data, json.load(stream))
if args.additional_data != None:
data.update(json.loads(args.additional_data))
deep_update(data, json.loads(args.additional_data))
if args.from_db:
configdb = ConfigDBConnector()
configdb.connect()
data.update(FormatConverter.db_to_output(configdb.get_config()))
deep_update(data, FormatConverter.db_to_output(configdb.get_config()))
if args.template != None:
template_file = os.path.abspath(args.template)

View File

@ -111,7 +111,7 @@ class TestCfgGen(TestCase):
self.assertEqual(output.strip(), "{'Ethernet116': {'name': 'ARISTA02T1', 'port': 'Ethernet1/1'}, 'Ethernet124': {'name': 'ARISTA04T1', 'port': 'Ethernet1/1'}, 'Ethernet112': {'name': 'ARISTA01T1', 'port': 'Ethernet1/1'}, 'Ethernet120': {'name': 'ARISTA03T1', 'port': 'Ethernet1/1'}}")
def test_minigraph_peers_with_range(self):
argument = '-m "' + self.sample_graph_bgp_speaker + '" -p "' + self.port_config + '" -v minigraph_bgp_peers_with_range'
argument = '-m "' + self.sample_graph_bgp_speaker + '" -p "' + self.port_config + '" -v BGP_PEER_RANGE.values\(\)'
output = self.run_script(argument)
self.assertEqual(output.strip(), "[{'name': 'BGPSLBPassive', 'ip_range': ['10.10.10.10/26', '100.100.100.100/26']}]")

@ -1 +1 @@
Subproject commit 6c7e22362fbc05ba455e7e336e2a88430de0de18
Subproject commit e4f7161b055a345813424004f17b116a055d590a