Merge pull request #791 from pulumi/AllowUnknownsPreview
Supply unknown properties to providers during preview.
This commit is contained in:
commit
208b7296be
|
@ -70,7 +70,7 @@ func plan(info *planContext, opts deployOptions) (*planResult, error) {
|
|||
}
|
||||
|
||||
// Generate a plan; this API handles all interesting cases (create, update, delete).
|
||||
plan := deploy.NewPlan(ctx, target, target.Snapshot, source, analyzers)
|
||||
plan := deploy.NewPlan(ctx, target, target.Snapshot, source, analyzers, opts.DryRun)
|
||||
return &planResult{
|
||||
Ctx: ctx,
|
||||
Info: info,
|
||||
|
|
|
@ -23,6 +23,7 @@ type Plan struct {
|
|||
olds map[resource.URN]*resource.State // a map of all old resources.
|
||||
source Source // the source of new resources.
|
||||
analyzers []tokens.QName // the analyzers to run during this plan's generation.
|
||||
preview bool // true if this plan is to be previewed rather than applied.
|
||||
}
|
||||
|
||||
// NewPlan creates a new deployment plan from a resource snapshot plus a package to evaluate.
|
||||
|
@ -34,7 +35,9 @@ type Plan struct {
|
|||
//
|
||||
// Note that a plan uses internal concurrency and parallelism in various ways, so it must be closed if for some reason
|
||||
// a plan isn't carried out to its final conclusion. This will result in cancelation and reclamation of OS resources.
|
||||
func NewPlan(ctx *plugin.Context, target *Target, prev *Snapshot, source Source, analyzers []tokens.QName) *Plan {
|
||||
func NewPlan(ctx *plugin.Context, target *Target, prev *Snapshot, source Source, analyzers []tokens.QName,
|
||||
preview bool) *Plan {
|
||||
|
||||
contract.Assert(ctx != nil)
|
||||
contract.Assert(target != nil)
|
||||
contract.Assert(source != nil)
|
||||
|
@ -61,6 +64,7 @@ func NewPlan(ctx *plugin.Context, target *Target, prev *Snapshot, source Source,
|
|||
olds: olds,
|
||||
source: source,
|
||||
analyzers: analyzers,
|
||||
preview: preview,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -296,11 +296,14 @@ func (iter *PlanIterator) makeRegisterResouceSteps(e RegisterResourceEvent) ([]S
|
|||
}
|
||||
}
|
||||
|
||||
// We only allow unknown property values to be exposed to the provider if we are performing a preview.
|
||||
allowUnknowns := iter.p.preview
|
||||
|
||||
// Ensure the provider is okay with this resource and fetch the inputs to pass to subsequent methods.
|
||||
news, inputs := new.Inputs, new.Inputs
|
||||
if prov != nil {
|
||||
var failures []plugin.CheckFailure
|
||||
inputs, failures, err = prov.Check(urn, olds, news)
|
||||
inputs, failures, err = prov.Check(urn, olds, news, allowUnknowns)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if iter.issueCheckErrors(new, urn, failures) {
|
||||
|
@ -354,7 +357,7 @@ func (iter *PlanIterator) makeRegisterResouceSteps(e RegisterResourceEvent) ([]S
|
|||
// The properties changed; we need to figure out whether to do an update or replacement.
|
||||
var diff plugin.DiffResult
|
||||
if prov != nil {
|
||||
if diff, err = prov.Diff(urn, old.ID, oldState, inputs); err != nil {
|
||||
if diff, err = prov.Diff(urn, old.ID, oldState, inputs, allowUnknowns); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
@ -367,7 +370,7 @@ func (iter *PlanIterator) makeRegisterResouceSteps(e RegisterResourceEvent) ([]S
|
|||
// had assumed that we were going to carry them over from the old resource, which is no longer true.
|
||||
if prov != nil {
|
||||
var failures []plugin.CheckFailure
|
||||
inputs, failures, err = prov.Check(urn, nil, news)
|
||||
inputs, failures, err = prov.Check(urn, nil, news, allowUnknowns)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if iter.issueCheckErrors(new, urn, failures) {
|
||||
|
|
|
@ -24,7 +24,7 @@ func TestNullPlan(t *testing.T) {
|
|||
assert.Nil(t, err)
|
||||
targ := &Target{Name: tokens.QName("null")}
|
||||
prev := NewSnapshot(targ.Name, Manifest{}, nil)
|
||||
plan := NewPlan(ctx, targ, prev, NullSource, nil)
|
||||
plan := NewPlan(ctx, targ, prev, NullSource, nil, false)
|
||||
iter, err := plan.Start(Options{})
|
||||
assert.Nil(t, err)
|
||||
assert.NotNil(t, iter)
|
||||
|
@ -45,7 +45,7 @@ func TestErrorPlan(t *testing.T) {
|
|||
assert.Nil(t, err)
|
||||
targ := &Target{Name: tokens.QName("errs")}
|
||||
prev := NewSnapshot(targ.Name, Manifest{}, nil)
|
||||
plan := NewPlan(ctx, targ, prev, &errorSource{err: errors.New("ITERATE"), duringIterate: true}, nil)
|
||||
plan := NewPlan(ctx, targ, prev, &errorSource{err: errors.New("ITERATE"), duringIterate: true}, nil, false)
|
||||
iter, err := plan.Start(Options{})
|
||||
assert.Nil(t, iter)
|
||||
assert.NotNil(t, err)
|
||||
|
@ -60,7 +60,7 @@ func TestErrorPlan(t *testing.T) {
|
|||
assert.Nil(t, err)
|
||||
targ := &Target{Name: tokens.QName("errs")}
|
||||
prev := NewSnapshot(targ.Name, Manifest{}, nil)
|
||||
plan := NewPlan(ctx, targ, prev, &errorSource{err: errors.New("NEXT"), duringIterate: false}, nil)
|
||||
plan := NewPlan(ctx, targ, prev, &errorSource{err: errors.New("NEXT"), duringIterate: false}, nil, false)
|
||||
iter, err := plan.Start(Options{})
|
||||
assert.Nil(t, err)
|
||||
assert.NotNil(t, iter)
|
||||
|
@ -216,7 +216,7 @@ func TestBasicCRUDPlan(t *testing.T) {
|
|||
source := NewFixedSource(pkgname, []SourceEvent{newStateA, newStateB, newStateC})
|
||||
|
||||
// Next up, create a plan from the new and old, and validate its shape.
|
||||
plan := NewPlan(ctx, targ, oldsnap, source, nil)
|
||||
plan := NewPlan(ctx, targ, oldsnap, source, nil, false)
|
||||
|
||||
// Next, validate the steps and ensure that we see all of the expected ones. Note that there aren't any
|
||||
// dependencies between the steps, so we must validate it in a way that's insensitive of order.
|
||||
|
@ -398,7 +398,7 @@ func (prov *testProvider) Configure(vars map[tokens.ModuleMember]string) error {
|
|||
return prov.config(vars)
|
||||
}
|
||||
func (prov *testProvider) Check(urn resource.URN,
|
||||
olds, news resource.PropertyMap) (resource.PropertyMap, []plugin.CheckFailure, error) {
|
||||
olds, news resource.PropertyMap, _ bool) (resource.PropertyMap, []plugin.CheckFailure, error) {
|
||||
return prov.check(urn, olds, news)
|
||||
}
|
||||
func (prov *testProvider) Create(urn resource.URN, props resource.PropertyMap) (resource.ID,
|
||||
|
@ -406,7 +406,7 @@ func (prov *testProvider) Create(urn resource.URN, props resource.PropertyMap) (
|
|||
return prov.create(urn, props)
|
||||
}
|
||||
func (prov *testProvider) Diff(urn resource.URN, id resource.ID,
|
||||
olds resource.PropertyMap, news resource.PropertyMap) (plugin.DiffResult, error) {
|
||||
olds resource.PropertyMap, news resource.PropertyMap, _ bool) (plugin.DiffResult, error) {
|
||||
return prov.diff(urn, id, olds, news)
|
||||
}
|
||||
func (prov *testProvider) Update(urn resource.URN, id resource.ID,
|
||||
|
|
|
@ -28,9 +28,11 @@ type Provider interface {
|
|||
Configure(vars map[tokens.ModuleMember]string) error
|
||||
// Check validates that the given property bag is valid for a resource of the given type and returns the inputs
|
||||
// that should be passed to successive calls to Diff, Create, or Update for this resource.
|
||||
Check(urn resource.URN, olds, news resource.PropertyMap) (resource.PropertyMap, []CheckFailure, error)
|
||||
Check(urn resource.URN, olds, news resource.PropertyMap,
|
||||
allowUnknowns bool) (resource.PropertyMap, []CheckFailure, error)
|
||||
// Diff checks what impacts a hypothetical update will have on the resource's properties.
|
||||
Diff(urn resource.URN, id resource.ID, olds resource.PropertyMap, news resource.PropertyMap) (DiffResult, error)
|
||||
Diff(urn resource.URN, id resource.ID, olds resource.PropertyMap, news resource.PropertyMap,
|
||||
allowUnknowns bool) (DiffResult, error)
|
||||
// Create allocates a new instance of the provided resource and returns its unique resource.ID.
|
||||
Create(urn resource.URN, news resource.PropertyMap) (resource.ID, resource.PropertyMap, resource.Status, error)
|
||||
// Update updates an existing resource with new values.
|
||||
|
|
|
@ -71,16 +71,18 @@ func (p *provider) Configure(vars map[tokens.ModuleMember]string) error {
|
|||
|
||||
// Check validates that the given property bag is valid for a resource of the given type.
|
||||
func (p *provider) Check(urn resource.URN,
|
||||
olds, news resource.PropertyMap) (resource.PropertyMap, []CheckFailure, error) {
|
||||
olds, news resource.PropertyMap, allowUnknowns bool) (resource.PropertyMap, []CheckFailure, error) {
|
||||
|
||||
label := fmt.Sprintf("%s.Check(%s)", p.label(), urn)
|
||||
glog.V(7).Infof("%s executing (#olds=%d,#news=%d", label, len(olds), len(news))
|
||||
|
||||
molds, err := MarshalProperties(olds, MarshalOptions{Label: fmt.Sprintf("%s.olds", label)})
|
||||
molds, err := MarshalProperties(olds, MarshalOptions{Label: fmt.Sprintf("%s.olds", label),
|
||||
KeepUnknowns: allowUnknowns})
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
mnews, err := MarshalProperties(news, MarshalOptions{Label: fmt.Sprintf("%s.news", label)})
|
||||
mnews, err := MarshalProperties(news, MarshalOptions{Label: fmt.Sprintf("%s.news", label),
|
||||
KeepUnknowns: allowUnknowns})
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
@ -99,7 +101,7 @@ func (p *provider) Check(urn resource.URN,
|
|||
var inputs resource.PropertyMap
|
||||
if ins := resp.GetInputs(); ins != nil {
|
||||
inputs, err = UnmarshalProperties(ins, MarshalOptions{
|
||||
Label: fmt.Sprintf("%s.inputs", label), RejectUnknowns: true})
|
||||
Label: fmt.Sprintf("%s.inputs", label), KeepUnknowns: allowUnknowns, RejectUnknowns: !allowUnknowns})
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
@ -117,7 +119,7 @@ func (p *provider) Check(urn resource.URN,
|
|||
|
||||
// Diff checks what impacts a hypothetical update will have on the resource's properties.
|
||||
func (p *provider) Diff(urn resource.URN, id resource.ID,
|
||||
olds resource.PropertyMap, news resource.PropertyMap) (DiffResult, error) {
|
||||
olds resource.PropertyMap, news resource.PropertyMap, allowUnknowns bool) (DiffResult, error) {
|
||||
contract.Assert(urn != "")
|
||||
contract.Assert(id != "")
|
||||
contract.Assert(news != nil)
|
||||
|
@ -127,11 +129,12 @@ func (p *provider) Diff(urn resource.URN, id resource.ID,
|
|||
glog.V(7).Infof("%s: executing (#olds=%d,#news=%d)", label, len(olds), len(news))
|
||||
|
||||
molds, err := MarshalProperties(olds, MarshalOptions{
|
||||
Label: fmt.Sprintf("%s.olds", label), ElideAssetContents: true})
|
||||
Label: fmt.Sprintf("%s.olds", label), ElideAssetContents: true, KeepUnknowns: allowUnknowns})
|
||||
if err != nil {
|
||||
return DiffResult{}, err
|
||||
}
|
||||
mnews, err := MarshalProperties(news, MarshalOptions{Label: fmt.Sprintf("%s.news", label)})
|
||||
mnews, err := MarshalProperties(news, MarshalOptions{Label: fmt.Sprintf("%s.news", label),
|
||||
KeepUnknowns: allowUnknowns})
|
||||
if err != nil {
|
||||
return DiffResult{}, err
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue