def _perform_read_filter_check(self, read_filter): if read_filter is None: self.service_logger.error('Passed in a None filter') raise YPYServiceError('Filter cannot be None') if not isinstance(read_filter, YList) and not hasattr( read_filter, '_meta_info'): self.service_logger.error('Illegal filter type passed in for read') raise YPYServiceError('Illegal filter')
def _perform_read_filter_check(self, read_filter): if read_filter is None: self.service_logger.error('Passed in a None filter') err_msg = "'filter' cannot be None" raise YPYServiceError(error_msg=err_msg) if not isinstance(read_filter, YList) and not hasattr( read_filter, '_meta_info'): err_msg = "Illegal 'filter' type passed in for read" self.service_logger.error(err_msg) raise YPYServiceError(error_msg=err_msg)
def get_config(self, provider, source, get_filter, with_defaults_option=None): """Execute a get-config operation to retrieve all or part of a specified configuration. Args: provider (ydk.providers.ServiceProvider): A provider instance. source (Datastore): Particular configuration to retrieve. Valid options are Datastore.candidate, Datastore.running, and Datastore.startup. get_filter (object): A YDK entity object used as a subtree filter or XPath filter. with_defaults (WithDefaultsModeEnum): The explicit defaults processing mode requested. Returns: A YDK entity object represents copy of the running datastore subset and/or state data that matched the filter criteria (if any). An empty data container indicates that the request did not produce any results. Raises: YPYModelError: If validation error occurs. YPYServiceError: If other error has occurred. Possible errors could be: - A server side error - If there isn't enough information in the entity to prepare the message (missing keys for example). """ if source is None: err_msg = "'source' cannot be None" raise YPYServiceError(error_msg=err_msg) if with_defaults_option is not None and not isinstance(with_defaults_option, ietf_netconf_with_defaults.WithDefaultsModeEnum): err_msg = "optional arg 'with_defaults_option' must be of type ietf_netconf_with_defaults.WithDefaultsModeEnum" raise YPYServiceError(error_msg=err_msg) self.service_logger.info('Executing get-config RPC') rpc = ietf_netconf.GetConfigRpc() rpc.input.filter = get_filter _validate_datastore_options(source, 'get-config:source') rpc.input.source = _get_rpc_datastore_object(source, rpc.input.source) rpc.input.with_defaults = with_defaults_option rpc = MetaService.normalize_meta(provider._get_capabilities(), rpc) result = provider.execute( provider.sp_instance.encode_rpc(rpc), '' ) result = payload_convert(result) if len(result) == 0: return None return provider.decode(result, None)
def edit_config(self, provider, target, config, default_operation=None, error_option=None, test_option=None): """Execute an edit-config operation to load all or part of a specified configuration to the specified target configuration. Args: provider (ydk.providers.ServiceProvider): A provider instance. target (Datastore): Particular configuration to copy from. Valid options are Datastore.candidate, Datastore.running. config (object): A YDK entity object used as a config block. default_operation (EditConfigRpc.Input.DefaultOperationEnum): Selects the default operation for this edit-config request. error_option (EditConfigRpc.Input.ErrorOptionEnum): Selects the error option for this edit-config request. test_option (EditConfigRpc.Input.TestOptionEnum): Selects the test option for this edit-config request. Returns: An ok reply string if operation succeeds. Raises: YPYModelError: If validation error occurs. YPYServiceError: If other error has occurred. Possible errors could be: - A server side error - If there isn't enough information in the entity to prepare the message (missing keys for example). """ if None in (target, config): self.service_logger.error('Passed in a None arg') err_msg = "'target' and 'config' cannot be None" raise YPYServiceError(error_msg=err_msg) if default_operation is not None and not isinstance(default_operation, ietf_netconf.EditConfigRpc.Input.DefaultOperationEnum): err_msg = "optional arg 'default_operation' must be of type ietf_netconf.EditConfigRpc.Input.DefaultOperationEnum" raise YPYServiceError(error_msg=err_msg) if error_option is not None and not isinstance(error_option, ietf_netconf.EditConfigRpc.Input.ErrorOptionEnum): err_msg = "optional arg 'error_option' must be of type ietf_netconf.EditConfigRpc.Input.ErrorOptionEnum" raise YPYServiceError(error_msg=err_msg) if test_option is not None and not isinstance(test_option, ietf_netconf.EditConfigRpc.Input.TestOptionEnum): err_msg = "optional arg 'test_option' must be of type ietf_netconf.EditConfigRpc.Input.TestOptionEnum" raise YPYServiceError(error_msg=err_msg) self.service_logger.info('Executing edit-config RPC') rpc = ietf_netconf.EditConfigRpc() _validate_datastore_options(target, 'edit-config:target') rpc.input.target = _get_rpc_datastore_object(target, rpc.input.target) rpc.input.config = config rpc.input.default_operation = default_operation rpc.input.error_option = error_option rpc.input.test_option = test_option return self.executor.execute_rpc(provider, rpc)
def copy_config(self, provider, target, source, with_defaults_option=None): """ Execute a copy-config operation to create or replace an entire configuration datastore with the contents of another complete configuration datastore. Args: provider (ydk.providers.ServiceProvider): A provider instance. target (Datastore | str): Particular configuration to copy to. Valid options are Datastore.candidate, Datastore.running, Datastore.startup and url(str) if the device has such feature advertised in device capability. source (Datastore | str | object): Particular configuration to copy from. Valid options are Datastore.candidate, Datastore.running, Datastore.startup and url(str) if the deivce has such feature advertised in capability. YDK entity object could also be used as a config block for this parameter. with_defaults (WithDefaultsModeEnum): The explicit defaults processing mode requested. Returns: An ok reply string if operation succeeds. Raises: YPYModelError: If validation error occurs. YPYServiceError: If other error has occurred. Possible errors could be: - A server side error - If there isn't enough information in the entity to prepare the message (missing keys for example). """ if None in (target, source): self.service_logger.error('Passed in a None arg') err_msg = "'target' and 'source' cannot be None" raise YPYServiceError(error_msg=err_msg) if with_defaults_option is not None and not isinstance( with_defaults_option, ietf_netconf_with_defaults.WithDefaultsModeEnum): err_msg = "optional arg 'with_defaults_option' must be of type ietf_netconf_with_defaults.WithDefaultsModeEnum" raise YPYServiceError(error_msg=err_msg) self.service_logger.info('Executing copy-config RPC') rpc = ietf_netconf.CopyConfigRpc() _validate_datastore_options(source, 'copy-config:source') _validate_datastore_options(target, 'copy-config:target') rpc.input.source = _get_rpc_datastore_object(source, rpc.input.source) rpc.input.target = _get_rpc_datastore_object(target, rpc.input.target) rpc.input.with_defaults = with_defaults_option return self.executor.execute_rpc(provider, rpc)
def _entity_exists(self, provider, entity): if None in (provider, entity): self.service_logger.error('Passed in a None arg') err_msg = "'provider' and 'entity' cannot be None" raise YPYServiceError(error_msg=err_msg) read_entity = self.read(provider, self._create_update_entity_filter(entity)) if not read_entity._has_data(): err_msg = "'entity' does not exist on remote server - cannot perform update operation" self.service_logger.error(err_msg) raise YPYServiceError(error_msg=err_msg) return True
def validate(self, provider, source=None): """Execute a validate operation to validate the contents of the specified configuration. Args: provider (ydk.providers.ServiceProvider): A provider instance. source (Datastore | str | object): Particular configuration to validate. Valid options are Datastore.candidate, Datastore.running, Datastore.startup and url(str) if the deivce has such feature advertised in device capability. YDK entity object could also be used as a config block for this parameter. Returns: An ok reply string if operation succeeds. Raises: YPYModelError: If validation error occurs. YPYServiceError: If other error has occurred. Possible errors could be: - A server side error - If there isn't enough information in the entity to prepare the message (missing keys for example). """ if source is None: err_msg = "'source' cannot be None" raise YPYServiceError(error_msg=err_msg) self.service_logger.info('Executing validate RPC') rpc = ietf_netconf.ValidateRpc() if source is not None: _validate_datastore_options(source, 'validate:source') rpc.input.source = _get_rpc_datastore_object(source, rpc.input.source) return self.executor.execute_rpc(provider, rpc)
def unlock(self, provider, target): """Execute an unlock operation to release a configuration lock, previously obtained with the 'lock' operation. Args: provider (ydk.providers.ServiceProvider): A provider instance. target (Datastore): Particular configuration to unlock. Valid options are Datastore.candidate, Datastore.running, and Datastore.startup if the device has such feature advertised. Returns: An ok reply string if operation succeeds. Raises: YPYModelError: If validation error occurs. YPYServiceError: If other error has occurred. Possible errors could be: - A server side error - If there isn't enough information in the entity to prepare the message (missing keys for example). """ if target is None: err_msg = "'target' cannot be None" raise YPYServiceError(error_msg=err_msg) self.service_logger.info('Executing unlock RPC') rpc = ietf_netconf.UnlockRpc() _validate_datastore_options(target, 'unlock:target') rpc.input.target = _get_rpc_datastore_object(target, rpc.input.target) return self.executor.execute_rpc(provider, rpc)
def delete_config(self, provider, target): """Execute an delete-config operation to delete a configuration datastore. Args: provider (ydk.providers.ServiceProvider): A provider instance. target (Datastore.startup | str): Particular configuration to delete. Valid options are Datastore.startup or url(str). Returns: An ok reply string if operation succeeds. Raises: YPYModelError: If validation error occurs. YPYServiceError: If other error has occurred. Possible errors could be: - A server side error - If there isn't enough information in the entity to prepare the message (missing keys for example). """ if target is None: err_msg = "'target' cannot be None" raise YPYServiceError(error_msg=err_msg) self.service_logger.info('Executing delete-config RPC') rpc = ietf_netconf.DeleteConfigRpc() _validate_datastore_options(target, 'delete-config:target') rpc.input.target = _get_rpc_datastore_object(target, rpc.input.target) return self.executor.execute_rpc(provider, rpc)
def update(self, provider, entity): """ Update the entity Args: - provider: An instance of ydk.providers.ServiceProvider - entity: An an entity class defined under the ydk.models package or subpackages Note: - A given member of an entity can be deleted by setting its attribute to an instance of ydk.types.Delete class. - An entity can only be updated if it exists on the server. Otherwise a YPYServiceError will be raised Returns: None Raises: `YPYModelError <ydk.errors.html#ydk.errors.YPYModelError>`_ if validation failed. `YPYServiceError <ydk.errors.html#ydk.errors.YPYServiceError>`_ if other error has occurred. Possible errors could be a service side error or if there isn't enough information in the entity to prepare the message (missing keys for example) """ # first read the object if None in (provider, entity): self.service_logger.error('Passed in a None arg') err_msg = "'provider' and 'entity' cannot be None" raise YPYServiceError(error_msg=err_msg) #if self._entity_exists(provider, entity): # read has succeeded so do an edit-config MetaService.normalize_meta(provider._get_capabilities(), entity) self._execute_crud_operation_on_provider(provider, entity, 'UPDATE', False)
def read(self, provider, read_filter, only_config=False): """ Read the entity or entities Args: - provider: An instance of ydk.providers.ServiceProvider - read_filter: A read_filter is an instance of an entity class. An entity class is a class defined under the ydk.models package that is not an Enum , Identity of subclass of FixedBitsDict) . Attributes of this entity class may contain values that act as match expressions or can be explicitly marked as to be read by assigning an instance of ydk.types.READ class to them. - only_config: Flag that indicates that only data that represents configuration data is to be fetched. Default is set to False i.e. both oper and config data will be fetched. Returns: The entity or entities as identified by the read_filter. Raises: `YPYModelError <ydk.errors.html#ydk.errors.YPYModelError>`_ if validation failed. `YPYServiceError <ydk.errors.html#ydk.errors.YPYServiceError>`_ if other error has occurred. Possible errors could be - a server side error - if there isn't enough information in the entity to prepare the message (missing keys for example) - if the type to be returned cannot be determined. """ if None in (provider, read_filter): self.service_logger.error('Passed in a None arg') err_msg = "'provider' and 'read_filter' cannot be None" raise YPYServiceError(error_msg=err_msg) MetaService.normalize_meta(provider._get_capabilities(), read_filter) self._perform_read_filter_check(read_filter) payload = self._execute_crud_operation_on_provider( provider, read_filter, 'READ', only_config) return provider.decode(payload, read_filter)
def delete(self, provider, entity): """ Delete the entity Args: provider: An instance of ydk.providers.ServiceProvider entity: An an entity class defined under the ydk.models package or subpackages Returns: None Raises: `YPYModelError <ydk.errors.html#ydk.errors.YPYModelError>`_ if validation failed. `YPYServiceError <ydk.errors.html#ydk.errors.YPYServiceError>`_ if other error has occurred. Possible errors could be a service side error or if there isn't enough information in the entity to prepare the message (missing keys for example) """ if None in (provider, entity): self.service_logger.error('Passed in a None arg') err_msg = "'provider' and 'entity' cannot be None" raise YPYServiceError(error_msg=err_msg) MetaService.normalize_meta(provider._get_capabilities(), entity) self._execute_crud_operation_on_provider(provider, entity, 'DELETE', False)
def execute_rpc(self, provider, rpc): """ Execute the RPC Args: provider: An instance of ydk.providers.ServiceProvider rpc: An instance of an RPC class defined under the ydk.models package or subpackages Returns: None Raises: `YPYModelError <ydk.errors.html#ydk.errors.YPYModelError>`_ if validation. `YPYServiceError <ydk.errors.html#ydk.errors.YPYServiceError>`_ if other error has occurred. Possible errors could be - a server side error - if there isn't enough information in the entity to prepare the message (missing keys for example) """ if None in (provider, rpc): self.service_logger.error('Passed in a None arg') err_msg = "'provider' and 'rpc' cannot be None" raise YPYServiceError(error_msg=err_msg) try: rpc = MetaService.normalize_meta(provider._get_capabilities(), rpc) self.service_logger.info('Executor operation initiated') result = provider.execute(provider.sp_instance.encode_rpc(rpc), '') return provider.decode(result, rpc) finally: self.service_logger.info('Executor operation completed')
def decode(self, decoder, payload): if None in (decoder, payload): msg = "'decoder' and 'payload' cannot be None" raise YPYServiceError(error_msg=msg) self.service_logger.info('Decoding operation initiated') entity = self.operate_on_object_or_dictionary( payload, CodecService._decode_payload, [decoder]) self.service_logger.info('Decoding operation completed') return entity
def encode(self, encoder, entity): if None in (encoder, entity): msg = "'encoder' and 'entity' cannot be None" raise YPYServiceError(error_msg=msg) self.service_logger.info('Encoding operation initiated') payload = self.operate_on_object_or_dictionary( entity, CodecService._encode_entity, [encoder]) self.service_logger.info('Encoding operation completed') return payload
def _check_type_mismatch(value, member): # type mismatches for ATTRIBUTE, REFERENCE_ENUM, REFERENCE_IDENTITY, # REFREENCE_BITS and REFREENCE_ANYXML are covered by validation if member.mtype == REFERENCE_CLASS: value_clazz_name = value.__class__.__name__ member_clazz_name = member.clazz_name.split('.')[-1] if any(( # not value.__class__.__module__.startswith('ydk.models'), isinstance(value, list), value_clazz_name != member_clazz_name)): raise YPYServiceError(error_msg=_TYPE_MISMATCH_CLASS.format( value_clazz_name, member_clazz_name)) elif member.mtype == REFERENCE_LIST: if not type(value) == YList: raise YPYServiceError(error_msg=_TYPE_MISMATCH_LIST.format( value.__class__.__name__, member.name)) elif member.mtype == REFERENCE_LEAFLIST: if not type(value) == YLeafList: raise YPYServiceError(error_msg=_TYPE_MISMATCH_LLIST.format( value.__class__.__name__, member.name))
def _set_parent_imeta(entity, child_imeta=None): if isinstance(entity, (YList, YLeafList, YListItem)): _set_parent_imeta(entity.parent) elif entity: entity.i_meta = _copy_meta(entity._meta_info()) if child_imeta: child_imeta.parent = entity.i_meta if hasattr(entity, 'parent'): if entity.parent is entity: raise YPYServiceError(error_msg=_ERR_USER_PPOINTER) else: _set_parent_imeta(entity.parent, entity.i_meta)
def _create_update_entity_filter(self, entity): if entity is None: self.service_logger.error('Passed in a None entity') err_msg = "'entity' cannot be None" raise YPYServiceError(error_msg=err_msg) module = importlib.import_module(entity._meta_info().pmodule_name) update_filter = getattr(module, entity._meta_info().name)() # copy over the keys for key_member in entity._meta_info().key_members(): key_val = getattr(entity, key_member.presentation_name) update_filter.__dict__[key_member.presentation_name] = key_val return update_filter
def _execute_crud_operation_on_provider(self, provider, entity, operation, only_config): if None in (provider, entity, operation, only_config): self.service_logger.error('Passed in a None arg') err_msg = "'provider', 'entity', 'operation', and 'only_config' cannot be None" raise YPYServiceError(error_msg=err_msg) try: self.service_logger.info( '{0} operation initiated'.format(operation)) return self.execute_payload( provider, provider.encode(entity, operation, only_config), operation) finally: self.service_logger.info( '{0} operation completed'.format(operation))
def get(self, provider, get_filter, with_defaults_option=None): """Execute a get operation to retrieve running configuration and device state information. Args: provider (ydk.providers.ServiceProvider): A provider instance. get_filter (object): A YDK entity object specifies the portion of the system configuration and state data to retrieve. with_defaults (WithDefaultsModeEnum): The explicit defaults processing mode requested. Returns: A YDK entity object represents copy of the running datastore subset and/or state data that matched the filter criteria (if any). An empty data container indicates that the request did not produce any results Raises: YPYModelError: If validation error occurs. YPYServiceError: If other error has occurred. Possible errors could be: - A server side error - If there isn't enough information in the entity to prepare the message (missing keys for example). """ if with_defaults_option is not None and not isinstance(with_defaults_option, ietf_netconf_with_defaults.WithDefaultsModeEnum): err_msg = "optional arg 'with_defaults_option' must be of type ietf_netconf_with_defaults.WithDefaultsModeEnum" raise YPYServiceError(error_msg=err_msg) self.service_logger.info('Executing get RPC') rpc = ietf_netconf.GetRpc() rpc.input.filter = get_filter rpc.input.with_defaults = with_defaults_option rpc = MetaService.normalize_meta(provider._get_capabilities(), rpc) result = provider.execute( provider.sp_instance.encode_rpc(rpc), '' ) result = payload_convert(result) if len(result) == 0: return None return provider.decode(result, None)
def _validate_datastore_options(datastore, option): res = True if option == 'copy-config:target': res = isinstance(datastore, (str, Datastore)) elif option == 'copy-config:source': res = isinstance(datastore, (str, object, Datastore)) elif option == 'delete-config:target': res = isinstance(datastore, str) or datastore == Datastore.startup elif option == 'edit-config:target': res = datastore in (Datastore.candidate, Datastore.running) elif option == 'get-config:source': res = isinstance(datastore, Datastore) elif option == 'lock:target': res = isinstance(datastore, Datastore) elif option == 'unlock:target': res = isinstance(datastore, Datastore) elif option == 'validate:source': res = isinstance(datastore, (str, object, Datastore)) if not res: err_msg = _get_datastore_errmsg(option, datastore) raise YPYServiceError(error_msg=err_msg)
def normalize_meta(cls, capabilities, entity): """ Get meta information from entity._meta_info(), modify and inject i_meta attribute back to entity. Args: cls: First argument for class method capabilities: List of capabilities get from provider entity: An instance of YDK object Returns: entity: An instance of YDK object Raises: `YPYModelError <ydk.errors.html#ydk.errors.YPYModelError>`_ if try to access an unsupported feature. """ if None in (capabilities, entity): raise YPYServiceError(error_msg=_ERR_ARG_CHK) deviation_tables = MetaService.get_active_deviation_tables( capabilities, entity) MetaService.inject_imeta(entity, deviation_tables) return entity