func()

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
}