diff --git a/dockers/docker-dhcp-relay/Dockerfile.j2 b/dockers/docker-dhcp-relay/Dockerfile.j2 index a7e1a1cffb..3c6614c492 100644 --- a/dockers/docker-dhcp-relay/Dockerfile.j2 +++ b/dockers/docker-dhcp-relay/Dockerfile.j2 @@ -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"] diff --git a/dockers/docker-dhcp-relay/isc-dhcp-relay.j2 b/dockers/docker-dhcp-relay/isc-dhcp-relay.j2 index 1c50b685eb..cdedfcf969 100644 --- a/dockers/docker-dhcp-relay/isc-dhcp-relay.j2 +++ b/dockers/docker-dhcp-relay/isc-dhcp-relay.j2 @@ -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 %}" diff --git a/dockers/docker-dhcp-relay/start.sh b/dockers/docker-dhcp-relay/start.sh index 5c2e9de097..37c3f488a5 100755 --- a/dockers/docker-dhcp-relay/start.sh +++ b/dockers/docker-dhcp-relay/start.sh @@ -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 diff --git a/dockers/docker-dhcp-relay/wait_for_intf.sh.j2 b/dockers/docker-dhcp-relay/wait_for_intf.sh.j2 new file mode 100755 index 0000000000..b859a43b07 --- /dev/null +++ b/dockers/docker-dhcp-relay/wait_for_intf.sh.j2 @@ -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 %} + diff --git a/dockers/docker-fpm-frr/bgpd.conf.j2 b/dockers/docker-fpm-frr/bgpd.conf.j2 index c66d5bfb23..0f1e255b5c 100644 --- a/dockers/docker-fpm-frr/bgpd.conf.j2 +++ b/dockers/docker-fpm-frr/bgpd.conf.j2 @@ -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 %} diff --git a/dockers/docker-fpm-frr/config.sh b/dockers/docker-fpm-frr/config.sh index 0636a6dc41..ef7a13a214 100755 --- a/dockers/docker-fpm-frr/config.sh +++ b/dockers/docker-fpm-frr/config.sh @@ -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 diff --git a/dockers/docker-fpm-frr/zebra.conf.j2 b/dockers/docker-fpm-frr/zebra.conf.j2 index 1ce06eecd2..8b967f9867 100644 --- a/dockers/docker-fpm-frr/zebra.conf.j2 +++ b/dockers/docker-fpm-frr/zebra.conf.j2 @@ -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 diff --git a/dockers/docker-fpm-gobgp/gobgpd.conf.j2 b/dockers/docker-fpm-gobgp/gobgpd.conf.j2 index c6ec7a4fd1..c51c10563b 100644 --- a/dockers/docker-fpm-gobgp/gobgpd.conf.j2 +++ b/dockers/docker-fpm-gobgp/gobgpd.conf.j2 @@ -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]] diff --git a/dockers/docker-fpm-gobgp/start.sh b/dockers/docker-fpm-gobgp/start.sh index 636fceea0c..83afbda4f7 100755 --- a/dockers/docker-fpm-gobgp/start.sh +++ b/dockers/docker-fpm-gobgp/start.sh @@ -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 diff --git a/dockers/docker-fpm-gobgp/zebra.conf.j2 b/dockers/docker-fpm-gobgp/zebra.conf.j2 index 1ce06eecd2..8b967f9867 100644 --- a/dockers/docker-fpm-gobgp/zebra.conf.j2 +++ b/dockers/docker-fpm-gobgp/zebra.conf.j2 @@ -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 diff --git a/dockers/docker-fpm-quagga/bgpd.conf.j2 b/dockers/docker-fpm-quagga/bgpd.conf.j2 index 02cf40fa8b..295cb2563a 100644 --- a/dockers/docker-fpm-quagga/bgpd.conf.j2 +++ b/dockers/docker-fpm-quagga/bgpd.conf.j2 @@ -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') %} diff --git a/dockers/docker-fpm-quagga/zebra.conf.j2 b/dockers/docker-fpm-quagga/zebra.conf.j2 index 1ce06eecd2..8b967f9867 100644 --- a/dockers/docker-fpm-quagga/zebra.conf.j2 +++ b/dockers/docker-fpm-quagga/zebra.conf.j2 @@ -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 diff --git a/dockers/docker-lldp-sv2/lldpd.conf.j2 b/dockers/docker-lldp-sv2/lldpd.conf.j2 index 4cfe48065e..ffbf7e6993 100644 --- a/dockers/docker-lldp-sv2/lldpd.conf.j2 +++ b/dockers/docker-lldp-sv2/lldpd.conf.j2 @@ -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 %} diff --git a/dockers/docker-lldp-sv2/start.sh b/dockers/docker-lldp-sv2/start.sh index 63c8d32c34..3a765c6f54 100755 --- a/dockers/docker-lldp-sv2/start.sh +++ b/dockers/docker-lldp-sv2/start.sh @@ -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 diff --git a/dockers/docker-orchagent/arp_update b/dockers/docker-orchagent/arp_update index 8291818e50..cfd87c1dc5 100755 --- a/dockers/docker-orchagent/arp_update +++ b/dockers/docker-orchagent/arp_update @@ -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 ; diff --git a/dockers/docker-orchagent/ipinip.json.j2 b/dockers/docker-orchagent/ipinip.json.j2 index 6ffafd2974..2f411b088e 100644 --- a/dockers/docker-orchagent/ipinip.json.j2 +++ b/dockers/docker-orchagent/ipinip.json.j2 @@ -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", diff --git a/dockers/docker-orchagent/mirror.json.j2 b/dockers/docker-orchagent/mirror.json.j2 index 4aa710cfcb..3a3fc6eed0 100644 --- a/dockers/docker-orchagent/mirror.json.j2 +++ b/dockers/docker-orchagent/mirror.json.j2 @@ -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 %} ] diff --git a/dockers/docker-orchagent/orchagent.sh b/dockers/docker-orchagent/orchagent.sh index 328ce8fc05..7103afcb81 100755 --- a/dockers/docker-orchagent/orchagent.sh +++ b/dockers/docker-orchagent/orchagent.sh @@ -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` diff --git a/dockers/docker-orchagent/ports.json.j2 b/dockers/docker-orchagent/ports.json.j2 index f59ee993ee..48be831025 100644 --- a/dockers/docker-orchagent/ports.json.j2 +++ b/dockers/docker-orchagent/ports.json.j2 @@ -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 %} ] diff --git a/dockers/docker-orchagent/start.sh b/dockers/docker-orchagent/start.sh index 5f961a8bd2..1eba99192b 100755 --- a/dockers/docker-orchagent/start.sh +++ b/dockers/docker-orchagent/start.sh @@ -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 diff --git a/dockers/docker-orchagent/swssconfig.sh b/dockers/docker-orchagent/swssconfig.sh index 2530aca06b..c4043bd86d 100755 --- a/dockers/docker-orchagent/swssconfig.sh +++ b/dockers/docker-orchagent/swssconfig.sh @@ -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 " diff --git a/dockers/docker-snmp-sv2/alias_map.j2 b/dockers/docker-snmp-sv2/alias_map.j2 index 0f91fa26ea..bd68353a91 100644 --- a/dockers/docker-snmp-sv2/alias_map.j2 +++ b/dockers/docker-snmp-sv2/alias_map.j2 @@ -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 %} } diff --git a/dockers/docker-snmp-sv2/snmpd.conf.j2 b/dockers/docker-snmp-sv2/snmpd.conf.j2 index c5d299af05..246924cfd3 100644 --- a/dockers/docker-snmp-sv2/snmpd.conf.j2 +++ b/dockers/docker-snmp-sv2/snmpd.conf.j2 @@ -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 %} diff --git a/dockers/docker-snmp-sv2/start.sh b/dockers/docker-snmp-sv2/start.sh index ffbe8f1967..201239b1e7 100755 --- a/dockers/docker-snmp-sv2/start.sh +++ b/dockers/docker-snmp-sv2/start.sh @@ -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 diff --git a/dockers/docker-snmp-sv2/sysDescription.j2 b/dockers/docker-snmp-sv2/sysDescription.j2 index 648ed16104..207a8bf7de 100644 --- a/dockers/docker-snmp-sv2/sysDescription.j2 +++ b/dockers/docker-snmp-sv2/sysDescription.j2 @@ -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 }} diff --git a/dockers/docker-teamd/start.sh b/dockers/docker-teamd/start.sh index fe4bfe1c58..6b0a3d7858 100755 --- a/dockers/docker-teamd/start.sh +++ b/dockers/docker-teamd/start.sh @@ -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 diff --git a/dockers/docker-teamd/teamd.j2 b/dockers/docker-teamd/teamd.j2 index d6693719f1..d9ea1b790f 100644 --- a/dockers/docker-teamd/teamd.j2 +++ b/dockers/docker-teamd/teamd.j2 @@ -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 %} diff --git a/files/build_templates/docker_image_ctl.j2 b/files/build_templates/docker_image_ctl.j2 index 3ae3acaed3..042db764df 100644 --- a/files/build_templates/docker_image_ctl.j2 +++ b/files/build_templates/docker_image_ctl.j2 @@ -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() { diff --git a/files/build_templates/swss.service.j2 b/files/build_templates/swss.service.j2 index ed6b852f18..af922530d8 100644 --- a/files/build_templates/swss.service.j2 +++ b/files/build_templates/swss.service.j2 @@ -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 %} diff --git a/files/image_config/interfaces/interfaces-config.service b/files/image_config/interfaces/interfaces-config.service index 0cc7f29815..86706da225 100644 --- a/files/image_config/interfaces/interfaces-config.service +++ b/files/image_config/interfaces/interfaces-config.service @@ -1,6 +1,7 @@ [Unit] Description=Update interfaces configuration -Before=database.service +Requires=database.service +After=database.service [Service] Type=oneshot diff --git a/files/image_config/interfaces/interfaces-config.sh b/files/image_config/interfaces/interfaces-config.sh index d2b42051cc..400b89a594 100755 --- a/files/image_config/interfaces/interfaces-config.sh +++ b/files/image_config/interfaces/interfaces-config.sh @@ -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 diff --git a/files/image_config/interfaces/interfaces.j2 b/files/image_config/interfaces/interfaces.j2 index 425badf7f2..f96c0740c5 100644 --- a/files/image_config/interfaces/interfaces.j2 +++ b/files/image_config/interfaces/interfaces.j2 @@ -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 %} diff --git a/files/image_config/ntp/ntp-config.service b/files/image_config/ntp/ntp-config.service index 948e7f4953..05e6211b97 100644 --- a/files/image_config/ntp/ntp-config.service +++ b/files/image_config/ntp/ntp-config.service @@ -1,6 +1,8 @@ [Unit] Description=Update NTP configuration Before=ntp.service +Requires=database.service +After=database.service [Service] Type=oneshot diff --git a/files/image_config/ntp/ntp-config.sh b/files/image_config/ntp/ntp-config.sh index 2465058ba0..7c79a16c0e 100755 --- a/files/image_config/ntp/ntp-config.sh +++ b/files/image_config/ntp/ntp-config.sh @@ -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 diff --git a/files/image_config/ntp/ntp.conf.j2 b/files/image_config/ntp/ntp.conf.j2 index 3ae0c1804e..ae72820339 100644 --- a/files/image_config/ntp/ntp.conf.j2 +++ b/files/image_config/ntp/ntp.conf.j2 @@ -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: -{% 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 diff --git a/files/image_config/rsyslog/rsyslog-config.service b/files/image_config/rsyslog/rsyslog-config.service index be3c209e75..e013b99203 100644 --- a/files/image_config/rsyslog/rsyslog-config.service +++ b/files/image_config/rsyslog/rsyslog-config.service @@ -1,5 +1,7 @@ [Unit] Description=Update rsyslog configuration +Requires=database.service +After=database.service [Service] Type=oneshot diff --git a/files/image_config/rsyslog/rsyslog-config.sh b/files/image_config/rsyslog/rsyslog-config.sh index 06a4934a4b..c8ba7b9945 100755 --- a/files/image_config/rsyslog/rsyslog-config.sh +++ b/files/image_config/rsyslog/rsyslog-config.sh @@ -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 diff --git a/files/image_config/rsyslog/rsyslog.conf.j2 b/files/image_config/rsyslog/rsyslog.conf.j2 index 264ddd8dd7..063f119f6b 100644 --- a/files/image_config/rsyslog/rsyslog.conf.j2 +++ b/files/image_config/rsyslog/rsyslog.conf.j2 @@ -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 %} diff --git a/files/image_config/updategraph/updategraph.service b/files/image_config/updategraph/updategraph.service index ba0b5dcb85..c66e9be757 100644 --- a/files/image_config/updategraph/updategraph.service +++ b/files/image_config/updategraph/updategraph.service @@ -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 diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index 1877e55285..565a1a43d0 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -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)) diff --git a/src/sonic-config-engine/sonic-cfggen b/src/sonic-config-engine/sonic-cfggen index 070b3100ea..5303557c4f 100755 --- a/src/sonic-config-engine/sonic-cfggen +++ b/src/sonic-config-engine/sonic-cfggen @@ -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__": diff --git a/src/sonic-config-engine/tests/sample_output/interfaces b/src/sonic-config-engine/tests/sample_output/interfaces index 5c57bf8fac..aed23f8a5c 100644 --- a/src/sonic-config-engine/tests/sample_output/interfaces +++ b/src/sonic-config-engine/tests/sample_output/interfaces @@ -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 diff --git a/src/sonic-config-engine/tests/sample_output/mirror.json b/src/sonic-config-engine/tests/sample_output/mirror.json index 54065700a2..225235067e 100644 --- a/src/sonic-config-engine/tests/sample_output/mirror.json +++ b/src/sonic-config-engine/tests/sample_output/mirror.json @@ -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", diff --git a/src/sonic-config-engine/tests/test_cfggen.py b/src/sonic-config-engine/tests/test_cfggen.py index 153b0bb14f..cf0eb4d8cc 100644 --- a/src/sonic-config-engine/tests/test_cfggen.py +++ b/src/sonic-config-engine/tests/test_cfggen.py @@ -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'}") diff --git a/src/sonic-config-engine/tests/test_j2files.py b/src/sonic-config-engine/tests/test_j2files.py index 0f9264eb1d..9b71fc72b9 100644 --- a/src/sonic-config-engine/tests/test_j2files.py +++ b/src/sonic-config-engine/tests/test_j2files.py @@ -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() diff --git a/src/sonic-config-engine/translate_acl b/src/sonic-config-engine/translate_acl index 5525eff967..b8138cf36b 100755 --- a/src/sonic-config-engine/translate_acl +++ b/src/sonic-config-engine/translate_acl @@ -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() diff --git a/src/sonic-py-swsssdk b/src/sonic-py-swsssdk index 9b54b80f17..7f8e7c5ad9 160000 --- a/src/sonic-py-swsssdk +++ b/src/sonic-py-swsssdk @@ -1 +1 @@ -Subproject commit 9b54b80f1783808c5ae2a30e189f24a7404a8c95 +Subproject commit 7f8e7c5ad9747af1d8ce5317eb1ece65ed4c0c7a