func (o *OnDemandProbeClient) matchGremlinExpr(node *graph.Node, gremlin string) bool { tr := traversal.NewGremlinTraversalParser(strings.NewReader(gremlin), o.graph) ts, err := tr.Parse() if err != nil { logging.GetLogger().Errorf("Gremlin expression error: %s", err.Error()) return false } res, err := ts.Exec() if err != nil { logging.GetLogger().Errorf("Gremlin execution error: %s", err.Error()) return false } for _, value := range res.Values() { n, ok := value.(*graph.Node) if !ok { logging.GetLogger().Error("Gremlin expression doesn't return node") return false } if node.ID == n.ID { return true } } return false }
func TestGraphPathTraversal(t *testing.T) { g := newGraph(t) n1 := g.NewNode(graph.GenID(), graph.Metadata{"Type": "host", "Name": "localhost"}) n2 := g.NewNode(graph.GenID(), graph.Metadata{"Name": "N2", "Type": "T2"}) n3 := g.NewNode(graph.GenID(), graph.Metadata{"Name": "N3", "Type": "T3"}) g.Link(n1, n2, graph.Metadata{"RelationType": "ownership"}) g.Link(n2, n3, graph.Metadata{"RelationType": "ownership"}) query := `G.V().Has("Name", "N3").GraphPath()` tp := traversal.NewGremlinTraversalParser(strings.NewReader(query), g) tp.AddTraversalExtension(NewTopologyTraversalExtension()) ts, err := tp.Parse() if err != nil { t.Fatal(err.Error()) } res, err := ts.Exec() if err != nil { t.Fatal(err.Error()) } if len(res.Values()) != 1 || res.Values()[0].(string) != "localhost[Type=host]/N2[Type=T2]/N3[Type=T3]" { t.Fatalf("Should return 1 path, returned: %v", res.Values()) } }
func (pi *PacketInjectorApi) getNode(gremlinQuery string) *graph.Node { pi.Graph.RLock() defer pi.Graph.RUnlock() tr := traversal.NewGremlinTraversalParser(strings.NewReader(gremlinQuery), pi.Graph) ts, err := tr.Parse() if err != nil { return nil } res, err := ts.Exec() if err != nil { return nil } for _, value := range res.Values() { switch value.(type) { case *graph.Node: return value.(*graph.Node) default: return nil } } return nil }
func (c *CaptureApiHandler) getCaptureCount(r ApiResource) ApiResource { capture := r.(*Capture) tr := traversal.NewGremlinTraversalParser(strings.NewReader(capture.GremlinQuery), c.Graph) ts, err := tr.Parse() if err != nil { logging.GetLogger().Errorf("Gremlin expression error: %s", err.Error()) return r } res, err := ts.Exec() if err != nil { logging.GetLogger().Errorf("Gremlin execution error: %s", err.Error()) return r } for _, value := range res.Values() { switch value.(type) { case *graph.Node: n := value.(*graph.Node) if common.IsCaptureAllowed(n.Metadata()["Type"].(string)) { capture.Count = capture.Count + 1 } case []*graph.Node: capture.Count = capture.Count + len(value.([]*graph.Node)) default: capture.Count = 0 } } return capture }
func (t *TopologyApi) topologySearch(w http.ResponseWriter, r *auth.AuthenticatedRequest) { w.Header().Set("Content-Type", "application/json; charset=UTF-8") resource := Topology{} data, _ := ioutil.ReadAll(r.Body) if len(data) != 0 { if err := json.Unmarshal(data, &resource); err != nil { w.WriteHeader(http.StatusBadRequest) w.Write([]byte(err.Error())) return } if err := validator.Validate(resource); err != nil { w.WriteHeader(http.StatusBadRequest) w.Write([]byte(err.Error())) return } } if resource.GremlinQuery == "" { w.WriteHeader(http.StatusNoContent) return } tr := traversal.NewGremlinTraversalParser(strings.NewReader(resource.GremlinQuery), t.Graph) tr.AddTraversalExtension(topology.NewTopologyTraversalExtension()) if t.TableClient != nil { tr.AddTraversalExtension(ftraversal.NewFlowTraversalExtension(t.TableClient, t.Storage)) } ts, err := tr.Parse() if err != nil { w.WriteHeader(http.StatusBadRequest) w.Write([]byte(err.Error())) return } res, err := ts.Exec() if err != nil { w.WriteHeader(http.StatusBadRequest) w.Write([]byte(err.Error())) return } w.WriteHeader(http.StatusOK) if err := json.NewEncoder(w).Encode(res); err != nil { panic(err) } }
func isGremlinExpr(v interface{}, param string) error { query, ok := v.(string) if !ok { return GremlinNotValid(errors.New("not a string")) } tr := traversal.NewGremlinTraversalParser(strings.NewReader(query), &graph.Graph{}) tr.AddTraversalExtension(topology.NewTopologyTraversalExtension()) tr.AddTraversalExtension(ftraversal.NewFlowTraversalExtension(nil, nil)) if _, err := tr.Parse(); err != nil { return GremlinNotValid(err) } return nil }
func (o *OnDemandProbeListener) onCaptureDeleted(capture *api.Capture) { o.Graph.Lock() defer o.Graph.Unlock() tr := traversal.NewGremlinTraversalParser(strings.NewReader(capture.GremlinQuery), o.Graph) ts, err := tr.Parse() if err != nil { logging.GetLogger().Errorf("Gremlin expression error: %s", err.Error()) return } res, err := ts.Exec() if err != nil { logging.GetLogger().Errorf("Gremlin execution error: %s", err.Error()) return } for _, value := range res.Values() { switch value.(type) { case *graph.Node: if o.unregisterProbe(value.(*graph.Node)) { metadata := value.(*graph.Node).Metadata() metadata["State/FlowCapture"] = "OFF" delete(metadata, "CaptureID") o.Graph.SetMetadata(value.(*graph.Node), metadata) } case []*graph.Node: for _, node := range value.([]*graph.Node) { if o.unregisterProbe(node) { metadata := node.Metadata() metadata["State/FlowCapture"] = "OFF" delete(metadata, "CaptureID") o.Graph.SetMetadata(node, metadata) } } default: logging.GetLogger().Error("Gremlin expression doesn't return node") return } } }
func (o *OnDemandProbeListener) onCaptureAdded(capture *api.Capture) { o.Graph.Lock() defer o.Graph.Unlock() tr := traversal.NewGremlinTraversalParser(strings.NewReader(capture.GremlinQuery), o.Graph) ts, err := tr.Parse() if err != nil { logging.GetLogger().Errorf("Gremlin expression error: %s", err.Error()) return } res, err := ts.Exec() if err != nil { logging.GetLogger().Errorf("Gremlin execution error: %s", err.Error()) return } for _, value := range res.Values() { switch value.(type) { case *graph.Node: if o.registerProbe(value.(*graph.Node), capture) { t := o.Graph.StartMetadataTransaction(value.(*graph.Node)) t.AddMetadata("State/FlowCapture", "ON") t.AddMetadata("CaptureID", capture.UUID) t.Commit() } case []*graph.Node: for _, node := range value.([]*graph.Node) { if o.registerProbe(node, capture) { t := o.Graph.StartMetadataTransaction(node) t.AddMetadata("State/FlowCapture", "ON") t.AddMetadata("CaptureID", capture.UUID) t.Commit() } } default: logging.GetLogger().Error("Gremlin expression doesn't return node") return } } }
func (o *OnDemandProbeClient) onCaptureDeleted(capture *api.Capture) { o.Lock() defer o.Unlock() o.graph.Lock() defer o.graph.Unlock() delete(o.captures, capture.UUID) tr := traversal.NewGremlinTraversalParser(strings.NewReader(capture.GremlinQuery), o.graph) ts, err := tr.Parse() if err != nil { logging.GetLogger().Errorf("Gremlin expression error: %s", err.Error()) return } res, err := ts.Exec() if err != nil { logging.GetLogger().Errorf("Gremlin execution error: %s", err.Error()) return } for _, value := range res.Values() { switch e := value.(type) { case *graph.Node: if !o.unregisterProbe(e) { logging.GetLogger().Errorf("Failed to stop capture on %s", e.ID) } case []*graph.Node: for _, node := range e { if !o.unregisterProbe(node) { logging.GetLogger().Errorf("Failed to stop capture on %s", node.ID) } } default: logging.GetLogger().Error("Gremlin expression doesn't return node") return } } }
func TestRegexPredicate(t *testing.T) { g := newGraph(t) g.NewNode(graph.GenID(), graph.Metadata{"Type": "host", "Name": "localhost"}) query := `G.V().Has("Name", Regex("^local.*st$")).Count()` tp := traversal.NewGremlinTraversalParser(strings.NewReader(query), g) tp.AddTraversalExtension(NewTopologyTraversalExtension()) ts, err := tp.Parse() if err != nil { t.Fatal(err.Error()) } res, err := ts.Exec() if err != nil { t.Fatal(err.Error()) } if len(res.Values()) != 1 || res.Values()[0].(int) != 1 { t.Fatalf("Regex should exactly match 1 node, returned: %v", res.Values()) } }