[configdb] Migrate minigraph configurations to DB (#942)

Modify minigraph parser output format so it fit DB schema
Modify configuration templates to fit new schema
Systemd services dependencies are modified so database starts before any configuration consumer
This commit is contained in:
Taoyu Li 2017-09-12 14:13:27 -07:00 committed by GitHub
parent bc73082922
commit c9cc7aea41
47 changed files with 458 additions and 428 deletions

View File

@ -25,5 +25,6 @@ RUN rm -rf /debs
COPY ["start.sh", "isc-dhcp-relay.sh", "/usr/bin/"]
COPY ["supervisord.conf", "/etc/supervisor/conf.d/"]
COPY ["isc-dhcp-relay.j2", "/usr/share/sonic/templates/"]
COPY ["wait_for_intf.sh.j2", "/usr/share/sonic/templates/"]
ENTRYPOINT ["/usr/bin/supervisord"]

View File

@ -1,25 +1,25 @@
SERVERS="{{ dhcp_servers | join(' ') }}"
SERVERS="{{ DHCP_SERVER | join(' ') }}"
INTERFACES="
{%- set add_preceding_space = { 'flag': False } %}
{%- for interface in minigraph_interfaces %}
{%- if interface['addr'] | ipv4 %}
{%- for (name, prefix) in INTERFACE %}
{%- if prefix | ipv4 %}
{%- if add_preceding_space.flag %} {% endif %}
{{ interface['attachto'] }}
{{ name }}
{%- set _dummy = add_preceding_space.update({'flag': True}) %}
{%- endif %}
{%- endfor %}
{%- for vlan_interface in minigraph_vlan_interfaces %}
{%- if vlan_interface['addr'] | ipv4 %}
{%- for (name, prefix) in VLAN_INTERFACE %}
{%- if prefix | ipv4 %}
{%- if add_preceding_space.flag %} {% endif %}
{{ vlan_interface['attachto'] }}
{{ name }}
{%- set _dummy = add_preceding_space.update({'flag': True}) %}
{%- endif %}
{%- endfor %}
{%- for pc_interface in minigraph_portchannel_interfaces %}
{%- if pc_interface['addr'] | ipv4 %}
{%- for (name, prefix) in PORTCHANNEL_INTERFACE %}
{%- if prefix | ipv4 %}
{%- if add_preceding_space.flag %} {% endif %}
{{ pc_interface['attachto'] }}
{{ name }}
{%- set _dummy = add_preceding_space.update({'flag': True}) %}
{%- endif %}
{%- endfor %}"

View File

@ -1,42 +1,16 @@
#!/usr/bin/env bash
function wait_until_iface_exists
{
IFACE=$1
echo "Waiting for interface ${IFACE}..."
# Wait for the interface to come up (i.e., 'ip link show' returns 0)
until ip link show $IFACE > /dev/null 2>&1; do
sleep 1
done
echo "Interface ${IFACE} is created"
}
# Create isc-dhcp-relay config file
sonic-cfggen -m /etc/sonic/minigraph.xml -t /usr/share/sonic/templates/isc-dhcp-relay.j2 > /etc/default/isc-dhcp-relay
sonic-cfggen -d -t /usr/share/sonic/templates/isc-dhcp-relay.j2 > /etc/default/isc-dhcp-relay
rm -f /var/run/rsyslogd.pid
supervisorctl start rsyslogd
# Wait for all interfaces to come up before starting the DHCP relay
FRONT_PANEL_IFACES=$(sonic-cfggen -m /etc/sonic/minigraph.xml --var-json "minigraph_interfaces" | grep "\"attachto\":" | sed 's/^\s*"attachto":\s"\(.*\)".*$/\1/')
for IFACE in $FRONT_PANEL_IFACES; do
wait_until_iface_exists $IFACE
done
VLAN_IFACES=$(sonic-cfggen -m /etc/sonic/minigraph.xml --var-json "minigraph_vlan_interfaces" | grep "\"attachto\":" | sed 's/^\s*"attachto":\s"\(.*\)".*$/\1/')
for IFACE in $VLAN_IFACES; do
wait_until_iface_exists $IFACE
done
PORTCHANNEL_IFACES=$(sonic-cfggen -m /etc/sonic/minigraph.xml --var-json "minigraph_portchannel_interfaces" | grep "\"attachto\":" | sed 's/^\s*"attachto":\s"\(.*\)".*$/\1/')
for IFACE in $PORTCHANNEL_IFACES; do
wait_until_iface_exists $IFACE
done
sonic-cfggen -d -t /usr/share/sonic/templates/wait_for_intf.sh.j2 > /usr/bin/wait_for_intf.sh
chmod +x /usr/bin/wait_for_intf.sh
/usr/bin/wait_for_intf.sh
# Start the DHCP relay
supervisorctl start isc-dhcp-relay

View File

@ -0,0 +1,28 @@
#!/usr/bin/env bash
function wait_until_iface_exists
{
IFACE=$1
echo "Waiting for interface ${IFACE}..."
# Wait for the interface to come up (i.e., 'ip link show' returns 0)
until ip link show $IFACE > /dev/null 2>&1; do
sleep 1
done
echo "Interface ${IFACE} is created"
}
# Wait for all interfaces to come up before starting the DHCP relay
{% for (name, prefix) in INTERFACE %}
wait_until_iface_exists {{ name }}
{% endfor %}
{% for (name, prefix) in VLAN_INTERFACE %}
wait_until_iface_exists {{ name }}
{% endfor %}
{% for (name, prefix) in PORTCHANNEL_INTERFACE %}
wait_until_iface_exists {{ name }}
{% endfor %}

View File

@ -1,13 +1,13 @@
!
{% block banner %}
! =========== Managed by sonic-cfggen DO NOT edit manually! ====================
! generated by templates/quagga/bgpd.conf.j2 using minigraph_facts.py
! generated by templates/quagga/bgpd.conf.j2 with config DB data
! file: bgpd.conf
!
{% endblock banner %}
!
{% block system_init %}
hostname {{ inventory_hostname }}
hostname {{ DEVICE_METADATA['localhost']['hostname'] }}
password zebra
log syslog informational
log facility local4
@ -23,25 +23,25 @@ router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }}
bgp bestpath as-path multipath-relax
no bgp default ipv4-unicast
{# TODO: use lo[0] for backward compatibility, will revisit the case with multiple lo interfaces #}
bgp router-id {{ minigraph_lo_interfaces[0]['addr'] }}
bgp router-id {{ LOOPBACK_INTERFACE.keys()[0][1] }}
{# advertise loopback #}
{% for lo in minigraph_lo_interfaces %}
{% if lo['addr'] | ipv4 %}
network {{ lo['addr'] }}/32
{% elif lo['addr'] | ipv6 %}
{% for (name, prefix) in LOOPBACK_INTERFACE %}
{% if prefix | ipv4 %}
network {{ prefix | ip }}/32
{% elif prefix | ipv6 %}
address-family ipv6
network {{ lo['addr'] }}/128
network {{ prefix | ip }}/128
exit-address-family
{% endif %}
{% endfor %}
{% endblock bgp_init %}
{% block vlan_advertisement %}
{% for vlan_interface in minigraph_vlan_interfaces %}
{% if vlan_interface['addr'] | ipv4 %}
network {{ vlan_interface['subnet'] }}
{% elif vlan_interface['addr'] | ipv6 %}
{% for (name, prefix) in VLAN_INTERFACE %}
{% if prefix | ipv4 %}
network {{ prefix }}
{% elif prefix | ipv6 %}
address-family ipv6
network {{ vlan_interface['subnet'] }}
network {{ prefix }}
exit-address-family
{% endif %}
{% endfor %}
@ -51,7 +51,7 @@ router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }}
{% if bgp_session['asn'] != 0 %}
neighbor {{ neighbor_addr }} remote-as {{ bgp_session['asn'] }}
neighbor {{ neighbor_addr }} description {{ bgp_session['name'] }}
{% if minigraph_devices[inventory_hostname]['type'] == 'ToRRouter' %}
{% if DEVICE_METADATA['localhost']['type'] == 'ToRRouter' %}
neighbor {{ neighbor_addr }} allowas-in 1
{% endif %}
{% if neighbor_addr | ipv4 %}

View File

@ -1,14 +1,14 @@
#!/bin/bash
mkdir -p /etc/frr
sonic-cfggen -m /etc/sonic/minigraph.xml -t /usr/share/sonic/templates/bgpd.conf.j2 >/etc/frr/bgpd.conf
sonic-cfggen -m /etc/sonic/minigraph.xml -t /usr/share/sonic/templates/zebra.conf.j2 >/etc/frr/zebra.conf
sonic-cfggen -d -t /usr/share/sonic/templates/bgpd.conf.j2 >/etc/frr/bgpd.conf
sonic-cfggen -d -t /usr/share/sonic/templates/zebra.conf.j2 >/etc/frr/zebra.conf
sonic-cfggen -m /etc/sonic/minigraph.xml -t /usr/share/sonic/templates/isolate.j2 >/usr/sbin/bgp-isolate
sonic-cfggen -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 -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

@ -1,26 +1,26 @@
!
{% block banner %}
! =========== Managed by sonic-cfggen DO NOT edit manually! ====================
! generated by templates/quagga/zebra.conf.j2 using minigraph_facts.py
! generated by templates/quagga/zebra.conf.j2 using config DB data
! file: zebra.conf
!
{% endblock banner %}
!
{% block sys_init %}
hostname {{ inventory_hostname }}
hostname {{ DEVICE_METADATA['localhost']['hostname'] }}
password zebra
enable password zebra
{% endblock sys_init %}
!
{% block interfaces %}
! Enable link-detect (default disabled)
{% for interface in minigraph_interfaces %}
interface {{ interface['attachto'] }}
{% for (name, prefix) in INTERFACE %}
interface {{ name }}
link-detect
!
{% endfor %}
{% for interface in minigraph_portchannels.keys() %}
interface {{ interface }}
{% for pc in PORTCHANNEL %}
interface {{ pc }}
link-detect
!
{% endfor %}
@ -28,26 +28,34 @@ link-detect
!
{% block default_route %}
! set static default route to mgmt gateway as a backup to learned default
ip route 0.0.0.0/0 {{ minigraph_mgmt_interface['gwaddr'] }} 200
{% for (name, prefix) in MGMT_INTERFACE %}
{% if prefix | ipv4 %}
ip route 0.0.0.0/0 {{ MGMT_INTERFACE[(name, prefix)]['gwaddr'] }} 200
{% endif %}
{% endfor %}
{% endblock default_route %}
!
{% block source_loopback %}
! Set ip source to loopback for bgp learned routes
route-map RM_SET_SRC permit 10
set src {{ minigraph_lo_interfaces[0]['addr'] }}
!
{% set lo_ipv4_addrs = [] %}
{% set lo_ipv6_addrs = [] %}
{% if minigraph_lo_interfaces is defined %}
{% for interface in minigraph_lo_interfaces %}
{% if interface['addr'] is defined and interface['addr']|ipv6 %}
{% if lo_ipv6_addrs.append(interface['addr']) %}
{% if LOOPBACK_INTERFACE %}
{% for (name, prefix) in LOOPBACK_INTERFACE %}
{% if prefix | ipv6 %}
{% if lo_ipv6_addrs.append(prefix) %}
{% endif %}
{% else %}
{% if lo_ipv4_addrs.append(prefix) %}
{% endif %}
{% endif %}
{% endfor %}
{% endif %}
! Set ip source to loopback for bgp learned routes
route-map RM_SET_SRC permit 10
set src {{ lo_ipv4_addrs[0] | ip }}
!
{% if lo_ipv6_addrs|length > 0 %}
route-map RM_SET_SRC6 permit 10
set src {{ lo_ipv6_addrs[0] }}
set src {{ lo_ipv6_addrs[0] | ip }}
!
{% endif %}
ip protocol bgp route-map RM_SET_SRC

View File

@ -1,6 +1,6 @@
[global.config]
as = {{ DEVICE_METADATA['localhost']['bgp_asn'] }}
router-id = "{{ minigraph_lo_interfaces[0]['addr'] }}"
router-id = "{{ LOOPBACK_INTERFACE.keys()[0][1] }}"
{% for neighbor_addr, bgp_session in BGP_NEIGHBOR.iteritems() %}
{% if bgp_session['asn'] != 0 %}
[[neighbors]]

View File

@ -1,14 +1,14 @@
#!/usr/bin/env bash
mkdir -p /etc/quagga
sonic-cfggen -m /etc/sonic/minigraph.xml -t /usr/share/sonic/templates/gobgpd.conf.j2 > /etc/gobgp/gobgpd.conf
sonic-cfggen -m /etc/sonic/minigraph.xml -t /usr/share/sonic/templates/zebra.conf.j2 > /etc/quagga/zebra.conf
sonic-cfggen -d -t /usr/share/sonic/templates/gobgpd.conf.j2 > /etc/gobgp/gobgpd.conf
sonic-cfggen -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 -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 -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

@ -1,26 +1,26 @@
!
{% block banner %}
! =========== Managed by sonic-cfggen DO NOT edit manually! ====================
! generated by templates/quagga/zebra.conf.j2 using minigraph_facts.py
! generated by templates/quagga/zebra.conf.j2 using config DB data
! file: zebra.conf
!
{% endblock banner %}
!
{% block sys_init %}
hostname {{ inventory_hostname }}
hostname {{ DEVICE_METADATA['localhost']['hostname'] }}
password zebra
enable password zebra
{% endblock sys_init %}
!
{% block interfaces %}
! Enable link-detect (default disabled)
{% for interface in minigraph_interfaces %}
interface {{ interface['attachto'] }}
{% for (name, prefix) in INTERFACE %}
interface {{ name }}
link-detect
!
{% endfor %}
{% for interface in minigraph_portchannels.keys() %}
interface {{ interface }}
{% for pc in PORTCHANNEL %}
interface {{ pc }}
link-detect
!
{% endfor %}
@ -28,26 +28,34 @@ link-detect
!
{% block default_route %}
! set static default route to mgmt gateway as a backup to learned default
ip route 0.0.0.0/0 {{ minigraph_mgmt_interface['gwaddr'] }} 200
{% for (name, prefix) in MGMT_INTERFACE %}
{% if prefix | ipv4 %}
ip route 0.0.0.0/0 {{ MGMT_INTERFACE[(name, prefix)]['gwaddr'] }} 200
{% endif %}
{% endfor %}
{% endblock default_route %}
!
{% block source_loopback %}
! Set ip source to loopback for bgp learned routes
route-map RM_SET_SRC permit 10
set src {{ minigraph_lo_interfaces[0]['addr'] }}
!
{% set lo_ipv4_addrs = [] %}
{% set lo_ipv6_addrs = [] %}
{% if minigraph_lo_interfaces is defined %}
{% for interface in minigraph_lo_interfaces %}
{% if interface['addr'] is defined and interface['addr']|ipv6 %}
{% if lo_ipv6_addrs.append(interface['addr']) %}
{% if LOOPBACK_INTERFACE %}
{% for (name, prefix) in LOOPBACK_INTERFACE %}
{% if prefix | ipv6 %}
{% if lo_ipv6_addrs.append(prefix) %}
{% endif %}
{% else %}
{% if lo_ipv4_addrs.append(prefix) %}
{% endif %}
{% endif %}
{% endfor %}
{% endif %}
! Set ip source to loopback for bgp learned routes
route-map RM_SET_SRC permit 10
set src {{ lo_ipv4_addrs[0] | ip }}
!
{% if lo_ipv6_addrs|length > 0 %}
route-map RM_SET_SRC6 permit 10
set src {{ lo_ipv6_addrs[0] }}
set src {{ lo_ipv6_addrs[0] | ip }}
!
{% endif %}
ip protocol bgp route-map RM_SET_SRC

View File

@ -1,13 +1,13 @@
!
{% block banner %}
! =========== Managed by sonic-cfggen DO NOT edit manually! ====================
! generated by templates/quagga/bgpd.conf.j2 using minigraph_facts.py
! generated by templates/quagga/bgpd.conf.j2 with config DB data
! file: bgpd.conf
!
{% endblock banner %}
!
{% block system_init %}
hostname {{ inventory_hostname }}
hostname {{ DEVICE_METADATA['localhost']['hostname'] }}
password zebra
log syslog informational
log facility local4
@ -28,30 +28,34 @@ router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }}
bgp bestpath as-path multipath-relax
no bgp default ipv4-unicast
{# Advertise graceful restart capability for ToR #}
{% if minigraph_devices[inventory_hostname]['type'] == 'ToRRouter' %}
{% if DEVICE_METADATA['localhost']['type'] == 'ToRRouter' %}
bgp graceful-restart
{% endif %}
{# TODO: use lo[0] for backward compatibility, will revisit the case with multiple lo interfaces #}
bgp router-id {{ minigraph_lo_interfaces[0]['addr'] }}
{% for (name, prefix) in LOOPBACK_INTERFACE %}
{# TODO: use v4 lo for backward compatibility, will revisit the case with multiple lo interfaces #}
{% if prefix | ipv4 %}
bgp router-id {{ prefix | ip }}
{% endif %}
{% endfor %}
{# advertise loopback #}
{% for lo in minigraph_lo_interfaces %}
{% if lo['addr'] | ipv4 %}
network {{ lo['addr'] }}/32
{% elif lo['addr'] | ipv6 %}
{% for (name, prefix) in LOOPBACK_INTERFACE %}
{% if prefix | ipv4 %}
network {{ prefix | ip }}/32
{% elif prefix | ipv6 %}
address-family ipv6
network {{ lo['addr'] }}/128
network {{ prefix | ip }}/128
exit-address-family
{% endif %}
{% endfor %}
{% endblock bgp_init %}
{% endif %}
{% block vlan_advertisement %}
{% for vlan_interface in minigraph_vlan_interfaces %}
{% if vlan_interface['addr'] | ipv4 %}
network {{ vlan_interface['subnet'] }}
{% elif vlan_interface['addr'] | ipv6 %}
{% for (name, prefix) in VLAN_INTERFACE %}
{% if prefix | ipv4 %}
network {{ prefix }}
{% elif prefix | ipv6 %}
address-family ipv6
network {{ vlan_interface['subnet'] }}
network {{ prefix }}
exit-address-family
{% endif %}
{% endfor %}
@ -66,7 +70,7 @@ router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }}
{% endif %}
{% if neighbor_addr | ipv4 %}
address-family ipv4
{% if minigraph_devices[inventory_hostname]['type'] == 'ToRRouter' %}
{% if DEVICE_METADATA['localhost']['type'] == 'ToRRouter' %}
neighbor {{ neighbor_addr }} allowas-in 1
{% endif %}
neighbor {{ neighbor_addr }} activate
@ -75,7 +79,7 @@ router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }}
{% endif %}
{% if neighbor_addr | ipv6 %}
address-family ipv6
{% if minigraph_devices[inventory_hostname]['type'] == 'ToRRouter' %}
{% if DEVICE_METADATA['localhost']['type'] == 'ToRRouter' %}
neighbor {{ neighbor_addr }} allowas-in 1
{% endif %}
neighbor {{ neighbor_addr }} activate
@ -86,6 +90,7 @@ router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }}
{% endfor %}
{% endblock bgp_sessions %}
{% block bgp_peers_with_range %}
{% if BGP_PEER_RANGE %}
{% for bgp_peer in BGP_PEER_RANGE.values() %}
neighbor {{ bgp_peer['name'] }} peer-group
neighbor {{ bgp_peer['name'] }} passive
@ -107,6 +112,7 @@ router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }}
maximum-paths 64
exit-address-family
{% endfor %}
{% endif %}
{% endblock bgp_peers_with_range %}
!
{% if DEVICE_METADATA['localhost'].has_key('bgp_asn') %}

View File

@ -1,26 +1,26 @@
!
{% block banner %}
! =========== Managed by sonic-cfggen DO NOT edit manually! ====================
! generated by templates/quagga/zebra.conf.j2 using minigraph_facts.py
! generated by templates/quagga/zebra.conf.j2 using config DB data
! file: zebra.conf
!
{% endblock banner %}
!
{% block sys_init %}
hostname {{ inventory_hostname }}
hostname {{ DEVICE_METADATA['localhost']['hostname'] }}
password zebra
enable password zebra
{% endblock sys_init %}
!
{% block interfaces %}
! Enable link-detect (default disabled)
{% for interface in minigraph_interfaces %}
interface {{ interface['attachto'] }}
{% for (name, prefix) in INTERFACE %}
interface {{ name }}
link-detect
!
{% endfor %}
{% for interface in minigraph_portchannels.keys() %}
interface {{ interface }}
{% for pc in PORTCHANNEL %}
interface {{ pc }}
link-detect
!
{% endfor %}
@ -28,26 +28,34 @@ link-detect
!
{% block default_route %}
! set static default route to mgmt gateway as a backup to learned default
ip route 0.0.0.0/0 {{ minigraph_mgmt_interface['gwaddr'] }} 200
{% for (name, prefix) in MGMT_INTERFACE %}
{% if prefix | ipv4 %}
ip route 0.0.0.0/0 {{ MGMT_INTERFACE[(name, prefix)]['gwaddr'] }} 200
{% endif %}
{% endfor %}
{% endblock default_route %}
!
{% block source_loopback %}
! Set ip source to loopback for bgp learned routes
route-map RM_SET_SRC permit 10
set src {{ minigraph_lo_interfaces[0]['addr'] }}
!
{% set lo_ipv4_addrs = [] %}
{% set lo_ipv6_addrs = [] %}
{% if minigraph_lo_interfaces is defined %}
{% for interface in minigraph_lo_interfaces %}
{% if interface['addr'] is defined and interface['addr']|ipv6 %}
{% if lo_ipv6_addrs.append(interface['addr']) %}
{% if LOOPBACK_INTERFACE %}
{% for (name, prefix) in LOOPBACK_INTERFACE %}
{% if prefix | ipv6 %}
{% if lo_ipv6_addrs.append(prefix) %}
{% endif %}
{% else %}
{% if lo_ipv4_addrs.append(prefix) %}
{% endif %}
{% endif %}
{% endfor %}
{% endif %}
! Set ip source to loopback for bgp learned routes
route-map RM_SET_SRC permit 10
set src {{ lo_ipv4_addrs[0] | ip }}
!
{% if lo_ipv6_addrs|length > 0 %}
route-map RM_SET_SRC6 permit 10
set src {{ lo_ipv6_addrs[0] }}
set src {{ lo_ipv6_addrs[0] | ip }}
!
{% endif %}
ip protocol bgp route-map RM_SET_SRC

View File

@ -1,5 +1,3 @@
{% for member in minigraph_ports.keys() %}
{% if member in minigraph_neighbors %}
configure ports {{ member }} lldp portidsubtype local {{ minigraph_ports[member]['alias'] }} description {{ minigraph_neighbors[member]['name'] }}:{{ minigraph_neighbors[member]['port'] }}
{% endif %}
{% for neighbor in DEVICE_NEIGHBOR %}
configure ports {{ DEVICE_NEIGHBOR[neighbor]['local_port'] }} lldp portidsubtype local {{ PORT[DEVICE_NEIGHBOR[neighbor]['local_port']]['alias'] }} description {{ neighbor }}:{{ DEVICE_NEIGHBOR[neighbor]['port'] }}
{% endfor %}

View File

@ -1,6 +1,6 @@
#!/usr/bin/env bash
sonic-cfggen -m /etc/sonic/minigraph.xml -t /usr/share/sonic/templates/lldpd.conf.j2 > /etc/lldpd.conf
sonic-cfggen -d -t /usr/share/sonic/templates/lldpd.conf.j2 > /etc/lldpd.conf
mkdir -p /var/sonic
echo "# Config files managed by sonic-config-engine" > /var/sonic/config_status

View File

@ -4,7 +4,7 @@
# arp_update: Send gratuitous ARP requests to VLAN member neighbors to refresh
# the neighbors state.
VLAN=`sonic-cfggen -m /etc/sonic/minigraph.xml -v 'minigraph_vlans.keys() | join(" ")'`
VLAN=`sonic-cfggen -d -v 'VLAN.keys() | join(" ") if VLAN'`
for vlan in $VLAN; do
# generate a list of arping commands:
# arping -q -w 0 -c 1 -i <VLAN interface> <IP 1>;

View File

@ -2,8 +2,8 @@
{
"TUNNEL_DECAP_TABLE:IPINIP_TUNNEL" : {
"tunnel_type":"IPINIP",
"src_ip":"{{ minigraph_lo_interfaces[0]['addr'] }}",
"dst_ip":"{{ minigraph_lo_interfaces[0]['addr'] }}",
"src_ip":"{{ LOOPBACK_INTERFACE.keys()[0][1] | ip }}",
"dst_ip":"{{ LOOPBACK_INTERFACE.keys()[0][1] | ip }}",
{% if onie_switch_asic == "mlnx" %}
"dscp_mode":"uniform",
"ecn_mode":"standard",

View File

@ -1,9 +1,10 @@
[
{% if erspan_dst %}
{% if MIRROR_SESSION %}
{% for session in MIRROR_SESSION %}
{
"MIRROR_SESSION_TABLE:everflow": {
"src_ip": "{{ minigraph_lo_interfaces[0]['addr'] }}",
"dst_ip": "{{ erspan_dst[0] }}",
"MIRROR_SESSION_TABLE:{{session}}": {
"src_ip": "{{ MIRROR_SESSION[session]['src_ip'] }}",
"dst_ip": "{{ MIRROR_SESSION[session]['dst_ip'] }}",
{% if onie_switch_asic == "mlnx" %}
"gre_type": "0x6558",
"queue": "1",
@ -15,7 +16,9 @@
"ttl": "255"
},
"OP": "SET"
}
}{% if not loop.last %},{% endif %}
{% endfor %}
{% endif %}
]

View File

@ -2,7 +2,7 @@
# Export platform information. Required to be able to write
# vendor specific code.
export platform=`sonic-cfggen -m /etc/sonic/minigraph.xml -v onie_switch_asic`
export platform=`sonic-cfggen -v onie_switch_asic`
ASIC=`sonic-cfggen -y /etc/sonic/sonic_version.yml -v asic_type`

View File

@ -1,11 +1,15 @@
[
{% for interface in ethernet_interfaces %}
{% if PORT %}
{% for port in PORT %}
{% if PORT[port].has_key('speed') %}
{
"PORT_TABLE:{{ interface['name'] }}": {
"speed": "{{ interface['speed'] }}"
"PORT_TABLE:{{ port }}": {
"speed": "{{ PORT[port]['speed'] }}"
},
"OP": "SET"
}{% if not loop.last %},{% endif %}
{% endif %}
{% endfor %}
{% endif %}
]

View File

@ -2,11 +2,11 @@
mkdir -p /etc/swss/config.d/
sonic-cfggen -m /etc/sonic/minigraph.xml -t /usr/share/sonic/templates/ipinip.json.j2 > /etc/swss/config.d/ipinip.json
sonic-cfggen -m /etc/sonic/minigraph.xml -t /usr/share/sonic/templates/mirror.json.j2 > /etc/swss/config.d/mirror.json
sonic-cfggen -m /etc/sonic/minigraph.xml -t /usr/share/sonic/templates/ports.json.j2 > /etc/swss/config.d/ports.json
sonic-cfggen -m /etc/sonic/minigraph.xml -d -t /usr/share/sonic/templates/ipinip.json.j2 > /etc/swss/config.d/ipinip.json
sonic-cfggen -m /etc/sonic/minigraph.xml -d -t /usr/share/sonic/templates/mirror.json.j2 > /etc/swss/config.d/mirror.json
sonic-cfggen -m /etc/sonic/minigraph.xml -d -t /usr/share/sonic/templates/ports.json.j2 > /etc/swss/config.d/ports.json
export platform=`sonic-cfggen -m /etc/sonic/minigraph.xml -v platform`
export platform=`sonic-cfggen -v platform`
rm -f /var/run/rsyslogd.pid
@ -34,7 +34,7 @@ supervisorctl start neighsyncd
supervisorctl start swssconfig
# Start arp_update when VLAN exists
VLAN=`sonic-cfggen -m /etc/sonic/minigraph.xml -v 'minigraph_vlans.keys() | join(" ")'`
VLAN=`sonic-cfggen -d -v 'VLAN.keys() | join(" ") if VLAN'`
if [ "$VLAN" != "" ]; then
supervisorctl start arp_update
fi

View File

@ -36,7 +36,7 @@ function fast_reboot {
# Restore FDB and ARP table ASAP
fast_reboot
HWSKU=`sonic-cfggen -m /etc/sonic/minigraph.xml -v minigraph_hwsku`
HWSKU=`sonic-cfggen -m /etc/sonic/minigraph.xml -d -v DEVICE_METADATA["localhost"]["hwsku"]`
SWSSCONFIG_ARGS="00-copp.config.json ipinip.json mirror.json ports.json "

View File

@ -1,5 +1,5 @@
{
{% for member in minigraph_ports.keys() %}
"{{member}}": "{{minigraph_ports[member]['alias']}}"{% if not loop.last %},{% endif %}
{% for member in PORT %}
"{{member}}": "{{PORT[member]['alias']}}"{% if not loop.last %},{% endif %}
{% endfor %}
}

View File

@ -13,18 +13,22 @@
# AGENT BEHAVIOUR
#
{% if minigraph_mgmt_interface.addr | ipv4 %}
{% if MGMT_INTERFACE %}
# Listen for connections on localhost, loopback ip and mgmt (eth0) ip
agentAddress udp:127.0.0.1:161
agentAddress udp:{{ minigraph_mgmt_interface.addr }}:161
{% for minigraph_lo_interface in minigraph_lo_interfaces %}
{% for (name, prefix) in MGMT_INTERFACE %}
{% if prefix | ipv4 %}
agentAddress udp:{{ prefix | ip }}:161
{% endif %}
{% endfor %}
# TODO: only support ipv4 lo addresses, add ipv6 support later
{% if minigraph_lo_interface.addr | ipv4 %}
agentAddress udp:{{ minigraph_lo_interface.addr }}:161
{% for (name, prefix) in LOOPBACK_INTERFACE %}
{% if prefix | ipv4 %}
agentAddress udp:{{ prefix | ip }}:161
{% endif %}
{% endfor %}
{% else %}
# Listen on all addresses as mgmt ip not specified in minigraph
# Listen on all addresses as mgmt ip not specified
agentAddress udp:161
{% endif %}

View File

@ -1,11 +1,11 @@
#!/usr/bin/env bash
mkdir -p /etc/ssw
sonic-cfggen -m /etc/sonic/minigraph.xml -y /etc/sonic/sonic_version.yml -t /usr/share/sonic/templates/sysDescription.j2 > /etc/ssw/sysDescription
sonic-cfggen -d -y /etc/sonic/sonic_version.yml -t /usr/share/sonic/templates/sysDescription.j2 > /etc/ssw/sysDescription
mkdir -p /etc/snmp
sonic-cfggen -m /etc/sonic/minigraph.xml -y /etc/sonic/snmp.yml -t /usr/share/sonic/templates/snmpd.conf.j2 > /etc/snmp/snmpd.conf
sonic-cfggen -m /etc/sonic/minigraph.xml -t /usr/share/sonic/templates/alias_map.j2 > /etc/snmp/alias_map.json
sonic-cfggen -d -y /etc/sonic/snmp.yml -t /usr/share/sonic/templates/snmpd.conf.j2 > /etc/snmp/snmpd.conf
sonic-cfggen -d -t /usr/share/sonic/templates/alias_map.j2 > /etc/snmp/alias_map.json
mkdir -p /var/sonic
echo "# Config files managed by sonic-config-engine" > /var/sonic/config_status

View File

@ -1 +1 @@
SONiC Software Version: SONiC.{{ build_version }} - HwSku: {{ minigraph_hwsku }} - Distribution: Debian {{ debian_version }} - Kernel: {{ kernel_version }}
SONiC Software Version: SONiC.{{ build_version }} - HwSku: {{ DEVICE_METADATA['localhost']['hwsku'] }} - Distribution: Debian {{ debian_version }} - Kernel: {{ kernel_version }}

View File

@ -15,8 +15,8 @@ if [ "$SONIC_ASIC_TYPE" == "mellanox" -o "$SONIC_ASIC_TYPE" == "centec" ]; then
MAC_ADDRESS=$(python -c "print '$MAC_ADDRESS'[:-2] + '$aligned_last_byte'") # put aligned byte into the end of MAC
fi
for pc in `sonic-cfggen -m /etc/sonic/minigraph.xml -v "minigraph_portchannels.keys() | join(' ')"`; do
sonic-cfggen -m /etc/sonic/minigraph.xml -a '{"pc":"'$pc'","hwaddr":"'$MAC_ADDRESS'"}' -t /usr/share/sonic/templates/teamd.j2 > $TEAMD_CONF_PATH/$pc.conf
for pc in `sonic-cfggen -d -v "PORTCHANNEL.keys() | join(' ') if PORTCHANNEL"`; do
sonic-cfggen -d -a '{"pc":"'$pc'","hwaddr":"'$MAC_ADDRESS'"}' -t /usr/share/sonic/templates/teamd.j2 > $TEAMD_CONF_PATH/$pc.conf
done
mkdir -p /var/sonic

View File

@ -5,14 +5,14 @@
"name": "lacp",
"active": true,
{# Use 75% links upperbound as min-links #}
"min_ports": {{ (minigraph_portchannels[pc]['members'] | length * 0.75) | round(0, 'ceil') | int }},
"min_ports": {{ (PORTCHANNEL[pc]['members'] | length * 0.75) | round(0, 'ceil') | int }},
"tx_hash": ["eth", "ipv4", "ipv6"]
},
"link_watch": {
"name": "ethtool"
},
"ports": {
{% for member in minigraph_portchannels[pc]['members'] %}
{% for member in PORTCHANNEL[pc]['members'] %}
"{{ member }}": {}{% if not loop.last %},{% endif %}
{% endfor %}

View File

@ -2,7 +2,9 @@
# Obtain our platform and HWSKU as we will mount directories with these names in each docker
PLATFORM=`sonic-cfggen -v platform`
HWSKU=`sonic-cfggen -m /etc/sonic/minigraph.xml -v minigraph_hwsku`
{%- if docker_container_name != "database" %}
HWSKU=`sonic-cfggen -d -v 'DEVICE_METADATA["localhost"]["hwsku"]'`
{%- endif %}
start() {
docker inspect --type container {{docker_container_name}} &>/dev/null
@ -16,9 +18,19 @@ start() {
{%- endif %}
-v /var/run/redis:/var/run/redis:rw \
-v /usr/share/sonic/device/$PLATFORM:/usr/share/sonic/platform:ro \
{%- if docker_container_name != "database" %}
-v /usr/share/sonic/device/$PLATFORM/$HWSKU:/usr/share/sonic/hwsku:ro \
{%- endif %}
--name={{docker_container_name}} {{docker_image_name}}:latest
fi
{%- if docker_container_name == "database" %}
while true; do
if [[ "$(docker exec -i database redis-cli ping)" =~ PONG.* ]]; then
break
fi
sleep 1
done
{%- endif %}
}
attach() {

View File

@ -5,6 +5,7 @@ Requires=database.service
Requires=opennsl-modules-3.16.0-4-amd64.service
{% endif %}
After=database.service
After=interfaces-config.service
{% if sonic_asic_platform == 'broadcom' %}
After=opennsl-modules-3.16.0-4-amd64.service
{% endif %}

View File

@ -1,6 +1,7 @@
[Unit]
Description=Update interfaces configuration
Before=database.service
Requires=database.service
After=database.service
[Service]
Type=oneshot

View File

@ -1,6 +1,6 @@
#!/bin/bash
sonic-cfggen -m /etc/sonic/minigraph.xml -t /usr/share/sonic/templates/interfaces.j2 >/etc/network/interfaces
sonic-cfggen -d -t /usr/share/sonic/templates/interfaces.j2 >/etc/network/interfaces
[ -f /var/run/dhclient.eth0.pid ] && kill `cat /var/run/dhclient.eth0.pid` && rm -f /var/run/dhclient.eth0.pid
service networking restart
ifdown lo && ifup lo

View File

@ -10,34 +10,36 @@
auto lo
iface lo inet loopback
# Use command 'ip addr list dev lo' to check all addresses
{% for minigraph_lo_interface in minigraph_lo_interfaces %}
iface lo {{ 'inet' if minigraph_lo_interface['addr'] | ipv4 else 'inet6' }} static
address {{ minigraph_lo_interface['addr'] }}
netmask {{ minigraph_lo_interface['mask'] }}
{% for (name, prefix) in LOOPBACK_INTERFACE %}
iface lo {{ 'inet' if prefix | ipv4 else 'inet6' }} static
address {{ prefix | ip }}
netmask {{ prefix | netmask if prefix | ipv4 else prefix | prefixlen }}
#
{% endfor %}
{% endblock loopback %}
{% block mgmt_interface %}
# The management network interface
auto eth0
{% if minigraph_mgmt_interface['addr'] %}
iface eth0 inet static
address {{ minigraph_mgmt_interface['addr'] }}
netmask {{ minigraph_mgmt_interface['mask'] }}
{% if MGMT_INTERFACE %}
{% for (name, prefix) in MGMT_INTERFACE %}
iface eth0 {{ 'inet' if prefix | ipv4 else 'inet6' }} static
address {{ prefix | ip }}
netmask {{ prefix | netmask if prefix | ipv4 else prefix | prefixlen }}
########## management network policy routing rules
# management port up rules
up ip route add default via {{ minigraph_mgmt_interface['gwaddr'] }} dev eth0 table default
up ip rule add from {{ minigraph_mgmt_interface['addr'] }}/32 table default
{% for prefix in forced_mgmt_routes %}
up ip rule add to {{ prefix }} table default
up ip route add default via {{ MGMT_INTERFACE[(name, prefix)]['gwaddr'] }} dev eth0 table default
up ip rule add from {{ prefix | ip }}/32 table default
{% for route in MGMT_INTERFACE[(name, prefix)]['forced_mgmt_routes'] %}
up ip rule add to {{ route }} table default
{% endfor %}
# management port down rules
down ip route delete default via {{ minigraph_mgmt_interface['gwaddr'] }} dev eth0 table default
down ip rule delete from {{ minigraph_mgmt_interface['addr'] }}/32 table default
{% for prefix in forced_mgmt_routes %}
down ip rule delete to {{ prefix }} table default
down ip route delete default via {{ MGMT_INTERFACE[(name, prefix)]['gwaddr'] }} dev eth0 table default
down ip rule delete from {{ prefix | ip }}/32 table default
{% for route in MGMT_INTERFACE[(name, prefix)]['forced_mgmt_routes'] %}
down ip rule delete to {{ route }} table default
{% endfor %}
{# TODO: COPP policy type rules #}
{% endfor %}
{% else %}
iface eth0 inet dhcp
{% endif %}
@ -45,19 +47,18 @@ iface eth0 inet dhcp
{% endblock mgmt_interface %}
{% block front_panel_interfaces %}
# The switch front panel interfaces
{% for interface in minigraph_interfaces %}
allow-hotplug {{ interface['attachto'] }}
iface {{ interface['attachto'] }} {{ 'inet' if interface['addr'] | ipv4 else 'inet6' }} static
{% for (name, prefix) in INTERFACE %}
allow-hotplug {{ name }}
iface {{ name }} {{ 'inet' if prefix | ipv4 else 'inet6' }} static
mtu 9216
address {{ interface['addr'] }}
netmask {{ interface['mask'] }}
address {{ prefix | ip }}
netmask {{ prefix | netmask if prefix | ipv4 else prefix | prefixlen }}
#
{% endfor %}
{% if minigraph_vlans.keys() | length %}
{% if VLAN %}
# "|| true" is added to suppress the error when interface is already a member of VLAN
{% endif %}
{% for vlan in minigraph_vlans.keys()|sort %}
{% for member in minigraph_vlans[vlan]['members'] %}
{% for vlan in VLAN.keys()|sort %}
{% for member in VLAN[vlan]['members'] %}
allow-hotplug {{ member }}
iface {{ member }} inet manual
pre-up ifconfig {{ member }} up mtu 9216
@ -66,12 +67,12 @@ iface {{ member }} inet manual
#
{% endfor %}
{% endfor %}
{% if minigraph_portchannels.keys() | length %}
{% endif %}
{% if PORTCHANNEL %}
# "|| true" is added to suppress the error when interface is already a member of LAG
# "ip link show | grep -q master" is added to ensure interface is enslaved
{% endif %}
{% for pc in minigraph_portchannels.keys()|sort %}
{% for member in minigraph_portchannels[pc]['members'] %}
{% for pc in PORTCHANNEL.keys()|sort %}
{% for member in PORTCHANNEL[pc]['members'] %}
allow-hotplug {{ member }}
iface {{ member }} inet manual
pre-up teamdctl {{ pc }} port add {{ member }} || true
@ -80,30 +81,31 @@ iface {{ member }} inet manual
#
{% endfor %}
{% endfor %}
{% endif %}
{% endblock front_panel_interfaces %}
{% if minigraph_vlans.keys() | length %}
{% block vlan_interfaces %}
{% if VLAN_INTERFACE %}
# Vlan interfaces
{% for vlan_interface in minigraph_vlan_interfaces %}
auto {{ vlan_interface['attachto'] }}
iface {{ vlan_interface['attachto'] }} {{ 'inet' if vlan_interface['addr'] | ipv4 else 'inet6' }} static
{% for (name, prefix) in VLAN_INTERFACE.keys() | sort %}
auto {{ name }}
iface {{ name }} {{ 'inet' if prefix | ipv4 else 'inet6' }} static
bridge_ports none
address {{ vlan_interface['addr'] }}
netmask {{ vlan_interface['mask'] }}
address {{ prefix | ip }}
netmask {{ prefix | netmask if prefix | ipv4 else prefix | prefixlen }}
{% endfor %}
#
{% endif %}
{% endblock vlan_interfaces %}
{% endif %}
{% if minigraph_portchannels.keys() | length %}
{% block pc_interfaces %}
{% if PORTCHANNEL_INTERFACE %}
# Portchannel interfaces
{% for pc_interface in minigraph_portchannel_interfaces %}
allow-hotplug {{ pc_interface['attachto'] }}
iface {{ pc_interface['attachto'] }} {{ 'inet' if pc_interface['addr'] | ipv4 else 'inet6' }} static
{% for (name, prefix) in PORTCHANNEL_INTERFACE.keys() | sort %}
allow-hotplug {{ name }}
iface {{ name }} {{ 'inet' if prefix | ipv4 else 'inet6' }} static
mtu 9216
address {{ pc_interface['addr'] }}
netmask {{ pc_interface['mask'] }}
address {{ prefix | ip }}
netmask {{ prefix | netmask if prefix | ipv4 else prefix | prefixlen }}
#
{% endfor %}
{% endblock pc_interfaces %}
{% endif %}
{% endblock pc_interfaces %}

View File

@ -1,6 +1,8 @@
[Unit]
Description=Update NTP configuration
Before=ntp.service
Requires=database.service
After=database.service
[Service]
Type=oneshot

View File

@ -1,3 +1,3 @@
#!/bin/bash
sonic-cfggen -m /etc/sonic/minigraph.xml -t /usr/share/sonic/templates/ntp.conf.j2 >/etc/ntp.conf
sonic-cfggen -d -t /usr/share/sonic/templates/ntp.conf.j2 >/etc/ntp.conf

View File

@ -23,13 +23,15 @@ filegen clockstats file clockstats type day enable
# pool.ntp.org maps to about 1000 low-stratum NTP servers. Your server will
# pick a different set every time it starts up. Please consider joining the
# pool: <http://www.pool.ntp.org/join.html>
{% for ntp_server in ntp_servers %}
{% for ntp_server in NTP_SERVER %}
server {{ ntp_server }} iburst
{% endfor %}
#only listen on localhost and eth0 ips (default is to listen on all ip addresses)
interface ignore wildcard
interface listen {{ minigraph_mgmt_interface.addr }}
{% for (mgmt_intf, mgmt_prefix) in MGMT_INTERFACE %}
interface listen {{ mgmt_prefix | ip }}
{% endfor %}
interface listen 127.0.0.1
# Access control configuration; see /usr/share/doc/ntp-doc/html/accopt.html for

View File

@ -1,5 +1,7 @@
[Unit]
Description=Update rsyslog configuration
Requires=database.service
After=database.service
[Service]
Type=oneshot

View File

@ -1,4 +1,4 @@
#!/bin/bash
sonic-cfggen -m /etc/sonic/minigraph.xml -t /usr/share/sonic/templates/rsyslog.conf.j2 >/etc/rsyslog.conf
sonic-cfggen -d -t /usr/share/sonic/templates/rsyslog.conf.j2 >/etc/rsyslog.conf
systemctl restart rsyslog

View File

@ -41,7 +41,7 @@ $template SONiCFileFormat,"%timegenerated%.%timegenerated:::date-subseconds% %HO
$ActionFileDefaultTemplate SONiCFileFormat
#Set remote syslog server
{% for server in syslog_servers %}
{% for server in SYSLOG_SERVER %}
*.* @{{ server }}:514;SONiCFileFormat
{% endfor %}

View File

@ -1,8 +1,6 @@
[Unit]
Description=download minigraph from graph service
Before=ntp-config.service
Before=rsyslog-config.service
Before=interfaces-config.service
Before=database.service
[Service]
Type=oneshot

View File

@ -91,18 +91,20 @@ def parse_png(png, hname):
if enddevice == hname:
if port_alias_map.has_key(endport):
endport = port_alias_map[endport]
neighbors[endport] = {'name': startdevice, 'port': startport}
neighbors[startdevice] = {'local_port': endport, 'port': startport}
else:
if port_alias_map.has_key(startport):
startport = port_alias_map[startport]
neighbors[startport] = {'name': enddevice, 'port': endport}
neighbors[enddevice] = {'local_port': startport, 'port': endport}
if child.tag == str(QName(ns, "Devices")):
for device in child.findall(str(QName(ns, "Device"))):
(lo_prefix, mgmt_prefix, name, hwsku, d_type) = parse_device(device)
lo_addr = None if not lo_prefix else lo_prefix.split('/')[0]
mgmt_addr = None if not mgmt_prefix else mgmt_prefix.split('/')[0]
devices[name] = {'lo_addr': lo_addr, 'type': d_type, 'mgmt_addr': mgmt_addr, 'hwsku': hwsku}
device_data = {'lo_addr': lo_prefix, 'type': d_type, 'mgmt_addr': mgmt_prefix, 'hwsku': hwsku }
if neighbors.has_key(name):
neighbors[name].update(device_data)
else:
devices[name] = device_data
if child.tag == str(QName(ns, "DeviceInterfaceLinks")):
for if_link in child.findall(str(QName(ns, 'DeviceLinkBase'))):
@ -131,71 +133,28 @@ def parse_dpg(dpg, hname):
continue
ipintfs = child.find(str(QName(ns, "IPInterfaces")))
intfs = []
intfs = {}
for ipintf in ipintfs.findall(str(QName(ns, "IPInterface"))):
intfalias = ipintf.find(str(QName(ns, "AttachTo"))).text
intfname = port_alias_map.get(intfalias, intfalias)
ipprefix = ipintf.find(str(QName(ns, "Prefix"))).text
ipn = ipaddress.IPNetwork(ipprefix)
ipaddr = ipn.ip
prefix_len = ipn.prefixlen
addr_bits = ipn.max_prefixlen
subnet = ipaddress.IPNetwork(str(ipn.network) + '/' + str(prefix_len))
ipmask = ipn.netmask
intf = {'addr': ipaddr, 'subnet': subnet}
if isinstance(ipn, ipaddress.IPv4Network):
intf['mask'] = ipmask
else:
intf['mask'] = str(prefix_len)
intf.update({'attachto': intfname, 'prefixlen': int(prefix_len)})
# TODO: remove peer_addr after dependency removed
ipaddr_val = int(ipn.ip)
peer_addr_val = None
if int(prefix_len) == addr_bits - 2:
if ipaddr_val & 0x3 == 1:
peer_addr_val = ipaddr_val + 1
else:
peer_addr_val = ipaddr_val - 1
elif int(prefix_len) == addr_bits - 1:
if ipaddr_val & 0x1 == 0:
peer_addr_val = ipaddr_val + 1
else:
peer_addr_val = ipaddr_val - 1
if peer_addr_val is not None:
intf['peer_addr'] = ipaddress.IPAddress(peer_addr_val)
intfs.append(intf)
intfs[(intfname, ipprefix)] = {}
lointfs = child.find(str(QName(ns, "LoopbackIPInterfaces")))
lo_intfs = []
lo_intfs = {}
for lointf in lointfs.findall(str(QName(ns1, "LoopbackIPInterface"))):
intfname = lointf.find(str(QName(ns, "AttachTo"))).text
ipprefix = lointf.find(str(QName(ns1, "PrefixStr"))).text
ipn = ipaddress.IPNetwork(ipprefix)
ipaddr = ipn.ip
prefix_len = ipn.prefixlen
ipmask = ipn.netmask
lo_intf = {'name': intfname, 'addr': ipaddr, 'prefixlen': prefix_len}
if isinstance(ipn, ipaddress.IPv4Network):
lo_intf['mask'] = ipmask
else:
lo_intf['mask'] = str(prefix_len)
lo_intfs.append(lo_intf)
lo_intfs[(intfname, ipprefix)] = {}
mgmtintfs = child.find(str(QName(ns, "ManagementIPInterfaces")))
mgmt_intf = None
mgmt_intf = {}
for mgmtintf in mgmtintfs.findall(str(QName(ns1, "ManagementIPInterface"))):
intfname = mgmtintf.find(str(QName(ns, "AttachTo"))).text
ipprefix = mgmtintf.find(str(QName(ns1, "PrefixStr"))).text
mgmtipn = ipaddress.IPNetwork(ipprefix)
# Ignore IPv6 management address
if mgmtipn.version == 6:
continue
ipaddr = mgmtipn.ip
prefix_len = str(mgmtipn.prefixlen)
ipmask = mgmtipn.netmask
gwaddr = ipaddress.IPAddress(int(mgmtipn.network) + 1)
mgmt_intf = {'addr': ipaddr, 'prefixlen': prefix_len, 'mask': ipmask, 'gwaddr': gwaddr}
mgmt_intf[(intfname, ipprefix)] = {'gwaddr': gwaddr}
pcintfs = child.find(str(QName(ns, "PortChannelInterfaces")))
pc_intfs = []
@ -206,7 +165,7 @@ def parse_dpg(dpg, hname):
pcmbr_list = pcintfmbr.split(';')
for i, member in enumerate(pcmbr_list):
pcmbr_list[i] = port_alias_map.get(member, member)
pcs[pcintfname] = {'name': pcintfname, 'members': pcmbr_list}
pcs[pcintfname] = {'members': pcmbr_list}
vlanintfs = child.find(str(QName(ns, "VlanInterfaces")))
vlan_intfs = []
@ -218,7 +177,7 @@ def parse_dpg(dpg, hname):
vmbr_list = vintfmbr.split(';')
for i, member in enumerate(vmbr_list):
vmbr_list[i] = port_alias_map.get(member, member)
vlan_attributes = {'name': vintfname, 'members': vmbr_list, 'vlanid': vlanid}
vlan_attributes = {'members': vmbr_list, 'vlanid': vlanid}
sonic_vlan_name = "Vlan%s" % vlanid
vlans[sonic_vlan_name] = vlan_attributes
@ -243,7 +202,7 @@ def parse_dpg(dpg, hname):
acl_intfs = port_alias_map.values()
break;
if acl_intfs:
acls[aclname] = { 'AttachTo': acl_intfs, 'IsMirror': is_mirror }
acls[aclname] = { 'policy_desc': aclname, 'ports': acl_intfs, 'type': 'mirror' if is_mirror else 'L3'}
return intfs, lo_intfs, mgmt_intf, vlans, pcs, acls
return None, None, None, None, None, None
@ -326,51 +285,17 @@ def parse_meta(meta, hname):
return syslog_servers, dhcp_servers, ntp_servers, mgmt_routes, erspan_dst, deployment_id
def parse_deviceinfo(meta, hwsku):
ethernet_interfaces = []
ethernet_interfaces = {}
for device_info in meta.findall(str(QName(ns, "DeviceInfo"))):
dev_sku = device_info.find(str(QName(ns, "HwSku"))).text
if dev_sku == hwsku:
interfaces = device_info.find(str(QName(ns, "EthernetInterfaces")))
for interface in interfaces.findall(str(QName(ns1, "EthernetInterface"))):
name = interface.find(str(QName(ns, "InterfaceName"))).text
alias = interface.find(str(QName(ns, "InterfaceName"))).text
speed = interface.find(str(QName(ns, "Speed"))).text
ethernet_interfaces.append({ 'name':name, 'speed':speed })
ethernet_interfaces[port_alias_map.get(alias, alias)] = speed
return ethernet_interfaces
def get_console_info(devices, dev, port):
for k, v in devices.items():
if k == dev:
break
else:
return {}
ret_val = v
ret_val.update({
'ts_port': port,
'ts_dev': dev
})
return ret_val
def get_mgmt_info(devices, dev, port):
for k, v in devices.items():
if k == dev:
break
else:
return {}
ret_val = v
ret_val.update({
'mgmt_port': port,
'mgmt_dev': dev
})
return ret_val
def parse_port_config(hwsku, platform=None, port_config_file=None):
port_config_candidates = []
if port_config_file != None:
@ -401,7 +326,7 @@ def parse_port_config(hwsku, platform=None, port_config_file=None):
alias = name
else:
alias = tokens[2].strip()
ports[name] = {'name': name, 'alias': alias}
ports[name] = {'alias': alias}
port_alias_map[alias] = name
return ports
@ -424,7 +349,7 @@ def parse_xml(filename, platform=None, port_config_file=None):
neighbors = None
devices = None
hostname = None
ethernet_interfaces = []
port_speeds = {}
syslog_servers = []
dhcp_servers = []
ntp_servers = []
@ -455,93 +380,91 @@ def parse_xml(filename, platform=None, port_config_file=None):
elif child.tag == str(QName(ns, "MetadataDeclaration")):
(syslog_servers, dhcp_servers, ntp_servers, mgmt_routes, erspan_dst, deployment_id) = parse_meta(child, hostname)
elif child.tag == str(QName(ns, "DeviceInfos")):
ethernet_interfaces = parse_deviceinfo(child, hwsku)
port_speeds = parse_deviceinfo(child, hwsku)
results = {}
results['minigraph_hwsku'] = hwsku
# 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['DEVICE_METADATA'] = {'localhost': {
'bgp_asn': bgp_asn,
'deployment_id': deployment_id,
'hostname': hostname,
'hwsku': hwsku,
'type': devices[hostname]['type']
}}
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).
if mgmt_routes:
# TODO: differentiate v4 and v6
mgmt_intf.itervalues().next()['forced_mgmt_routes'] = mgmt_routes
results['MGMT_INTERFACE'] = mgmt_intf
results['LOOPBACK_INTERFACE'] = lo_intfs
phyport_intfs = []
vlan_intfs = []
pc_intfs = []
phyport_intfs = {}
vlan_intfs = {}
pc_intfs = {}
for intf in intfs:
intfname = intf['attachto']
if intfname[0:4] == 'Vlan':
vlan_intfs.append(intf)
elif intfname[0:11] == 'PortChannel':
pc_intfs.append(intf)
if intf[0][0:4] == 'Vlan':
vlan_intfs[intf] = {}
elif intf[0][0:11] == 'PortChannel':
pc_intfs[intf] = {}
else:
phyport_intfs.append(intf)
phyport_intfs[intf] = {}
results['minigraph_interfaces'] = sorted(phyport_intfs, key=lambda x: x['attachto'])
results['minigraph_vlan_interfaces'] = sorted(vlan_intfs, key=lambda x: x['attachto'])
results['minigraph_portchannel_interfaces'] = sorted(pc_intfs, key=lambda x: x['attachto'])
results['minigraph_ports'] = ports
results['minigraph_vlans'] = vlans
results['minigraph_portchannels'] = pcs
results['minigraph_mgmt_interface'] = mgmt_intf
results['minigraph_lo_interfaces'] = lo_intfs
results['minigraph_acls'] = acls
results['minigraph_neighbors'] = neighbors
results['minigraph_devices'] = devices
results['minigraph_underlay_neighbors'] = u_neighbors
results['minigraph_underlay_devices'] = u_devices
results['minigraph_as_xml'] = mini_graph_path
if devices != None:
results['minigraph_console'] = get_console_info(devices, console_dev, console_port)
results['minigraph_mgmt'] = get_mgmt_info(devices, mgmt_dev, mgmt_port)
results['minigraph_hostname'] = hostname
results['inventory_hostname'] = hostname
results['syslog_servers'] = syslog_servers
results['dhcp_servers'] = dhcp_servers
results['ntp_servers'] = ntp_servers
results['forced_mgmt_routes'] = mgmt_routes
results['erspan_dst'] = erspan_dst
results['deployment_id'] = deployment_id
results['ethernet_interfaces'] = ethernet_interfaces
results['INTERFACE'] = phyport_intfs
results['VLAN_INTERFACE'] = vlan_intfs
results['PORTCHANNEL_INTERFACE'] = pc_intfs
for port_name in port_speeds:
ports.setdefault(port_name, {})['speed'] = port_speeds[port_name]
results['PORT'] = ports
results['PORTCHANNEL'] = pcs
results['VLAN'] = vlans
results['DEVICE_NEIGHBOR'] = neighbors
results['SYSLOG_SERVER'] = dict((item, {}) for item in syslog_servers)
results['DHCP_SERVER'] = dict((item, {}) for item in dhcp_servers)
results['NTP_SERVER'] = dict((item, {}) for item in ntp_servers)
results['ACL_TABLE'] = acls
mirror_sessions = {}
if erspan_dst:
lo_addr = '0.0.0.0'
for lo in lo_intfs:
lo_network = ipaddress.IPNetwork(lo[1])
if lo_network.version == 4:
lo_addr = str(lo_network.ip)
break
count = 0
for dst in erspan_dst:
mirror_sessions['everflow{}'.format(count)] = {"dst_ip": dst, "src_ip": lo_addr}
count += 1
results['MIRROR_SESSION'] = mirror_sessions
return results
def parse_device_desc_xml(filename):
root = ET.parse(filename).getroot()
(lo_prefix, mgmt_prefix, hostname, hwsku, d_type) = parse_device(root)
results = {}
results['minigraph_hwsku'] = hwsku
results['minigraph_hostname'] = hostname
results['inventory_hostname'] = hostname
results['DEVICE_METADATA'] = {'localhost': {
'hostname': hostname,
'hwsku': hwsku,
}}
lo_intfs = []
ipn = ipaddress.IPNetwork(lo_prefix)
ipaddr = ipn.ip
prefix_len = ipn.prefixlen
ipmask = ipn.netmask
lo_intf = {'name': None, 'addr': ipaddr, 'prefixlen': prefix_len}
if isinstance(ipn, ipaddress.IPv4Network):
lo_intf['mask'] = ipmask
else:
lo_intf['mask'] = str(prefix_len)
lo_intfs.append(lo_intf)
results['minigraph_lo_interfaces'] = lo_intfs
results['LOOPBACK_INTERFACE'] = {('lo', lo_prefix): {}}
mgmt_intf = {}
mgmtipn = ipaddress.IPNetwork(mgmt_prefix)
gwaddr = ipaddress.IPAddress(int(mgmtipn.network) + 1)
results['MGMT_INTERFACE'] = {('eth0', mgmt_prefix): {'gwaddr': gwaddr}}
mgmt_intf = None
mgmt_ipn = ipaddress.IPNetwork(mgmt_prefix)
ipaddr = mgmt_ipn.ip
prefix_len = str(mgmt_ipn.prefixlen)
ipmask = mgmt_ipn.netmask
gwaddr = ipaddress.IPAddress(int(mgmt_ipn.network) + 1)
mgmt_intf = {'addr': ipaddr, 'prefixlen': prefix_len, 'mask': ipmask, 'gwaddr': gwaddr}
results['minigraph_mgmt_interface'] = mgmt_intf
return results
port_alias_map = {}
def print_parse_xml(filename):
results = parse_xml(filename)
print(json.dumps(results, indent=3, cls=minigraph_encoder))

View File

@ -22,6 +22,7 @@ import yaml
import jinja2
import netaddr
import json
from functools import partial
from minigraph import minigraph_encoder
from minigraph import parse_xml
from minigraph import parse_device_desc_xml
@ -32,11 +33,11 @@ from swsssdk import ConfigDBConnector
def is_ipv4(value):
if not value:
return False
if isinstance(value, netaddr.IPAddress):
if isinstance(value, netaddr.IPNetwork):
addr = value
else:
try:
addr = netaddr.IPAddress(str(value))
addr = netaddr.IPNetwork(str(value))
except:
return False
return addr.version == 4
@ -44,15 +45,25 @@ def is_ipv4(value):
def is_ipv6(value):
if not value:
return False
if isinstance(value, netaddr.IPAddress):
if isinstance(value, netaddr.IPNetwork):
addr = value
else:
try:
addr = netaddr.IPAddress(str(value))
addr = netaddr.IPNetwork(str(value))
except:
return False
return addr.version == 6
def prefix_attr(attr, value):
if not value:
return None
else:
try:
prefix = netaddr.IPNetwork(str(value))
except:
return None
return str(getattr(prefix, attr))
def unique_name(l):
name_list = []
new_list = []
@ -79,10 +90,31 @@ TODO(taoyl): Current version of config db only supports BGP admin states.
def output_to_db(output_data):
db_data = {}
for table_name in output_data:
if table_name == 'BGP_NEIGHBOR' or table_name == 'BGP_PEER_RANGE' or table_name == 'DEVICE_METADATA':
if table_name[0].isupper():
db_data[table_name] = output_data[table_name]
return db_data
@staticmethod
def to_serialized(data):
for table in data:
if type(data[table]) is dict:
for key in data[table].keys():
new_key = ConfigDBConnector.serialize_key(key)
if new_key != key:
data[table][new_key] = data[table].pop(key)
return data
@staticmethod
def to_deserialized(data):
for table in data:
if type(data[table]) is dict:
for key in data[table].keys():
new_key = ConfigDBConnector.deserialize_key(key)
if new_key != key:
data[table][new_key] = data[table].pop(key)
return data
def deep_update(dst, src):
for key, value in src.iteritems():
if isinstance(value, dict):
@ -138,11 +170,11 @@ def main():
for yaml_file in args.yaml:
with open(yaml_file, 'r') as stream:
additional_data = yaml.load(stream)
deep_update(data, additional_data)
deep_update(data, FormatConverter.to_deserialized(additional_data))
for json_file in args.json:
with open(json_file, 'r') as stream:
deep_update(data, json.load(stream))
deep_update(data, FormatConverter.to_deserialized(json.load(stream)))
if args.additional_data != None:
deep_update(data, json.loads(args.additional_data))
@ -158,6 +190,8 @@ def main():
env.filters['ipv4'] = is_ipv4
env.filters['ipv6'] = is_ipv6
env.filters['unique_name'] = unique_name
for attr in ['ip', 'network', 'prefixlen', 'netmask']:
env.filters[attr] = partial(prefix_attr, attr)
template = env.get_template(template_file)
print template.render(data)
@ -174,7 +208,7 @@ def main():
configdb.set_config(FormatConverter.output_to_db(data))
if args.print_data:
print json.dumps(data, indent=4, cls=minigraph_encoder)
print json.dumps(FormatConverter.to_serialized(data), indent=4, cls=minigraph_encoder)
if __name__ == "__main__":

View File

@ -27,6 +27,16 @@ iface eth0 inet static
# management port down rules
down ip route delete default via 10.0.0.1 dev eth0 table default
down ip rule delete from 10.0.0.100/32 table default
iface eth0 inet6 static
address 2603:10e2:0:2902::8
netmask 64
########## management network policy routing rules
# management port up rules
up ip route add default via 2603:10e2:0:2902::1 dev eth0 table default
up ip rule add from 2603:10e2:0:2902::8/32 table default
# management port down rules
down ip route delete default via 2603:10e2:0:2902::1 dev eth0 table default
down ip rule delete from 2603:10e2:0:2902::8/32 table default
#
# The switch front panel interfaces
# "|| true" is added to suppress the error when interface is already a member of VLAN

View File

@ -1,6 +1,6 @@
[
{
"MIRROR_SESSION_TABLE:everflow": {
"MIRROR_SESSION_TABLE:everflow0": {
"src_ip": "10.1.0.32",
"dst_ip": "2.2.2.2",
"gre_type": "0x88be",

View File

@ -31,17 +31,17 @@ class TestCfgGen(TestCase):
self.assertEqual(output, '')
def test_device_desc(self):
argument = '-v minigraph_hwsku -M "' + self.sample_device_desc + '"'
argument = '-v "DEVICE_METADATA[\'localhost\'][\'hwsku\']" -M "' + self.sample_device_desc + '"'
output = self.run_script(argument)
self.assertEqual(output.strip(), 'ACS-MSN2700')
def test_device_desc_mgmt_ip(self):
argument = '-v "minigraph_mgmt_interface[\'addr\']" -M "' + self.sample_device_desc + '"'
argument = '-v "MGMT_INTERFACE.keys()[0]" -M "' + self.sample_device_desc + '"'
output = self.run_script(argument)
self.assertEqual(output.strip(), '10.0.1.5')
self.assertEqual(output.strip(), "('eth0', '10.0.1.5/28')")
def test_minigraph_sku(self):
argument = '-v minigraph_hwsku -m "' + self.sample_graph + '"'
argument = '-v "DEVICE_METADATA[\'localhost\'][\'hwsku\']" -m "' + self.sample_graph + '"'
output = self.run_script(argument)
self.assertEqual(output.strip(), 'Force10-Z9100')
@ -51,7 +51,7 @@ class TestCfgGen(TestCase):
self.assertTrue(len(output.strip()) > 0)
def test_jinja_expression(self):
argument = '-m "' + self.sample_graph + '" -v "minigraph_devices[minigraph_hostname][\'type\']"'
argument = '-m "' + self.sample_graph + '" -v "DEVICE_METADATA[\'localhost\'][\'type\']"'
output = self.run_script(argument)
self.assertEqual(output.strip(), 'LeafRouter')
@ -71,44 +71,44 @@ class TestCfgGen(TestCase):
self.assertEqual(output.strip(), 'value1\nvalue2')
def test_minigraph_acl(self):
argument = '-m "' + self.sample_graph_t0 + '" -p "' + self.port_config + '" -v minigraph_acls'
argument = '-m "' + self.sample_graph_t0 + '" -p "' + self.port_config + '" -v ACL_TABLE'
output = self.run_script(argument)
self.assertEqual(output.strip(), "{'dataacl': {'IsMirror': False, 'AttachTo': ['Ethernet112', 'Ethernet116', 'Ethernet120', 'Ethernet124']}}")
self.assertEqual(output.strip(), "{'dataacl': {'type': 'L3', 'policy_desc': 'dataacl', 'ports': ['Ethernet112', 'Ethernet116', 'Ethernet120', 'Ethernet124']}}")
def test_minigraph_interfaces(self):
argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v minigraph_interfaces'
argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v \'INTERFACE.keys()\''
output = self.run_script(argument)
self.assertEqual(output.strip(), "[{'subnet': IPv4Network('10.0.0.58/31'), 'peer_addr': IPv4Address('10.0.0.59'), 'addr': IPv4Address('10.0.0.58'), 'mask': IPv4Address('255.255.255.254'), 'attachto': 'Ethernet0', 'prefixlen': 31}, {'subnet': IPv6Network('fc00::74/126'), 'peer_addr': IPv6Address('fc00::76'), 'addr': IPv6Address('fc00::75'), 'mask': '126', 'attachto': 'Ethernet0', 'prefixlen': 126}]")
self.assertEqual(output.strip(), "[('Ethernet0', '10.0.0.58/31'), ('Ethernet0', 'FC00::75/126')]")
def test_minigraph_vlans(self):
argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v minigraph_vlans'
argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v VLAN'
output = self.run_script(argument)
self.assertEqual(output.strip(), "{'Vlan1000': {'name': 'Vlan1000', 'members': ['Ethernet8'], 'vlanid': '1000'}}")
self.assertEqual(output.strip(), "{'Vlan1000': {'members': ['Ethernet8'], 'vlanid': '1000'}}")
def test_minigraph_vlan_interfaces(self):
argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v minigraph_vlan_interfaces'
argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v "VLAN_INTERFACE.keys()"'
output = self.run_script(argument)
self.assertEqual(output.strip(), "[{'prefixlen': 27, 'subnet': IPv4Network('192.168.0.0/27'), 'mask': IPv4Address('255.255.255.224'), 'addr': IPv4Address('192.168.0.1'), 'attachto': 'Vlan1000'}]")
self.assertEqual(output.strip(), "[('Vlan1000', '192.168.0.1/27')]")
def test_minigraph_portchannels(self):
argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v minigraph_portchannels'
argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v PORTCHANNEL'
output = self.run_script(argument)
self.assertEqual(output.strip(), "{'PortChannel01': {'name': 'PortChannel01', 'members': ['Ethernet4']}}")
self.assertEqual(output.strip(), "{'PortChannel01': {'members': ['Ethernet4']}}")
def test_minigraph_portchannels_more_member(self):
argument = '-m "' + self.sample_graph_pc_test + '" -p "' + self.port_config + '" -v minigraph_portchannels'
argument = '-m "' + self.sample_graph_pc_test + '" -p "' + self.port_config + '" -v PORTCHANNEL'
output = self.run_script(argument)
self.assertEqual(output.strip(), "{'PortChannel01': {'name': 'PortChannel01', 'members': ['Ethernet112', 'Ethernet116', 'Ethernet120', 'Ethernet124']}}")
self.assertEqual(output.strip(), "{'PortChannel01': {'members': ['Ethernet112', 'Ethernet116', 'Ethernet120', 'Ethernet124']}}")
def test_minigraph_portchannel_interfaces(self):
argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v minigraph_portchannel_interfaces'
argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v "PORTCHANNEL_INTERFACE.keys()"'
output = self.run_script(argument)
self.assertEqual(output.strip(), "[{'subnet': IPv4Network('10.0.0.56/31'), 'peer_addr': IPv4Address('10.0.0.57'), 'addr': IPv4Address('10.0.0.56'), 'mask': IPv4Address('255.255.255.254'), 'attachto': 'PortChannel01', 'prefixlen': 31}, {'subnet': IPv6Network('fc00::70/126'), 'peer_addr': IPv6Address('fc00::72'), 'addr': IPv6Address('fc00::71'), 'mask': '126', 'attachto': 'PortChannel01', 'prefixlen': 126}]")
self.assertEqual(output.strip(), "[('PortChannel01', 'FC00::71/126'), ('PortChannel01', '10.0.0.56/31')]")
def test_minigraph_neighbors(self):
argument = '-m "' + self.sample_graph_t0 + '" -p "' + self.port_config + '" -v minigraph_neighbors'
argument = '-m "' + self.sample_graph_t0 + '" -p "' + self.port_config + '" -v "DEVICE_NEIGHBOR[\'ARISTA01T1\']"'
output = self.run_script(argument)
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'}}")
self.assertEqual(output.strip(), "{'mgmt_addr': None, 'hwsku': 'Arista', 'lo_addr': None, 'local_port': 'Ethernet112', 'type': 'LeafRouter', 'port': 'Ethernet1/1'}")
def test_minigraph_peers_with_range(self):
argument = '-m "' + self.sample_graph_bgp_speaker + '" -p "' + self.port_config + '" -v BGP_PEER_RANGE.values\(\)'
@ -116,11 +116,11 @@ class TestCfgGen(TestCase):
self.assertEqual(output.strip(), "[{'name': 'BGPSLBPassive', 'ip_range': ['10.10.10.10/26', '100.100.100.100/26']}]")
def test_minigraph_deployment_id(self):
argument = '-m "' + self.sample_graph_bgp_speaker + '" -p "' + self.port_config + '" -v deployment_id'
argument = '-m "' + self.sample_graph_bgp_speaker + '" -p "' + self.port_config + '" -v "DEVICE_METADATA[\'localhost\'][\'deployment_id\']"'
output = self.run_script(argument)
self.assertEqual(output.strip(), "1")
def test_minigraph_ethernet_interfaces(self):
argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v ethernet_interfaces'
argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v "PORT[\'Ethernet8\']"'
output = self.run_script(argument)
self.assertEqual(output.strip(), "[{'speed': '10000', 'name': 'fortyGigE0/0'}, {'speed': '25000', 'name': 'fortyGigE0/4'}, {'speed': '40000', 'name': 'fortyGigE0/8'}, {'speed': '1000000', 'name': 'fortyGigE0/12'}]")
self.assertEqual(output.strip(), "{'alias': 'fortyGigE0/8', 'speed': '40000'}")

View File

@ -40,7 +40,7 @@ class TestJ2Files(TestCase):
self.assertTrue(filecmp.cmp(sample_output, self.output_file))
# Test T0 minigraph
argument = '-m ' + self.t0_minigraph + ' -p ' + self.t0_port_config + ' -v "minigraph_portchannels.keys() | join(\' \')"'
argument = '-m ' + self.t0_minigraph + ' -p ' + self.t0_port_config + ' -v "PORTCHANNEL.keys() | join(\' \') if PORTCHANNEL"'
output = self.run_script(argument) # Mock the output via config.sh in docker-teamd
pc_list = output.split()
@ -51,7 +51,7 @@ class TestJ2Files(TestCase):
test_render_teamd(self, pc_name, self.t0_minigraph, sample_output)
# Test port channel test minigraph
argument = '-m ' + self.pc_minigraph + ' -p ' + self.t0_port_config + ' -v "minigraph_portchannels.keys() | join(\' \')"'
argument = '-m ' + self.pc_minigraph + ' -p ' + self.t0_port_config + ' -v "PORTCHANNEL.keys() | join(\' \') if PORTCHANNEL"'
output = self.run_script(argument) # Mock the output via config.sh in docker-teamd
pc_list = output.split()

View File

@ -110,13 +110,14 @@ def generate_rule_json(table_name, rule, max_priority, mirror):
rule_props["TCP_FLAGS"] = '0x{:02x}/0x{:02x}'.format(tcp_flags, tcp_flags)
return rule_data
def generate_table_json(aclset, aclname, ports, mirror, max_priority, output_path='.'):
def generate_table_json(aclset, aclname, ports, t_type, max_priority, output_path='.'):
table_name = aclname.replace(" ", "_").replace("-", "_")
#table_name = generate_random_table_name()
mirror = (t_type == 'mirror')
table_props = {}
table_props["policy_desc"] = table_name
table_props["type"] = "mirror" if mirror else "L3"
table_props["type"] = t_type
table_props["ports"] = ports
table_data = [{}]
@ -138,7 +139,7 @@ def translate_acl_fixed_port(filename, output_path, port, max_priority):
yang_acl = pybindJSON.load(filename, openconfig_acl, "openconfig_acl")
for aclsetname in yang_acl.acl.acl_sets.acl_set:
aclset = yang_acl.acl.acl_sets.acl_set[aclsetname]
generate_table_json(aclset, aclsetname, port, max_priority, output_path)
generate_table_json(aclset, aclsetname, port, 'l3', max_priority, output_path)
return
def translate_acl(filename, output_path, mini_acl, max_priority):
@ -146,10 +147,10 @@ def translate_acl(filename, output_path, mini_acl, max_priority):
for aclsetname in yang_acl.acl.acl_sets.acl_set:
tablename = aclsetname.replace(" ", "_").replace("-", "_")
if mini_acl.has_key(tablename):
is_mirror = mini_acl[tablename]['IsMirror']
ports = ','.join(mini_acl[tablename]['AttachTo'])
t_type = mini_acl[tablename]['type']
ports = ','.join(mini_acl[tablename]['ports'])
aclset = yang_acl.acl.acl_sets.acl_set[aclsetname]
generate_table_json(aclset, aclsetname, ports, is_mirror, max_priority, output_path)
generate_table_json(aclset, aclsetname, ports, t_type, max_priority, output_path)
return
def main():
@ -166,8 +167,8 @@ def main():
translate_acl_fixed_port(args.input, args.output_path, args.port, args.max_priority)
elif args.minigraph:
mini_data = parse_xml(args.minigraph, port_config_file=args.port_config)
if mini_data['minigraph_acls']:
translate_acl(args.input, args.output_path, mini_data['minigraph_acls'], args.max_priority)
if mini_data['ACL_TABLE']:
translate_acl(args.input, args.output_path, mini_data['ACL_TABLE'], args.max_priority)
if __name__ == "__main__":
main()

@ -1 +1 @@
Subproject commit 9b54b80f1783808c5ae2a30e189f24a7404a8c95
Subproject commit 7f8e7c5ad9747af1d8ce5317eb1ece65ed4c0c7a