in pkg/cloud/rgraph/workflow/plan/plan.go [57:127]
func (pl *planner) plan(ctx context.Context) (*Result, error) {
// Assemble the "got" graph. This will get the current state of any
// resources and also enumerate any resouces that are currently linked that
// are not in the "want" graph.
gotBuilder := pl.want.NewBuilderWithEmptyNodes()
// Fetch the current resource graph from Cloud.
// TODO: resource_prefix, ownership due to prefix etc.
err := trclosure.Do(ctx, pl.cloud, gotBuilder,
trclosure.OnGetFunc(func(n rnode.Builder) error {
n.SetOwnership(rnode.OwnershipManaged)
return nil
}),
)
if err != nil {
return nil, err
}
pl.got, err = gotBuilder.Build()
if err != nil {
return nil, fmt.Errorf("%s: %w", errPrefix, err)
}
// Figure out what to do with Nodes in "got" that aren't in "want". These
// are resources that will no longer by referenced in the updated graph.
for _, gotNode := range pl.got.All() {
switch {
case pl.want.Get(gotNode.ID()) != nil:
// Node exists in "want", don't need to do anything.
case gotNode.Ownership() == rnode.OwnershipExternal:
// TODO: clone the node from the "got" graph for "want" unchanged.
case gotNode.Ownership() == rnode.OwnershipManaged:
// Nodes that are no longer referenced should be deleted.
wantNodeBuilder := gotNode.Builder()
wantNodeBuilder.SetState(rnode.NodeDoesNotExist)
wantNode, err := wantNodeBuilder.Build()
if err != nil {
return nil, err
}
err = pl.want.AddTombstone(wantNode)
if err != nil {
return nil, err
}
default:
return nil, fmt.Errorf("%s: node %s has invalid ownership %s", errPrefix, gotNode.ID(), gotNode.Ownership())
}
}
// Compute the local plan for each resource.
if err := localplan.PlanWantGraph(pl.got, pl.want); err != nil {
return nil, err
}
if err := pl.propagateRecreates(); err != nil {
return nil, err
}
if err := pl.sanityCheck(); err != nil {
return nil, err
}
acts, err := actions.Do(pl.got, pl.want)
if err != nil {
return nil, fmt.Errorf("%s: %w", errPrefix, err)
}
return &Result{
Got: pl.got,
Want: pl.want,
Actions: acts,
}, nil
}