terraform: new Graph API that can return the graph for each op
This commit is contained in:
parent
9197422881
commit
fb8f2e2753
|
@ -189,13 +189,55 @@ func NewContext(opts *ContextOpts) (*Context, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
type ContextGraphOpts struct {
|
type ContextGraphOpts struct {
|
||||||
|
// If true, validates the graph structure (checks for cycles).
|
||||||
Validate bool
|
Validate bool
|
||||||
Verbose bool
|
|
||||||
|
// Legacy graphs only: won't prune the graph
|
||||||
|
Verbose bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// Graph returns the graph for this config.
|
// Graph returns the graph used for the given operation type.
|
||||||
func (c *Context) Graph(g *ContextGraphOpts) (*Graph, error) {
|
//
|
||||||
return c.graphBuilder(g).Build(RootModulePath)
|
// The most extensive or complex graph type is GraphTypePlan.
|
||||||
|
func (c *Context) Graph(typ GraphType, opts *ContextGraphOpts) (*Graph, error) {
|
||||||
|
if opts == nil {
|
||||||
|
opts = &ContextGraphOpts{Validate: true}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch typ {
|
||||||
|
case GraphTypeApply:
|
||||||
|
return (&ApplyGraphBuilder{
|
||||||
|
Module: c.module,
|
||||||
|
Diff: c.diff,
|
||||||
|
State: c.state,
|
||||||
|
Providers: c.components.ResourceProviders(),
|
||||||
|
Provisioners: c.components.ResourceProvisioners(),
|
||||||
|
Destroy: c.destroy,
|
||||||
|
Validate: opts.Validate,
|
||||||
|
}).Build(RootModulePath)
|
||||||
|
|
||||||
|
case GraphTypePlan:
|
||||||
|
return (&PlanGraphBuilder{
|
||||||
|
Module: c.module,
|
||||||
|
State: c.state,
|
||||||
|
Providers: c.components.ResourceProviders(),
|
||||||
|
Targets: c.targets,
|
||||||
|
Validate: opts.Validate,
|
||||||
|
}).Build(RootModulePath)
|
||||||
|
|
||||||
|
case GraphTypePlanDestroy:
|
||||||
|
return (&DestroyPlanGraphBuilder{
|
||||||
|
Module: c.module,
|
||||||
|
State: c.state,
|
||||||
|
Targets: c.targets,
|
||||||
|
Validate: opts.Validate,
|
||||||
|
}).Build(RootModulePath)
|
||||||
|
|
||||||
|
case GraphTypeLegacy:
|
||||||
|
return c.graphBuilder(opts).Build(RootModulePath)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, fmt.Errorf("unknown graph type: %s", typ)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GraphBuilder returns the GraphBuilder that will be used to create
|
// GraphBuilder returns the GraphBuilder that will be used to create
|
||||||
|
@ -360,7 +402,7 @@ func (c *Context) Input(mode InputMode) error {
|
||||||
|
|
||||||
if mode&InputModeProvider != 0 {
|
if mode&InputModeProvider != 0 {
|
||||||
// Build the graph
|
// Build the graph
|
||||||
graph, err := c.Graph(&ContextGraphOpts{Validate: true})
|
graph, err := c.Graph(GraphTypeLegacy, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -390,20 +432,11 @@ func (c *Context) Apply() (*State, error) {
|
||||||
X_legacyGraph := experiment.Enabled(experiment.X_legacyGraph)
|
X_legacyGraph := experiment.Enabled(experiment.X_legacyGraph)
|
||||||
|
|
||||||
// Build the graph.
|
// Build the graph.
|
||||||
var graph *Graph
|
graphType := GraphTypeLegacy
|
||||||
var err error
|
|
||||||
if !X_legacyGraph {
|
if !X_legacyGraph {
|
||||||
graph, err = (&ApplyGraphBuilder{
|
graphType = GraphTypeApply
|
||||||
Module: c.module,
|
|
||||||
Diff: c.diff,
|
|
||||||
State: c.state,
|
|
||||||
Providers: c.components.ResourceProviders(),
|
|
||||||
Provisioners: c.components.ResourceProvisioners(),
|
|
||||||
Destroy: c.destroy,
|
|
||||||
}).Build(RootModulePath)
|
|
||||||
} else {
|
|
||||||
graph, err = c.Graph(&ContextGraphOpts{Validate: true})
|
|
||||||
}
|
}
|
||||||
|
graph, err := c.Graph(graphType, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -475,26 +508,15 @@ func (c *Context) Plan() (*Plan, error) {
|
||||||
X_legacyGraph := experiment.Enabled(experiment.X_legacyGraph)
|
X_legacyGraph := experiment.Enabled(experiment.X_legacyGraph)
|
||||||
|
|
||||||
// Build the graph.
|
// Build the graph.
|
||||||
var graph *Graph
|
graphType := GraphTypeLegacy
|
||||||
var err error
|
|
||||||
if !X_legacyGraph {
|
if !X_legacyGraph {
|
||||||
if c.destroy {
|
if c.destroy {
|
||||||
graph, err = (&DestroyPlanGraphBuilder{
|
graphType = GraphTypePlanDestroy
|
||||||
Module: c.module,
|
|
||||||
State: c.state,
|
|
||||||
Targets: c.targets,
|
|
||||||
}).Build(RootModulePath)
|
|
||||||
} else {
|
} else {
|
||||||
graph, err = (&PlanGraphBuilder{
|
graphType = GraphTypePlan
|
||||||
Module: c.module,
|
|
||||||
State: c.state,
|
|
||||||
Providers: c.components.ResourceProviders(),
|
|
||||||
Targets: c.targets,
|
|
||||||
}).Build(RootModulePath)
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
graph, err = c.Graph(&ContextGraphOpts{Validate: true})
|
|
||||||
}
|
}
|
||||||
|
graph, err := c.Graph(graphType, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -522,7 +544,7 @@ func (c *Context) Plan() (*Plan, error) {
|
||||||
if X_legacyGraph {
|
if X_legacyGraph {
|
||||||
// Now that we have a diff, we can build the exact graph that Apply will use
|
// Now that we have a diff, we can build the exact graph that Apply will use
|
||||||
// and catch any possible cycles during the Plan phase.
|
// and catch any possible cycles during the Plan phase.
|
||||||
if _, err := c.Graph(&ContextGraphOpts{Validate: true}); err != nil {
|
if _, err := c.Graph(GraphTypeLegacy, nil); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -548,7 +570,7 @@ func (c *Context) Refresh() (*State, error) {
|
||||||
c.state = c.state.DeepCopy()
|
c.state = c.state.DeepCopy()
|
||||||
|
|
||||||
// Build the graph
|
// Build the graph
|
||||||
graph, err := c.Graph(&ContextGraphOpts{Validate: true})
|
graph, err := c.Graph(GraphTypeLegacy, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -619,7 +641,7 @@ func (c *Context) Validate() ([]string, []error) {
|
||||||
// We also validate the graph generated here, but this graph doesn't
|
// We also validate the graph generated here, but this graph doesn't
|
||||||
// necessarily match the graph that Plan will generate, so we'll validate the
|
// necessarily match the graph that Plan will generate, so we'll validate the
|
||||||
// graph again later after Planning.
|
// graph again later after Planning.
|
||||||
graph, err := c.Graph(&ContextGraphOpts{Validate: true})
|
graph, err := c.Graph(GraphTypeLegacy, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, []error{err}
|
return nil, []error{err}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
package terraform
|
||||||
|
|
||||||
|
//go:generate stringer -type=GraphType context_graph_type.go
|
||||||
|
|
||||||
|
// GraphType is an enum of the type of graph to create with a Context.
|
||||||
|
// The values of the constants may change so they shouldn't be depended on;
|
||||||
|
// always use the constant name.
|
||||||
|
type GraphType byte
|
||||||
|
|
||||||
|
const (
|
||||||
|
GraphTypeInvalid GraphType = 0
|
||||||
|
GraphTypeLegacy GraphType = iota
|
||||||
|
GraphTypePlan
|
||||||
|
GraphTypePlanDestroy
|
||||||
|
GraphTypeApply
|
||||||
|
)
|
||||||
|
|
||||||
|
// GraphTypeMap is a mapping of human-readable string to GraphType. This
|
||||||
|
// is useful to use as the mechanism for human input for configurable
|
||||||
|
// graph types.
|
||||||
|
var GraphTypeMap = map[string]GraphType{
|
||||||
|
"apply": GraphTypeApply,
|
||||||
|
"plan": GraphTypePlan,
|
||||||
|
"plan-destroy": GraphTypePlanDestroy,
|
||||||
|
"legacy": GraphTypeLegacy,
|
||||||
|
}
|
|
@ -33,13 +33,16 @@ type ApplyGraphBuilder struct {
|
||||||
|
|
||||||
// Destroy, if true, represents a pure destroy operation
|
// Destroy, if true, represents a pure destroy operation
|
||||||
Destroy bool
|
Destroy bool
|
||||||
|
|
||||||
|
// Validate will do structural validation of the graph.
|
||||||
|
Validate bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// See GraphBuilder
|
// See GraphBuilder
|
||||||
func (b *ApplyGraphBuilder) Build(path []string) (*Graph, error) {
|
func (b *ApplyGraphBuilder) Build(path []string) (*Graph, error) {
|
||||||
return (&BasicGraphBuilder{
|
return (&BasicGraphBuilder{
|
||||||
Steps: b.Steps(),
|
Steps: b.Steps(),
|
||||||
Validate: true,
|
Validate: b.Validate,
|
||||||
Name: "ApplyGraphBuilder",
|
Name: "ApplyGraphBuilder",
|
||||||
}).Build(path)
|
}).Build(path)
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,13 +19,16 @@ type DestroyPlanGraphBuilder struct {
|
||||||
|
|
||||||
// Targets are resources to target
|
// Targets are resources to target
|
||||||
Targets []string
|
Targets []string
|
||||||
|
|
||||||
|
// Validate will do structural validation of the graph.
|
||||||
|
Validate bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// See GraphBuilder
|
// See GraphBuilder
|
||||||
func (b *DestroyPlanGraphBuilder) Build(path []string) (*Graph, error) {
|
func (b *DestroyPlanGraphBuilder) Build(path []string) (*Graph, error) {
|
||||||
return (&BasicGraphBuilder{
|
return (&BasicGraphBuilder{
|
||||||
Steps: b.Steps(),
|
Steps: b.Steps(),
|
||||||
Validate: true,
|
Validate: b.Validate,
|
||||||
Name: "DestroyPlanGraphBuilder",
|
Name: "DestroyPlanGraphBuilder",
|
||||||
}).Build(path)
|
}).Build(path)
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,13 +31,16 @@ type PlanGraphBuilder struct {
|
||||||
|
|
||||||
// DisableReduce, if true, will not reduce the graph. Great for testing.
|
// DisableReduce, if true, will not reduce the graph. Great for testing.
|
||||||
DisableReduce bool
|
DisableReduce bool
|
||||||
|
|
||||||
|
// Validate will do structural validation of the graph.
|
||||||
|
Validate bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// See GraphBuilder
|
// See GraphBuilder
|
||||||
func (b *PlanGraphBuilder) Build(path []string) (*Graph, error) {
|
func (b *PlanGraphBuilder) Build(path []string) (*Graph, error) {
|
||||||
return (&BasicGraphBuilder{
|
return (&BasicGraphBuilder{
|
||||||
Steps: b.Steps(),
|
Steps: b.Steps(),
|
||||||
Validate: true,
|
Validate: b.Validate,
|
||||||
Name: "PlanGraphBuilder",
|
Name: "PlanGraphBuilder",
|
||||||
}).Build(path)
|
}).Build(path)
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
// Code generated by "stringer -type=GraphType context_graph_type.go"; DO NOT EDIT
|
||||||
|
|
||||||
|
package terraform
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
const _GraphType_name = "GraphTypeInvalidGraphTypeLegacyGraphTypePlanGraphTypePlanDestroyGraphTypeApply"
|
||||||
|
|
||||||
|
var _GraphType_index = [...]uint8{0, 16, 31, 44, 64, 78}
|
||||||
|
|
||||||
|
func (i GraphType) String() string {
|
||||||
|
if i >= GraphType(len(_GraphType_index)-1) {
|
||||||
|
return fmt.Sprintf("GraphType(%d)", i)
|
||||||
|
}
|
||||||
|
return _GraphType_name[_GraphType_index[i]:_GraphType_index[i+1]]
|
||||||
|
}
|
Loading…
Reference in New Issue