Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incorrect bundle model reference #1091

Closed
ldacol opened this issue Aug 29, 2023 · 2 comments
Closed

Incorrect bundle model reference #1091

ldacol opened this issue Aug 29, 2023 · 2 comments
Assignees

Comments

@ldacol
Copy link

ldacol commented Aug 29, 2023

Issue tracker is ONLY used for reporting bugs. Please use the YDK Community for any support issues.

Expected Behavior

I should be able to get an XML generated code from the correct bundle family

Current Behavior

Using the incorrect bundle juniper_junos_18_4R3/_yang

Steps to Reproduce

Run below script with the following yaml payload or any payload and see that name spaces in the XML payload are junos instead of junos-qfx

junos-conf-root:configuration:
  version: 20.2R3.9
  junos-conf-chassis:chassis:
      aggregated-devices:
        ethernet:
          device-count: 5
      redundancy:
        graceful-switchover: {}

Your Script

import json
import yaml
import xmltodict
import xml.etree.ElementTree
from lxml import etree
import re
import os
import json

from ydk.providers import CodecServiceProvider
from ydk.services import CodecService

ydk_model_path_juniper_junos_18_4R3 = '/Users/ldacol/ydk_vne/lib/python3.8/site-packages/ydk/models/juniper_junos_18_4R3/_yang'
ydk_model_path_juniper_junos_20_2R3 = '/Users/ldacol/ydk_vne/lib/python3.8/site-packages/ydk/models/juniper_junos_20_2R3/_yang'
ydk_model_path_juniper_junos_20_4R3 = '/Users/ldacol/ydk_vne/lib/python3.8/site-packages/ydk/models/juniper_junos_20_4R3/_yang'
ydk_model_path_juniper_junos_qfx_20_2R3 = '/Users/ldacol/ydk_vne/lib/python3.8/site-packages/ydk/models/juniper_junos_qfx_20_2R3/_yang'

def yang_yaml_to_xml(yaml_file, juniper_family, juniper_version):

    mode = 'rb'

    CODEC = CodecService()

    JSON_PROVIDER = CodecServiceProvider(type='json')
    XML_PROVIDER = CodecServiceProvider(type='xml')

    with open(yaml_file, mode) as yaml_in:
        yaml_object = yaml.safe_load(yaml_in)

    if juniper_family == 'junos':
        if juniper_version == '18.4R3':
            JSON_PROVIDER.initialize('juniper-junos-184R3', ydk_model_path_juniper_junos_18_4R3)
            XML_PROVIDER.initialize('juniper-junos-184R3', ydk_model_path_juniper_junos_18_4R3)
        elif juniper_version == '20.2R3':
            JSON_PROVIDER.initialize('juniper-junos-202R3', ydk_model_path_juniper_junos_20_2R3)
            XML_PROVIDER.initialize('juniper-junos-202R3', ydk_model_path_juniper_junos_20_2R3)
        elif juniper_version == '20.4R3':
            JSON_PROVIDER.initialize('juniper-junos-204R3', ydk_model_path_juniper_junos_20_4R3)
            XML_PROVIDER.initialize('juniper-junos-204R3', ydk_model_path_juniper_junos_20_4R3)
    elif juniper_family == 'junos-qfx':
        if juniper_version == '20.2R3':
            JSON_PROVIDER.initialize('juniper-junos-qfx-202R3', ydk_model_path_juniper_junos_qfx_20_2R3)
            XML_PROVIDER.initialize('juniper-junos-qfx-202R3', ydk_model_path_juniper_junos_qfx_20_2R3)

    config_json_yang = json.dumps(yaml_object)
    decoded_json_yang = CODEC.decode(JSON_PROVIDER, config_json_yang)

    yang_xml = CODEC.encode(XML_PROVIDER, decoded_json_yang)

    return yang_xml

# Function Call
yang_yaml_to_xml(yaml_payload, 'junos-qfx' , '20.2R3')

Logs

Enable logging and post the logs below

YDK conversion from a JSON payload completes, however the incorrect bundle is used.

A debug session of the python code shows that JSON_PROVIDER and XML_PROVIDER reference to the correct root_schema_table before running decoded_json_yang = CODEC.decode(JSON_PROVIDER, config_json_yang) however after CODEC.decode is run the JSON_PROVIDER refers to two root_schema_table (junos-18_4R3 and junos-qfx-202R3). Eventually the decoded_json_yang variable contains elements referring to the incorrect module. Removing the Junos 18.4 modules will lead to an exception "Hit an Exception: No YDK bundle installed for node path 'junos-conf-root:configuration'"

<configuration xmlns="http://yang.juniper.net/junos/conf/root">       < ---------- should be junos-qfx
  <version>20.2R3.9</version>
  <vlans xmlns="http://yang.juniper.net/junos/conf/vlans">          < ---------- should be junos-qfx
    <vlan>
      ........
    </vlan>

System Information

Issue can be reproduced both on a Mac and a Linux system with YDK 0.8.6.5 installed and python 3.8 (Mac) or 3.6 (Linux Centos)

@ygorelik
Copy link
Collaborator

ygorelik commented Sep 1, 2023

Reproducing script:

import os
import logging

from ydk.providers import CodecServiceProvider
from ydk.services import CodecService

import ydk.models.cisco_ios_xr as xr_663
import ydk.models.cisco_iosxr_demo as xr_673

ydk_model_path_iosxr_663 = os.path.join(xr_663.__path__[0], '_yang')
ydk_model_path_iosxr_673 = os.path.join(xr_673.__path__[0], '_yang')

def enable_logging(level):
    log = logging.getLogger('ydk')
    log.setLevel(level)
    handler = logging.StreamHandler()
    formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
    handler.setFormatter(formatter)
    log.addHandler(handler)

def json_to_xml(json_str, xr_version):

    codec = CodecService()

    JSON_PROVIDER = CodecServiceProvider(type='json')
    XML_PROVIDER = CodecServiceProvider(type='xml')

    if xr_version == '663':
        JSON_PROVIDER.initialize('cisco_ios_xr', ydk_model_path_iosxr_663)
        XML_PROVIDER.initialize('cisco_ios_xr', ydk_model_path_iosxr_663)
    elif xr_version == '673':
        JSON_PROVIDER.initialize('cisco_iosxr_demo', ydk_model_path_iosxr_673)
        XML_PROVIDER.initialize('cisco_iosxr_demo', ydk_model_path_iosxr_673)
    else:
        print(f'UNKNOWN XR VERSION {xr_version}')
        return ''

    decoded_json_yang = codec.decode(JSON_PROVIDER, json_str)

    yang_xml = codec.encode(XML_PROVIDER, decoded_json_yang)

    return yang_xml

json_payload = '''
{
  "Cisco-IOS-XR-ifmgr-cfg:interface-configurations": {
    "interface-configuration": [
      {
        "active": "act",
        "interface-name": "Loopback0"
      }
    ]
  }
}
'''

if __name__ == '__main__':
    enable_logging(logging.DEBUG)
    xml = json_to_xml(json_payload, '673')
    print(xml)

ygorelik pushed a commit to ygorelik/ydk-gen that referenced this issue Sep 1, 2023
@ygorelik ygorelik added the ready label Sep 1, 2023
@ygorelik
Copy link
Collaborator

ygorelik commented Sep 7, 2023

After the bug fix we can see in the debug level log (attached) that all modules are loaded from requested bundle. Example:

2023-09-07 11:04:28,906 - ydk - DEBUG - Extracting module names from JSON payload
2023-09-07 11:04:28,908 - ydk - DEBUG - Loading module 'Cisco-IOS-XR-ifmgr-cfg', revision ''
2023-09-07 11:04:28,909 - ydk - DEBUG - [libyang] Searching for "Cisco-IOS-XR-ifmgr-cfg" in /Users/ygorelik/venv3.10/lib/python3.10/site-packages/ydk/models/cisco_iosxr_demo/_yang.
2023-09-07 11:04:28,922 - ydk - DEBUG - [libyang] Searching for "Cisco-IOS-XR-ifmgr-cfg" in /Users/ygorelik/ydk-gen/scripts/issues/1091.
2023-09-07 11:04:28,924 - ydk - DEBUG - [libyang] Loading schema from "/Users/ygorelik/venv3.10/lib/python3.10/site-packages/ydk/models/cisco_iosxr_demo/_yang/Cisco-IOS-XR-ifmgr-cfg.yang" file.

ydk.log

@ygorelik ygorelik closed this as completed Sep 7, 2023
ygorelik pushed a commit to ygorelik/ydk-gen that referenced this issue Sep 8, 2023
ygorelik added a commit to ygorelik/ydk-gen that referenced this issue Sep 13, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants