terraform: GraphNodeProxy
This commit is contained in:
parent
a0d9bc0f19
commit
f24a1533f2
|
@ -0,0 +1,55 @@
|
||||||
|
package terraform
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/hashicorp/terraform/dag"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GraphNodeProxy must be implemented by nodes that are proxies.
|
||||||
|
//
|
||||||
|
// A node that is a proxy says that anything that depends on this
|
||||||
|
// node (the proxy), should also copy all the things that the proxy
|
||||||
|
// itself depends on. Example:
|
||||||
|
//
|
||||||
|
// A => proxy => C
|
||||||
|
//
|
||||||
|
// Should transform into (two edges):
|
||||||
|
//
|
||||||
|
// A => proxy => C
|
||||||
|
// A => C
|
||||||
|
//
|
||||||
|
// The purpose for this is because some transforms only look at direct
|
||||||
|
// edge connections and the proxy generally isn't meaningful in those
|
||||||
|
// situations, so we should complete all the edges.
|
||||||
|
type GraphNodeProxy interface {
|
||||||
|
Proxy() bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// ProxyTransformer is a transformer that goes through the graph, finds
|
||||||
|
// vertices that are marked as proxies, and connects through their
|
||||||
|
// dependents. See above for what a proxy is.
|
||||||
|
type ProxyTransformer struct{}
|
||||||
|
|
||||||
|
func (t *ProxyTransformer) Transform(g *Graph) error {
|
||||||
|
for _, v := range g.Vertices() {
|
||||||
|
pn, ok := v.(GraphNodeProxy)
|
||||||
|
if !ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we don't want to be proxies, don't do it
|
||||||
|
if !pn.Proxy() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Connect all the things that depend on this to things that
|
||||||
|
// we depend on as the proxy. See docs for GraphNodeProxy for
|
||||||
|
// a visual explanation.
|
||||||
|
for _, s := range g.UpEdges(v).List() {
|
||||||
|
for _, t := range g.DownEdges(v).List() {
|
||||||
|
g.Connect(dag.BasicEdge(s, t))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -0,0 +1,52 @@
|
||||||
|
package terraform
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform/dag"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestProxyTransformer(t *testing.T) {
|
||||||
|
var g Graph
|
||||||
|
proxy := &testNodeProxy{NameValue: "proxy"}
|
||||||
|
g.Add("A")
|
||||||
|
g.Add("C")
|
||||||
|
g.Add(proxy)
|
||||||
|
g.Connect(dag.BasicEdge("A", proxy))
|
||||||
|
g.Connect(dag.BasicEdge(proxy, "C"))
|
||||||
|
|
||||||
|
{
|
||||||
|
tf := &ProxyTransformer{}
|
||||||
|
if err := tf.Transform(&g); err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
actual := strings.TrimSpace(g.String())
|
||||||
|
expected := strings.TrimSpace(testProxyTransformStr)
|
||||||
|
if actual != expected {
|
||||||
|
t.Fatalf("bad: %s", actual)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type testNodeProxy struct {
|
||||||
|
NameValue string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *testNodeProxy) Name() string {
|
||||||
|
return n.NameValue
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *testNodeProxy) Proxy() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
const testProxyTransformStr = `
|
||||||
|
A
|
||||||
|
C
|
||||||
|
proxy
|
||||||
|
C
|
||||||
|
proxy
|
||||||
|
C
|
||||||
|
`
|
Loading…
Reference in New Issue