Commit 578c898f authored by Lluis Gifre Renom's avatar Lluis Gifre Renom
Browse files

Device - gNMI OpenConfig Driver:

- Corrected Interface composition
- Corrected Network Instance static route parsing
- Corrected Network Instance static route composition
Corrected Network Instance interface composition
parent 2b2ade7c
Loading
Loading
Loading
Loading
+20 −18
Original line number Diff line number Diff line
@@ -21,14 +21,14 @@ from .YangHandler import YangHandler
LOGGER = logging.getLogger(__name__)

class InterfaceHandler(_Handler):
    def get_resource_key(self) -> str: return '/interface'
    def get_resource_key(self) -> str: return '/interface/subinterface'
    def get_path(self) -> str: return '/openconfig-interfaces:interfaces'

    def compose(
        self, resource_key : str, resource_value : Dict, yang_handler : YangHandler, delete : bool = False
    ) -> Tuple[str, str]:
        if_name   = get_str(resource_value, 'name'    )  # ethernet-1/1
        sif_index = get_int(resource_value, 'sub_if_index', 0)  # 0
        sif_index = get_int(resource_value, 'index', 0)  # 0

        if delete:
            PATH_TMPL = '/interfaces/interface[name={:s}]/subinterfaces/subinterface[index={:d}]'
@@ -36,38 +36,40 @@ class InterfaceHandler(_Handler):
            str_data = json.dumps({})
            return str_path, str_data

        if_enabled       = get_bool(resource_value, 'enabled',             True)    # True/False
        sif_enabled      = get_bool(resource_value, 'sub_if_enabled',      True)    # True/False
        sif_vlan_id      = get_int (resource_value, 'sif_vlan_id',             )    # 127
        sif_ipv4_enabled = get_bool(resource_value, 'sub_if_ipv4_enabled', True)    # True/False
        sif_ipv4_address = get_str (resource_value, 'sub_if_ipv4_address'      )    # 172.16.0.1
        sif_ipv4_prefix  = get_int (resource_value, 'sub_if_ipv4_prefix'       )    # 24
        enabled        = get_bool(resource_value, 'enabled',  True) # True/False
        #if_type        = get_str (resource_value, 'type'         ) # 'l3ipvlan'
        vlan_id        = get_int (resource_value, 'vlan_id',      ) # 127
        address_ip     = get_str (resource_value, 'address_ip'    ) # 172.16.0.1
        address_prefix = get_int (resource_value, 'address_prefix') # 24
        mtu            = get_int (resource_value, 'mtu'           ) # 1500

        yang_ifs : libyang.DContainer = yang_handler.get_data_path('/openconfig-interfaces:interfaces')
        yang_if_path = 'interface[name="{:s}"]'.format(if_name)
        yang_if : libyang.DContainer = yang_ifs.create_path(yang_if_path)
        yang_if.create_path('config/name',    if_name   )
        if if_enabled is not None: yang_if.create_path('config/enabled', if_enabled)
        if enabled is not None: yang_if.create_path('config/enabled', enabled)
        if mtu     is not None: yang_if.create_path('config/mtu',     mtu)

        yang_sifs : libyang.DContainer = yang_if.create_path('subinterfaces')
        yang_sif_path = 'subinterface[index="{:d}"]'.format(sif_index)
        yang_sif : libyang.DContainer = yang_sifs.create_path(yang_sif_path)
        yang_sif.create_path('config/index', sif_index)
        if sif_enabled is not None: yang_sif.create_path('config/enabled', sif_enabled)
        if enabled is not None: yang_sif.create_path('config/enabled', enabled)

        if sif_vlan_id is not None:
        if vlan_id is not None:
            yang_subif_vlan : libyang.DContainer = yang_sif.create_path('openconfig-vlan:vlan')
            yang_subif_vlan.create_path('match/single-tagged/config/vlan-id', sif_vlan_id)
            yang_subif_vlan.create_path('match/single-tagged/config/vlan-id', vlan_id)

        yang_ipv4 : libyang.DContainer = yang_sif.create_path('openconfig-if-ip:ipv4')
        if sif_ipv4_enabled is not None: yang_ipv4.create_path('config/enabled', sif_ipv4_enabled)
        if enabled is not None: yang_ipv4.create_path('config/enabled', enabled)

        if sif_ipv4_address is not None:
        if address_ip is not None and address_prefix is not None:
            yang_ipv4_addrs : libyang.DContainer = yang_ipv4.create_path('addresses')
            yang_ipv4_addr_path = 'address[ip="{:s}"]'.format(sif_ipv4_address)
            yang_ipv4_addr_path = 'address[ip="{:s}"]'.format(address_ip)
            yang_ipv4_addr : libyang.DContainer = yang_ipv4_addrs.create_path(yang_ipv4_addr_path)
            yang_ipv4_addr.create_path('config/ip',            sif_ipv4_address)
            yang_ipv4_addr.create_path('config/prefix-length', sif_ipv4_prefix )
            yang_ipv4_addr.create_path('config/ip',            address_ip)
            yang_ipv4_addr.create_path('config/prefix-length', address_prefix)
            if mtu is not None: yang_ipv4_addr.create_path('config/mtu', mtu)

        str_path = '/interfaces/interface[name={:s}]'.format(if_name)
        str_data = yang_if.print_mem('json')
+14 −15
Original line number Diff line number Diff line
@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.

import json, libyang, logging, operator
import json, libyang, logging
from typing import Any, Dict, List, Tuple
from ._Handler import _Handler
from .Tools import get_str
@@ -125,26 +125,25 @@ class NetworkInstanceHandler(_Handler):
                ni_protocol_id = ni_protocol['identifier'].split(':')[-1]
                ni_protocol_name = ni_protocol['name']

                _protocol = {'id': ni_protocol_id, 'name': ni_protocol_name}
                entry_protocol_key = '{:s}/protocol[{:s}]'.format(entry_net_inst_key, ni_protocol_id)
                _protocol = {'name': ni_name, 'identifier': ni_protocol_id, 'protocol_name': ni_protocol_name}
                entry_protocol_key = '{:s}/protocols[{:s}]'.format(entry_net_inst_key, ni_protocol_id)
                entries.append((entry_protocol_key, _protocol))

                if ni_protocol_id == 'STATIC':
                    static_routes = ni_protocol.get('static-routes', {}).get('static', [])
                    for static_route in static_routes:
                        static_route_prefix = static_route['prefix']

                        next_hops = {
                            next_hop['index'] : {
                        for next_hop in static_route.get('next-hops', {}).get('next-hop', []):
                            static_route_metric = next_hop['config']['metric']
                            _static_route = {
                                'prefix'  : static_route_prefix,
                                'index'   : next_hop['index'],
                                'next_hop': next_hop['config']['next-hop'],
                                'metric'  : next_hop['config']['metric'],
                            }
                            for next_hop in static_route.get('next-hops', {}).get('next-hop', [])
                                'metric'  : static_route_metric,
                            }

                        _static_route = {'prefix': static_route_prefix, 'next_hops': next_hops}
                        entry_static_route_key = '{:s}/static_routes[{:s}]'.format(
                            entry_protocol_key, static_route_prefix
                            _static_route.update(_protocol)
                            entry_static_route_key = '{:s}/static_route[{:s}:{:d}]'.format(
                                entry_protocol_key, static_route_prefix, static_route_metric
                            )
                            entries.append((entry_static_route_key, _static_route))

+12 −10
Original line number Diff line number Diff line
@@ -30,19 +30,21 @@ class NetworkInstanceInterfaceHandler(_Handler):
        self, resource_key : str, resource_value : Dict, yang_handler : YangHandler, delete : bool = False
    ) -> Tuple[str, str]:
        ni_name   = get_str(resource_value, 'name'           ) # test-svc
        if_name   = get_str(resource_value, 'if_name'     ) # ethernet-1/1
        sif_index = get_int(resource_value, 'sif_index', 0) # 0
        if_id     = '{:s}.{:d}'.format(if_name, sif_index)
        ni_if_id  = get_str(resource_value, 'id'             ) # ethernet-1/1.0
        if_name   = get_str(resource_value, 'interface'      ) # ethernet-1/1
        sif_index = get_int(resource_value, 'subinterface', 0) # 0

        if IS_CEOS: ni_if_id = if_name

        if delete:
            PATH_TMPL = '/network-instances/network-instance[name={:s}]/interfaces/interface[id={:s}]'
            str_path = PATH_TMPL.format(ni_name, if_id)
            str_path = PATH_TMPL.format(ni_name, ni_if_id)
            str_data = json.dumps({})
            return str_path, str_data

        if IS_CEOS: if_id = if_name

        str_path = '/network-instances/network-instance[name={:s}]/interfaces/interface[id={:s}]'.format(ni_name, if_id)
        str_path = '/network-instances/network-instance[name={:s}]/interfaces/interface[id={:s}]'.format(
            ni_name, ni_if_id
        )
        #str_data = json.dumps({
        #    'id': if_id,
        #    'config': {'id': if_id, 'interface': if_name, 'subinterface': sif_index},
@@ -51,9 +53,9 @@ class NetworkInstanceInterfaceHandler(_Handler):
        yang_nis : libyang.DContainer = yang_handler.get_data_path('/openconfig-network-instance:network-instances')
        yang_ni : libyang.DContainer = yang_nis.create_path('network-instance[name="{:s}"]'.format(ni_name))
        yang_ni_ifs : libyang.DContainer = yang_ni.create_path('interfaces')
        yang_ni_if_path = 'interface[id="{:s}"]'.format(if_id)
        yang_ni_if_path = 'interface[id="{:s}"]'.format(ni_if_id)
        yang_ni_if : libyang.DContainer = yang_ni_ifs.create_path(yang_ni_if_path)
        yang_ni_if.create_path('config/id',           if_id)
        yang_ni_if.create_path('config/id',           ni_if_id)
        yang_ni_if.create_path('config/interface',    if_name)
        yang_ni_if.create_path('config/subinterface', sif_index)

+5 −2
Original line number Diff line number Diff line
@@ -21,8 +21,9 @@ from .YangHandler import YangHandler
LOGGER = logging.getLogger(__name__)

class NetworkInstanceStaticRouteHandler(_Handler):
    def get_resource_key(self) -> str: return '/network_instance/static_route'
    def get_path(self) -> str: return '/openconfig-network-instance:network-instances/network-instance/static_route'
    def get_resource_key(self) -> str: return '/network_instance/protocols/static_route'
    def get_path(self) -> str:
        return '/openconfig-network-instance:network-instances/network-instance/protocols/protocol/static-routes'

    def compose(
        self, resource_key : str, resource_value : Dict, yang_handler : YangHandler, delete : bool = False
@@ -40,6 +41,7 @@ class NetworkInstanceStaticRouteHandler(_Handler):
            return str_path, str_data

        next_hop       = get_str(resource_value, 'next_hop'      )   # '172.0.0.1'
        metric         = get_int(resource_value, 'metric'        )   # 20
        next_hop_index = get_str(resource_value, 'next_hop_index')   # AUTO_1_172-0-0-1

        PATH_TMPL = '/network-instances/network-instance[name={:s}]/protocols/protocol[identifier={:s}][name={:s}]'
@@ -78,6 +80,7 @@ class NetworkInstanceStaticRouteHandler(_Handler):
        yang_ni_pr_sr_nh : libyang.DContainer = yang_ni_pr_sr_nhs.create_path(yang_ni_pr_sr_nh_path)
        yang_ni_pr_sr_nh.create_path('config/index', next_hop_index)
        yang_ni_pr_sr_nh.create_path('config/next-hop', next_hop)
        yang_ni_pr_sr_nh.create_path('config/metric', metric)

        str_data = yang_ni_pr.print_mem('json')
        LOGGER.warning('[compose] str_data = {:s}'.format(str(str_data)))