engine: graph, resources: Add filtered graph function

This lets a resource query the resource graph in a controlled way.
This commit is contained in:
James Shubin
2019-10-25 09:36:27 -04:00
parent 31030343a2
commit eaab1aae28
3 changed files with 67 additions and 0 deletions

View File

@@ -200,6 +200,51 @@ func (obj *State) Init() error {
// return obj.Graph // we return in a func so it's fresh!
//},
FilteredGraph: func() (*pgraph.Graph, error) {
graph, err := pgraph.NewGraph("filtered")
if err != nil {
return nil, errwrap.Wrapf(err, "could not create graph")
}
// filter graph and build a new one...
adjacency := obj.Graph.Adjacency()
for v1 := range adjacency {
// check we're allowed
r1, ok := v1.(engine.GraphQueryableRes)
if !ok {
continue
}
// pass in information on requestor...
if err := r1.GraphQueryAllowed(
engine.GraphQueryableOptionKind(res.Kind()),
engine.GraphQueryableOptionName(res.Name()),
// TODO: add more information...
); err != nil {
continue
}
graph.AddVertex(v1)
for v2, edge := range adjacency[v1] {
r2, ok := v2.(engine.GraphQueryableRes)
if !ok {
continue
}
// pass in information on requestor...
if err := r2.GraphQueryAllowed(
engine.GraphQueryableOptionKind(res.Kind()),
engine.GraphQueryableOptionName(res.Name()),
// TODO: add more information...
); err != nil {
continue
}
//graph.AddVertex(v2) // redundant
graph.AddEdge(v1, v2, edge)
}
}
return graph, nil // we return in a func so it's fresh!
},
World: obj.World,
VarDir: obj.varDir,

View File

@@ -21,6 +21,7 @@ import (
"encoding/gob"
"fmt"
"github.com/purpleidea/mgmt/pgraph"
"github.com/purpleidea/mgmt/util/errwrap"
"gopkg.in/yaml.v2"
@@ -126,6 +127,14 @@ type Init struct {
// FIXME: it might be better to offer a safer, more limited, GraphQuery?
//Graph func() *pgraph.Graph // TODO: not implemented, use FilteredGraph
// FilteredGraph is a function that returns a filtered variant of the
// current graph. Only resource that have allowed themselves to be added
// into this graph will appear. If they did not consent, then those
// vertices and any associated edges, will not be present.
FilteredGraph func() (*pgraph.Graph, error)
// TODO: GraphQuery offers an interface to query the resource graph.
// World provides a connection to the outside world. This is most often
// used for communicating with the distributed database.
World World

View File

@@ -603,6 +603,19 @@ func TestResources2(t *testing.T) {
Recv: func() map[string]*engine.Send {
return map[string]*engine.Send{}
},
// Copied from state.go
FilteredGraph: func() (*pgraph.Graph, error) {
graph, err := pgraph.NewGraph("filtered")
if err != nil {
return nil, errwrap.Wrapf(err, "could not create graph")
}
// Hack: We just add ourself as allowed since
// we're just a one-vertex test suite...
graph.AddVertex(res) // hack!
return graph, nil // we return in a func so it's fresh!
},
}
// run Init
return func() error {