def _update_recurse(self, endpoint=None, max_depth=3, data=None): """ Update data about remote system :param endpoint: Endpoint from which recursive update starts :param max_depth: Maximum depth for recursive update. This parameter is essential to prevent reference loop :param data: Common dictionary which stores collected data on all levels of recursion :return: Dictionary with endpoints as keys and fresh data stored beneath such endpoint as dictionary value """ if not endpoint: endpoint = self.endpoint if endpoint[-1] == '/': endpoint = endpoint[:-1] if not data: data = {} # LOGGER.info(f"Updating data from {endpoint} with depth {max_depth}") if max_depth == 0 or endpoint in data.keys(): return data #print(endpoint) resp = self.get_data(endpoint) data[endpoint] = resp if isinstance(resp, dict): for key, value in resp.items(): if key == '@odata.id': if value == endpoint: continue data = self._update_recurse(value, max_depth - 1, data) if utils.is_iterable(value): endpoints = RedfishTools._endpoint_inception(value) for endp in endpoints: data = self._update_recurse(endp, max_depth - 1, data) return data
def _search_recurse(self, name, structure=None, i=0): """ Searches for `name` iterable object :param name: Name to search :param structure: Iterable structure to search in :param all_data: Common list with all collected pairs (key, value) passed through all levels of recursion :param i: just for debugging :return: List with all collected pairs (key, value) containing `name` """ tuple_list = [] if isinstance(structure, dict): for key, value in structure.items(): if utils.is_iterable(value): tuples = self._search_recurse(name, value, i + 1) if tuples: prefixed_tuples = utils.prefix_tuples(key, tuples) tuple_list += prefixed_tuples if name in (key, value): tuple_list.append((key, value)) elif isinstance(structure, list): for elem in structure: tuple_list += self._search_recurse(name, elem, i + 1) return tuple_list
def _get_basic_info(self, data=None): self._fetch() return_data = {} if not data: data = self.data for key, value in data.items(): if not utils.is_iterable(value): return_data[key] = value return self.filter_data(return_data)
def snake_case_dict(self, data): "Converts dictionary keys from CamelCase to snake_case" if not utils.is_iterable(data): return data # iterate over list and check them if isinstance(data, list): new_data = [ self.snake_case_dict(elem) for elem in data] return new_data # such element is in this dictionary new_data = {} for key, value in data.items(): new_key = underscore(key).replace(' ', '_') new_data[new_key] = self.snake_case_dict(value) return new_data
def _get_dict_containing(self, name, data=None, misses=5): """ finds a dictionary containing 'name' as key or value in data stored locally retrieved earlier from Redfish connector :param name: name to search in 'self.data' :return: dictionary containing name as key or value """ # starting point - default argument if data is None: data = self.data # we went too deep or cannot iterate over data if not misses or not utils.is_iterable(data): return None found = None # iterate over list and check them if isinstance(data, list): for elem in data: found = self._get_dict_containing(name, elem, misses) if found: return found return None # such element is in this dictionary for key, value in data.items(): try: if name in key or name in value: return data except TypeError: pass # if not found in current dictionary, we search through curent dict values for value in data.values(): found = self._get_dict_containing(name, value, misses-1) if found: return found return None
def filter_data(data, dot_replacement='-'): "Removes all odata entries and dots from data" if not utils.is_iterable(data): return data new_data = None if isinstance(data, list): new_data = [] for elem in data: new_elem = RedfishTools.filter_data(elem) if new_elem: new_data.append(new_elem) else: new_data = {} for key, value in data.items(): if 'odata' not in key: new_value = RedfishTools.filter_data(value) if new_value: key = key.replace('.', dot_replacement) new_data[key] = new_value return new_data
def _endpoint_inception(iterable, max_depth=3, endpoints=None): """ We need to go deeper. Aka extract_endpoints(). Search for every endpoint reference stored in iterable (list, dict) object. """ if not endpoints: endpoints = [] if isinstance(iterable, list): for elem in iterable: endpoints = RedfishTools._endpoint_inception(elem, max_depth - 1, endpoints) if isinstance(iterable, dict): for key, value in iterable.items(): if utils.is_iterable(value): endpoints = RedfishTools._endpoint_inception( value, max_depth - 1, endpoints) elif key == '@odata.id': endp = value.split('#')[0] if endp not in endpoints: endpoints.append(endp) return endpoints