Loading scripts/run_tests_locally-device-gnmi-openconfig.sh +1 −1 Original line number Diff line number Diff line Loading @@ -22,4 +22,4 @@ RCFILE=$PROJECTDIR/coverage/.coveragerc # Run unitary tests and analyze coverage of code at same time # helpful pytest flags: --log-level=INFO -o log_cli=true --verbose --maxfail=1 --durations=0 coverage run --rcfile=$RCFILE --append -m pytest --log-level=INFO --verbose \ device/tests/test_unitary_gnmi_openconfig.py device/tests/gnmi_openconfig/test_unitary_gnmi_openconfig.py src/device/service/drivers/gnmi_openconfig/handlers/InterfaceCounter.py +33 −33 Original line number Diff line number Diff line Loading @@ -12,11 +12,10 @@ # See the License for the specific language governing permissions and # limitations under the License. import json, logging import json, libyang, logging from typing import Any, Dict, List, Tuple import pyangbind.lib.pybindJSON as pybindJSON from . import openconfig from ._Handler import _Handler from .YangHandler import YangHandler LOGGER = logging.getLogger(__name__) Loading @@ -25,40 +24,41 @@ class InterfaceCounterHandler(_Handler): def get_resource_key(self) -> str: return '/interface/counters' def get_path(self) -> str: return '/openconfig-interfaces:interfaces/interface/state/counters' def parse(self, json_data : Dict) -> List[Tuple[str, Dict[str, Any]]]: def parse( self, json_data : Dict, yang_handler : YangHandler ) -> List[Tuple[str, Dict[str, Any]]]: LOGGER.info('json_data = {:s}'.format(json.dumps(json_data))) oc_interfaces = pybindJSON.loads_ietf(json_data, openconfig.interfaces, 'interfaces') LOGGER.info('oc_interfaces = {:s}'.format(pybindJSON.dumps(oc_interfaces, mode='ietf'))) counters = [] for interface_key, oc_interface in oc_interfaces.interface.items(): LOGGER.info('interface_key={:s} oc_interfaces={:s}'.format( interface_key, pybindJSON.dumps(oc_interface, mode='ietf') )) yang_interfaces_path = self.get_path() json_data_valid = yang_handler.parse_to_dict(yang_interfaces_path, json_data, fmt='json') interface = {} interface['name'] = oc_interface.name interface_counters = oc_interface.state.counters interface['in-broadcast-pkts' ] = interface_counters.in_broadcast_pkts interface['in-discards' ] = interface_counters.in_discards interface['in-errors' ] = interface_counters.in_errors interface['in-fcs-errors' ] = interface_counters.in_fcs_errors interface['in-multicast-pkts' ] = interface_counters.in_multicast_pkts interface['in-octets' ] = interface_counters.in_octets interface['in-pkts' ] = interface_counters.in_pkts interface['in-unicast-pkts' ] = interface_counters.in_unicast_pkts interface['out-broadcast-pkts'] = interface_counters.out_broadcast_pkts interface['out-discards' ] = interface_counters.out_discards interface['out-errors' ] = interface_counters.out_errors interface['out-multicast-pkts'] = interface_counters.out_multicast_pkts interface['out-octets' ] = interface_counters.out_octets interface['out-pkts' ] = interface_counters.out_pkts interface['out-unicast-pkts' ] = interface_counters.out_unicast_pkts entries = [] for interface in json_data_valid['interfaces']['interface']: LOGGER.info('interface={:s}'.format(str(interface))) interface_name = interface['name'] interface_counters = interface.get('state', {}).get('counters', {}) _interface = { 'name' : interface_name, 'in-broadcast-pkts' : interface_counters['in_broadcast_pkts' ], 'in-discards' : interface_counters['in_discards' ], 'in-errors' : interface_counters['in_errors' ], 'in-fcs-errors' : interface_counters['in_fcs_errors' ], 'in-multicast-pkts' : interface_counters['in_multicast_pkts' ], 'in-octets' : interface_counters['in_octets' ], 'in-pkts' : interface_counters['in_pkts' ], 'in-unicast-pkts' : interface_counters['in_unicast_pkts' ], 'out-broadcast-pkts': interface_counters['out_broadcast_pkts'], 'out-discards' : interface_counters['out_discards' ], 'out-errors' : interface_counters['out_errors' ], 'out-multicast-pkts': interface_counters['out_multicast_pkts'], 'out-octets' : interface_counters['out_octets' ], 'out-pkts' : interface_counters['out_pkts' ], 'out-unicast-pkts' : interface_counters['out_unicast_pkts' ], } LOGGER.info('interface = {:s}'.format(str(interface))) if len(interface) == 0: continue counters.append(('/interface[{:s}]'.format(interface['name']), interface)) entry_interface_key = '/interface[{:s}]'.format(interface_name) entries.append((entry_interface_key, _interface)) return counters return entries src/device/service/drivers/gnmi_openconfig/handlers/NetworkInstance.py +22 −12 Original line number Diff line number Diff line Loading @@ -12,11 +12,10 @@ # See the License for the specific language governing permissions and # limitations under the License. import json, libyang, logging import operator import json, libyang, logging, operator from typing import Any, Dict, List, Tuple from ._Handler import _Handler from .Tools import get_bool, get_int, get_str from .Tools import get_str from .YangHandler import YangHandler LOGGER = logging.getLogger(__name__) Loading Loading @@ -56,21 +55,32 @@ class NetworkInstanceHandler(_Handler): ni_type = get_str(resource_value, 'type') # L3VRF / L2VSI / ... ni_type = MAP_NETWORK_INSTANCE_TYPE.get(ni_type, ni_type) # 'DIRECTLY_CONNECTED' is implicitly added str_path = '/network-instances/network-instance[name={:s}]'.format(ni_name) #str_data = json.dumps({ # 'name': ni_name, # 'config': {'name': ni_name, 'type': ni_type}, #}) yang_nis : libyang.DContainer = yang_handler.get_data_path('/openconfig-network-instance:network-instances') yang_ni_path = 'network-instance[name="{:s}"]'.format(ni_name) yang_ni : libyang.DContainer = yang_nis.create_path(yang_ni_path) yang_ni.create_path('config/name', ni_name) yang_ni.create_path('config/type', ni_type) str_path = '/network-instances/network-instance[name={:s}]'.format(ni_name) str_data = json.dumps({ 'name': ni_name, 'config': {'name': ni_name, 'type': ni_type}, # 'DIRECTLY_CONNECTED' is implicitly added #'protocols': {'protocol': protocols}, }) str_data = yang_ni.print_mem('json') LOGGER.warning('str_data = {:s}'.format(str(str_data))) json_data = json.loads(str_data) json_data = json_data['openconfig-network-instance:network-instance'][0] str_data = json.dumps(json_data) return str_path, str_data def parse( self, json_data : Dict, yang_handler : YangHandler ) -> List[Tuple[str, Dict[str, Any]]]: LOGGER.debug('json_data = {:s}'.format(json.dumps(json_data))) LOGGER.info('json_data = {:s}'.format(json.dumps(json_data))) # Arista Parsing Fixes: # - Default instance comes with mpls/signaling-protocols/rsvp-te/global/hellos/state/hello-interval set to 0 Loading src/device/service/drivers/gnmi_openconfig/handlers/NetworkInstanceInterface.py +40 −12 Original line number Diff line number Diff line Loading @@ -12,20 +12,30 @@ # See the License for the specific language governing permissions and # limitations under the License. import json, logging import json, libyang, logging from typing import Any, Dict, List, Tuple from ._Handler import _Handler from .Tools import get_int, get_str from .YangHandler import YangHandler LOGGER = logging.getLogger(__name__) IS_CEOS = True class NetworkInstanceInterfaceHandler(_Handler): def get_resource_key(self) -> str: return '/network_instance/interface' def get_path(self) -> str: return '/network-instances/network-instance/interfaces' def get_path(self) -> str: return '/openconfig-network-instance:network-instances/network-instance/interfaces' def compose( 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 def compose(self, resource_key : str, resource_value : Dict, delete : bool = False) -> Tuple[str, str]: ni_name = str(resource_value['name' ]) # test-svc if_name = str(resource_value['if_name' ]) # ethernet-1/1 sif_index = int(resource_value['sif_index']) # 0 if IS_CEOS: if_id = if_name else: if_id = '{:s}.{:d}'.format(if_name, sif_index) if delete: Loading @@ -35,12 +45,30 @@ class NetworkInstanceInterfaceHandler(_Handler): return str_path, str_data str_path = '/network-instances/network-instance[name={:s}]/interfaces/interface[id={:s}]'.format(ni_name, if_id) str_data = json.dumps({ 'id': if_id, 'config': {'id': if_id, 'interface': if_name, 'subinterface': sif_index}, }) #str_data = json.dumps({ # 'id': if_id, # 'config': {'id': if_id, 'interface': if_name, 'subinterface': sif_index}, #}) 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 : 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/interface', if_name) yang_ni_if.create_path('config/subinterface', sif_index) str_data = yang_ni_if.print_mem('json') LOGGER.warning('[compose] str_data = {:s}'.format(str(str_data))) json_data = json.loads(str_data) json_data = json_data['openconfig-network-instance:interface'][0] str_data = json.dumps(json_data) return str_path, str_data def parse(self, json_data : Dict) -> List[Tuple[str, Dict[str, Any]]]: def parse( self, json_data : Dict, yang_handler : YangHandler ) -> List[Tuple[str, Dict[str, Any]]]: LOGGER.warning('[parse] json_data = {:s}'.format(str(json_data))) response = [] return response src/device/service/drivers/gnmi_openconfig/handlers/NetworkInstanceStaticRoute.py +56 −23 Original line number Diff line number Diff line Loading @@ -12,21 +12,25 @@ # See the License for the specific language governing permissions and # limitations under the License. import json, logging import json, libyang, logging from typing import Any, Dict, List, Tuple from ._Handler import _Handler from .Tools import get_int, get_str 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 '/network-instances/network-instance/static_route' def get_path(self) -> str: return '/openconfig-network-instance:network-instances/network-instance/static_route' def compose(self, resource_key : str, resource_value : Dict, delete : bool = False) -> Tuple[str, str]: ni_name = str(resource_value['name' ]) # test-svc prefix = str(resource_value['prefix' ]) # '172.0.1.0/24' def compose( 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 prefix = get_str(resource_value, 'prefix') # '172.0.1.0/24' identifier = 'STATIC' identifier = 'openconfig-policy-types:STATIC' name = 'static' if delete: PATH_TMPL = '/network-instances/network-instance[name={:s}]/protocols' Loading @@ -35,27 +39,56 @@ class NetworkInstanceStaticRouteHandler(_Handler): str_data = json.dumps({}) return str_path, str_data next_hop = str(resource_value['next_hop' ]) # '172.0.0.1' next_hop_index = int(resource_value.get('next_hop_index', 0)) # 0 next_hop = get_str(resource_value, 'next_hop' ) # '172.0.0.1' next_hop_index = get_int(resource_value, 'next_hop_index', 0) # 0 PATH_TMPL = '/network-instances/network-instance[name={:s}]/protocols/protocol[identifier={:s}][name={:s}]' str_path = PATH_TMPL.format(ni_name, identifier, name) str_data = json.dumps({ 'identifier': identifier, 'name': name, 'config': {'identifier': identifier, 'name': name, 'enabled': True}, 'static_routes': {'static': [{ 'prefix': prefix, 'config': {'prefix': prefix}, 'next_hops': { 'next-hop': [{ 'index': next_hop_index, 'config': {'index': next_hop_index, 'next_hop': next_hop} }] } }]} }) #str_data = json.dumps({ # 'identifier': identifier, 'name': name, # 'config': {'identifier': identifier, 'name': name, 'enabled': True}, # 'static_routes': {'static': [{ # 'prefix': prefix, # 'config': {'prefix': prefix}, # 'next_hops': { # 'next-hop': [{ # 'index': next_hop_index, # 'config': {'index': next_hop_index, 'next_hop': next_hop} # }] # } # }]} #}) 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_prs : libyang.DContainer = yang_ni.create_path('protocols') yang_ni_pr_path = 'protocol[identifier="{:s}"][name="{:s}"]'.format(identifier, name) yang_ni_pr : libyang.DContainer = yang_ni_prs.create_path(yang_ni_pr_path) yang_ni_pr.create_path('config/identifier', identifier) yang_ni_pr.create_path('config/name', name ) yang_ni_pr.create_path('config/enabled', True ) yang_ni_pr_srs : libyang.DContainer = yang_ni_pr.create_path('static-routes') yang_ni_pr_sr_path = 'static[prefix="{:s}"]'.format(prefix) yang_ni_pr_sr : libyang.DContainer = yang_ni_pr_srs.create_path(yang_ni_pr_sr_path) yang_ni_pr_sr.create_path('config/prefix', prefix) yang_ni_pr_sr_nhs : libyang.DContainer = yang_ni_pr_sr.create_path('next-hops') yang_ni_pr_sr_nh_path = 'next-hop[index="{:d}"]'.format(next_hop_index) 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) str_data = yang_ni_pr.print_mem('json') LOGGER.warning('[compose] str_data = {:s}'.format(str(str_data))) json_data = json.loads(str_data) json_data = json_data['openconfig-network-instance:protocol'][0] str_data = json.dumps(json_data) return str_path, str_data def parse(self, json_data : Dict) -> List[Tuple[str, Dict[str, Any]]]: def parse( self, json_data : Dict, yang_handler : YangHandler ) -> List[Tuple[str, Dict[str, Any]]]: LOGGER.warning('[parse] json_data = {:s}'.format(str(json_data))) response = [] return response Loading
scripts/run_tests_locally-device-gnmi-openconfig.sh +1 −1 Original line number Diff line number Diff line Loading @@ -22,4 +22,4 @@ RCFILE=$PROJECTDIR/coverage/.coveragerc # Run unitary tests and analyze coverage of code at same time # helpful pytest flags: --log-level=INFO -o log_cli=true --verbose --maxfail=1 --durations=0 coverage run --rcfile=$RCFILE --append -m pytest --log-level=INFO --verbose \ device/tests/test_unitary_gnmi_openconfig.py device/tests/gnmi_openconfig/test_unitary_gnmi_openconfig.py
src/device/service/drivers/gnmi_openconfig/handlers/InterfaceCounter.py +33 −33 Original line number Diff line number Diff line Loading @@ -12,11 +12,10 @@ # See the License for the specific language governing permissions and # limitations under the License. import json, logging import json, libyang, logging from typing import Any, Dict, List, Tuple import pyangbind.lib.pybindJSON as pybindJSON from . import openconfig from ._Handler import _Handler from .YangHandler import YangHandler LOGGER = logging.getLogger(__name__) Loading @@ -25,40 +24,41 @@ class InterfaceCounterHandler(_Handler): def get_resource_key(self) -> str: return '/interface/counters' def get_path(self) -> str: return '/openconfig-interfaces:interfaces/interface/state/counters' def parse(self, json_data : Dict) -> List[Tuple[str, Dict[str, Any]]]: def parse( self, json_data : Dict, yang_handler : YangHandler ) -> List[Tuple[str, Dict[str, Any]]]: LOGGER.info('json_data = {:s}'.format(json.dumps(json_data))) oc_interfaces = pybindJSON.loads_ietf(json_data, openconfig.interfaces, 'interfaces') LOGGER.info('oc_interfaces = {:s}'.format(pybindJSON.dumps(oc_interfaces, mode='ietf'))) counters = [] for interface_key, oc_interface in oc_interfaces.interface.items(): LOGGER.info('interface_key={:s} oc_interfaces={:s}'.format( interface_key, pybindJSON.dumps(oc_interface, mode='ietf') )) yang_interfaces_path = self.get_path() json_data_valid = yang_handler.parse_to_dict(yang_interfaces_path, json_data, fmt='json') interface = {} interface['name'] = oc_interface.name interface_counters = oc_interface.state.counters interface['in-broadcast-pkts' ] = interface_counters.in_broadcast_pkts interface['in-discards' ] = interface_counters.in_discards interface['in-errors' ] = interface_counters.in_errors interface['in-fcs-errors' ] = interface_counters.in_fcs_errors interface['in-multicast-pkts' ] = interface_counters.in_multicast_pkts interface['in-octets' ] = interface_counters.in_octets interface['in-pkts' ] = interface_counters.in_pkts interface['in-unicast-pkts' ] = interface_counters.in_unicast_pkts interface['out-broadcast-pkts'] = interface_counters.out_broadcast_pkts interface['out-discards' ] = interface_counters.out_discards interface['out-errors' ] = interface_counters.out_errors interface['out-multicast-pkts'] = interface_counters.out_multicast_pkts interface['out-octets' ] = interface_counters.out_octets interface['out-pkts' ] = interface_counters.out_pkts interface['out-unicast-pkts' ] = interface_counters.out_unicast_pkts entries = [] for interface in json_data_valid['interfaces']['interface']: LOGGER.info('interface={:s}'.format(str(interface))) interface_name = interface['name'] interface_counters = interface.get('state', {}).get('counters', {}) _interface = { 'name' : interface_name, 'in-broadcast-pkts' : interface_counters['in_broadcast_pkts' ], 'in-discards' : interface_counters['in_discards' ], 'in-errors' : interface_counters['in_errors' ], 'in-fcs-errors' : interface_counters['in_fcs_errors' ], 'in-multicast-pkts' : interface_counters['in_multicast_pkts' ], 'in-octets' : interface_counters['in_octets' ], 'in-pkts' : interface_counters['in_pkts' ], 'in-unicast-pkts' : interface_counters['in_unicast_pkts' ], 'out-broadcast-pkts': interface_counters['out_broadcast_pkts'], 'out-discards' : interface_counters['out_discards' ], 'out-errors' : interface_counters['out_errors' ], 'out-multicast-pkts': interface_counters['out_multicast_pkts'], 'out-octets' : interface_counters['out_octets' ], 'out-pkts' : interface_counters['out_pkts' ], 'out-unicast-pkts' : interface_counters['out_unicast_pkts' ], } LOGGER.info('interface = {:s}'.format(str(interface))) if len(interface) == 0: continue counters.append(('/interface[{:s}]'.format(interface['name']), interface)) entry_interface_key = '/interface[{:s}]'.format(interface_name) entries.append((entry_interface_key, _interface)) return counters return entries
src/device/service/drivers/gnmi_openconfig/handlers/NetworkInstance.py +22 −12 Original line number Diff line number Diff line Loading @@ -12,11 +12,10 @@ # See the License for the specific language governing permissions and # limitations under the License. import json, libyang, logging import operator import json, libyang, logging, operator from typing import Any, Dict, List, Tuple from ._Handler import _Handler from .Tools import get_bool, get_int, get_str from .Tools import get_str from .YangHandler import YangHandler LOGGER = logging.getLogger(__name__) Loading Loading @@ -56,21 +55,32 @@ class NetworkInstanceHandler(_Handler): ni_type = get_str(resource_value, 'type') # L3VRF / L2VSI / ... ni_type = MAP_NETWORK_INSTANCE_TYPE.get(ni_type, ni_type) # 'DIRECTLY_CONNECTED' is implicitly added str_path = '/network-instances/network-instance[name={:s}]'.format(ni_name) #str_data = json.dumps({ # 'name': ni_name, # 'config': {'name': ni_name, 'type': ni_type}, #}) yang_nis : libyang.DContainer = yang_handler.get_data_path('/openconfig-network-instance:network-instances') yang_ni_path = 'network-instance[name="{:s}"]'.format(ni_name) yang_ni : libyang.DContainer = yang_nis.create_path(yang_ni_path) yang_ni.create_path('config/name', ni_name) yang_ni.create_path('config/type', ni_type) str_path = '/network-instances/network-instance[name={:s}]'.format(ni_name) str_data = json.dumps({ 'name': ni_name, 'config': {'name': ni_name, 'type': ni_type}, # 'DIRECTLY_CONNECTED' is implicitly added #'protocols': {'protocol': protocols}, }) str_data = yang_ni.print_mem('json') LOGGER.warning('str_data = {:s}'.format(str(str_data))) json_data = json.loads(str_data) json_data = json_data['openconfig-network-instance:network-instance'][0] str_data = json.dumps(json_data) return str_path, str_data def parse( self, json_data : Dict, yang_handler : YangHandler ) -> List[Tuple[str, Dict[str, Any]]]: LOGGER.debug('json_data = {:s}'.format(json.dumps(json_data))) LOGGER.info('json_data = {:s}'.format(json.dumps(json_data))) # Arista Parsing Fixes: # - Default instance comes with mpls/signaling-protocols/rsvp-te/global/hellos/state/hello-interval set to 0 Loading
src/device/service/drivers/gnmi_openconfig/handlers/NetworkInstanceInterface.py +40 −12 Original line number Diff line number Diff line Loading @@ -12,20 +12,30 @@ # See the License for the specific language governing permissions and # limitations under the License. import json, logging import json, libyang, logging from typing import Any, Dict, List, Tuple from ._Handler import _Handler from .Tools import get_int, get_str from .YangHandler import YangHandler LOGGER = logging.getLogger(__name__) IS_CEOS = True class NetworkInstanceInterfaceHandler(_Handler): def get_resource_key(self) -> str: return '/network_instance/interface' def get_path(self) -> str: return '/network-instances/network-instance/interfaces' def get_path(self) -> str: return '/openconfig-network-instance:network-instances/network-instance/interfaces' def compose( 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 def compose(self, resource_key : str, resource_value : Dict, delete : bool = False) -> Tuple[str, str]: ni_name = str(resource_value['name' ]) # test-svc if_name = str(resource_value['if_name' ]) # ethernet-1/1 sif_index = int(resource_value['sif_index']) # 0 if IS_CEOS: if_id = if_name else: if_id = '{:s}.{:d}'.format(if_name, sif_index) if delete: Loading @@ -35,12 +45,30 @@ class NetworkInstanceInterfaceHandler(_Handler): return str_path, str_data str_path = '/network-instances/network-instance[name={:s}]/interfaces/interface[id={:s}]'.format(ni_name, if_id) str_data = json.dumps({ 'id': if_id, 'config': {'id': if_id, 'interface': if_name, 'subinterface': sif_index}, }) #str_data = json.dumps({ # 'id': if_id, # 'config': {'id': if_id, 'interface': if_name, 'subinterface': sif_index}, #}) 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 : 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/interface', if_name) yang_ni_if.create_path('config/subinterface', sif_index) str_data = yang_ni_if.print_mem('json') LOGGER.warning('[compose] str_data = {:s}'.format(str(str_data))) json_data = json.loads(str_data) json_data = json_data['openconfig-network-instance:interface'][0] str_data = json.dumps(json_data) return str_path, str_data def parse(self, json_data : Dict) -> List[Tuple[str, Dict[str, Any]]]: def parse( self, json_data : Dict, yang_handler : YangHandler ) -> List[Tuple[str, Dict[str, Any]]]: LOGGER.warning('[parse] json_data = {:s}'.format(str(json_data))) response = [] return response
src/device/service/drivers/gnmi_openconfig/handlers/NetworkInstanceStaticRoute.py +56 −23 Original line number Diff line number Diff line Loading @@ -12,21 +12,25 @@ # See the License for the specific language governing permissions and # limitations under the License. import json, logging import json, libyang, logging from typing import Any, Dict, List, Tuple from ._Handler import _Handler from .Tools import get_int, get_str 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 '/network-instances/network-instance/static_route' def get_path(self) -> str: return '/openconfig-network-instance:network-instances/network-instance/static_route' def compose(self, resource_key : str, resource_value : Dict, delete : bool = False) -> Tuple[str, str]: ni_name = str(resource_value['name' ]) # test-svc prefix = str(resource_value['prefix' ]) # '172.0.1.0/24' def compose( 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 prefix = get_str(resource_value, 'prefix') # '172.0.1.0/24' identifier = 'STATIC' identifier = 'openconfig-policy-types:STATIC' name = 'static' if delete: PATH_TMPL = '/network-instances/network-instance[name={:s}]/protocols' Loading @@ -35,27 +39,56 @@ class NetworkInstanceStaticRouteHandler(_Handler): str_data = json.dumps({}) return str_path, str_data next_hop = str(resource_value['next_hop' ]) # '172.0.0.1' next_hop_index = int(resource_value.get('next_hop_index', 0)) # 0 next_hop = get_str(resource_value, 'next_hop' ) # '172.0.0.1' next_hop_index = get_int(resource_value, 'next_hop_index', 0) # 0 PATH_TMPL = '/network-instances/network-instance[name={:s}]/protocols/protocol[identifier={:s}][name={:s}]' str_path = PATH_TMPL.format(ni_name, identifier, name) str_data = json.dumps({ 'identifier': identifier, 'name': name, 'config': {'identifier': identifier, 'name': name, 'enabled': True}, 'static_routes': {'static': [{ 'prefix': prefix, 'config': {'prefix': prefix}, 'next_hops': { 'next-hop': [{ 'index': next_hop_index, 'config': {'index': next_hop_index, 'next_hop': next_hop} }] } }]} }) #str_data = json.dumps({ # 'identifier': identifier, 'name': name, # 'config': {'identifier': identifier, 'name': name, 'enabled': True}, # 'static_routes': {'static': [{ # 'prefix': prefix, # 'config': {'prefix': prefix}, # 'next_hops': { # 'next-hop': [{ # 'index': next_hop_index, # 'config': {'index': next_hop_index, 'next_hop': next_hop} # }] # } # }]} #}) 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_prs : libyang.DContainer = yang_ni.create_path('protocols') yang_ni_pr_path = 'protocol[identifier="{:s}"][name="{:s}"]'.format(identifier, name) yang_ni_pr : libyang.DContainer = yang_ni_prs.create_path(yang_ni_pr_path) yang_ni_pr.create_path('config/identifier', identifier) yang_ni_pr.create_path('config/name', name ) yang_ni_pr.create_path('config/enabled', True ) yang_ni_pr_srs : libyang.DContainer = yang_ni_pr.create_path('static-routes') yang_ni_pr_sr_path = 'static[prefix="{:s}"]'.format(prefix) yang_ni_pr_sr : libyang.DContainer = yang_ni_pr_srs.create_path(yang_ni_pr_sr_path) yang_ni_pr_sr.create_path('config/prefix', prefix) yang_ni_pr_sr_nhs : libyang.DContainer = yang_ni_pr_sr.create_path('next-hops') yang_ni_pr_sr_nh_path = 'next-hop[index="{:d}"]'.format(next_hop_index) 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) str_data = yang_ni_pr.print_mem('json') LOGGER.warning('[compose] str_data = {:s}'.format(str(str_data))) json_data = json.loads(str_data) json_data = json_data['openconfig-network-instance:protocol'][0] str_data = json.dumps(json_data) return str_path, str_data def parse(self, json_data : Dict) -> List[Tuple[str, Dict[str, Any]]]: def parse( self, json_data : Dict, yang_handler : YangHandler ) -> List[Tuple[str, Dict[str, Any]]]: LOGGER.warning('[parse] json_data = {:s}'.format(str(json_data))) response = [] return response