def read_msg(self, message: Any) -> AcsReadMsgResult: """ Send DeleteObject message to TR-069 and poll for response(s). Input: - Object name (string) """ if type(message) == models.DeleteObjectResponse: if message.Status != 0: raise Tr069Error( 'Received DeleteObjectResponse with ' 'Status=%d' % message.Status, ) elif type(message) == models.Fault: raise Tr069Error( 'Received Fault in response to DeleteObject ' '(faultstring = %s)' % message.FaultString, ) else: return AcsReadMsgResult(False, None) self.acs.device_cfg.delete_object(self.deleted_param) obj_list_to_delete = get_all_objects_to_delete( self.acs.desired_cfg, self.acs.device_cfg, ) if len(obj_list_to_delete) > 0: return AcsReadMsgResult(True, None) if len( get_all_objects_to_add( self.acs.desired_cfg, self.acs.device_cfg, ), ) == 0: return AcsReadMsgResult(True, self.skip_transition) return AcsReadMsgResult(True, self.add_obj_transition)
def get_next_state(self) -> str: should_get_params = \ len( get_params_to_get( self.acs.device_cfg, self.acs.data_model, ), ) > 0 if should_get_params: return self.done_transition should_get_obj_params = \ len( get_object_params_to_get( self.acs.desired_cfg, self.acs.device_cfg, self.acs.data_model, ), ) > 0 if should_get_obj_params: return self.get_obj_params_transition elif len( get_all_objects_to_delete( self.acs.desired_cfg, self.acs.device_cfg, ), ) > 0: return self.rm_obj_transition elif len( get_all_objects_to_add( self.acs.desired_cfg, self.acs.device_cfg, ), ) > 0: return self.add_obj_transition return self.skip_transition
def get_msg(self) -> AcsMsgAndTransition: request = models.AddObject() self.added_param = get_all_objects_to_add(self.acs.desired_cfg, self.acs.device_cfg)[0] request.ObjectName = \ self.acs.data_model.get_parameter(self.added_param).path return AcsMsgAndTransition(request, None)
def read_msg(self, message: Any) -> AcsReadMsgResult: """ Process GetParameterValuesResponse Object parameters that have a reported value of None indicate that the object is not in the eNB's configuration. Most eNB devices will reply with a Fault message if we try to get values of parameters that don't exist on the data model, so this is an idiosyncrasy of Baicells QAFB. """ if not isinstance(message, models.GetParameterValuesResponse): return AcsReadMsgResult(False, None) path_to_val = {} for param_value_struct in message.ParameterList.ParameterValueStruct: path_to_val[param_value_struct.Name] = \ param_value_struct.Value.Data logger.debug('Received object parameters: %s', str(path_to_val)) num_plmns = self.acs.data_model.get_num_plmns() for i in range(1, num_plmns + 1): obj_name = ParameterName.PLMN_N % i obj_to_params = self.acs.data_model.get_numbered_param_names() param_name_list = obj_to_params[obj_name] for name in param_name_list: path = self.acs.data_model.get_parameter(name).path if path in path_to_val: value = path_to_val[path] if value is None: continue if obj_name not in self.acs.device_cfg.get_object_names(): self.acs.device_cfg.add_object(obj_name) magma_value = \ self.acs.data_model.transform_for_magma(name, value) self.acs.device_cfg.set_parameter_for_object(name, magma_value, obj_name) # Now we have enough information to build the desired configuration if self.acs.desired_cfg is None: self.acs.desired_cfg = build_desired_config( self.acs.mconfig, self.acs.service_config, self.acs.device_cfg, self.acs.data_model, self.acs.config_postprocessor, ) if len(get_all_objects_to_delete(self.acs.desired_cfg, self.acs.device_cfg)) > 0: return AcsReadMsgResult(True, self.rm_obj_transition) elif len(get_all_objects_to_add(self.acs.desired_cfg, self.acs.device_cfg)) > 0: return AcsReadMsgResult(True, self.add_obj_transition) elif len(get_all_param_values_to_set(self.acs.desired_cfg, self.acs.device_cfg, self.acs.data_model)) > 0: return AcsReadMsgResult(True, self.set_params_transition) return AcsReadMsgResult(True, self.skip_transition)
def read_msg(self, message: Any) -> Optional[str]: """ Send DeleteObject message to TR-069 and poll for response(s). Input: - Object name (string) """ if type(message) == models.DeleteObjectResponse: if message.Status != 0: raise Tr069Error('Received DeleteObjectResponse with ' 'Status=%d' % message.Status) elif type(message) == models.Fault: raise Tr069Error('Received Fault in response to DeleteObject ' '(faultstring = %s)' % message.FaultString) else: raise Tr069Error('Unexpected response type: %s' % type(message)) self.acs.device_cfg.delete_object(self.deleted_param) obj_list_to_delete = get_all_objects_to_delete(self.acs.desired_cfg, self.acs.device_cfg) if len(obj_list_to_delete) > 0: return None if len( get_all_objects_to_add(self.acs.desired_cfg, self.acs.device_cfg)) is 0: return self.skip_transition return self.add_obj_transition
def read_msg(self, message: Any) -> AcsReadMsgResult: """ Process GetParameterValuesResponse """ if not isinstance(message, models.GetParameterValuesResponse): return AcsReadMsgResult(False, None) path_to_val = {} for param_value_struct in message.ParameterList.ParameterValueStruct: path_to_val[param_value_struct.Name] = \ param_value_struct.Value.Data logging.debug('Received object parameters: %s', str(path_to_val)) # TODO: This might a string for some strange reason, investigate why # Get the names of parameters belonging to numbered objects num_plmns = \ int(self.acs.device_cfg.get_parameter(ParameterName.NUM_PLMNS)) for i in range(1, num_plmns + 1): obj_name = ParameterName.PLMN_N % i obj_to_params = self.acs.data_model.get_numbered_param_names() param_name_list = obj_to_params[obj_name] for name in param_name_list: path = self.acs.data_model.get_parameter(name).path value = path_to_val[path] magma_val = \ self.acs.data_model.transform_for_magma(name, value) self.acs.device_cfg.set_parameter_for_object( name, magma_val, obj_name) # Now we can have the desired state if self.acs.desired_cfg is None: self.acs.desired_cfg = build_desired_config( self.acs.mconfig, self.acs.service_config, self.acs.device_cfg, self.acs.data_model, self.acs.config_postprocessor, ) if len( get_all_objects_to_delete(self.acs.desired_cfg, self.acs.device_cfg)) > 0: return AcsReadMsgResult(True, self.rm_obj_transition) elif len( get_all_objects_to_add(self.acs.desired_cfg, self.acs.device_cfg)) > 0: return AcsReadMsgResult(True, self.add_obj_transition) elif len( get_all_param_values_to_set(self.acs.desired_cfg, self.acs.device_cfg, self.acs.data_model)) > 0: return AcsReadMsgResult(True, self.set_params_transition) return AcsReadMsgResult(True, self.skip_transition)
def get_msg(self, message: Any) -> AcsMsgAndTransition: request = models.AddObject() self.added_param = get_all_objects_to_add(self.acs.desired_cfg, self.acs.device_cfg)[0] desired_param = self.acs.data_model.get_parameter(self.added_param) desired_path = desired_param.path path_parts = desired_path.split('.') # If adding enumerated object, ie. XX.N. we should add it to the # parent object XX. so strip the index if len(path_parts) > 2 and \ path_parts[-1] == '' and path_parts[-2].isnumeric(): logger.debug('Stripping index from path=%s', desired_path) desired_path = '.'.join(path_parts[:-2]) + '.' request.ObjectName = desired_path return AcsMsgAndTransition(request, None)
def read_msg(self, message: Any) -> Optional[str]: if type(message) == models.Fault: logger.error('Received Fault in response to SetParameterValues') if message.SetParameterValuesFault is not None: for fault in message.SetParameterValuesFault: logger.error( 'SetParameterValuesFault Param: %s, Code: %s, String: %s', fault.ParameterName, fault.FaultCode, fault.FaultString, ) raise Tr069Error( 'Received Fault in response to SetParameterValues ' '(faultstring = %s)' % message.FaultString, ) elif not isinstance(message, models.SetParameterValuesResponse): return AcsReadMsgResult(False, None) if message.Status != 0: raise Tr069Error( 'Received SetParameterValuesResponse with ' 'Status=%d' % message.Status, ) param_name = ParameterName.ADMIN_STATE desired_admin_value = \ self.acs.desired_cfg.get_parameter(param_name) \ and self.admin_value magma_value = \ self.acs.data_model.transform_for_magma( param_name, desired_admin_value, ) self.acs.device_cfg.set_parameter(param_name, magma_value) if len( get_all_objects_to_delete( self.acs.desired_cfg, self.acs.device_cfg, ), ) > 0: return AcsReadMsgResult(True, self.del_obj_transition) elif len( get_all_objects_to_add( self.acs.desired_cfg, self.acs.device_cfg, ), ) > 0: return AcsReadMsgResult(True, self.add_obj_transition) else: return AcsReadMsgResult(True, self.done_transition)
def read_msg(self, message: Any) -> AcsReadMsgResult: if type(message) == models.AddObjectResponse: if message.Status != 0: raise Tr069Error('Received AddObjectResponse with ' 'Status=%d' % message.Status) elif type(message) == models.Fault: raise Tr069Error('Received Fault in response to AddObject ' '(faultstring = %s)' % message.FaultString) else: return AcsReadMsgResult(False, None) instance_n = message.InstanceNumber self.acs.device_cfg.add_object(self.added_param % instance_n) obj_list_to_add = get_all_objects_to_add(self.acs.desired_cfg, self.acs.device_cfg) if len(obj_list_to_add) > 0: return AcsReadMsgResult(True, None) return AcsReadMsgResult(True, self.done_transition)
def read_msg(self, message: Any) -> AcsReadMsgResult: """ Process GetParameterValuesResponse """ if not isinstance(message, models.GetParameterValuesResponse): return AcsReadMsgResult(False, None) path_to_val = {} if hasattr(message.ParameterList, 'ParameterValueStruct') and \ message.ParameterList.ParameterValueStruct is not None: for param_value_struct in message.ParameterList.ParameterValueStruct: path_to_val[param_value_struct.Name] = \ param_value_struct.Value.Data logger.debug('Received object parameters: %s', str(path_to_val)) # Number of PLMN objects reported can be incorrect. Let's count them num_plmns = 0 obj_to_params = self.acs.data_model.get_numbered_param_names() while True: obj_name = ParameterName.PLMN_N % (num_plmns + 1) if obj_name not in obj_to_params or len( obj_to_params[obj_name]) == 0: logger.warning( "eNB has PLMN %s but not defined in model", obj_name, ) break param_name_list = obj_to_params[obj_name] obj_path = self.acs.data_model.get_parameter( param_name_list[0]).path if obj_path not in path_to_val: break if not self.acs.device_cfg.has_object(obj_name): self.acs.device_cfg.add_object(obj_name) num_plmns += 1 for name in param_name_list: path = self.acs.data_model.get_parameter(name).path value = path_to_val[path] magma_val = \ self.acs.data_model.transform_for_magma(name, value) self.acs.device_cfg.set_parameter_for_object( name, magma_val, obj_name, ) num_plmns_reported = \ int(self.acs.device_cfg.get_parameter(ParameterName.NUM_PLMNS)) if num_plmns != num_plmns_reported: logger.warning( "eNB reported %d PLMNs but found %d", num_plmns_reported, num_plmns, ) self.acs.device_cfg.set_parameter( ParameterName.NUM_PLMNS, num_plmns, ) # Now we can have the desired state if self.acs.desired_cfg is None: self.acs.desired_cfg = build_desired_config( self.acs.mconfig, self.acs.service_config, self.acs.device_cfg, self.acs.data_model, self.acs.config_postprocessor, ) if len( get_all_objects_to_delete( self.acs.desired_cfg, self.acs.device_cfg, ), ) > 0: return AcsReadMsgResult(True, self.rm_obj_transition) elif len( get_all_objects_to_add( self.acs.desired_cfg, self.acs.device_cfg, ), ) > 0: return AcsReadMsgResult(True, self.add_obj_transition) elif len( get_all_param_values_to_set( self.acs.desired_cfg, self.acs.device_cfg, self.acs.data_model, ), ) > 0: return AcsReadMsgResult(True, self.set_params_transition) return AcsReadMsgResult(True, self.skip_transition)
def read_msg(self, message: Any) -> AcsReadMsgResult: """ Process GetParameterValuesResponse """ if not isinstance(message, models.GetParameterValuesResponse): return AcsReadMsgResult(msg_handled=False, next_state=None) path_to_val = {} for param_value_struct in message.ParameterList.ParameterValueStruct: path_to_val[param_value_struct.Name] = \ param_value_struct.Value.Data EnodebdLogger.debug('Received object parameters: %s', str(path_to_val)) # Parse simple params param_name_list = self.acs.data_model.get_parameter_names() for name in param_name_list: path = self.acs.data_model.get_parameter(name).path if path in path_to_val: value = path_to_val.get(path) magma_val = \ self.acs.data_model.transform_for_magma( name, value, ) self.acs.device_cfg.set_parameter(name, magma_val) # Parse object params num_plmns = self.acs.data_model.get_num_plmns() for i in range(1, num_plmns + 1): obj_name = ParameterName.PLMN_N % i obj_to_params = self.acs.data_model.get_numbered_param_names() param_name_list = obj_to_params[obj_name] for name in param_name_list: path = self.acs.data_model.get_parameter(name).path if path in path_to_val: value = path_to_val.get(path) if value is None: continue if obj_name not in self.acs.device_cfg.get_object_names(): self.acs.device_cfg.add_object(obj_name) magma_value = \ self.acs.data_model.transform_for_magma(name, value) self.acs.device_cfg.set_parameter_for_object( name, magma_value, obj_name, ) # Now we have enough information to build the desired configuration if self.acs.desired_cfg is None: self.acs.desired_cfg = build_desired_config( self.acs.mconfig, self.acs.service_config, self.acs.device_cfg, self.acs.data_model, self.acs.config_postprocessor, ) if len( get_all_objects_to_delete( self.acs.desired_cfg, self.acs.device_cfg, ), ) > 0: return AcsReadMsgResult( msg_handled=True, next_state=self.rm_obj_transition, ) elif len( get_all_objects_to_add( self.acs.desired_cfg, self.acs.device_cfg, ), ) > 0: return AcsReadMsgResult( msg_handled=True, next_state=self.add_obj_transition, ) elif len( get_all_param_values_to_set( self.acs.desired_cfg, self.acs.device_cfg, self.acs.data_model, ), ) > 0: return AcsReadMsgResult( msg_handled=True, next_state=self.set_params_transition, ) return AcsReadMsgResult( msg_handled=True, next_state=self.skip_transition, )