Add proper Plan type

This commit is contained in:
Fraser Waters 2021-11-23 16:09:18 +00:00
parent 37b22b8d3c
commit 94bf0840df
20 changed files with 74 additions and 61 deletions

View file

@ -45,7 +45,7 @@ type ApplierOptions struct {
// Applier applies the changes specified by this update operation against the target stack. // Applier applies the changes specified by this update operation against the target stack.
type Applier func(ctx context.Context, kind apitype.UpdateKind, stack Stack, op UpdateOperation, type Applier func(ctx context.Context, kind apitype.UpdateKind, stack Stack, op UpdateOperation,
opts ApplierOptions, events chan<- engine.Event) (deploy.Plan, engine.ResourceChanges, result.Result) opts ApplierOptions, events chan<- engine.Event) (*deploy.Plan, engine.ResourceChanges, result.Result)
func ActionLabel(kind apitype.UpdateKind, dryRun bool) string { func ActionLabel(kind apitype.UpdateKind, dryRun bool) string {
v := updateTextMap[kind] v := updateTextMap[kind]
@ -80,7 +80,7 @@ const (
) )
func PreviewThenPrompt(ctx context.Context, kind apitype.UpdateKind, stack Stack, func PreviewThenPrompt(ctx context.Context, kind apitype.UpdateKind, stack Stack,
op UpdateOperation, apply Applier) (deploy.Plan, engine.ResourceChanges, result.Result) { op UpdateOperation, apply Applier) (*deploy.Plan, engine.ResourceChanges, result.Result) {
// create a channel to hear about the update events from the engine. this will be used so that // create a channel to hear about the update events from the engine. this will be used so that
// we can build up the diff display in case the user asks to see the details of the diff // we can build up the diff display in case the user asks to see the details of the diff

View file

@ -161,7 +161,7 @@ type Backend interface {
RenameStack(ctx context.Context, stack Stack, newName tokens.QName) (StackReference, error) RenameStack(ctx context.Context, stack Stack, newName tokens.QName) (StackReference, error)
// Preview shows what would be updated given the current workspace's contents. // Preview shows what would be updated given the current workspace's contents.
Preview(ctx context.Context, stack Stack, op UpdateOperation) (deploy.Plan, engine.ResourceChanges, result.Result) Preview(ctx context.Context, stack Stack, op UpdateOperation) (*deploy.Plan, engine.ResourceChanges, result.Result)
// Update updates the target stack with the current workspace's contents (config and code). // Update updates the target stack with the current workspace's contents (config and code).
Update(ctx context.Context, stack Stack, op UpdateOperation) (engine.ResourceChanges, result.Result) Update(ctx context.Context, stack Stack, op UpdateOperation) (engine.ResourceChanges, result.Result)
// Import imports resources into a stack. // Import imports resources into a stack.

View file

@ -461,7 +461,7 @@ func (b *localBackend) PackPolicies(
} }
func (b *localBackend) Preview(ctx context.Context, stack backend.Stack, func (b *localBackend) Preview(ctx context.Context, stack backend.Stack,
op backend.UpdateOperation) (deploy.Plan, engine.ResourceChanges, result.Result) { op backend.UpdateOperation) (*deploy.Plan, engine.ResourceChanges, result.Result) {
if cmdutil.IsTruthy(os.Getenv(PulumiFilestateLockingEnvVar)) { if cmdutil.IsTruthy(os.Getenv(PulumiFilestateLockingEnvVar)) {
err := b.Lock(ctx, stack.Ref()) err := b.Lock(ctx, stack.Ref())
@ -548,7 +548,7 @@ func (b *localBackend) Watch(ctx context.Context, stack backend.Stack,
func (b *localBackend) apply( func (b *localBackend) apply(
ctx context.Context, kind apitype.UpdateKind, stack backend.Stack, ctx context.Context, kind apitype.UpdateKind, stack backend.Stack,
op backend.UpdateOperation, opts backend.ApplierOptions, op backend.UpdateOperation, opts backend.ApplierOptions,
events chan<- engine.Event) (deploy.Plan, engine.ResourceChanges, result.Result) { events chan<- engine.Event) (*deploy.Plan, engine.ResourceChanges, result.Result) {
stackRef := stack.Ref() stackRef := stack.Ref()
stackName := stackRef.Name() stackName := stackRef.Name()
@ -604,7 +604,7 @@ func (b *localBackend) apply(
// Perform the update // Perform the update
start := time.Now().Unix() start := time.Now().Unix()
var plan deploy.Plan var plan *deploy.Plan
var changes engine.ResourceChanges var changes engine.ResourceChanges
var updateRes result.Result var updateRes result.Result
switch kind { switch kind {

View file

@ -66,7 +66,7 @@ func (s *localStack) Rename(ctx context.Context, newName tokens.QName) (backend.
func (s *localStack) Preview( func (s *localStack) Preview(
ctx context.Context, ctx context.Context,
op backend.UpdateOperation) (deploy.Plan, engine.ResourceChanges, result.Result) { op backend.UpdateOperation) (*deploy.Plan, engine.ResourceChanges, result.Result) {
return backend.PreviewStack(ctx, s, op) return backend.PreviewStack(ctx, s, op)
} }

View file

@ -828,7 +828,7 @@ func (b *cloudBackend) RenameStack(ctx context.Context, stack backend.Stack,
} }
func (b *cloudBackend) Preview(ctx context.Context, stack backend.Stack, func (b *cloudBackend) Preview(ctx context.Context, stack backend.Stack,
op backend.UpdateOperation) (deploy.Plan, engine.ResourceChanges, result.Result) { op backend.UpdateOperation) (*deploy.Plan, engine.ResourceChanges, result.Result) {
// We can skip PreviewtThenPromptThenExecute, and just go straight to Execute. // We can skip PreviewtThenPromptThenExecute, and just go straight to Execute.
opts := backend.ApplierOptions{ opts := backend.ApplierOptions{
DryRun: true, DryRun: true,
@ -931,7 +931,7 @@ func (b *cloudBackend) createAndStartUpdate(
func (b *cloudBackend) apply( func (b *cloudBackend) apply(
ctx context.Context, kind apitype.UpdateKind, stack backend.Stack, ctx context.Context, kind apitype.UpdateKind, stack backend.Stack,
op backend.UpdateOperation, opts backend.ApplierOptions, op backend.UpdateOperation, opts backend.ApplierOptions,
events chan<- engine.Event) (deploy.Plan, engine.ResourceChanges, result.Result) { events chan<- engine.Event) (*deploy.Plan, engine.ResourceChanges, result.Result) {
actionLabel := backend.ActionLabel(kind, opts.DryRun) actionLabel := backend.ActionLabel(kind, opts.DryRun)
@ -985,7 +985,7 @@ func (b *cloudBackend) query(ctx context.Context, op backend.QueryOperation,
func (b *cloudBackend) runEngineAction( func (b *cloudBackend) runEngineAction(
ctx context.Context, kind apitype.UpdateKind, stackRef backend.StackReference, ctx context.Context, kind apitype.UpdateKind, stackRef backend.StackReference,
op backend.UpdateOperation, update client.UpdateIdentifier, token string, op backend.UpdateOperation, update client.UpdateIdentifier, token string,
callerEventsOpt chan<- engine.Event, dryRun bool) (deploy.Plan, engine.ResourceChanges, result.Result) { callerEventsOpt chan<- engine.Event, dryRun bool) (*deploy.Plan, engine.ResourceChanges, result.Result) {
contract.Assertf(token != "", "persisted actions require a token") contract.Assertf(token != "", "persisted actions require a token")
u, err := b.newUpdate(ctx, stackRef, op, update, token) u, err := b.newUpdate(ctx, stackRef, op, update, token)
@ -1039,7 +1039,7 @@ func (b *cloudBackend) runEngineAction(
engineCtx.ParentSpan = parentSpan.Context() engineCtx.ParentSpan = parentSpan.Context()
} }
var plan deploy.Plan var plan *deploy.Plan
var changes engine.ResourceChanges var changes engine.ResourceChanges
var res result.Result var res result.Result
switch kind { switch kind {

View file

@ -142,7 +142,7 @@ func (s *cloudStack) Rename(ctx context.Context, newName tokens.QName) (backend.
func (s *cloudStack) Preview( func (s *cloudStack) Preview(
ctx context.Context, ctx context.Context,
op backend.UpdateOperation) (deploy.Plan, engine.ResourceChanges, result.Result) { op backend.UpdateOperation) (*deploy.Plan, engine.ResourceChanges, result.Result) {
return backend.PreviewStack(ctx, s, op) return backend.PreviewStack(ctx, s, op)
} }

View file

@ -57,7 +57,7 @@ type MockBackend struct {
LogoutAllF func() error LogoutAllF func() error
CurrentUserF func() (string, error) CurrentUserF func() (string, error)
PreviewF func(context.Context, Stack, PreviewF func(context.Context, Stack,
UpdateOperation) (deploy.Plan, engine.ResourceChanges, result.Result) UpdateOperation) (*deploy.Plan, engine.ResourceChanges, result.Result)
UpdateF func(context.Context, Stack, UpdateF func(context.Context, Stack,
UpdateOperation) (engine.ResourceChanges, result.Result) UpdateOperation) (engine.ResourceChanges, result.Result)
ImportF func(context.Context, Stack, ImportF func(context.Context, Stack,
@ -180,7 +180,7 @@ func (be *MockBackend) GetStackCrypter(stackRef StackReference) (config.Crypter,
} }
func (be *MockBackend) Preview(ctx context.Context, stack Stack, func (be *MockBackend) Preview(ctx context.Context, stack Stack,
op UpdateOperation) (deploy.Plan, engine.ResourceChanges, result.Result) { op UpdateOperation) (*deploy.Plan, engine.ResourceChanges, result.Result) {
if be.PreviewF != nil { if be.PreviewF != nil {
return be.PreviewF(ctx, stack, op) return be.PreviewF(ctx, stack, op)
@ -335,7 +335,7 @@ type MockStack struct {
ConfigF func() config.Map ConfigF func() config.Map
SnapshotF func(ctx context.Context) (*deploy.Snapshot, error) SnapshotF func(ctx context.Context) (*deploy.Snapshot, error)
BackendF func() Backend BackendF func() Backend
PreviewF func(ctx context.Context, op UpdateOperation) (deploy.Plan, engine.ResourceChanges, result.Result) PreviewF func(ctx context.Context, op UpdateOperation) (*deploy.Plan, engine.ResourceChanges, result.Result)
UpdateF func(ctx context.Context, op UpdateOperation) (engine.ResourceChanges, result.Result) UpdateF func(ctx context.Context, op UpdateOperation) (engine.ResourceChanges, result.Result)
ImportF func(ctx context.Context, op UpdateOperation, ImportF func(ctx context.Context, op UpdateOperation,
imports []deploy.Import) (engine.ResourceChanges, result.Result) imports []deploy.Import) (engine.ResourceChanges, result.Result)
@ -383,7 +383,7 @@ func (ms *MockStack) Backend() Backend {
func (ms *MockStack) Preview( func (ms *MockStack) Preview(
ctx context.Context, ctx context.Context,
op UpdateOperation) (deploy.Plan, engine.ResourceChanges, result.Result) { op UpdateOperation) (*deploy.Plan, engine.ResourceChanges, result.Result) {
if ms.PreviewF != nil { if ms.PreviewF != nil {
return ms.PreviewF(ctx, op) return ms.PreviewF(ctx, op)

View file

@ -38,7 +38,7 @@ type Stack interface {
Backend() Backend // the backend this stack belongs to. Backend() Backend // the backend this stack belongs to.
// Preview changes to this stack. // Preview changes to this stack.
Preview(ctx context.Context, op UpdateOperation) (deploy.Plan, engine.ResourceChanges, result.Result) Preview(ctx context.Context, op UpdateOperation) (*deploy.Plan, engine.ResourceChanges, result.Result)
// Update this stack. // Update this stack.
Update(ctx context.Context, op UpdateOperation) (engine.ResourceChanges, result.Result) Update(ctx context.Context, op UpdateOperation) (engine.ResourceChanges, result.Result)
// Import resources into this stack. // Import resources into this stack.
@ -76,7 +76,7 @@ func RenameStack(ctx context.Context, s Stack, newName tokens.QName) (StackRefer
func PreviewStack( func PreviewStack(
ctx context.Context, ctx context.Context,
s Stack, s Stack,
op UpdateOperation) (deploy.Plan, engine.ResourceChanges, result.Result) { op UpdateOperation) (*deploy.Plan, engine.ResourceChanges, result.Result) {
return s.Backend().Preview(ctx, s, op) return s.Backend().Preview(ctx, s, op)
} }

View file

@ -869,7 +869,7 @@ func getRefreshOption(proj *workspace.Project, refresh string) (bool, error) {
return false, nil return false, nil
} }
func writePlan(path string, plan deploy.Plan, enc config.Encrypter, showSecrets bool) error { func writePlan(path string, plan *deploy.Plan, enc config.Encrypter, showSecrets bool) error {
f, err := os.Create(path) f, err := os.Create(path)
if err != nil { if err != nil {
return err return err
@ -883,7 +883,7 @@ func writePlan(path string, plan deploy.Plan, enc config.Encrypter, showSecrets
return json.NewEncoder(f).Encode(deploymentPlan) return json.NewEncoder(f).Encode(deploymentPlan)
} }
func readPlan(path string, dec config.Decrypter, enc config.Encrypter) (deploy.Plan, error) { func readPlan(path string, dec config.Decrypter, enc config.Encrypter) (*deploy.Plan, error) {
f, err := os.Open(path) f, err := os.Open(path)
if err != nil { if err != nil {
return nil, err return nil, err

View file

@ -218,7 +218,7 @@ type runActions interface {
// run executes the deployment. It is primarily responsible for handling cancellation. // run executes the deployment. It is primarily responsible for handling cancellation.
func (deployment *deployment) run(cancelCtx *Context, actions runActions, policyPacks map[string]string, func (deployment *deployment) run(cancelCtx *Context, actions runActions, policyPacks map[string]string,
preview bool) (deploy.Plan, ResourceChanges, result.Result) { preview bool) (*deploy.Plan, ResourceChanges, result.Result) {
// Change into the plugin context's working directory. // Change into the plugin context's working directory.
chdir, err := fsutil.Chdir(deployment.Plugctx.Pwd) chdir, err := fsutil.Chdir(deployment.Plugctx.Pwd)
@ -242,7 +242,7 @@ func (deployment *deployment) run(cancelCtx *Context, actions runActions, policy
start := time.Now() start := time.Now()
done := make(chan bool) done := make(chan bool)
var newPlan deploy.Plan var newPlan *deploy.Plan
var walkResult result.Result var walkResult result.Result
go func() { go func() {
opts := deploy.Options{ opts := deploy.Options{

View file

@ -27,7 +27,7 @@ func Destroy(
u UpdateInfo, u UpdateInfo,
ctx *Context, ctx *Context,
opts UpdateOptions, opts UpdateOptions,
dryRun bool) (deploy.Plan, ResourceChanges, result.Result) { dryRun bool) (*deploy.Plan, ResourceChanges, result.Result) {
contract.Require(u != nil, "u") contract.Require(u != nil, "u")
contract.Require(ctx != nil, "ctx") contract.Require(ctx != nil, "ctx")

View file

@ -21,7 +21,7 @@ import (
) )
func Import(u UpdateInfo, ctx *Context, opts UpdateOptions, imports []deploy.Import, func Import(u UpdateInfo, ctx *Context, opts UpdateOptions, imports []deploy.Import,
dryRun bool) (deploy.Plan, ResourceChanges, result.Result) { dryRun bool) (*deploy.Plan, ResourceChanges, result.Result) {
contract.Require(u != nil, "u") contract.Require(u != nil, "u")
contract.Require(ctx != nil, "ctx") contract.Require(ctx != nil, "ctx")

View file

@ -27,7 +27,7 @@ func Refresh(
u UpdateInfo, u UpdateInfo,
ctx *Context, ctx *Context,
opts UpdateOptions, opts UpdateOptions,
dryRun bool) (deploy.Plan, ResourceChanges, result.Result) { dryRun bool) (*deploy.Plan, ResourceChanges, result.Result) {
contract.Require(u != nil, "u") contract.Require(u != nil, "u")
contract.Require(ctx != nil, "ctx") contract.Require(ctx != nil, "ctx")

View file

@ -148,7 +148,7 @@ type UpdateOptions struct {
Host plugin.Host Host plugin.Host
// The plan to use for the update, if any. // The plan to use for the update, if any.
Plan deploy.Plan Plan *deploy.Plan
} }
// ResourceChanges contains the aggregate resource changes by operation type. // ResourceChanges contains the aggregate resource changes by operation type.
@ -168,7 +168,7 @@ func (changes ResourceChanges) HasChanges() bool {
return c > 0 return c > 0
} }
func Update(u UpdateInfo, ctx *Context, opts UpdateOptions, dryRun bool) (deploy.Plan, ResourceChanges, result.Result) { func Update(u UpdateInfo, ctx *Context, opts UpdateOptions, dryRun bool) (*deploy.Plan, ResourceChanges, result.Result) {
contract.Require(u != nil, "update") contract.Require(u != nil, "update")
contract.Require(ctx != nil, "ctx") contract.Require(ctx != nil, "ctx")
@ -423,7 +423,7 @@ func newUpdateSource(
} }
func update(ctx *Context, info *deploymentContext, opts deploymentOptions, func update(ctx *Context, info *deploymentContext, opts deploymentOptions,
preview bool) (deploy.Plan, ResourceChanges, result.Result) { preview bool) (*deploy.Plan, ResourceChanges, result.Result) {
// Refresh and Import do not execute Policy Packs. // Refresh and Import do not execute Policy Packs.
policies := map[string]string{} policies := map[string]string{}

View file

@ -152,7 +152,7 @@ type resourcePlans struct {
func newResourcePlan() *resourcePlans { func newResourcePlan() *resourcePlans {
return &resourcePlans{ return &resourcePlans{
plans: make(Plan), plans: NewPlan(),
} }
} }
@ -160,19 +160,19 @@ func (m *resourcePlans) set(urn resource.URN, plan *ResourcePlan) {
m.m.Lock() m.m.Lock()
defer m.m.Unlock() defer m.m.Unlock()
m.plans[urn] = plan m.plans.ResourcePlans[urn] = plan
} }
func (m *resourcePlans) get(urn resource.URN) (*ResourcePlan, bool) { func (m *resourcePlans) get(urn resource.URN) (*ResourcePlan, bool) {
m.m.RLock() m.m.RLock()
defer m.m.RUnlock() defer m.m.RUnlock()
p, ok := m.plans[urn] p, ok := m.plans.ResourcePlans[urn]
return p, ok return p, ok
} }
func (m *resourcePlans) plan() Plan { func (m *resourcePlans) plan() *Plan {
return m.plans return &m.plans
} }
// A Deployment manages the iterative computation and execution of a deployment based on a stream of goal states. // A Deployment manages the iterative computation and execution of a deployment based on a stream of goal states.
@ -183,7 +183,7 @@ type Deployment struct {
target *Target // the deployment target. target *Target // the deployment target.
prev *Snapshot // the old resource snapshot for comparison. prev *Snapshot // the old resource snapshot for comparison.
olds map[resource.URN]*resource.State // a map of all old resources. olds map[resource.URN]*resource.State // a map of all old resources.
plan Plan // a map of all planned resource changes, if any. plan *Plan // a map of all planned resource changes, if any.
imports []Import // resources to import, if this is an import deployment. imports []Import // resources to import, if this is an import deployment.
isImport bool // true if this is an import deployment. isImport bool // true if this is an import deployment.
schemaLoader schema.Loader // the schema cache for this deployment, if any. schemaLoader schema.Loader // the schema cache for this deployment, if any.
@ -331,7 +331,7 @@ func buildResourceMap(prev *Snapshot, preview bool) ([]*resource.State, map[reso
// //
// Note that a deployment uses internal concurrency and parallelism in various ways, so it must be closed if for some // Note that a deployment uses internal concurrency and parallelism in various ways, so it must be closed if for some
// reason it isn't carried out to its final conclusion. This will result in cancellation and reclamation of resources. // reason it isn't carried out to its final conclusion. This will result in cancellation and reclamation of resources.
func NewDeployment(ctx *plugin.Context, target *Target, prev *Snapshot, plan Plan, source Source, func NewDeployment(ctx *plugin.Context, target *Target, prev *Snapshot, plan *Plan, source Source,
localPolicyPackPaths []string, preview bool, backendClient BackendClient) (*Deployment, error) { localPolicyPackPaths []string, preview bool, backendClient BackendClient) (*Deployment, error) {
contract.Assert(ctx != nil) contract.Assert(ctx != nil)
@ -439,7 +439,7 @@ func (d *Deployment) generateEventURN(event SourceEvent) resource.URN {
} }
// Execute executes a deployment to completion, using the given cancellation context and running a preview or update. // Execute executes a deployment to completion, using the given cancellation context and running a preview or update.
func (d *Deployment) Execute(ctx context.Context, opts Options, preview bool) (Plan, result.Result) { func (d *Deployment) Execute(ctx context.Context, opts Options, preview bool) (*Plan, result.Result) {
deploymentExec := &deploymentExecutor{deployment: d} deploymentExec := &deploymentExecutor{deployment: d}
return deploymentExec.Execute(ctx, opts, preview) return deploymentExec.Execute(ctx, opts, preview)
} }

View file

@ -114,7 +114,7 @@ func (ex *deploymentExecutor) reportError(urn resource.URN, err error) {
// Execute executes a deployment to completion, using the given cancellation context and running a preview // Execute executes a deployment to completion, using the given cancellation context and running a preview
// or update. // or update.
func (ex *deploymentExecutor) Execute(callerCtx context.Context, opts Options, preview bool) (Plan, result.Result) { func (ex *deploymentExecutor) Execute(callerCtx context.Context, opts Options, preview bool) (*Plan, result.Result) {
// Set up a goroutine that will signal cancellation to the deployment's plugins if the caller context is cancelled. // Set up a goroutine that will signal cancellation to the deployment's plugins if the caller context is cancelled.
// We do not hang this off of the context we create below because we do not want the failure of a single step to // We do not hang this off of the context we create below because we do not want the failure of a single step to
// cause other steps to fail. // cause other steps to fail.
@ -270,7 +270,7 @@ func (ex *deploymentExecutor) Execute(callerCtx context.Context, opts Options, p
// Check that we did operations for everything expected in the plan. We mutate ResourcePlan.Ops as we run // Check that we did operations for everything expected in the plan. We mutate ResourcePlan.Ops as we run
// so by the time we get here everything in the map should have an empty ops list // so by the time we get here everything in the map should have an empty ops list
if ex.deployment.plan != nil { if ex.deployment.plan != nil {
for urn, resourcePlan := range ex.deployment.plan { for urn, resourcePlan := range ex.deployment.plan.ResourcePlans {
if len(resourcePlan.Ops) != 0 { if len(resourcePlan.Ops) != 0 {
return nil, result.Errorf("Expected resource operations for %v but none were seen.", urn) return nil, result.Errorf("Expected resource operations for %v but none were seen.", urn)
} }
@ -445,7 +445,7 @@ func (ex *deploymentExecutor) retirePendingDeletes(callerCtx context.Context, op
func (ex *deploymentExecutor) importResources( func (ex *deploymentExecutor) importResources(
callerCtx context.Context, callerCtx context.Context,
opts Options, opts Options,
preview bool) (Plan, result.Result) { preview bool) (*Plan, result.Result) {
if len(ex.deployment.imports) == 0 { if len(ex.deployment.imports) == 0 {
return nil, nil return nil, nil

View file

@ -4,9 +4,12 @@ import (
"fmt" "fmt"
"sort" "sort"
"strings" "strings"
"time"
"github.com/pulumi/pulumi/pkg/v3/resource/deploy/providers" "github.com/pulumi/pulumi/pkg/v3/resource/deploy/providers"
"github.com/pulumi/pulumi/pkg/v3/version"
"github.com/pulumi/pulumi/sdk/v3/go/common/resource" "github.com/pulumi/pulumi/sdk/v3/go/common/resource"
"github.com/pulumi/pulumi/sdk/v3/go/common/resource/config"
"github.com/pulumi/pulumi/sdk/v3/go/common/tokens" "github.com/pulumi/pulumi/sdk/v3/go/common/tokens"
"github.com/pulumi/pulumi/sdk/v3/go/common/util/contract" "github.com/pulumi/pulumi/sdk/v3/go/common/util/contract"
) )
@ -17,7 +20,28 @@ import (
// accept any value (including no value) as valid. For operations, a same step is allowed in place of an update or // accept any value (including no value) as valid. For operations, a same step is allowed in place of an update or
// a replace step, and an update is allowed in place of a replace step. All resource options are required to match // a replace step, and an update is allowed in place of a replace step. All resource options are required to match
// exactly. // exactly.
type Plan map[resource.URN]*ResourcePlan type Plan struct {
ResourcePlans map[resource.URN]*ResourcePlan
Manifest Manifest
// Any environment variables that were set when the plan was created. Values are encrypted.
EnvironmentVariables map[string][]byte
// The configuration in use during the plan.
Config map[string]config.Value
}
func NewPlan() Plan {
manifest := Manifest{
Time: time.Now(),
Version: version.Version,
// Plugins: sm.plugins, - Explicitly dropped, since we don't use the plugin list in the manifest anymore.
}
manifest.Magic = manifest.NewMagic()
return Plan{
ResourcePlans: make(map[resource.URN]*ResourcePlan),
Manifest: manifest,
}
}
// Goal is a desired state for a resource object. Normally it represents a subset of the resource's state expressed by // Goal is a desired state for a resource object. Normally it represents a subset of the resource's state expressed by
// a program, however if Output is true, it represents a more complete, post-deployment view of the state. // a program, however if Output is true, it represents a more complete, post-deployment view of the state.

View file

@ -165,7 +165,7 @@ func (se *stepExecutor) ExecuteRegisterResourceOutputs(e RegisterResourceOutputs
// If a plan is present check that these outputs match what we recorded before // If a plan is present check that these outputs match what we recorded before
if se.deployment.plan != nil { if se.deployment.plan != nil {
resourcePlan, ok := se.deployment.plan[urn] resourcePlan, ok := se.deployment.plan.ResourcePlans[urn]
if !ok { if !ok {
return result.FromError(fmt.Errorf("no plan for resource %v", urn)) return result.FromError(fmt.Errorf("no plan for resource %v", urn))
} else { } else {

View file

@ -183,7 +183,7 @@ func (sg *stepGenerator) GenerateSteps(event RegisterResourceEvent) ([]Step, res
// Check each proposed step against the relevant resource plan, if any // Check each proposed step against the relevant resource plan, if any
for _, s := range steps { for _, s := range steps {
if sg.deployment.plan != nil { if sg.deployment.plan != nil {
if resourcePlan, ok := sg.deployment.plan[s.URN()]; ok { if resourcePlan, ok := sg.deployment.plan.ResourcePlans[s.URN()]; ok {
if len(resourcePlan.Ops) == 0 { if len(resourcePlan.Ops) == 0 {
return nil, result.Errorf("%v is not allowed by the plan: no more steps were expected for this resource", s.Op()) return nil, result.Errorf("%v is not allowed by the plan: no more steps were expected for this resource", s.Op())
} }
@ -314,7 +314,7 @@ func (sg *stepGenerator) generateSteps(event RegisterResourceEvent) ([]Step, res
// If there is a plan for this resource, validate that the program goal conforms to the plan. // If there is a plan for this resource, validate that the program goal conforms to the plan.
// If theres no plan for this resource check that nothing has been changed. // If theres no plan for this resource check that nothing has been changed.
if sg.deployment.plan != nil { if sg.deployment.plan != nil {
resourcePlan, ok := sg.deployment.plan[urn] resourcePlan, ok := sg.deployment.plan.ResourcePlans[urn]
if !ok { if !ok {
if old == nil { if old == nil {
// We could error here, but we'll trigger an error later on anyway that Create isn't valid here // We could error here, but we'll trigger an error later on anyway that Create isn't valid here
@ -817,7 +817,7 @@ func (sg *stepGenerator) GenerateDeletes(targetsOpt map[resource.URN]bool) ([]St
// Check each proposed delete against the relevant resource plan // Check each proposed delete against the relevant resource plan
for _, s := range dels { for _, s := range dels {
if sg.deployment.plan != nil { if sg.deployment.plan != nil {
if resourcePlan, ok := sg.deployment.plan[s.URN()]; ok { if resourcePlan, ok := sg.deployment.plan.ResourcePlans[s.URN()]; ok {
if len(resourcePlan.Ops) == 0 { if len(resourcePlan.Ops) == 0 {
return nil, result.Errorf("%v is not allowed by the plan: no more steps were expected for this resource", s.Op()) return nil, result.Errorf("%v is not allowed by the plan: no more steps were expected for this resource", s.Op())
} }

View file

@ -1,10 +1,7 @@
package stack package stack
import ( import (
"time"
"github.com/pulumi/pulumi/pkg/v3/resource/deploy" "github.com/pulumi/pulumi/pkg/v3/resource/deploy"
"github.com/pulumi/pulumi/pkg/v3/version"
"github.com/pulumi/pulumi/sdk/v3/go/common/apitype" "github.com/pulumi/pulumi/sdk/v3/go/common/apitype"
"github.com/pulumi/pulumi/sdk/v3/go/common/resource" "github.com/pulumi/pulumi/sdk/v3/go/common/resource"
"github.com/pulumi/pulumi/sdk/v3/go/common/resource/config" "github.com/pulumi/pulumi/sdk/v3/go/common/resource/config"
@ -71,9 +68,9 @@ func SerializeResourcePlan(
}, nil }, nil
} }
func SerializePlan(plan deploy.Plan, enc config.Encrypter, showSecrets bool) (apitype.DeploymentPlanV1, error) { func SerializePlan(plan *deploy.Plan, enc config.Encrypter, showSecrets bool) (apitype.DeploymentPlanV1, error) {
resourcePlans := map[resource.URN]apitype.ResourcePlanV1{} resourcePlans := map[resource.URN]apitype.ResourcePlanV1{}
for urn, plan := range plan { for urn, plan := range plan.ResourcePlans {
serializedPlan, err := SerializeResourcePlan(plan, enc, showSecrets) serializedPlan, err := SerializeResourcePlan(plan, enc, showSecrets)
if err != nil { if err != nil {
return apitype.DeploymentPlanV1{}, err return apitype.DeploymentPlanV1{}, err
@ -81,16 +78,8 @@ func SerializePlan(plan deploy.Plan, enc config.Encrypter, showSecrets bool) (ap
resourcePlans[urn] = serializedPlan resourcePlans[urn] = serializedPlan
} }
// Bit odd this isn't part of deploy.Plan but that's just a map right now. We need to change that to track config and things so we'll move this then.
manifest := deploy.Manifest{
Time: time.Now(),
Version: version.Version,
// Plugins: sm.plugins, - Explicitly dropped, since we don't use the plugin list in the manifest anymore.
}
manifest.Magic = manifest.NewMagic()
return apitype.DeploymentPlanV1{ return apitype.DeploymentPlanV1{
Manifest: manifest.Serialize(), Manifest: plan.Manifest.Serialize(),
ResourcePlans: resourcePlans, ResourcePlans: resourcePlans,
}, nil }, nil
} }
@ -151,14 +140,14 @@ func DeserializeResourcePlan(
}, nil }, nil
} }
func DeserializePlan(plan apitype.DeploymentPlanV1, dec config.Decrypter, enc config.Encrypter) (deploy.Plan, error) { func DeserializePlan(plan apitype.DeploymentPlanV1, dec config.Decrypter, enc config.Encrypter) (*deploy.Plan, error) {
deserializedPlan := deploy.Plan{} deserializedPlan := &deploy.Plan{}
for urn, resourcePlan := range plan.ResourcePlans { for urn, resourcePlan := range plan.ResourcePlans {
deserializedResourcePlan, err := DeserializeResourcePlan(resourcePlan, dec, enc) deserializedResourcePlan, err := DeserializeResourcePlan(resourcePlan, dec, enc)
if err != nil { if err != nil {
return nil, err return nil, err
} }
deserializedPlan[urn] = deserializedResourcePlan deserializedPlan.ResourcePlans[urn] = deserializedResourcePlan
} }
return deserializedPlan, nil return deserializedPlan, nil
} }