def expand_forward_edges_in_scope(dgraph_client: DgraphClient, node: BaseView, lens: str) -> None: for edge_name, edge_type in node._get_forward_edge_types().items(): if isinstance(edge_type, list): inner_edge_type = edge_type[0] else: inner_edge_type = edge_type edges_in_lens = edge_in_lens(dgraph_client, node.uid, edge_name, lens) for edge in edges_in_lens: for neighbors in edge.values(): if not isinstance(neighbors, list): neighbors = [neighbors] for neighbor in neighbors: if neighbor.get("~scope"): neighbor.pop("~scope") node_edge = getattr(node, edge_name) try: neighbor_view = inner_edge_type( dgraph_client, node_key=neighbor["node_key"], uid=neighbor["uid"], ) except Exception as e: LOGGER.error(f"neighbor_view failed with: {e}") continue LOGGER.debug(neighbor_view, neighbor_view.uid, neighbor_view.node_key) if isinstance(node_edge, list): node_edge.append(neighbor_view) else: node_edge = neighbor_view setattr(node, edge_name, node_edge)
def from_dict(cls: Type[V], d: Dict[str, Any], graph_client: Any) -> V: from grapl_analyzerlib.nodes.base import BaseView self_schema = cls.node_schema() self_props = {} for name, value in d.items(): # If it's a property ty = self_schema.prop_type( name) # type: Union[Tuple[EdgeT, str], PropType, None] if ty is None: # This can happen if you're working with BaseViews, since we may not have the schema # but are still working with predicates # Rather than enforcing the type via schema we infer it and set it LOGGER.debug(f"Could not find type: {name} {value} {ty}") if isinstance(value, dict): if value.get("uid"): value = BaseView.from_dict(value, graph_client) if isinstance(value, list): if value and value[0].get("uid"): value = [ BaseView.from_dict(v, graph_client) for v in value ] self_props[name] = value elif isinstance(ty, PropType): deserialized_prop = deserialize_prop(value, ty) self_props[name] = deserialized_prop elif isinstance(ty[0], EdgeT) and isinstance(ty[1], str): edge_ty: EdgeT = ty[0] # rev_name: str = ty[ # 1 # ] # TODO: We should add a reverse edge from our neighbor to us edge_viewable: Any = edge_ty.dest().associated_viewable() self_props[name] = deserialize_edge(edge_viewable, edge_ty, value, graph_client) else: raise NotImplementedError self_props["node_types"] = self_props.pop("dgraph.type") self_node = cls(graph_client=graph_client, **self_props) return self_node
def lens_to_dict(dgraph_client: DgraphClient, lens_name: str) -> List[Dict[str, Any]]: current_graph = get_lens_scope(dgraph_client, lens_name) LOGGER.info(f"Getting lens as dict {current_graph}") if not current_graph or not current_graph.get("scope"): return [] nodes = [] for graph in current_graph["scope"]: try: nodes.append(BaseView.from_dict(dgraph_client, graph)) except Exception as e: LOGGER.error("Failed to get NodeView from dict", e) if current_graph.get("scope"): current_graph.pop("scope") for node in nodes: node.expand() node.get_neighbor( EntityQuery, "expand(_all_)", "", EntityQuery().with_lenses( LensQuery().with_lens_name(eq=lens_name)), ) results = [{"node": current_graph, "edges": []}] lens_risks = get_lens_risks(dgraph_client, lens_name) for node in lens_risks: edges = [] risks = node.get("risks", []) if not risks: LOGGER.warning( f"Node in engagement graph has no connected risks {node}") for risk in risks: try: risk["node_key"] = node["node_key"] + risk["analyzer_name"] edge = { "from": node["node_key"], "edge_name": "risks", "to": risk["node_key"], } edges.append(edge) except Exception as e: LOGGER.error(f"risk edge failed: {risk} {e}") results.append({ "node": node, "edges": edges, }) results.extend([n.to_dict() for n in concrete_nodes]) results.extend(expanded_dynamic_nodes) return results