diff --git a/pkg/backend/display/json.go b/pkg/backend/display/json.go index f4403ee45066..61efe69b4f73 100644 --- a/pkg/backend/display/json.go +++ b/pkg/backend/display/json.go @@ -85,7 +85,7 @@ func stateForJSONOutput(s *resource.State, opts Options) *resource.State { return resource.NewState(s.Type, s.URN, s.Custom, s.Delete, s.ID, inputs, outputs, s.Parent, s.Protect, s.External, s.Dependencies, s.InitErrors, s.Provider, s.PropertyDependencies, s.PendingReplacement, s.AdditionalSecretOutputs, s.Aliases, &s.CustomTimeouts, - s.ImportID, s.RetainOnDelete) + s.ImportID, s.RetainOnDelete, s.DeletedWithParent) } // ShowJSONEvents renders incremental engine events to stdout. diff --git a/pkg/backend/snapshot.go b/pkg/backend/snapshot.go index b1a2d5ef132d..7420d99c86f2 100644 --- a/pkg/backend/snapshot.go +++ b/pkg/backend/snapshot.go @@ -231,6 +231,12 @@ func (ssm *sameSnapshotMutation) mustWrite(step *deploy.SameStep) bool { return true } + // If the DeletedWithParent attribute of this resource has changed, we must write the checkpoint. + if old.DeletedWithParent != new.DeletedWithParent { + logging.V(9).Infof("SnapshotManager: mustWrite() true because of DeletedWithParent") + return true + } + // If the protection attribute of this resource has changed, we must write the checkpoint. if old.Protect != new.Protect { logging.V(9).Infof("SnapshotManager: mustWrite() true because of Protect") diff --git a/pkg/backend/snapshot_test.go b/pkg/backend/snapshot_test.go index 0ee84587b349..93727192036b 100644 --- a/pkg/backend/snapshot_test.go +++ b/pkg/backend/snapshot_test.go @@ -603,7 +603,7 @@ func TestDeletion(t *testing.T) { }) manager, sp := MockSetup(t, snap) - step := deploy.NewDeleteStep(nil, resourceA) + step := deploy.NewDeleteStep(nil, map[resource.URN]bool{}, resourceA) mutation, err := manager.BeginMutation(step) if !assert.NoError(t, err) { t.FailNow() @@ -629,7 +629,7 @@ func TestFailedDelete(t *testing.T) { }) manager, sp := MockSetup(t, snap) - step := deploy.NewDeleteStep(nil, resourceA) + step := deploy.NewDeleteStep(nil, map[resource.URN]bool{}, resourceA) mutation, err := manager.BeginMutation(step) if !assert.NoError(t, err) { t.FailNow() @@ -802,7 +802,7 @@ func TestRecordingDeleteSuccess(t *testing.T) { resourceA, }) manager, sp := MockSetup(t, snap) - step := deploy.NewDeleteStep(nil, resourceA) + step := deploy.NewDeleteStep(nil, map[resource.URN]bool{}, resourceA) mutation, err := manager.BeginMutation(step) if !assert.NoError(t, err) { t.FailNow() @@ -834,7 +834,7 @@ func TestRecordingDeleteFailure(t *testing.T) { resourceA, }) manager, sp := MockSetup(t, snap) - step := deploy.NewDeleteStep(nil, resourceA) + step := deploy.NewDeleteStep(nil, map[resource.URN]bool{}, resourceA) mutation, err := manager.BeginMutation(step) if !assert.NoError(t, err) { t.FailNow() diff --git a/pkg/engine/lifecycletest/pulumi_test.go b/pkg/engine/lifecycletest/pulumi_test.go index d5b57ee64ab6..122ec30f67ab 100644 --- a/pkg/engine/lifecycletest/pulumi_test.go +++ b/pkg/engine/lifecycletest/pulumi_test.go @@ -3702,6 +3702,117 @@ func TestRetainOnDelete(t *testing.T) { assert.Len(t, snap.Resources, 0) } +func TestDeletedWithParent(t *testing.T) { + t.Parallel() + + idCounter := 0 + + topParentURN := resource.URN("") + + loaders := []*deploytest.ProviderLoader{ + deploytest.NewProviderLoader("pkgA", semver.MustParse("1.0.0"), func() (plugin.Provider, error) { + return &deploytest.Provider{ + DiffF: func( + urn resource.URN, + id resource.ID, + olds, news resource.PropertyMap, + ignoreChanges []string) (plugin.DiffResult, error) { + if !olds["foo"].DeepEquals(news["foo"]) { + // If foo changes do a replace, we use this to check we don't delete on replace + return plugin.DiffResult{ + Changes: plugin.DiffSome, + ReplaceKeys: []resource.PropertyKey{"foo"}, + }, nil + } + return plugin.DiffResult{}, nil + }, + CreateF: func(urn resource.URN, news resource.PropertyMap, timeout float64, + preview bool) (resource.ID, resource.PropertyMap, resource.Status, error) { + resourceID := resource.ID(fmt.Sprintf("created-id-%d", idCounter)) + idCounter = idCounter + 1 + return resourceID, news, resource.StatusOK, nil + }, + DeleteF: func(urn resource.URN, id resource.ID, olds resource.PropertyMap, + timeout float64) (resource.Status, error) { + if urn != topParentURN { + // Only top parent should be actually deleted + assert.Fail(t, "Delete was called") + } + return resource.StatusOK, nil + }, + }, nil + }, deploytest.WithoutGrpc), + } + + ins := resource.NewPropertyMapFromMap(map[string]interface{}{ + "foo": "bar", + }) + + createResource := true + + program := deploytest.NewLanguageRuntime(func(_ plugin.RunInfo, monitor *deploytest.ResourceMonitor) error { + + if createResource { + aURN, _, _, err := monitor.RegisterResource("pkgA:m:typA", "resA", true, deploytest.ResourceOptions{ + Inputs: ins, + }) + assert.NoError(t, err) + topParentURN = aURN + + bURN, _, _, err := monitor.RegisterResource("pkgA:m:typA", "resB", true, deploytest.ResourceOptions{ + Inputs: ins, + Parent: aURN, + DeletedWithParent: true, + }) + assert.NoError(t, err) + + _, _, _, err = monitor.RegisterResource("pkgA:m:typA", "resC", true, deploytest.ResourceOptions{ + Inputs: ins, + Parent: bURN, + DeletedWithParent: true, + }) + assert.NoError(t, err) + } + + return nil + }) + host := deploytest.NewPluginHost(nil, nil, program, loaders...) + + p := &TestPlan{ + Options: UpdateOptions{Host: host}, + } + + project := p.GetProject() + + // Run an update to create the resource + snap, res := TestOp(Update).Run(project, p.GetTarget(t, nil), p.Options, false, p.BackendClient, nil) + assert.Nil(t, res) + assert.NotNil(t, snap) + assert.Len(t, snap.Resources, 4) + assert.Equal(t, "created-id-0", snap.Resources[1].ID.String()) + assert.Equal(t, "created-id-1", snap.Resources[2].ID.String()) + assert.Equal(t, "created-id-2", snap.Resources[3].ID.String()) + + // Run a new update which will cause a replace, we shouldn't see a provider delete but should get a new id + ins = resource.NewPropertyMapFromMap(map[string]interface{}{ + "foo": "baz", + }) + snap, res = TestOp(Update).Run(project, p.GetTarget(t, snap), p.Options, false, p.BackendClient, nil) + assert.Nil(t, res) + assert.NotNil(t, snap) + assert.Len(t, snap.Resources, 4) + assert.Equal(t, "created-id-3", snap.Resources[1].ID.String()) + assert.Equal(t, "created-id-4", snap.Resources[2].ID.String()) + assert.Equal(t, "created-id-5", snap.Resources[3].ID.String()) + + // Run a new update which will cause a delete, we still shouldn't see a provider delete + createResource = false + snap, res = TestOp(Update).Run(project, p.GetTarget(t, snap), p.Options, false, p.BackendClient, nil) + assert.Nil(t, res) + assert.NotNil(t, snap) + assert.Len(t, snap.Resources, 0) +} + func TestInvalidGetIDReportsUserError(t *testing.T) { t.Parallel() diff --git a/pkg/resource/deploy/deploytest/resourcemonitor.go b/pkg/resource/deploy/deploytest/resourcemonitor.go index a7b3162d86e9..08b37704996c 100644 --- a/pkg/resource/deploy/deploytest/resourcemonitor.go +++ b/pkg/resource/deploy/deploytest/resourcemonitor.go @@ -86,6 +86,7 @@ func NewResourceMonitor(resmon pulumirpc.ResourceMonitorClient) *ResourceMonitor type ResourceOptions struct { Parent resource.URN + DeletedWithParent bool Protect bool Dependencies []resource.URN Provider string @@ -222,6 +223,7 @@ func (rm *ResourceMonitor) RegisterResource(t tokens.Type, name string, custom b RetainOnDelete: opts.RetainOnDelete, AdditionalSecretOutputs: additionalSecretOutputs, Aliases: aliasObjects, + DeletedWithParent: opts.DeletedWithParent, } // submit request diff --git a/pkg/resource/deploy/import.go b/pkg/resource/deploy/import.go index bb4a7413a7b8..c435cc0e3ce7 100644 --- a/pkg/resource/deploy/import.go +++ b/pkg/resource/deploy/import.go @@ -169,7 +169,7 @@ func (i *importer) getOrCreateStackResource(ctx context.Context) (resource.URN, typ, name := resource.RootStackType, fmt.Sprintf("%s-%s", projectName, stackName) urn := resource.NewURN(stackName.Q(), projectName, "", typ, tokens.QName(name)) state := resource.NewState(typ, urn, false, false, "", resource.PropertyMap{}, nil, "", false, false, nil, nil, "", - nil, false, nil, nil, nil, "", false) + nil, false, nil, nil, nil, "", false, false) // TODO(seqnum) should stacks be created with 1? When do they ever get recreated/replaced? if !i.executeSerial(ctx, NewCreateStep(i.deployment, noopEvent(0), state)) { return "", false, false @@ -255,7 +255,7 @@ func (i *importer) registerProviders(ctx context.Context) (map[resource.URN]stri } state := resource.NewState(typ, urn, true, false, "", inputs, nil, "", false, false, nil, nil, "", nil, false, - nil, nil, nil, "", false) + nil, nil, nil, "", false, false) // TODO(seqnum) should default providers be created with 1? When do they ever get recreated/replaced? if issueCheckErrors(i.deployment, state, urn, failures) { return nil, nil, false @@ -355,7 +355,7 @@ func (i *importer) importResources(ctx context.Context) result.Result { // Create the new desired state. Note that the resource is protected. new := resource.NewState(urn.Type(), urn, true, false, imp.ID, resource.PropertyMap{}, nil, parent, imp.Protect, - false, nil, nil, provider, nil, false, nil, nil, nil, "", false) + false, nil, nil, provider, nil, false, nil, nil, nil, "", false, false) steps = append(steps, newImportDeploymentStep(i.deployment, new, randomSeed)) } diff --git a/pkg/resource/deploy/source_eval.go b/pkg/resource/deploy/source_eval.go index 07f77f723eff..d26d04d97ba2 100644 --- a/pkg/resource/deploy/source_eval.go +++ b/pkg/resource/deploy/source_eval.go @@ -329,7 +329,7 @@ func (d *defaultProviders) newRegisterDefaultProviderEvent( goal: resource.NewGoal( providers.MakeProviderType(req.Package()), req.Name(), true, inputs, "", false, nil, "", nil, nil, nil, - nil, nil, nil, "", nil, nil, false), + nil, nil, nil, "", nil, nil, false, false), done: done, } return event, done, nil @@ -944,6 +944,7 @@ func (rm *resmon) RegisterResource(ctx context.Context, id := resource.ID(req.GetImportId()) customTimeouts := req.GetCustomTimeouts() retainOnDelete := req.GetRetainOnDelete() + deletedWithParent := req.GetDeletedWithParent() // Custom resources must have a three-part type so that we can 1) identify if they are providers and 2) retrieve the // provider responsible for managing a particular resource (based on the type's Package). @@ -1110,9 +1111,9 @@ func (rm *resmon) RegisterResource(ctx context.Context, logging.V(5).Infof( "ResourceMonitor.RegisterResource received: t=%v, name=%v, custom=%v, #props=%v, parent=%v, protect=%v, "+ "provider=%v, deps=%v, deleteBeforeReplace=%v, ignoreChanges=%v, aliases=%v, customTimeouts=%v, "+ - "providers=%v, replaceOnChanges=%v, retainOnDelete=%v", + "providers=%v, replaceOnChanges=%v, retainOnDelete=%v, deletedWithParent=%v", t, name, custom, len(props), parent, protect, providerRef, dependencies, deleteBeforeReplace, ignoreChanges, - aliases, timeouts, providerRefs, replaceOnChanges, retainOnDelete) + aliases, timeouts, providerRefs, replaceOnChanges, retainOnDelete, deletedWithParent) // If this is a remote component, fetch its provider and issue the construct call. Otherwise, register the resource. var result *RegisterResult @@ -1153,7 +1154,7 @@ func (rm *resmon) RegisterResource(ctx context.Context, step := ®isterResourceEvent{ goal: resource.NewGoal(t, name, custom, props, parent, protect, dependencies, providerRef.String(), nil, propertyDependencies, deleteBeforeReplace, ignoreChanges, - additionalSecretOutputs, aliases, id, &timeouts, replaceOnChanges, retainOnDelete), + additionalSecretOutputs, aliases, id, &timeouts, replaceOnChanges, retainOnDelete, deletedWithParent), done: make(chan *RegisterResult), } @@ -1207,6 +1208,7 @@ func (rm *resmon) RegisterResource(ctx context.Context, // • additionalSecretOutputs // • replaceOnChanges // • retainOnDelete + // • deletedWithParent // Revisit these semantics in Pulumi v4.0 // See this issue for more: https://github.com/pulumi/pulumi/issues/9704 if !custom { @@ -1231,6 +1233,9 @@ func (rm *resmon) RegisterResource(ctx context.Context, rm.checkComponentOption(result.State.URN, "retainOnDelete", func() bool { return retainOnDelete }) + rm.checkComponentOption(result.State.URN, "deletedWithParent", func() bool { + return deletedWithParent + }) } logging.V(5).Infof( diff --git a/pkg/resource/deploy/source_eval_test.go b/pkg/resource/deploy/source_eval_test.go index cdc42e8663a1..4cb3026c138c 100644 --- a/pkg/resource/deploy/source_eval_test.go +++ b/pkg/resource/deploy/source_eval_test.go @@ -71,7 +71,7 @@ func fixedProgram(steps []RegisterResourceEvent) deploytest.ProgramFunc { s.Done(&RegisterResult{ State: resource.NewState(g.Type, urn, g.Custom, false, id, g.Properties, outs, g.Parent, g.Protect, false, g.Dependencies, nil, g.Provider, g.PropertyDependencies, false, nil, nil, nil, - "", false), + "", false, false), }) } return nil @@ -181,16 +181,16 @@ func TestRegisterNoDefaultProviders(t *testing.T) { // Register a component resource. &testRegEvent{ goal: resource.NewGoal(componentURN.Type(), componentURN.Name(), false, resource.PropertyMap{}, "", false, - nil, "", []string{}, nil, nil, nil, nil, nil, "", nil, nil, false), + nil, "", []string{}, nil, nil, nil, nil, nil, "", nil, nil, false, false), }, // Register a couple resources using provider A. &testRegEvent{ goal: resource.NewGoal("pkgA:index:typA", "res1", true, resource.PropertyMap{}, componentURN, false, nil, - providerARef.String(), []string{}, nil, nil, nil, nil, nil, "", nil, nil, false), + providerARef.String(), []string{}, nil, nil, nil, nil, nil, "", nil, nil, false, false), }, &testRegEvent{ goal: resource.NewGoal("pkgA:index:typA", "res2", true, resource.PropertyMap{}, componentURN, false, nil, - providerARef.String(), []string{}, nil, nil, nil, nil, nil, "", nil, nil, false), + providerARef.String(), []string{}, nil, nil, nil, nil, nil, "", nil, nil, false, false), }, // Register two more providers. newProviderEvent("pkgA", "providerB", nil, ""), @@ -198,11 +198,11 @@ func TestRegisterNoDefaultProviders(t *testing.T) { // Register a few resources that use the new providers. &testRegEvent{ goal: resource.NewGoal("pkgB:index:typB", "res3", true, resource.PropertyMap{}, "", false, nil, - providerBRef.String(), []string{}, nil, nil, nil, nil, nil, "", nil, nil, false), + providerBRef.String(), []string{}, nil, nil, nil, nil, nil, "", nil, nil, false, false), }, &testRegEvent{ goal: resource.NewGoal("pkgB:index:typC", "res4", true, resource.PropertyMap{}, "", false, nil, - providerCRef.String(), []string{}, nil, nil, nil, nil, nil, "", nil, nil, false), + providerCRef.String(), []string{}, nil, nil, nil, nil, nil, "", nil, nil, false, false), }, } @@ -236,7 +236,7 @@ func TestRegisterNoDefaultProviders(t *testing.T) { reg.Done(&RegisterResult{ State: resource.NewState(goal.Type, urn, goal.Custom, false, id, goal.Properties, resource.PropertyMap{}, goal.Parent, goal.Protect, false, goal.Dependencies, nil, goal.Provider, goal.PropertyDependencies, - false, nil, nil, nil, "", false), + false, nil, nil, nil, "", false, false), }) processed++ @@ -267,25 +267,25 @@ func TestRegisterDefaultProviders(t *testing.T) { // Register a component resource. &testRegEvent{ goal: resource.NewGoal(componentURN.Type(), componentURN.Name(), false, resource.PropertyMap{}, "", false, - nil, "", []string{}, nil, nil, nil, nil, nil, "", nil, nil, false), + nil, "", []string{}, nil, nil, nil, nil, nil, "", nil, nil, false, false), }, // Register a couple resources from package A. &testRegEvent{ goal: resource.NewGoal("pkgA:m:typA", "res1", true, resource.PropertyMap{}, - componentURN, false, nil, "", []string{}, nil, nil, nil, nil, nil, "", nil, nil, false), + componentURN, false, nil, "", []string{}, nil, nil, nil, nil, nil, "", nil, nil, false, false), }, &testRegEvent{ goal: resource.NewGoal("pkgA:m:typA", "res2", true, resource.PropertyMap{}, - componentURN, false, nil, "", []string{}, nil, nil, nil, nil, nil, "", nil, nil, false), + componentURN, false, nil, "", []string{}, nil, nil, nil, nil, nil, "", nil, nil, false, false), }, // Register a few resources from other packages. &testRegEvent{ goal: resource.NewGoal("pkgB:m:typB", "res3", true, resource.PropertyMap{}, "", false, - nil, "", []string{}, nil, nil, nil, nil, nil, "", nil, nil, false), + nil, "", []string{}, nil, nil, nil, nil, nil, "", nil, nil, false, false), }, &testRegEvent{ goal: resource.NewGoal("pkgB:m:typC", "res4", true, resource.PropertyMap{}, "", false, - nil, "", []string{}, nil, nil, nil, nil, nil, "", nil, nil, false), + nil, "", []string{}, nil, nil, nil, nil, nil, "", nil, nil, false, false), }, } @@ -330,7 +330,7 @@ func TestRegisterDefaultProviders(t *testing.T) { reg.Done(&RegisterResult{ State: resource.NewState(goal.Type, urn, goal.Custom, false, id, goal.Properties, resource.PropertyMap{}, goal.Parent, goal.Protect, false, goal.Dependencies, nil, goal.Provider, goal.PropertyDependencies, - false, nil, nil, nil, "", false), + false, nil, nil, nil, "", false, false), }) processed++ @@ -422,7 +422,7 @@ func TestReadInvokeNoDefaultProviders(t *testing.T) { read.Done(&ReadResult{ State: resource.NewState(read.Type(), urn, true, false, read.ID(), read.Properties(), resource.PropertyMap{}, read.Parent(), false, false, read.Dependencies(), nil, read.Provider(), nil, - false, nil, nil, nil, "", false), + false, nil, nil, nil, "", false, false), }) reads++ } @@ -509,7 +509,7 @@ func TestReadInvokeDefaultProviders(t *testing.T) { e.Done(&RegisterResult{ State: resource.NewState(goal.Type, urn, goal.Custom, false, id, goal.Properties, resource.PropertyMap{}, goal.Parent, goal.Protect, false, goal.Dependencies, nil, goal.Provider, goal.PropertyDependencies, - false, nil, nil, nil, "", false), + false, nil, nil, nil, "", false, false), }) registers++ @@ -518,7 +518,7 @@ func TestReadInvokeDefaultProviders(t *testing.T) { e.Done(&ReadResult{ State: resource.NewState(e.Type(), urn, true, false, e.ID(), e.Properties(), resource.PropertyMap{}, e.Parent(), false, false, e.Dependencies(), nil, e.Provider(), nil, false, - nil, nil, nil, "", false), + nil, nil, nil, "", false, false), }) reads++ } @@ -673,7 +673,7 @@ func TestDisableDefaultProviders(t *testing.T) { event.Done(&ReadResult{ State: resource.NewState(event.Type(), urn, true, false, event.ID(), event.Properties(), resource.PropertyMap{}, event.Parent(), false, false, event.Dependencies(), nil, event.Provider(), nil, - false, nil, nil, nil, "", false), + false, nil, nil, nil, "", false, false), }) reads++ case RegisterResourceEvent: @@ -681,7 +681,7 @@ func TestDisableDefaultProviders(t *testing.T) { event.Done(&RegisterResult{ State: resource.NewState(event.Goal().Type, urn, true, false, event.Goal().ID, event.Goal().Properties, resource.PropertyMap{}, event.Goal().Parent, false, false, event.Goal().Dependencies, nil, - event.Goal().Provider, nil, false, nil, nil, nil, "", false), + event.Goal().Provider, nil, false, nil, nil, nil, "", false, false), }) registers++ default: diff --git a/pkg/resource/deploy/step.go b/pkg/resource/deploy/step.go index 68b39310b82d..1a532ac7e609 100644 --- a/pkg/resource/deploy/step.go +++ b/pkg/resource/deploy/step.go @@ -268,29 +268,38 @@ func (s *CreateStep) Apply(preview bool) (resource.Status, StepCompleteFunc, err // DeleteStep is a mutating step that deletes an existing resource. If `old` is marked "External", // DeleteStep is a no-op. type DeleteStep struct { - deployment *Deployment // the current deployment. - old *resource.State // the state of the existing resource. - replacing bool // true if part of a replacement. + deployment *Deployment // the current deployment. + old *resource.State // the state of the existing resource. + replacing bool // true if part of a replacement. + otherDeletions map[resource.URN]bool // other resources that the planner decided to delete } var _ Step = (*DeleteStep)(nil) -func NewDeleteStep(deployment *Deployment, old *resource.State) Step { +func NewDeleteStep(deployment *Deployment, otherDeletions map[resource.URN]bool, old *resource.State) Step { contract.Assert(old != nil) contract.Assert(old.URN != "") contract.Assert(old.ID != "" || !old.Custom) contract.Assert(!old.Custom || old.Provider != "" || providers.IsProviderType(old.Type)) + contract.Assert(otherDeletions != nil) return &DeleteStep{ - deployment: deployment, - old: old, + deployment: deployment, + old: old, + otherDeletions: otherDeletions, } } -func NewDeleteReplacementStep(deployment *Deployment, old *resource.State, pendingReplace bool) Step { +func NewDeleteReplacementStep( + deployment *Deployment, + otherDeletions map[resource.URN]bool, + old *resource.State, + pendingReplace bool, +) Step { contract.Assert(old != nil) contract.Assert(old.URN != "") contract.Assert(old.ID != "" || !old.Custom) contract.Assert(!old.Custom || old.Provider != "" || providers.IsProviderType(old.Type)) + contract.Assert(otherDeletions != nil) // There are two cases in which we create a delete-replacment step: // @@ -307,9 +316,10 @@ func NewDeleteReplacementStep(deployment *Deployment, old *resource.State, pendi contract.Assert(pendingReplace != old.Delete) old.PendingReplacement = pendingReplace return &DeleteStep{ - deployment: deployment, - old: old, - replacing: true, + deployment: deployment, + otherDeletions: otherDeletions, + old: old, + replacing: true, } } @@ -335,6 +345,17 @@ func (s *DeleteStep) New() *resource.State { return nil } func (s *DeleteStep) Res() *resource.State { return s.old } func (s *DeleteStep) Logical() bool { return !s.replacing } +func isDeletingParent(parent resource.URN, otherDeletions map[resource.URN]bool) bool { + if parent == "" { + return false + } + r, ok := otherDeletions[parent] + if !ok { + return false + } + return r +} + func (s *DeleteStep) Apply(preview bool) (resource.Status, StepCompleteFunc, error) { // Refuse to delete protected resources (unless we're replacing them in // which case we will of checked protect elsewhere) @@ -352,6 +373,8 @@ func (s *DeleteStep) Apply(preview bool) (resource.Status, StepCompleteFunc, err // Deleting an External resource is a no-op, since Pulumi does not own the lifecycle. } else if s.old.RetainOnDelete { // Deleting a "drop on delete" is a no-op as the user has explicitly asked us to not delete the resource. + } else if s.old.DeletedWithParent && isDeletingParent(s.old.Parent, s.otherDeletions) { + // No need to delete this resource since this resource will be deleted along with its parent } else if s.old.Custom { // Not preview and not external and not Drop and is custom, do the actual delete @@ -784,7 +807,7 @@ func (s *RefreshStep) Apply(preview bool) (resource.Status, StepCompleteFunc, er s.new = resource.NewState(s.old.Type, s.old.URN, s.old.Custom, s.old.Delete, resourceID, inputs, outputs, s.old.Parent, s.old.Protect, s.old.External, s.old.Dependencies, initErrors, s.old.Provider, s.old.PropertyDependencies, s.old.PendingReplacement, s.old.AdditionalSecretOutputs, s.old.Aliases, - &s.old.CustomTimeouts, s.old.ImportID, s.old.RetainOnDelete) + &s.old.CustomTimeouts, s.old.ImportID, s.old.RetainOnDelete, s.old.DeletedWithParent) } else { s.new = nil } @@ -933,7 +956,8 @@ func (s *ImportStep) Apply(preview bool) (resource.Status, StepCompleteFunc, err // differences between the old and new states are between the inputs and outputs. s.old = resource.NewState(s.new.Type, s.new.URN, s.new.Custom, false, s.new.ID, read.Inputs, read.Outputs, s.new.Parent, s.new.Protect, false, s.new.Dependencies, s.new.InitErrors, s.new.Provider, - s.new.PropertyDependencies, false, nil, nil, &s.new.CustomTimeouts, s.new.ImportID, s.new.RetainOnDelete) + s.new.PropertyDependencies, false, nil, nil, &s.new.CustomTimeouts, s.new.ImportID, s.new.RetainOnDelete, + s.new.DeletedWithParent) // If this step came from an import deployment, we need to fetch any required inputs from the state. if s.planned { diff --git a/pkg/resource/deploy/step_generator.go b/pkg/resource/deploy/step_generator.go index 746d071dc9f8..a771ccf0a2ea 100644 --- a/pkg/resource/deploy/step_generator.go +++ b/pkg/resource/deploy/step_generator.go @@ -199,6 +199,7 @@ func (sg *stepGenerator) GenerateReadSteps(event ReadResourceEvent) ([]Step, res nil, /* customTimeouts */ "", /* importID */ false, /* retainOnDelete */ + false, /* deletedWithParent */ ) old, hasOld := sg.deployment.Olds()[urn] @@ -494,7 +495,7 @@ func (sg *stepGenerator) generateSteps(event RegisterResourceEvent) ([]Step, res // get serialized into the checkpoint file. new := resource.NewState(goal.Type, urn, goal.Custom, false, "", inputs, nil, goal.Parent, goal.Protect, false, goal.Dependencies, goal.InitErrors, goal.Provider, goal.PropertyDependencies, false, - goal.AdditionalSecretOutputs, aliasUrns, &goal.CustomTimeouts, "", goal.RetainOnDelete) + goal.AdditionalSecretOutputs, aliasUrns, &goal.CustomTimeouts, "", goal.RetainOnDelete, goal.DeletedWithParent) // Mark the URN/resource as having been seen. So we can run analyzers on all resources seen, as well as // lookup providers for calculating replacement of resources that use the provider. @@ -951,7 +952,7 @@ func (sg *stepGenerator) generateStepsFromDiff( logging.V(7).Infof("Planner decided to delete '%v' due to dependence on condemned resource '%v'", dependentResource.URN, urn) - steps = append(steps, NewDeleteReplacementStep(sg.deployment, dependentResource, true)) + steps = append(steps, NewDeleteReplacementStep(sg.deployment, sg.deletes, dependentResource, true)) // Mark the condemned resource as deleted. We won't know until later in the deployment whether // or not we're going to be replacing this resource. sg.deletes[dependentResource.URN] = true @@ -959,7 +960,7 @@ func (sg *stepGenerator) generateStepsFromDiff( } return append(steps, - NewDeleteReplacementStep(sg.deployment, old, true), + NewDeleteReplacementStep(sg.deployment, sg.deletes, old, true), NewReplaceStep(sg.deployment, old, new, diff.ReplaceKeys, diff.ChangedKeys, diff.DetailedDiff, false), NewCreateReplacementStep( sg.deployment, event, old, new, diff.ReplaceKeys, diff.ChangedKeys, diff.DetailedDiff, false), @@ -1035,7 +1036,7 @@ func (sg *stepGenerator) GenerateDeletes(targetsOpt map[resource.URN]bool) ([]St logging.V(7).Infof("Planner decided to delete '%v' due to replacement", res.URN) sg.deletes[res.URN] = true - dels = append(dels, NewDeleteReplacementStep(sg.deployment, res, false)) + dels = append(dels, NewDeleteReplacementStep(sg.deployment, sg.deletes, res, false)) } else if _, aliased := sg.aliased[res.URN]; !sg.sames[res.URN] && !sg.updates[res.URN] && !sg.replaces[res.URN] && !sg.reads[res.URN] && !aliased { // NOTE: we deliberately do not check sg.deletes here, as it is possible for us to issue multiple @@ -1043,7 +1044,7 @@ func (sg *stepGenerator) GenerateDeletes(targetsOpt map[resource.URN]bool) ([]St logging.V(7).Infof("Planner decided to delete '%v'", res.URN) sg.deletes[res.URN] = true if !res.PendingReplacement { - dels = append(dels, NewDeleteStep(sg.deployment, res)) + dels = append(dels, NewDeleteStep(sg.deployment, sg.deletes, res)) } else { dels = append(dels, NewRemovePendingReplaceStep(sg.deployment, res)) } @@ -1241,7 +1242,10 @@ func (sg *stepGenerator) GeneratePendingDeletes() []Step { logging.V(7).Infof( "stepGenerator.GeneratePendingDeletes(): resource (%v, %v) is pending deletion", res.URN, res.ID) sg.pendingDeletes[res] = true - dels = append(dels, NewDeleteStep(sg.deployment, res)) + // TODO: Should we support DeletedWithParent with PendingDeletes + // Special case might be when child is marked as pending deletion but we now want to delete the parent, + // so ultimately there is no need to delete the child anymore + dels = append(dels, NewDeleteStep(sg.deployment, map[resource.URN]bool{}, res)) } } } diff --git a/pkg/resource/stack/deployment.go b/pkg/resource/stack/deployment.go index 64f9d0e742ec..eaa2a1fc8273 100644 --- a/pkg/resource/stack/deployment.go +++ b/pkg/resource/stack/deployment.go @@ -329,6 +329,7 @@ func SerializeResource(res *resource.State, enc config.Encrypter, showSecrets bo Aliases: res.Aliases, ImportID: res.ImportID, RetainOnDelete: res.RetainOnDelete, + DeletedWithParent: res.DeletedWithParent, } if res.CustomTimeouts.IsNotEmpty() { @@ -512,7 +513,7 @@ func DeserializeResource(res apitype.ResourceV3, dec config.Decrypter, enc confi res.Type, res.URN, res.Custom, res.Delete, res.ID, inputs, outputs, res.Parent, res.Protect, res.External, res.Dependencies, res.InitErrors, res.Provider, res.PropertyDependencies, res.PendingReplacement, res.AdditionalSecretOutputs, res.Aliases, res.CustomTimeouts, - res.ImportID, res.RetainOnDelete), nil + res.ImportID, res.RetainOnDelete, res.DeletedWithParent), nil } func DeserializeOperation(op apitype.OperationV2, dec config.Decrypter, diff --git a/pkg/resource/stack/deployment_test.go b/pkg/resource/stack/deployment_test.go index af1893c5f775..707d5f086c1f 100644 --- a/pkg/resource/stack/deployment_test.go +++ b/pkg/resource/stack/deployment_test.go @@ -99,6 +99,7 @@ func TestDeploymentSerialization(t *testing.T) { nil, "", false, + false, ) dep, err := SerializeResource(res, config.NopEncrypter, false /* showSecrets */) diff --git a/proto/.checksum.txt b/proto/.checksum.txt index 46b4346b741b..cd91bb37d4ed 100644 --- a/proto/.checksum.txt +++ b/proto/.checksum.txt @@ -12,4 +12,4 @@ 3300935796 5024 proto/pulumi/language.proto 2700626499 1743 proto/pulumi/plugin.proto 1451439690 19667 proto/pulumi/provider.proto -3808155704 10824 proto/pulumi/resource.proto +3982623411 11021 proto/pulumi/resource.proto diff --git a/proto/pulumi/resource.proto b/proto/pulumi/resource.proto index 56712490b12c..874f7779c816 100644 --- a/proto/pulumi/resource.proto +++ b/proto/pulumi/resource.proto @@ -117,6 +117,7 @@ message RegisterResourceRequest { string pluginDownloadURL = 24; // the server URL of the provider to use when servicing this request. bool retainOnDelete = 25; // if true the engine will not call the resource providers delete method for this resource. repeated Alias aliases = 26; // a list of additional aliases that should be considered the same. + bool deletedWithParent = 27; // if true and parent is set the engine will not call the resource providers delete method for this resource when parent is deleted. } // RegisterResourceResponse is returned by the engine after a resource has finished being initialized. It includes the diff --git a/sdk/dotnet/Pulumi/Deployment/Deployment_RegisterResource.cs b/sdk/dotnet/Pulumi/Deployment/Deployment_RegisterResource.cs index 8b98fbe450f8..ef0d3d24a084 100644 --- a/sdk/dotnet/Pulumi/Deployment/Deployment_RegisterResource.cs +++ b/sdk/dotnet/Pulumi/Deployment/Deployment_RegisterResource.cs @@ -91,6 +91,7 @@ private static void PopulateRequest(RegisterResourceRequest request, PrepareResu }, Remote = remote, RetainOnDelete = options.RetainOnDelete ?? false, + DeletedWithParent = options.DeletedWithParent ?? false, }; if (customOpts != null) diff --git a/sdk/dotnet/Pulumi/PublicAPI.Shipped.txt b/sdk/dotnet/Pulumi/PublicAPI.Shipped.txt index bdc89965e566..a5f231a535ee 100644 --- a/sdk/dotnet/Pulumi/PublicAPI.Shipped.txt +++ b/sdk/dotnet/Pulumi/PublicAPI.Shipped.txt @@ -200,6 +200,8 @@ Pulumi.ResourceOptions.PluginDownloadURL.get -> string Pulumi.ResourceOptions.PluginDownloadURL.set -> void Pulumi.ResourceOptions.RetainOnDelete.get -> bool? Pulumi.ResourceOptions.RetainOnDelete.set -> void +Pulumi.ResourceOptions.DeletedWithParent.get -> bool? +Pulumi.ResourceOptions.DeletedWithParent.set -> void Pulumi.ResourceTransformation Pulumi.ResourceTransformationArgs Pulumi.ResourceTransformationArgs.Args.get -> Pulumi.ResourceArgs diff --git a/sdk/dotnet/Pulumi/Resources/ResourceOptions.cs b/sdk/dotnet/Pulumi/Resources/ResourceOptions.cs index 4cbc4a52ae74..0d1b51a922ad 100644 --- a/sdk/dotnet/Pulumi/Resources/ResourceOptions.cs +++ b/sdk/dotnet/Pulumi/Resources/ResourceOptions.cs @@ -123,5 +123,11 @@ public List ReplaceOnChanges /// If set to True, the providers Delete method will not be called for this resource. /// public bool? RetainOnDelete { get; set; } + + /// + /// If set to True and parent is set, the providers Delete method will not be called for this resource + /// if parent is being deleted as well. + /// + public bool? DeletedWithParent { get; set; } } } diff --git a/sdk/dotnet/Pulumi/Resources/ResourceOptions_Copy.cs b/sdk/dotnet/Pulumi/Resources/ResourceOptions_Copy.cs index 844c4eead87a..e02bf4a2ca4d 100644 --- a/sdk/dotnet/Pulumi/Resources/ResourceOptions_Copy.cs +++ b/sdk/dotnet/Pulumi/Resources/ResourceOptions_Copy.cs @@ -23,7 +23,8 @@ internal static TResourceOptions CreateCopy(ResourceOptions op Urn = options.Urn, Version = options.Version, PluginDownloadURL = options.PluginDownloadURL, - RetainOnDelete = options.RetainOnDelete + RetainOnDelete = options.RetainOnDelete, + DeletedWithParent = options.DeletedWithParent }; internal static CustomResourceOptions CreateCustomResourceOptionsCopy(ResourceOptions? options) diff --git a/sdk/dotnet/Pulumi/Resources/ResourceOptions_Merge.cs b/sdk/dotnet/Pulumi/Resources/ResourceOptions_Merge.cs index 5ec6ee11b0c4..91ac16360285 100644 --- a/sdk/dotnet/Pulumi/Resources/ResourceOptions_Merge.cs +++ b/sdk/dotnet/Pulumi/Resources/ResourceOptions_Merge.cs @@ -15,6 +15,7 @@ internal static void MergeNormalOptions(ResourceOptions options1, ResourceOption options1.Provider = options2.Provider ?? options1.Provider; options1.CustomTimeouts = options2.CustomTimeouts ?? options1.CustomTimeouts; options1.RetainOnDelete = options2.RetainOnDelete ?? options1.RetainOnDelete; + options1.DeletedWithParent = options2.DeletedWithParent ?? options1.DeletedWithParent; options1.IgnoreChanges.AddRange(options2.IgnoreChanges); options1.ResourceTransformations.AddRange(options2.ResourceTransformations); diff --git a/sdk/go/common/apitype/core.go b/sdk/go/common/apitype/core.go index 5ea009917010..e4e0634dcace 100644 --- a/sdk/go/common/apitype/core.go +++ b/sdk/go/common/apitype/core.go @@ -326,6 +326,9 @@ type ResourceV3 struct { ImportID resource.ID `json:"importID,omitempty" yaml:"importID,omitempty"` // If set to True, the providers Delete method will not be called for this resource. Pulumi simply stops tracking the deleted resource. RetainOnDelete bool `json:"retainOnDelete,omitempty" yaml:"retainOnDelete,omitempty"` + // If set to True and parent is set, the providers Delete method will not be called for this resource + // if parent is being deleted as well. + DeletedWithParent bool `json:"deletedWithParent,omitempty" yaml:"deletedWithParent,omitempty"` } // ManifestV1 captures meta-information about this checkpoint file, such as versions of binaries, etc. diff --git a/sdk/go/common/resource/resource_goal.go b/sdk/go/common/resource/resource_goal.go index 3f23889e65dc..d9e25748b286 100644 --- a/sdk/go/common/resource/resource_goal.go +++ b/sdk/go/common/resource/resource_goal.go @@ -40,6 +40,9 @@ type Goal struct { ReplaceOnChanges []string // a list of property paths that if changed should force a replacement. // if set to True, the providers Delete method will not be called for this resource. RetainOnDelete bool + // if set to True and parent is set, the providers Delete method will not be called for this resource + // if parent is being deleted as well. + DeletedWithParent bool } // NewGoal allocates a new resource goal state. @@ -47,7 +50,7 @@ func NewGoal(t tokens.Type, name tokens.QName, custom bool, props PropertyMap, parent URN, protect bool, dependencies []URN, provider string, initErrors []string, propertyDependencies map[PropertyKey][]URN, deleteBeforeReplace *bool, ignoreChanges []string, additionalSecretOutputs []PropertyKey, aliases []Alias, id ID, customTimeouts *CustomTimeouts, - replaceOnChanges []string, retainOnDelete bool) *Goal { + replaceOnChanges []string, retainOnDelete bool, deletedWithParent bool) *Goal { g := &Goal{ Type: t, @@ -67,6 +70,7 @@ func NewGoal(t tokens.Type, name tokens.QName, custom bool, props PropertyMap, ID: id, ReplaceOnChanges: replaceOnChanges, RetainOnDelete: retainOnDelete, + DeletedWithParent: deletedWithParent, } if customTimeouts != nil { diff --git a/sdk/go/common/resource/resource_state.go b/sdk/go/common/resource/resource_state.go index 612d579e915c..758bd458a054 100644 --- a/sdk/go/common/resource/resource_state.go +++ b/sdk/go/common/resource/resource_state.go @@ -44,6 +44,7 @@ type State struct { CustomTimeouts CustomTimeouts // A config block that will be used to configure timeouts for CRUD operations. ImportID ID // the resource's import id, if this was an imported resource. RetainOnDelete bool // if set to True, the providers Delete method will not be called for this resource. + DeletedWithParent bool // If set to True and parent is set, the providers Delete method will not be called for this resource if parent is being deleted as well. } func (s *State) GetAliasURNs() []URN { @@ -64,7 +65,7 @@ func NewState(t tokens.Type, urn URN, custom bool, del bool, id ID, external bool, dependencies []URN, initErrors []string, provider string, propertyDependencies map[PropertyKey][]URN, pendingReplacement bool, additionalSecretOutputs []PropertyKey, aliases []URN, timeouts *CustomTimeouts, - importID ID, retainOnDelete bool) *State { + importID ID, retainOnDelete bool, deletedWithParent bool) *State { contract.Assertf(t != "", "type was empty") contract.Assertf(custom || id == "", "is custom or had empty ID") @@ -90,6 +91,7 @@ func NewState(t tokens.Type, urn URN, custom bool, del bool, id ID, Aliases: aliases, ImportID: importID, RetainOnDelete: retainOnDelete, + DeletedWithParent: deletedWithParent, } if timeouts != nil { diff --git a/sdk/go/pulumi/context.go b/sdk/go/pulumi/context.go index bd3bab4c1d42..abe419abd139 100644 --- a/sdk/go/pulumi/context.go +++ b/sdk/go/pulumi/context.go @@ -856,6 +856,7 @@ func (ctx *Context) registerResource( Remote: remote, ReplaceOnChanges: inputs.replaceOnChanges, RetainOnDelete: inputs.retainOnDelete, + DeletedWithParent: inputs.deletedWithParent, }) if err != nil { logging.V(9).Infof("RegisterResource(%s, %s): error: %v", t, name, err) @@ -1247,6 +1248,7 @@ type resourceInputs struct { pluginDownloadURL string replaceOnChanges []string retainOnDelete bool + deletedWithParent bool } // prepareResourceInputs prepares the inputs for a resource operation, shared between read and register. @@ -1334,6 +1336,7 @@ func (ctx *Context) prepareResourceInputs(res Resource, props Input, t string, o pluginDownloadURL: state.pluginDownloadURL, replaceOnChanges: resOpts.replaceOnChanges, retainOnDelete: opts.RetainOnDelete, + deletedWithParent: opts.DeletedWithParent, }, nil } diff --git a/sdk/go/pulumi/resource.go b/sdk/go/pulumi/resource.go index bc69910b25e3..8457d39329f2 100644 --- a/sdk/go/pulumi/resource.go +++ b/sdk/go/pulumi/resource.go @@ -311,6 +311,9 @@ type resourceOptions struct { PluginDownloadURL string // If set to True, the providers Delete method will not be called for this resource. RetainOnDelete bool + // If set to True and parent is set, the providers Delete method will not be called for this resource + // if parent is being deleted as well. + DeletedWithParent bool } type invokeOptions struct { @@ -590,3 +593,11 @@ func RetainOnDelete(b bool) ResourceOption { ro.RetainOnDelete = b }) } + +// If set to True and parent is set, the providers Delete method will not be called for this resource +// if parent is being deleted as well. +func DeletedWithParent(b bool) ResourceOption { + return resourceOption(func(ro *resourceOptions) { + ro.DeletedWithParent = b + }) +} diff --git a/sdk/nodejs/proto/resource_pb.js b/sdk/nodejs/proto/resource_pb.js index e43605f6d2d8..b3f538cdfff9 100644 --- a/sdk/nodejs/proto/resource_pb.js +++ b/sdk/nodejs/proto/resource_pb.js @@ -1297,7 +1297,8 @@ proto.pulumirpc.RegisterResourceRequest.toObject = function(includeInstance, msg plugindownloadurl: jspb.Message.getFieldWithDefault(msg, 24, ""), retainondelete: jspb.Message.getBooleanFieldWithDefault(msg, 25, false), aliasesList: jspb.Message.toObjectList(msg.getAliasesList(), - pulumi_alias_pb.Alias.toObject, includeInstance) + pulumi_alias_pb.Alias.toObject, includeInstance), + deletedwithparent: jspb.Message.getBooleanFieldWithDefault(msg, 27, false) }; if (includeInstance) { @@ -1445,6 +1446,10 @@ proto.pulumirpc.RegisterResourceRequest.deserializeBinaryFromReader = function(m reader.readMessage(value,pulumi_alias_pb.Alias.deserializeBinaryFromReader); msg.addAliases(value); break; + case 27: + var value = /** @type {boolean} */ (reader.readBool()); + msg.setDeletedwithparent(value); + break; default: reader.skipField(); break; @@ -1653,6 +1658,13 @@ proto.pulumirpc.RegisterResourceRequest.serializeBinaryToWriter = function(messa pulumi_alias_pb.Alias.serializeBinaryToWriter ); } + f = message.getDeletedwithparent(); + if (f) { + writer.writeBool( + 27, + f + ); + } }; @@ -2631,6 +2643,24 @@ proto.pulumirpc.RegisterResourceRequest.prototype.clearAliasesList = function() }; +/** + * optional bool deletedWithParent = 27; + * @return {boolean} + */ +proto.pulumirpc.RegisterResourceRequest.prototype.getDeletedwithparent = function() { + return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 27, false)); +}; + + +/** + * @param {boolean} value + * @return {!proto.pulumirpc.RegisterResourceRequest} returns this + */ +proto.pulumirpc.RegisterResourceRequest.prototype.setDeletedwithparent = function(value) { + return jspb.Message.setProto3BooleanField(this, 27, value); +}; + + /** * List of repeated fields within this message type. diff --git a/sdk/nodejs/resource.ts b/sdk/nodejs/resource.ts index 2534f2318e8e..e035d8f3a712 100644 --- a/sdk/nodejs/resource.ts +++ b/sdk/nodejs/resource.ts @@ -599,6 +599,11 @@ export interface ResourceOptions { * If set to True, the providers Delete method will not be called for this resource. */ retainOnDelete?: boolean; + /** + * If set to True and parent is set, the providers Delete method will not be called for this resource + * if parent is being deleted as well. + */ + deletedWithParent?: boolean; // !!! IMPORTANT !!! If you add a new field to this type, make sure to add test that verifies // that mergeOptions works properly for it. diff --git a/sdk/nodejs/runtime/resource.ts b/sdk/nodejs/runtime/resource.ts index 48f53c3c0544..d80ed2faf3ae 100644 --- a/sdk/nodejs/runtime/resource.ts +++ b/sdk/nodejs/runtime/resource.ts @@ -317,6 +317,7 @@ export function registerResource(res: Resource, parent: Resource | undefined, t: req.setReplaceonchangesList(opts.replaceOnChanges || []); req.setPlugindownloadurl(opts.pluginDownloadURL || ""); req.setRetainondelete(opts.retainOnDelete || false); + req.setDeletedwithparent(opts.deletedWithParent || false); const customTimeouts = new resproto.RegisterResourceRequest.CustomTimeouts(); if (opts.customTimeouts != null) { diff --git a/sdk/proto/go/resource.pb.go b/sdk/proto/go/resource.pb.go index 537c36f59460..16669bc906e6 100644 --- a/sdk/proto/go/resource.pb.go +++ b/sdk/proto/go/resource.pb.go @@ -360,6 +360,7 @@ type RegisterResourceRequest struct { PluginDownloadURL string `protobuf:"bytes,24,opt,name=pluginDownloadURL,proto3" json:"pluginDownloadURL,omitempty"` // the server URL of the provider to use when servicing this request. RetainOnDelete bool `protobuf:"varint,25,opt,name=retainOnDelete,proto3" json:"retainOnDelete,omitempty"` // if true the engine will not call the resource providers delete method for this resource. Aliases []*Alias `protobuf:"bytes,26,rep,name=aliases,proto3" json:"aliases,omitempty"` // a list of additional aliases that should be considered the same. + DeletedWithParent bool `protobuf:"varint,27,opt,name=deletedWithParent,proto3" json:"deletedWithParent,omitempty"` // if true and parent is set the engine will not call the resource providers delete method for this resource when parent is deleted. } func (x *RegisterResourceRequest) Reset() { @@ -576,6 +577,13 @@ func (x *RegisterResourceRequest) GetAliases() []*Alias { return nil } +func (x *RegisterResourceRequest) GetDeletedWithParent() bool { + if x != nil { + return x.DeletedWithParent + } + return false +} + // RegisterResourceResponse is returned by the engine after a resource has finished being initialized. It includes the // auto-assigned URN, the provider-assigned ID, and any other properties initialized by the engine. type RegisterResourceResponse struct { @@ -1020,7 +1028,7 @@ var file_pulumi_resource_proto_rawDesc = []byte{ 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x0a, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, - 0x65, 0x73, 0x22, 0xd3, 0x0b, 0x0a, 0x17, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, + 0x65, 0x73, 0x22, 0x81, 0x0c, 0x0a, 0x17, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, @@ -1093,117 +1101,120 @@ var file_pulumi_resource_proto_rawDesc = []byte{ 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x2a, 0x0a, 0x07, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x65, 0x73, 0x18, 0x1a, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x70, 0x75, 0x6c, 0x75, 0x6d, 0x69, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x07, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x65, - 0x73, 0x1a, 0x2a, 0x0a, 0x14, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x44, 0x65, 0x70, - 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x72, 0x6e, - 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x75, 0x72, 0x6e, 0x73, 0x1a, 0x58, 0x0a, - 0x0e, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x73, 0x12, - 0x16, 0x0a, 0x06, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x06, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x75, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, - 0x16, 0x0a, 0x06, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x06, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x1a, 0x80, 0x01, 0x0a, 0x19, 0x50, 0x72, 0x6f, 0x70, + 0x73, 0x12, 0x2c, 0x0a, 0x11, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x57, 0x69, 0x74, 0x68, + 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x1b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x64, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x64, 0x57, 0x69, 0x74, 0x68, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x1a, + 0x2a, 0x0a, 0x14, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x44, 0x65, 0x70, 0x65, 0x6e, + 0x64, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x72, 0x6e, 0x73, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x75, 0x72, 0x6e, 0x73, 0x1a, 0x58, 0x0a, 0x0e, 0x43, + 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x73, 0x12, 0x16, 0x0a, + 0x06, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x63, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x16, 0x0a, + 0x06, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x1a, 0x80, 0x01, 0x0a, 0x19, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, + 0x74, 0x79, 0x44, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x4d, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x37, 0x2e, 0x70, 0x75, 0x6c, 0x75, 0x6d, 0x69, 0x72, 0x70, 0x63, + 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, + 0x79, 0x44, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x52, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x3c, 0x0a, 0x0e, 0x50, 0x72, 0x6f, 0x76, + 0x69, 0x64, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, + 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xc2, 0x03, 0x0a, 0x18, 0x52, 0x65, 0x67, 0x69, 0x73, + 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x03, 0x75, 0x72, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x2f, 0x0a, 0x06, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x06, + 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x73, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x18, + 0x0a, 0x07, 0x73, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, + 0x07, 0x73, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x71, 0x0a, 0x14, 0x70, 0x72, 0x6f, 0x70, + 0x65, 0x72, 0x74, 0x79, 0x44, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, + 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3d, 0x2e, 0x70, 0x75, 0x6c, 0x75, 0x6d, 0x69, 0x72, + 0x70, 0x63, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x50, 0x72, 0x6f, 0x70, + 0x65, 0x72, 0x74, 0x79, 0x44, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, + 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x14, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x44, + 0x65, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x1a, 0x2a, 0x0a, 0x14, 0x50, + 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x44, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x63, + 0x69, 0x65, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x72, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, + 0x09, 0x52, 0x04, 0x75, 0x72, 0x6e, 0x73, 0x1a, 0x81, 0x01, 0x0a, 0x19, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x44, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x4d, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x37, 0x2e, 0x70, 0x75, 0x6c, 0x75, 0x6d, 0x69, 0x72, + 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x4e, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x38, 0x2e, 0x70, 0x75, 0x6c, 0x75, 0x6d, 0x69, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x65, - 0x72, 0x74, 0x79, 0x44, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x52, - 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x3c, 0x0a, 0x0e, 0x50, 0x72, - 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, - 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, - 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xc2, 0x03, 0x0a, 0x18, 0x52, 0x65, 0x67, - 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6e, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x2f, 0x0a, 0x06, 0x6f, 0x62, 0x6a, 0x65, 0x63, - 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, - 0x52, 0x06, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x62, - 0x6c, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x73, 0x74, 0x61, 0x62, 0x6c, 0x65, - 0x12, 0x18, 0x0a, 0x07, 0x73, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, - 0x09, 0x52, 0x07, 0x73, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x71, 0x0a, 0x14, 0x70, 0x72, - 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x44, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x63, 0x69, - 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3d, 0x2e, 0x70, 0x75, 0x6c, 0x75, 0x6d, - 0x69, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x50, 0x72, - 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x44, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x63, 0x69, - 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x14, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, - 0x79, 0x44, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x1a, 0x2a, 0x0a, - 0x14, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x44, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x65, - 0x6e, 0x63, 0x69, 0x65, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x72, 0x6e, 0x73, 0x18, 0x01, 0x20, - 0x03, 0x28, 0x09, 0x52, 0x04, 0x75, 0x72, 0x6e, 0x73, 0x1a, 0x81, 0x01, 0x0a, 0x19, 0x50, 0x72, - 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x44, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x63, 0x69, - 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x4e, 0x0a, 0x05, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x38, 0x2e, 0x70, 0x75, 0x6c, 0x75, 0x6d, - 0x69, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x50, 0x72, - 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x44, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x63, 0x69, - 0x65, 0x73, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x65, 0x0a, - 0x1e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, - 0x6e, 0x12, 0x31, 0x0a, 0x07, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x07, 0x6f, 0x75, 0x74, - 0x70, 0x75, 0x74, 0x73, 0x22, 0xe4, 0x01, 0x0a, 0x15, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x49, 0x6e, 0x76, 0x6f, 0x6b, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, - 0x0a, 0x03, 0x74, 0x6f, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x74, 0x6f, 0x6b, - 0x12, 0x2b, 0x0a, 0x04, 0x61, 0x72, 0x67, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, - 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x04, 0x61, 0x72, 0x67, 0x73, 0x12, 0x1a, 0x0a, - 0x08, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x08, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, - 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, - 0x69, 0x6f, 0x6e, 0x12, 0x28, 0x0a, 0x0f, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x52, 0x65, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x61, 0x63, - 0x63, 0x65, 0x70, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x2c, 0x0a, - 0x11, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x55, - 0x52, 0x4c, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, - 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x55, 0x52, 0x4c, 0x32, 0xd4, 0x04, 0x0a, 0x0f, - 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x12, - 0x5a, 0x0a, 0x0f, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x46, 0x65, 0x61, 0x74, 0x75, - 0x72, 0x65, 0x12, 0x21, 0x2e, 0x70, 0x75, 0x6c, 0x75, 0x6d, 0x69, 0x72, 0x70, 0x63, 0x2e, 0x53, - 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x70, 0x75, 0x6c, 0x75, 0x6d, 0x69, 0x72, 0x70, - 0x63, 0x2e, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, - 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x47, 0x0a, 0x06, 0x49, - 0x6e, 0x76, 0x6f, 0x6b, 0x65, 0x12, 0x20, 0x2e, 0x70, 0x75, 0x6c, 0x75, 0x6d, 0x69, 0x72, 0x70, - 0x63, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x6e, 0x76, 0x6f, 0x6b, 0x65, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x70, 0x75, 0x6c, 0x75, 0x6d, 0x69, - 0x72, 0x70, 0x63, 0x2e, 0x49, 0x6e, 0x76, 0x6f, 0x6b, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x00, 0x12, 0x4f, 0x0a, 0x0c, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x49, 0x6e, - 0x76, 0x6f, 0x6b, 0x65, 0x12, 0x20, 0x2e, 0x70, 0x75, 0x6c, 0x75, 0x6d, 0x69, 0x72, 0x70, 0x63, - 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x6e, 0x76, 0x6f, 0x6b, 0x65, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x70, 0x75, 0x6c, 0x75, 0x6d, 0x69, 0x72, - 0x70, 0x63, 0x2e, 0x49, 0x6e, 0x76, 0x6f, 0x6b, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x39, 0x0a, 0x04, 0x43, 0x61, 0x6c, 0x6c, 0x12, 0x16, 0x2e, - 0x70, 0x75, 0x6c, 0x75, 0x6d, 0x69, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x70, 0x75, 0x6c, 0x75, 0x6d, 0x69, 0x72, 0x70, - 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, - 0x12, 0x51, 0x0a, 0x0c, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x12, 0x1e, 0x2e, 0x70, 0x75, 0x6c, 0x75, 0x6d, 0x69, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65, 0x61, - 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x1f, 0x2e, 0x70, 0x75, 0x6c, 0x75, 0x6d, 0x69, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65, 0x61, - 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x00, 0x12, 0x5d, 0x0a, 0x10, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, - 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x22, 0x2e, 0x70, 0x75, 0x6c, 0x75, 0x6d, 0x69, - 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x70, 0x75, + 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x50, 0x72, 0x6f, 0x70, + 0x65, 0x72, 0x74, 0x79, 0x44, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, + 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x65, 0x0a, 0x1e, 0x52, + 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4f, + 0x75, 0x74, 0x70, 0x75, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, + 0x03, 0x75, 0x72, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6e, 0x12, + 0x31, 0x0a, 0x07, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x07, 0x6f, 0x75, 0x74, 0x70, 0x75, + 0x74, 0x73, 0x22, 0xe4, 0x01, 0x0a, 0x15, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, + 0x6e, 0x76, 0x6f, 0x6b, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, + 0x74, 0x6f, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x74, 0x6f, 0x6b, 0x12, 0x2b, + 0x0a, 0x04, 0x61, 0x72, 0x67, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, + 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x04, 0x61, 0x72, 0x67, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x70, + 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, + 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, + 0x6e, 0x12, 0x28, 0x0a, 0x0f, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x61, 0x63, 0x63, 0x65, + 0x70, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x2c, 0x0a, 0x11, 0x70, + 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x55, 0x52, 0x4c, + 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x44, 0x6f, + 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x55, 0x52, 0x4c, 0x32, 0xd4, 0x04, 0x0a, 0x0f, 0x52, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x12, 0x5a, 0x0a, + 0x0f, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, + 0x12, 0x21, 0x2e, 0x70, 0x75, 0x6c, 0x75, 0x6d, 0x69, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x75, 0x70, + 0x70, 0x6f, 0x72, 0x74, 0x73, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x70, 0x75, 0x6c, 0x75, 0x6d, 0x69, 0x72, 0x70, 0x63, 0x2e, + 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x47, 0x0a, 0x06, 0x49, 0x6e, 0x76, + 0x6f, 0x6b, 0x65, 0x12, 0x20, 0x2e, 0x70, 0x75, 0x6c, 0x75, 0x6d, 0x69, 0x72, 0x70, 0x63, 0x2e, + 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x6e, 0x76, 0x6f, 0x6b, 0x65, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x70, 0x75, 0x6c, 0x75, 0x6d, 0x69, 0x72, 0x70, + 0x63, 0x2e, 0x49, 0x6e, 0x76, 0x6f, 0x6b, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x00, 0x12, 0x4f, 0x0a, 0x0c, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x49, 0x6e, 0x76, 0x6f, + 0x6b, 0x65, 0x12, 0x20, 0x2e, 0x70, 0x75, 0x6c, 0x75, 0x6d, 0x69, 0x72, 0x70, 0x63, 0x2e, 0x52, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x6e, 0x76, 0x6f, 0x6b, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x70, 0x75, 0x6c, 0x75, 0x6d, 0x69, 0x72, 0x70, 0x63, + 0x2e, 0x49, 0x6e, 0x76, 0x6f, 0x6b, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x00, 0x30, 0x01, 0x12, 0x39, 0x0a, 0x04, 0x43, 0x61, 0x6c, 0x6c, 0x12, 0x16, 0x2e, 0x70, 0x75, + 0x6c, 0x75, 0x6d, 0x69, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x70, 0x75, 0x6c, 0x75, 0x6d, 0x69, 0x72, 0x70, 0x63, 0x2e, + 0x43, 0x61, 0x6c, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x51, + 0x0a, 0x0c, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x1e, + 0x2e, 0x70, 0x75, 0x6c, 0x75, 0x6d, 0x69, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x52, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, + 0x2e, 0x70, 0x75, 0x6c, 0x75, 0x6d, 0x69, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x52, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x00, 0x12, 0x5d, 0x0a, 0x10, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x22, 0x2e, 0x70, 0x75, 0x6c, 0x75, 0x6d, 0x69, 0x72, 0x70, + 0x63, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x70, 0x75, 0x6c, 0x75, + 0x6d, 0x69, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, + 0x12, 0x5e, 0x0a, 0x17, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x73, 0x12, 0x29, 0x2e, 0x70, 0x75, 0x6c, 0x75, 0x6d, 0x69, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, - 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x00, 0x12, 0x5e, 0x0a, 0x17, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x73, 0x12, 0x29, 0x2e, - 0x70, 0x75, 0x6c, 0x75, 0x6d, 0x69, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, - 0x65, 0x72, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, - 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, - 0x22, 0x00, 0x42, 0x34, 0x5a, 0x32, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, - 0x2f, 0x70, 0x75, 0x6c, 0x75, 0x6d, 0x69, 0x2f, 0x70, 0x75, 0x6c, 0x75, 0x6d, 0x69, 0x2f, 0x73, - 0x64, 0x6b, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x3b, 0x70, - 0x75, 0x6c, 0x75, 0x6d, 0x69, 0x72, 0x70, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, + 0x42, 0x34, 0x5a, 0x32, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, + 0x75, 0x6c, 0x75, 0x6d, 0x69, 0x2f, 0x70, 0x75, 0x6c, 0x75, 0x6d, 0x69, 0x2f, 0x73, 0x64, 0x6b, + 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x3b, 0x70, 0x75, 0x6c, + 0x75, 0x6d, 0x69, 0x72, 0x70, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/sdk/python/lib/pulumi/resource.py b/sdk/python/lib/pulumi/resource.py index 33f79236996d..50f55b383583 100644 --- a/sdk/python/lib/pulumi/resource.py +++ b/sdk/python/lib/pulumi/resource.py @@ -487,6 +487,12 @@ class ResourceOptions: If set to True, the providers Delete method will not be called for this resource. """ + deleted_with_parent: Optional[bool] + """ + If set to True and parent is set, the providers Delete method will not be called for this resource + if parent is being deleted as well. + """ + # pylint: disable=redefined-builtin def __init__( self, @@ -512,6 +518,7 @@ def __init__( replace_on_changes: Optional[List[str]] = None, plugin_download_url: Optional[str] = None, retain_on_delete: Optional[bool] = None, + deleted_with_parent: Optional[bool] = None, ) -> None: """ :param Optional[Resource] parent: If provided, the currently-constructing resource should be the child of @@ -552,6 +559,8 @@ def __init__( from the provided url. This url overrides the plugin download url inferred from the current package and should rarely be used. :param Optional[bool] retain_on_delete: If set to True, the providers Delete method will not be called for this resource. + :param Optional[bool] deleted_with_parent: If set to True and parent is set, the providers Delete method will not be called for this resource + if parent is being deleted as well. """ # Expose 'merge' again this this object, but this time as an instance method. @@ -577,6 +586,7 @@ def __init__( self.replace_on_changes = replace_on_changes self.depends_on = depends_on self.retain_on_delete = retain_on_delete + self.deleted_with_parent = deleted_with_parent # Proactively check that `depends_on` values are of type # `Resource`. We cannot complete the check in the general case @@ -704,6 +714,11 @@ def expand_providers(providers) -> Optional[Sequence["ProviderResource"]]: if source.retain_on_delete is None else source.retain_on_delete ) + dest.deleted_with_parent = ( + dest.deleted_with_parent + if source.deleted_with_parent is None + else source.deleted_with_parent + ) # Now, if we are left with a .providers that is just a single key/value pair, then # collapse that down into .provider form. diff --git a/sdk/python/lib/pulumi/runtime/proto/resource_pb2.py b/sdk/python/lib/pulumi/runtime/proto/resource_pb2.py index 2922cb4abe4a..f45a1116cba0 100644 --- a/sdk/python/lib/pulumi/runtime/proto/resource_pb2.py +++ b/sdk/python/lib/pulumi/runtime/proto/resource_pb2.py @@ -18,7 +18,7 @@ from . import alias_pb2 as pulumi_dot_alias__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x15pulumi/resource.proto\x12\tpulumirpc\x1a\x1bgoogle/protobuf/empty.proto\x1a\x1cgoogle/protobuf/struct.proto\x1a\x15pulumi/provider.proto\x1a\x12pulumi/alias.proto\"$\n\x16SupportsFeatureRequest\x12\n\n\x02id\x18\x01 \x01(\t\"-\n\x17SupportsFeatureResponse\x12\x12\n\nhasSupport\x18\x01 \x01(\x08\"\xae\x02\n\x13ReadResourceRequest\x12\n\n\x02id\x18\x01 \x01(\t\x12\x0c\n\x04type\x18\x02 \x01(\t\x12\x0c\n\x04name\x18\x03 \x01(\t\x12\x0e\n\x06parent\x18\x04 \x01(\t\x12+\n\nproperties\x18\x05 \x01(\x0b\x32\x17.google.protobuf.Struct\x12\x14\n\x0c\x64\x65pendencies\x18\x06 \x03(\t\x12\x10\n\x08provider\x18\x07 \x01(\t\x12\x0f\n\x07version\x18\x08 \x01(\t\x12\x15\n\racceptSecrets\x18\t \x01(\x08\x12\x1f\n\x17\x61\x64\x64itionalSecretOutputs\x18\n \x03(\t\x12\x17\n\x0f\x61\x63\x63\x65ptResources\x18\x0c \x01(\x08\x12\x19\n\x11pluginDownloadURL\x18\r \x01(\tJ\x04\x08\x0b\x10\x0cR\x07\x61liases\"P\n\x14ReadResourceResponse\x12\x0b\n\x03urn\x18\x01 \x01(\t\x12+\n\nproperties\x18\x02 \x01(\x0b\x32\x17.google.protobuf.Struct\"\xb2\x08\n\x17RegisterResourceRequest\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x0e\n\x06parent\x18\x03 \x01(\t\x12\x0e\n\x06\x63ustom\x18\x04 \x01(\x08\x12\'\n\x06object\x18\x05 \x01(\x0b\x32\x17.google.protobuf.Struct\x12\x0f\n\x07protect\x18\x06 \x01(\x08\x12\x14\n\x0c\x64\x65pendencies\x18\x07 \x03(\t\x12\x10\n\x08provider\x18\x08 \x01(\t\x12Z\n\x14propertyDependencies\x18\t \x03(\x0b\x32<.pulumirpc.RegisterResourceRequest.PropertyDependenciesEntry\x12\x1b\n\x13\x64\x65leteBeforeReplace\x18\n \x01(\x08\x12\x0f\n\x07version\x18\x0b \x01(\t\x12\x15\n\rignoreChanges\x18\x0c \x03(\t\x12\x15\n\racceptSecrets\x18\r \x01(\x08\x12\x1f\n\x17\x61\x64\x64itionalSecretOutputs\x18\x0e \x03(\t\x12\x11\n\taliasURNs\x18\x0f \x03(\t\x12\x10\n\x08importId\x18\x10 \x01(\t\x12I\n\x0e\x63ustomTimeouts\x18\x11 \x01(\x0b\x32\x31.pulumirpc.RegisterResourceRequest.CustomTimeouts\x12\"\n\x1a\x64\x65leteBeforeReplaceDefined\x18\x12 \x01(\x08\x12\x1d\n\x15supportsPartialValues\x18\x13 \x01(\x08\x12\x0e\n\x06remote\x18\x14 \x01(\x08\x12\x17\n\x0f\x61\x63\x63\x65ptResources\x18\x15 \x01(\x08\x12\x44\n\tproviders\x18\x16 \x03(\x0b\x32\x31.pulumirpc.RegisterResourceRequest.ProvidersEntry\x12\x18\n\x10replaceOnChanges\x18\x17 \x03(\t\x12\x19\n\x11pluginDownloadURL\x18\x18 \x01(\t\x12\x16\n\x0eretainOnDelete\x18\x19 \x01(\x08\x12!\n\x07\x61liases\x18\x1a \x03(\x0b\x32\x10.pulumirpc.Alias\x1a$\n\x14PropertyDependencies\x12\x0c\n\x04urns\x18\x01 \x03(\t\x1a@\n\x0e\x43ustomTimeouts\x12\x0e\n\x06\x63reate\x18\x01 \x01(\t\x12\x0e\n\x06update\x18\x02 \x01(\t\x12\x0e\n\x06\x64\x65lete\x18\x03 \x01(\t\x1at\n\x19PropertyDependenciesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\x46\n\x05value\x18\x02 \x01(\x0b\x32\x37.pulumirpc.RegisterResourceRequest.PropertyDependencies:\x02\x38\x01\x1a\x30\n\x0eProvidersEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\xf7\x02\n\x18RegisterResourceResponse\x12\x0b\n\x03urn\x18\x01 \x01(\t\x12\n\n\x02id\x18\x02 \x01(\t\x12\'\n\x06object\x18\x03 \x01(\x0b\x32\x17.google.protobuf.Struct\x12\x0e\n\x06stable\x18\x04 \x01(\x08\x12\x0f\n\x07stables\x18\x05 \x03(\t\x12[\n\x14propertyDependencies\x18\x06 \x03(\x0b\x32=.pulumirpc.RegisterResourceResponse.PropertyDependenciesEntry\x1a$\n\x14PropertyDependencies\x12\x0c\n\x04urns\x18\x01 \x03(\t\x1au\n\x19PropertyDependenciesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12G\n\x05value\x18\x02 \x01(\x0b\x32\x38.pulumirpc.RegisterResourceResponse.PropertyDependencies:\x02\x38\x01\"W\n\x1eRegisterResourceOutputsRequest\x12\x0b\n\x03urn\x18\x01 \x01(\t\x12(\n\x07outputs\x18\x02 \x01(\x0b\x32\x17.google.protobuf.Struct\"\xa2\x01\n\x15ResourceInvokeRequest\x12\x0b\n\x03tok\x18\x01 \x01(\t\x12%\n\x04\x61rgs\x18\x02 \x01(\x0b\x32\x17.google.protobuf.Struct\x12\x10\n\x08provider\x18\x03 \x01(\t\x12\x0f\n\x07version\x18\x04 \x01(\t\x12\x17\n\x0f\x61\x63\x63\x65ptResources\x18\x05 \x01(\x08\x12\x19\n\x11pluginDownloadURL\x18\x06 \x01(\t2\xd4\x04\n\x0fResourceMonitor\x12Z\n\x0fSupportsFeature\x12!.pulumirpc.SupportsFeatureRequest\x1a\".pulumirpc.SupportsFeatureResponse\"\x00\x12G\n\x06Invoke\x12 .pulumirpc.ResourceInvokeRequest\x1a\x19.pulumirpc.InvokeResponse\"\x00\x12O\n\x0cStreamInvoke\x12 .pulumirpc.ResourceInvokeRequest\x1a\x19.pulumirpc.InvokeResponse\"\x00\x30\x01\x12\x39\n\x04\x43\x61ll\x12\x16.pulumirpc.CallRequest\x1a\x17.pulumirpc.CallResponse\"\x00\x12Q\n\x0cReadResource\x12\x1e.pulumirpc.ReadResourceRequest\x1a\x1f.pulumirpc.ReadResourceResponse\"\x00\x12]\n\x10RegisterResource\x12\".pulumirpc.RegisterResourceRequest\x1a#.pulumirpc.RegisterResourceResponse\"\x00\x12^\n\x17RegisterResourceOutputs\x12).pulumirpc.RegisterResourceOutputsRequest\x1a\x16.google.protobuf.Empty\"\x00\x42\x34Z2github.com/pulumi/pulumi/sdk/v3/proto/go;pulumirpcb\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x15pulumi/resource.proto\x12\tpulumirpc\x1a\x1bgoogle/protobuf/empty.proto\x1a\x1cgoogle/protobuf/struct.proto\x1a\x15pulumi/provider.proto\x1a\x12pulumi/alias.proto\"$\n\x16SupportsFeatureRequest\x12\n\n\x02id\x18\x01 \x01(\t\"-\n\x17SupportsFeatureResponse\x12\x12\n\nhasSupport\x18\x01 \x01(\x08\"\xae\x02\n\x13ReadResourceRequest\x12\n\n\x02id\x18\x01 \x01(\t\x12\x0c\n\x04type\x18\x02 \x01(\t\x12\x0c\n\x04name\x18\x03 \x01(\t\x12\x0e\n\x06parent\x18\x04 \x01(\t\x12+\n\nproperties\x18\x05 \x01(\x0b\x32\x17.google.protobuf.Struct\x12\x14\n\x0c\x64\x65pendencies\x18\x06 \x03(\t\x12\x10\n\x08provider\x18\x07 \x01(\t\x12\x0f\n\x07version\x18\x08 \x01(\t\x12\x15\n\racceptSecrets\x18\t \x01(\x08\x12\x1f\n\x17\x61\x64\x64itionalSecretOutputs\x18\n \x03(\t\x12\x17\n\x0f\x61\x63\x63\x65ptResources\x18\x0c \x01(\x08\x12\x19\n\x11pluginDownloadURL\x18\r \x01(\tJ\x04\x08\x0b\x10\x0cR\x07\x61liases\"P\n\x14ReadResourceResponse\x12\x0b\n\x03urn\x18\x01 \x01(\t\x12+\n\nproperties\x18\x02 \x01(\x0b\x32\x17.google.protobuf.Struct\"\xcd\x08\n\x17RegisterResourceRequest\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x0e\n\x06parent\x18\x03 \x01(\t\x12\x0e\n\x06\x63ustom\x18\x04 \x01(\x08\x12\'\n\x06object\x18\x05 \x01(\x0b\x32\x17.google.protobuf.Struct\x12\x0f\n\x07protect\x18\x06 \x01(\x08\x12\x14\n\x0c\x64\x65pendencies\x18\x07 \x03(\t\x12\x10\n\x08provider\x18\x08 \x01(\t\x12Z\n\x14propertyDependencies\x18\t \x03(\x0b\x32<.pulumirpc.RegisterResourceRequest.PropertyDependenciesEntry\x12\x1b\n\x13\x64\x65leteBeforeReplace\x18\n \x01(\x08\x12\x0f\n\x07version\x18\x0b \x01(\t\x12\x15\n\rignoreChanges\x18\x0c \x03(\t\x12\x15\n\racceptSecrets\x18\r \x01(\x08\x12\x1f\n\x17\x61\x64\x64itionalSecretOutputs\x18\x0e \x03(\t\x12\x11\n\taliasURNs\x18\x0f \x03(\t\x12\x10\n\x08importId\x18\x10 \x01(\t\x12I\n\x0e\x63ustomTimeouts\x18\x11 \x01(\x0b\x32\x31.pulumirpc.RegisterResourceRequest.CustomTimeouts\x12\"\n\x1a\x64\x65leteBeforeReplaceDefined\x18\x12 \x01(\x08\x12\x1d\n\x15supportsPartialValues\x18\x13 \x01(\x08\x12\x0e\n\x06remote\x18\x14 \x01(\x08\x12\x17\n\x0f\x61\x63\x63\x65ptResources\x18\x15 \x01(\x08\x12\x44\n\tproviders\x18\x16 \x03(\x0b\x32\x31.pulumirpc.RegisterResourceRequest.ProvidersEntry\x12\x18\n\x10replaceOnChanges\x18\x17 \x03(\t\x12\x19\n\x11pluginDownloadURL\x18\x18 \x01(\t\x12\x16\n\x0eretainOnDelete\x18\x19 \x01(\x08\x12!\n\x07\x61liases\x18\x1a \x03(\x0b\x32\x10.pulumirpc.Alias\x12\x19\n\x11\x64\x65letedWithParent\x18\x1b \x01(\x08\x1a$\n\x14PropertyDependencies\x12\x0c\n\x04urns\x18\x01 \x03(\t\x1a@\n\x0e\x43ustomTimeouts\x12\x0e\n\x06\x63reate\x18\x01 \x01(\t\x12\x0e\n\x06update\x18\x02 \x01(\t\x12\x0e\n\x06\x64\x65lete\x18\x03 \x01(\t\x1at\n\x19PropertyDependenciesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\x46\n\x05value\x18\x02 \x01(\x0b\x32\x37.pulumirpc.RegisterResourceRequest.PropertyDependencies:\x02\x38\x01\x1a\x30\n\x0eProvidersEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\xf7\x02\n\x18RegisterResourceResponse\x12\x0b\n\x03urn\x18\x01 \x01(\t\x12\n\n\x02id\x18\x02 \x01(\t\x12\'\n\x06object\x18\x03 \x01(\x0b\x32\x17.google.protobuf.Struct\x12\x0e\n\x06stable\x18\x04 \x01(\x08\x12\x0f\n\x07stables\x18\x05 \x03(\t\x12[\n\x14propertyDependencies\x18\x06 \x03(\x0b\x32=.pulumirpc.RegisterResourceResponse.PropertyDependenciesEntry\x1a$\n\x14PropertyDependencies\x12\x0c\n\x04urns\x18\x01 \x03(\t\x1au\n\x19PropertyDependenciesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12G\n\x05value\x18\x02 \x01(\x0b\x32\x38.pulumirpc.RegisterResourceResponse.PropertyDependencies:\x02\x38\x01\"W\n\x1eRegisterResourceOutputsRequest\x12\x0b\n\x03urn\x18\x01 \x01(\t\x12(\n\x07outputs\x18\x02 \x01(\x0b\x32\x17.google.protobuf.Struct\"\xa2\x01\n\x15ResourceInvokeRequest\x12\x0b\n\x03tok\x18\x01 \x01(\t\x12%\n\x04\x61rgs\x18\x02 \x01(\x0b\x32\x17.google.protobuf.Struct\x12\x10\n\x08provider\x18\x03 \x01(\t\x12\x0f\n\x07version\x18\x04 \x01(\t\x12\x17\n\x0f\x61\x63\x63\x65ptResources\x18\x05 \x01(\x08\x12\x19\n\x11pluginDownloadURL\x18\x06 \x01(\t2\xd4\x04\n\x0fResourceMonitor\x12Z\n\x0fSupportsFeature\x12!.pulumirpc.SupportsFeatureRequest\x1a\".pulumirpc.SupportsFeatureResponse\"\x00\x12G\n\x06Invoke\x12 .pulumirpc.ResourceInvokeRequest\x1a\x19.pulumirpc.InvokeResponse\"\x00\x12O\n\x0cStreamInvoke\x12 .pulumirpc.ResourceInvokeRequest\x1a\x19.pulumirpc.InvokeResponse\"\x00\x30\x01\x12\x39\n\x04\x43\x61ll\x12\x16.pulumirpc.CallRequest\x1a\x17.pulumirpc.CallResponse\"\x00\x12Q\n\x0cReadResource\x12\x1e.pulumirpc.ReadResourceRequest\x1a\x1f.pulumirpc.ReadResourceResponse\"\x00\x12]\n\x10RegisterResource\x12\".pulumirpc.RegisterResourceRequest\x1a#.pulumirpc.RegisterResourceResponse\"\x00\x12^\n\x17RegisterResourceOutputs\x12).pulumirpc.RegisterResourceOutputsRequest\x1a\x16.google.protobuf.Empty\"\x00\x42\x34Z2github.com/pulumi/pulumi/sdk/v3/proto/go;pulumirpcb\x06proto3') @@ -160,25 +160,25 @@ _READRESOURCERESPONSE._serialized_start=528 _READRESOURCERESPONSE._serialized_end=608 _REGISTERRESOURCEREQUEST._serialized_start=611 - _REGISTERRESOURCEREQUEST._serialized_end=1685 - _REGISTERRESOURCEREQUEST_PROPERTYDEPENDENCIES._serialized_start=1415 - _REGISTERRESOURCEREQUEST_PROPERTYDEPENDENCIES._serialized_end=1451 - _REGISTERRESOURCEREQUEST_CUSTOMTIMEOUTS._serialized_start=1453 - _REGISTERRESOURCEREQUEST_CUSTOMTIMEOUTS._serialized_end=1517 - _REGISTERRESOURCEREQUEST_PROPERTYDEPENDENCIESENTRY._serialized_start=1519 - _REGISTERRESOURCEREQUEST_PROPERTYDEPENDENCIESENTRY._serialized_end=1635 - _REGISTERRESOURCEREQUEST_PROVIDERSENTRY._serialized_start=1637 - _REGISTERRESOURCEREQUEST_PROVIDERSENTRY._serialized_end=1685 - _REGISTERRESOURCERESPONSE._serialized_start=1688 - _REGISTERRESOURCERESPONSE._serialized_end=2063 - _REGISTERRESOURCERESPONSE_PROPERTYDEPENDENCIES._serialized_start=1415 - _REGISTERRESOURCERESPONSE_PROPERTYDEPENDENCIES._serialized_end=1451 - _REGISTERRESOURCERESPONSE_PROPERTYDEPENDENCIESENTRY._serialized_start=1946 - _REGISTERRESOURCERESPONSE_PROPERTYDEPENDENCIESENTRY._serialized_end=2063 - _REGISTERRESOURCEOUTPUTSREQUEST._serialized_start=2065 - _REGISTERRESOURCEOUTPUTSREQUEST._serialized_end=2152 - _RESOURCEINVOKEREQUEST._serialized_start=2155 - _RESOURCEINVOKEREQUEST._serialized_end=2317 - _RESOURCEMONITOR._serialized_start=2320 - _RESOURCEMONITOR._serialized_end=2916 + _REGISTERRESOURCEREQUEST._serialized_end=1712 + _REGISTERRESOURCEREQUEST_PROPERTYDEPENDENCIES._serialized_start=1442 + _REGISTERRESOURCEREQUEST_PROPERTYDEPENDENCIES._serialized_end=1478 + _REGISTERRESOURCEREQUEST_CUSTOMTIMEOUTS._serialized_start=1480 + _REGISTERRESOURCEREQUEST_CUSTOMTIMEOUTS._serialized_end=1544 + _REGISTERRESOURCEREQUEST_PROPERTYDEPENDENCIESENTRY._serialized_start=1546 + _REGISTERRESOURCEREQUEST_PROPERTYDEPENDENCIESENTRY._serialized_end=1662 + _REGISTERRESOURCEREQUEST_PROVIDERSENTRY._serialized_start=1664 + _REGISTERRESOURCEREQUEST_PROVIDERSENTRY._serialized_end=1712 + _REGISTERRESOURCERESPONSE._serialized_start=1715 + _REGISTERRESOURCERESPONSE._serialized_end=2090 + _REGISTERRESOURCERESPONSE_PROPERTYDEPENDENCIES._serialized_start=1442 + _REGISTERRESOURCERESPONSE_PROPERTYDEPENDENCIES._serialized_end=1478 + _REGISTERRESOURCERESPONSE_PROPERTYDEPENDENCIESENTRY._serialized_start=1973 + _REGISTERRESOURCERESPONSE_PROPERTYDEPENDENCIESENTRY._serialized_end=2090 + _REGISTERRESOURCEOUTPUTSREQUEST._serialized_start=2092 + _REGISTERRESOURCEOUTPUTSREQUEST._serialized_end=2179 + _RESOURCEINVOKEREQUEST._serialized_start=2182 + _RESOURCEINVOKEREQUEST._serialized_end=2344 + _RESOURCEMONITOR._serialized_start=2347 + _RESOURCEMONITOR._serialized_end=2943 # @@protoc_insertion_point(module_scope) diff --git a/sdk/python/lib/pulumi/runtime/resource.py b/sdk/python/lib/pulumi/runtime/resource.py index 6fdcc86366b0..5317566f7525 100644 --- a/sdk/python/lib/pulumi/runtime/resource.py +++ b/sdk/python/lib/pulumi/runtime/resource.py @@ -584,6 +584,7 @@ async def do_register(): remote=remote, replaceOnChanges=replace_on_changes, retainOnDelete=opts.retain_on_delete or False, + deletedWithParent=opts.deleted_with_parent or False, ) from ..resource import create_urn # pylint: disable=import-outside-toplevel