CiscoDevNet / ydk-gen

Generate model-driven APIs from YANG models
http://ciscodevnet.github.io/ydk-gen/
Apache License 2.0
137 stars 74 forks source link

The deepcopy of YLeafList changes type of member elements #904

Closed xulleon closed 5 years ago

xulleon commented 5 years ago

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

Expected Behavior

an object created by read from an asr9k device. try to use the YDK Object to replace the current configuration by rollback_obj.yfilter=REPLACE().

Current Behavior

When I test yfilter with cisco native model, it works find. However, when I use openconfig, it does not like yfilter. Please see the info below.

rollback_obj = copy.deepcopy(rtr.feature_cfg_obj[feature]['tc_setup_config'])

even I do not use copy.deepcopy the same issue was found.

rollback_obj.yfilter = REPLACE()

(Pdb) rtr.feature_cfg_obj[feature]['tc_setup_config']
<ydk.models.openconfig_iosxr_701.openconfig_network_instance.NetworkInstances object at 0xef786b4c>
(Pdb) feature_create =parameters['ydk_service'].create(rtr.provider['config'],rollback_obj)
CREATE operation initiated
2019-03-25T17:47:31: %YDK-INFO: CREATE operation initiated
Validation error for property NetworkInstances.NetworkInstance.Config.enabled_address_families . Error message (INVALID_TYPE, Invalid type: 'YListItem'. Expected type: 'Address_FamilyIdentity').
2019-03-25T17:47:31: %YDK-ERROR: Validation error for property NetworkInstances.NetworkInstance.Config.enabled_address_families . Error message (INVALID_TYPE, Invalid type: 'YListItem'. Expected type: 'Address_FamilyIdentity').
Validation error for property NetworkInstances.NetworkInstance.Config.enabled_address_families . Error message (INVALID_TYPE, Invalid type: 'YListItem'. Expected type: 'Address_FamilyIdentity').
2019-03-25T17:47:31: %YDK-ERROR: Validation error for property NetworkInstances.NetworkInstance.Config.enabled_address_families . Error message (INVALID_TYPE, Invalid type: 'YListItem'. Expected type: 'Address_FamilyIdentity').
CREATE operation completed
2019-03-25T17:47:31: %YDK-INFO: CREATE operation completed
*** ydk.errors.YPYModelError:
  NetworkInstances.NetworkInstance.Config.enabled_address_families: (INVALID_TYPE, Invalid type: 'YListItem'. Expected type: 'Address_FamilyIdentity')
  NetworkInstances.NetworkInstance.Config.enabled_address_families: (INVALID_TYPE, Invalid type: 'YListItem'. Expected type: 'Address_FamilyIdentity')

But if I use the original ydk obj, it does not have any issue

(Pdb) feature_create =parameters['ydk_service'].create(rtr.provider['config'],rtr.feature_cfg_obj[feature]['tc_setup_config']). <<<<<<<ß------- this works fine

Steps to Reproduce

Your Script

Logs

Enable logging and post the logs below

System Information

ghost commented 5 years ago

Issue can be reproduced with below

from ydk.models.openconfig import openconfig_policy_types, openconfig_network_instance, openconfig_types 
import copy

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

codec = CodecService() 
codec_p = CodecServiceProvider(type="xml") 

nis = openconfig_network_instance.NetworkInstances()                                   
ni = openconfig_network_instance.NetworkInstances.NetworkInstance() 
ni.name = 'default'       
ni.config.enabled_address_families.append(openconfig_types.Ipv4Identity()) 
p = openconfig_network_instance.NetworkInstances.NetworkInstance.Protocols.Protocol() 
p.identifier = openconfig_policy_types.BgpIdentity() 
p.name = 'BGP' 

p.bgp.global_.config.as_ = 65001 
ni.protocols.protocol.append(p) 
nis.network_instance.append(ni) 

nis_copy = copy.deepcopy(nis) 
x =  codec.encode(codec_p, nis)

x_copy =  codec.encode(codec_p, nis_copy)                                                                                                      
---------------------------------------------------------------------------
YPYModelError                             Traceback (most recent call last)
<ipython-input-6-885fe83e15a9> in <module>
      1 x =  codec.encode(codec_p, nis)
      2 
----> 3 x_copy =  codec.encode(codec_p, nis_copy)

~/p_055/lib/python3.7/site-packages/ydk/services/codec_service.py in encode(self, encoder, entity)
     38             raise YPYServiceError(error_msg=msg)
     39         self.service_logger.info('Encoding operation initiated')
---> 40         payload = self.operate_on_object_or_dictionary(entity, CodecService._encode_entity, [encoder])
     41         self.service_logger.info('Encoding operation completed')
     42         return payload

~/p_055/lib/python3.7/site-packages/ydk/services/service.py in operate_on_object_or_dictionary(self, entity, function, args)
     30                 result[module] = function(child, *args)
     31         else:
---> 32             result = function(entity, *args)
     33         return result
     34 

~/p_055/lib/python3.7/site-packages/ydk/services/codec_service.py in _encode_entity(entity, encoder)
     59     def _encode_entity(entity, encoder):
     60         MetaService.normalize_meta([], entity)
---> 61         payload = encoder._encode(entity)
     62         return payload

~/p_055/lib/python3.7/site-packages/ydk/providers/codec_provider.py in _encode(self, entity)
     56     def _encode(self, entity):
     57         """ Encodes the entity into the desired encoding format """
---> 58         payload = self.encoder.encode(entity)
     59         self.logger.info('Result of encoding: \n{0}'.format(payload))
     60         return payload

~/p_055/lib/python3.7/site-packages/ydk/providers/_encoder.py in encode(self, entity)
     36     def encode(self, entity):
     37         ''' Convert the entity to an xml payload '''
---> 38         return etree.tostring(self.encode_to_xml(entity, etree.Element('a'), '', validate=is_yvalidate(entity)),
     39                               method='xml', pretty_print='True', encoding='utf-8').decode('utf-8')
     40 

~/p_055/lib/python3.7/site-packages/ydk/providers/_encoder.py in encode_to_xml(self, entity, root, optype, is_filter, validate)
    101                 child_list = value
    102                 for child in child_list:
--> 103                     self.encode_to_xml(child, elem, optype, validate=is_yvalidate(child, validate))
    104             elif member.mtype == REFERENCE_LEAFLIST and isinstance(value, list):
    105                 if hasattr(value, 'yfilter'):

~/p_055/lib/python3.7/site-packages/ydk/providers/_encoder.py in encode_to_xml(self, entity, root, optype, is_filter, validate)
     97                 continue
     98             elif member.mtype == REFERENCE_CLASS:
---> 99                 self.encode_to_xml(value, elem, optype, validate=is_yvalidate(value, validate))
    100             elif member.mtype == REFERENCE_LIST:
    101                 child_list = value

~/p_055/lib/python3.7/site-packages/ydk/providers/_encoder.py in encode_to_xml(self, entity, root, optype, is_filter, validate)
     48 
     49         if (validate):
---> 50             validate_entity(entity, optype)
     51 
     52         if entity_is_rpc_input(entity):

~/p_055/lib/python3.7/site-packages/ydk/providers/_validator.py in validate_entity(entity, optype)
     44         _errors.insert(0, '')
     45         errmsg = '\n  '.join(_errors)
---> 46         raise YPYModelError(errmsg)
     47 
     48 

YPYModelError: 
  NetworkInstances.NetworkInstance.Config.enabled_address_families: (INVALID_TYPE, Invalid type: 'YListItem'. Expected type: 'Address_FamilyIdentity')
ghost commented 5 years ago

Fixed with 69bbf2f7d7fb82a213bafc4dd545f07b763f7b6c