Share target checking code. (#3252)
This commit is contained in:
parent
c1ff9c37f8
commit
ef7b7d0bd1
|
@ -59,24 +59,15 @@ func GetDuplicateResourceAliasError(urn resource.URN) *Diag {
|
|||
)
|
||||
}
|
||||
|
||||
func GetResourceToRefreshCouldNotBeFoundError() *Diag {
|
||||
return newError("", 2010, "Resource to refresh '%v' could not be found in the stack.")
|
||||
func GetTargetCouldNotBeFoundError() *Diag {
|
||||
return newError("", 2010, "Target '%v' could not be found in the stack.")
|
||||
}
|
||||
|
||||
func GetResourceToRefreshCouldNotBeFoundDidYouForgetError() *Diag {
|
||||
return newError("", 2011, "Resource to refresh '%v' could not be found in the stack. "+
|
||||
"Did you forget to escape $ in your shell?")
|
||||
}
|
||||
|
||||
func GetResourceToDeleteCouldNotBeFoundError() *Diag {
|
||||
return newError("", 2012, "Resource to delete '%v' could not be found in the stack.")
|
||||
}
|
||||
|
||||
func GetResourceToDeleteCouldNotBeFoundDidYouForgetError() *Diag {
|
||||
return newError("", 2013, "Resource to delete '%v' could not be found in the stack. "+
|
||||
func GetTargetCouldNotBeFoundDidYouForgetError() *Diag {
|
||||
return newError("", 2011, "Target '%v' could not be found in the stack. "+
|
||||
"Did you forget to escape $ in your shell?")
|
||||
}
|
||||
|
||||
func GetCannotDeleteParentResourceWithoutAlsoDeletingChildError() *Diag {
|
||||
return newError("", 2014, "Cannot delete parent resource '%v' without also deleting child '%v'.")
|
||||
return newError("", 2012, "Cannot delete parent resource '%v' without also deleting child '%v'.")
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ package deploy
|
|||
import (
|
||||
"context"
|
||||
"math"
|
||||
"strings"
|
||||
|
||||
"github.com/blang/semver"
|
||||
"github.com/pkg/errors"
|
||||
|
@ -29,6 +30,7 @@ import (
|
|||
"github.com/pulumi/pulumi/pkg/resource/plugin"
|
||||
"github.com/pulumi/pulumi/pkg/tokens"
|
||||
"github.com/pulumi/pulumi/pkg/util/contract"
|
||||
"github.com/pulumi/pulumi/pkg/util/logging"
|
||||
"github.com/pulumi/pulumi/pkg/util/result"
|
||||
)
|
||||
|
||||
|
@ -331,3 +333,37 @@ func (p *Plan) Execute(ctx context.Context, opts Options, preview bool) result.R
|
|||
planExec := &planExecutor{plan: p}
|
||||
return planExec.Execute(ctx, opts, preview)
|
||||
}
|
||||
|
||||
// CheckTargets validates that all the targets passed in refer to existing resources. Diagnostics
|
||||
// are generated for any target that cannot be found.
|
||||
//
|
||||
// A map is returned of all the target URNs to facilitate later callers. The map can be 'nil'
|
||||
// indicating no targets, or will be non-nil and non-empty if there are targets.
|
||||
func (p *Plan) CheckTargets(targets []resource.URN) (map[resource.URN]bool, result.Result) {
|
||||
if len(targets) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
targetMap := make(map[resource.URN]bool)
|
||||
// Do an initial pass first to ensure that all the targets mentioned are ones we know about.
|
||||
hasUnknownTarget := false
|
||||
for _, target := range targets {
|
||||
if _, has := p.olds[target]; !has {
|
||||
hasUnknownTarget = true
|
||||
logging.V(7).Infof("Resource to delete (%v) could not be found in the stack.", target)
|
||||
if strings.Contains(string(target), "$") {
|
||||
p.Diag().Errorf(diag.GetTargetCouldNotBeFoundError(), target)
|
||||
} else {
|
||||
p.Diag().Errorf(diag.GetTargetCouldNotBeFoundDidYouForgetError(), target)
|
||||
}
|
||||
}
|
||||
|
||||
targetMap[target] = true
|
||||
}
|
||||
|
||||
if hasUnknownTarget {
|
||||
return nil, result.Bail()
|
||||
}
|
||||
|
||||
return targetMap, nil
|
||||
}
|
||||
|
|
|
@ -16,7 +16,6 @@ package deploy
|
|||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/pulumi/pulumi/pkg/diag"
|
||||
|
@ -322,17 +321,10 @@ func (pe *planExecutor) refresh(callerCtx context.Context, opts Options, preview
|
|||
return nil
|
||||
}
|
||||
|
||||
if len(opts.RefreshTargets) > 0 {
|
||||
for _, target := range opts.RefreshTargets {
|
||||
if _, has := pe.plan.olds[target]; !has {
|
||||
if strings.Contains(string(target), "$") {
|
||||
pe.plan.Diag().Errorf(diag.GetResourceToRefreshCouldNotBeFoundError(), target)
|
||||
} else {
|
||||
pe.plan.Diag().Errorf(diag.GetResourceToRefreshCouldNotBeFoundDidYouForgetError(), target)
|
||||
}
|
||||
return result.Bail()
|
||||
}
|
||||
}
|
||||
// Make sure if there were any targets specified, that they all refer to existing resources.
|
||||
targetMapOpt, res := pe.plan.CheckTargets(opts.RefreshTargets)
|
||||
if res != nil {
|
||||
return res
|
||||
}
|
||||
|
||||
// If the user did not provide any --target's, create a refresh step for each resource in the
|
||||
|
@ -341,7 +333,7 @@ func (pe *planExecutor) refresh(callerCtx context.Context, opts Options, preview
|
|||
steps := []Step{}
|
||||
resourceToStep := map[*resource.State]Step{}
|
||||
for _, res := range prev.Resources {
|
||||
if shouldRefresh(opts, res) {
|
||||
if targetMapOpt == nil || targetMapOpt[res.URN] {
|
||||
step := NewRefreshStep(pe.plan, res, nil)
|
||||
steps = append(steps, step)
|
||||
resourceToStep[res] = step
|
||||
|
@ -449,18 +441,3 @@ func (pe *planExecutor) rebuildBaseState(resourceToStep map[*resource.State]Step
|
|||
pe.plan.prev.Resources = resources
|
||||
pe.plan.olds, pe.plan.depGraph = olds, graph.NewDependencyGraph(resources)
|
||||
}
|
||||
|
||||
func shouldRefresh(opts Options, res *resource.State) bool {
|
||||
if len(opts.RefreshTargets) == 0 {
|
||||
return true
|
||||
}
|
||||
|
||||
//var found = false
|
||||
for _, urn := range opts.RefreshTargets {
|
||||
if urn == res.URN {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
|
|
@ -97,7 +97,7 @@ func (sg *stepGenerator) GenerateReadSteps(event ReadResourceEvent) ([]Step, res
|
|||
// we do not need to delete the resource - we know exactly what resource we are going
|
||||
// to get from the read.
|
||||
//
|
||||
// This operation is tenatively called "relinquish" - it semantically represents the
|
||||
// This operation is tentatively called "relinquish" - it semantically represents the
|
||||
// release of a resource from the management of Pulumi.
|
||||
if hasOld && !old.External && old.ID != event.ID() {
|
||||
logging.V(7).Infof(
|
||||
|
@ -556,31 +556,19 @@ func (sg *stepGenerator) GenerateDeletes(targets []resource.URN) ([]Step, result
|
|||
}
|
||||
}
|
||||
|
||||
if len(targets) > 0 {
|
||||
// Make sure if there were any targets specified, that they all refer to existing resources.
|
||||
targetMapOpt, res := sg.plan.CheckTargets(targets)
|
||||
if res != nil {
|
||||
return nil, res
|
||||
}
|
||||
|
||||
if targetMapOpt != nil {
|
||||
logging.V(7).Infof("Planner was asked to only delete '%v'", targets)
|
||||
|
||||
resourcesToDelete := make(map[resource.URN]bool)
|
||||
|
||||
// Do an initial pass first to ensure that all the targets mentioned are ones we know about.
|
||||
hasUnknownTarget := false
|
||||
for _, target := range targets {
|
||||
if _, has := sg.plan.olds[target]; !has {
|
||||
hasUnknownTarget = true
|
||||
logging.V(7).Infof("Resource to delete (%v) could not be found in the stack.", target)
|
||||
if strings.Contains(string(target), "$") {
|
||||
sg.plan.Diag().Errorf(diag.GetResourceToDeleteCouldNotBeFoundError(), target)
|
||||
} else {
|
||||
sg.plan.Diag().Errorf(diag.GetResourceToDeleteCouldNotBeFoundDidYouForgetError(), target)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if hasUnknownTarget {
|
||||
return nil, result.Bail()
|
||||
}
|
||||
|
||||
// Now actually use all the requested targets to figure out the exact set to delete.
|
||||
for _, target := range targets {
|
||||
for target := range targetMapOpt {
|
||||
current := sg.plan.olds[target]
|
||||
resourcesToDelete[target] = true
|
||||
|
||||
|
|
Loading…
Reference in a new issue