Skip to content

Commit

Permalink
Extend CustomResource interface to pass state for Update and Delete (#…
Browse files Browse the repository at this point in the history
…1801)

Previously the Update and Delete methods for Custom Resources
did not require access to the current state, but this is a
common requirement for updating and deleting resources.

This is also needed for supporting CloudFormation Custom Resources
as those require access to state in order to complete updates
and deletions.

relates to pulumi/pulumi-cdk#109
  • Loading branch information
flostadler authored Nov 6, 2024
1 parent c2f11ba commit 91e1b65
Show file tree
Hide file tree
Showing 5 changed files with 23 additions and 18 deletions.
9 changes: 7 additions & 2 deletions provider/pkg/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -1061,7 +1061,7 @@ func (p *cfnProvider) Update(ctx context.Context, req *pulumirpc.UpdateRequest)
if customResource, ok := p.customResources[resourceToken]; ok {
timeout := time.Duration(req.GetTimeout()) * time.Second
// Custom resource
outputs, err = customResource.Update(ctx, urn, id, newInputs, oldInputs, timeout)
outputs, err = customResource.Update(ctx, urn, id, newInputs, oldInputs, oldState, timeout)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -1128,8 +1128,13 @@ func (p *cfnProvider) Delete(ctx context.Context, req *pulumirpc.DeleteRequest)
return nil, errors.Wrapf(err, "failed to parse inputs for update")
}

// Retrieve the state.
state, err := plugin.UnmarshalProperties(req.GetProperties(), plugin.MarshalOptions{
Label: fmt.Sprintf("%s.state", label), KeepUnknowns: true, SkipNulls: true, KeepSecrets: true,
})

timeout := time.Duration(req.GetTimeout()) * time.Second
err = customResource.Delete(ctx, urn, id, oldInputs, timeout)
err = customResource.Delete(ctx, urn, id, oldInputs, state, timeout)
if err != nil {
return nil, err
}
Expand Down
8 changes: 4 additions & 4 deletions provider/pkg/provider/provider_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,7 @@ func TestUpdate(t *testing.T) {
}

t.Run("CustomResource", func(t *testing.T) {
mockCustomResource.EXPECT().Update(ctx, urn, "resource-id", gomock.Any(), gomock.Any(), 5*time.Minute).Return(
mockCustomResource.EXPECT().Update(ctx, urn, "resource-id", gomock.Any(), gomock.Any(), gomock.Any(), 5*time.Minute).Return(
resource.PropertyMap{"foo": resource.NewStringProperty("bar")}, nil,
)

Expand All @@ -410,7 +410,7 @@ func TestUpdate(t *testing.T) {
})

t.Run("CustomResource/Error", func(t *testing.T) {
mockCustomResource.EXPECT().Update(ctx, urn, "resource-id", gomock.Any(), gomock.Any(), 5*time.Minute).Return(
mockCustomResource.EXPECT().Update(ctx, urn, "resource-id", gomock.Any(), gomock.Any(), gomock.Any(), 5*time.Minute).Return(
nil, assert.AnError,
)

Expand Down Expand Up @@ -509,14 +509,14 @@ func TestDelete(t *testing.T) {
}

t.Run("CustomResource", func(t *testing.T) {
mockCustomResource.EXPECT().Delete(ctx, urn, "resource-id", gomock.Any(), gomock.Any()).Return(nil)
mockCustomResource.EXPECT().Delete(ctx, urn, "resource-id", gomock.Any(), gomock.Any(), gomock.Any()).Return(nil)

_, err := provider.Delete(ctx, req)
assert.NoError(t, err)
})

t.Run("CustomResource/Error", func(t *testing.T) {
mockCustomResource.EXPECT().Delete(ctx, urn, "resource-id", gomock.Any(), gomock.Any()).Return(assert.AnError)
mockCustomResource.EXPECT().Delete(ctx, urn, "resource-id", gomock.Any(), gomock.Any(), gomock.Any()).Return(assert.AnError)

_, err := provider.Delete(ctx, req)
assert.Error(t, err)
Expand Down
4 changes: 2 additions & 2 deletions provider/pkg/resources/custom.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ type CustomResource interface {
// Read returns the outputs and the updated inputs of the resource.
Read(ctx context.Context, urn resource.URN, id string, oldInputs, oldOutputs resource.PropertyMap) (outputs resource.PropertyMap, inputs resource.PropertyMap, exists bool, err error)
// Update applies the diff of the inputs to the resource and returns the updated outputs.
Update(ctx context.Context, urn resource.URN, id string, inputs, oldInputs resource.PropertyMap, timeout time.Duration) (resource.PropertyMap, error)
Update(ctx context.Context, urn resource.URN, id string, inputs, oldInputs, state resource.PropertyMap, timeout time.Duration) (resource.PropertyMap, error)
// Delete removes the resource from the cloud provider.
Delete(ctx context.Context, urn resource.URN, id string, inputs resource.PropertyMap, timeout time.Duration) error
Delete(ctx context.Context, urn resource.URN, id string, inputs, state resource.PropertyMap, timeout time.Duration) error
}
4 changes: 2 additions & 2 deletions provider/pkg/resources/extension_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ func (r *extensionResource) Read(ctx context.Context, urn resource.URN, id strin
return CheckpointObject(newInputs, rawState), newInputs, true, nil
}

func (r *extensionResource) Update(ctx context.Context, urn resource.URN, id string, inputs resource.PropertyMap, oldInputs resource.PropertyMap, timeout time.Duration) (resource.PropertyMap, error) {
func (r *extensionResource) Update(ctx context.Context, urn resource.URN, id string, inputs, oldInputs, state resource.PropertyMap, timeout time.Duration) (resource.PropertyMap, error) {
var typedOldInputs ExtensionResourceInputs
_, err := resourcex.Unmarshal(&typedOldInputs, oldInputs, resourcex.UnmarshalOptions{})
if err != nil {
Expand Down Expand Up @@ -198,7 +198,7 @@ func (r *extensionResource) Update(ctx context.Context, urn resource.URN, id str
return CheckpointObject(inputs, rawState), nil
}

func (r *extensionResource) Delete(ctx context.Context, urn resource.URN, id string, inputs resource.PropertyMap, timeout time.Duration) error {
func (r *extensionResource) Delete(ctx context.Context, urn resource.URN, id string, inputs, state resource.PropertyMap, timeout time.Duration) error {
var typedInputs ExtensionResourceInputs
_, err := resourcex.Unmarshal(&typedInputs, inputs, resourcex.UnmarshalOptions{})
if err != nil {
Expand Down
16 changes: 8 additions & 8 deletions provider/pkg/resources/mock_custom_resource.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 91e1b65

Please sign in to comment.