Add support to the go sdk for IgnoreChanges (#3514)
This commit is contained in:
parent
022826bac5
commit
3ac8dd5285
|
@ -3,6 +3,8 @@ CHANGELOG
|
|||
|
||||
## HEAD (Unreleased)
|
||||
|
||||
- Add support for IgnoreChanges in the go SDK [#3514](https://github.com/pulumi/pulumi/pull/3514)
|
||||
|
||||
- Support for a `go run` style workflow. Building or installing a pulumi program written in go is
|
||||
now optional. [3503](https://github.com/pulumi/pulumi/pull/3503)
|
||||
|
||||
|
|
|
@ -4946,3 +4946,83 @@ func TestSingleResourceDefaultProviderGolangLifecycle(t *testing.T) {
|
|||
}
|
||||
p.Run(t, nil)
|
||||
}
|
||||
|
||||
// This test validates the wiring of the IgnoreChanges prop in the go SDK.
|
||||
// It doesn't attempt to validate underlying behavior.
|
||||
func TestIgnoreChangesGolangLifecycle(t *testing.T) {
|
||||
var expectedIgnoreChanges []string
|
||||
|
||||
loaders := []*deploytest.ProviderLoader{
|
||||
deploytest.NewProviderLoader("pkgA", semver.MustParse("1.0.0"), func() (plugin.Provider, error) {
|
||||
return &deploytest.Provider{
|
||||
CreateF: func(urn resource.URN,
|
||||
news resource.PropertyMap, timeout float64) (resource.ID, resource.PropertyMap, resource.Status, error) {
|
||||
|
||||
return "created-id", news, resource.StatusOK, nil
|
||||
},
|
||||
ReadF: func(urn resource.URN, id resource.ID,
|
||||
inputs, state resource.PropertyMap) (plugin.ReadResult, resource.Status, error) {
|
||||
return plugin.ReadResult{Inputs: inputs, Outputs: state}, resource.StatusOK, nil
|
||||
},
|
||||
DiffF: func(urn resource.URN, id resource.ID,
|
||||
olds, news resource.PropertyMap, ignoreChanges []string) (plugin.DiffResult, error) {
|
||||
// just verify that the IgnoreChanges prop made it through
|
||||
assert.Equal(t, expectedIgnoreChanges, ignoreChanges)
|
||||
return plugin.DiffResult{}, nil
|
||||
},
|
||||
}, nil
|
||||
}),
|
||||
}
|
||||
|
||||
setupAndRunProgram := func(ignoreChanges []string) *deploy.Snapshot {
|
||||
program := deploytest.NewLanguageRuntime(func(info plugin.RunInfo, monitor *deploytest.ResourceMonitor) error {
|
||||
ctx, err := pulumi.NewContext(context.Background(), pulumi.RunInfo{
|
||||
Project: info.Project,
|
||||
Stack: info.Stack,
|
||||
Parallel: info.Parallel,
|
||||
DryRun: info.DryRun,
|
||||
MonitorAddr: info.MonitorAddress,
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
|
||||
return pulumi.RunWithContext(ctx, func(ctx *pulumi.Context) error {
|
||||
opts := pulumi.ResourceOpt{
|
||||
IgnoreChanges: ignoreChanges,
|
||||
}
|
||||
_, err := ctx.RegisterResource("pkgA:m:typA", "resA", true, nil, opts)
|
||||
assert.NoError(t, err)
|
||||
|
||||
return nil
|
||||
})
|
||||
})
|
||||
|
||||
host := deploytest.NewPluginHost(nil, nil, program, loaders...)
|
||||
p := &TestPlan{
|
||||
Options: UpdateOptions{host: host},
|
||||
Steps: []TestStep{
|
||||
{
|
||||
Op: Update,
|
||||
Validate: func(project workspace.Project, target deploy.Target, j *Journal,
|
||||
events []Event, res result.Result) result.Result {
|
||||
for _, event := range events {
|
||||
if event.Type == ResourcePreEvent {
|
||||
payload := event.Payload.(ResourcePreEventPayload)
|
||||
assert.Equal(t, []deploy.StepOp{deploy.OpCreate}, []deploy.StepOp{payload.Metadata.Op})
|
||||
}
|
||||
}
|
||||
return res
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
return p.Run(t, nil)
|
||||
}
|
||||
|
||||
// ignore changes specified
|
||||
ignoreChanges := []string{"b"}
|
||||
setupAndRunProgram(ignoreChanges)
|
||||
|
||||
// ignore changes empty
|
||||
ignoreChanges = []string{}
|
||||
setupAndRunProgram(ignoreChanges)
|
||||
}
|
||||
|
|
|
@ -287,6 +287,7 @@ func (ctx *Context) RegisterResource(
|
|||
DeleteBeforeReplace: inputs.deleteBeforeReplace,
|
||||
ImportId: inputs.importID,
|
||||
CustomTimeouts: inputs.customTimeouts,
|
||||
IgnoreChanges: inputs.ignoreChanges,
|
||||
})
|
||||
if err != nil {
|
||||
logging.V(9).Infof("RegisterResource(%s, %s): error: %v", t, name, err)
|
||||
|
@ -396,13 +397,14 @@ type resourceInputs struct {
|
|||
deleteBeforeReplace bool
|
||||
importID string
|
||||
customTimeouts *pulumirpc.RegisterResourceRequest_CustomTimeouts
|
||||
ignoreChanges []string
|
||||
}
|
||||
|
||||
// prepareResourceInputs prepares the inputs for a resource operation, shared between read and register.
|
||||
func (ctx *Context) prepareResourceInputs(props map[string]interface{}, opts ...ResourceOpt) (*resourceInputs, error) {
|
||||
// Get the parent and dependency URNs from the options, in addition to the protection bit. If there wasn't an
|
||||
// explicit parent, and a root stack resource exists, we will automatically parent to that.
|
||||
parent, optDeps, protect, provider, deleteBeforeReplace, importID, err := ctx.getOpts(opts...)
|
||||
parent, optDeps, protect, provider, deleteBeforeReplace, importID, ignoreChanges, err := ctx.getOpts(opts...)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "resolving options")
|
||||
}
|
||||
|
@ -455,6 +457,7 @@ func (ctx *Context) prepareResourceInputs(props map[string]interface{}, opts ...
|
|||
deleteBeforeReplace: deleteBeforeReplace,
|
||||
importID: string(importID),
|
||||
customTimeouts: timeouts,
|
||||
ignoreChanges: ignoreChanges,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
@ -473,13 +476,14 @@ func (ctx *Context) getTimeouts(opts ...ResourceOpt) *pulumirpc.RegisterResource
|
|||
|
||||
// getOpts returns a set of resource options from an array of them. This includes the parent URN, any dependency URNs,
|
||||
// a boolean indicating whether the resource is to be protected, and the URN and ID of the resource's provider, if any.
|
||||
func (ctx *Context) getOpts(opts ...ResourceOpt) (URN, []URN, bool, string, bool, ID, error) {
|
||||
func (ctx *Context) getOpts(opts ...ResourceOpt) (URN, []URN, bool, string, bool, ID, []string, error) {
|
||||
var parent Resource
|
||||
var deps []Resource
|
||||
var protect bool
|
||||
var provider ProviderResource
|
||||
var deleteBeforeReplace bool
|
||||
var importID ID
|
||||
var ignoreChanges []string
|
||||
for _, opt := range opts {
|
||||
if parent == nil && opt.Parent != nil {
|
||||
parent = opt.Parent
|
||||
|
@ -499,6 +503,9 @@ func (ctx *Context) getOpts(opts ...ResourceOpt) (URN, []URN, bool, string, bool
|
|||
if importID == "" && opt.Import != "" {
|
||||
importID = opt.Import
|
||||
}
|
||||
if ignoreChanges == nil && opt.IgnoreChanges != nil {
|
||||
ignoreChanges = opt.IgnoreChanges
|
||||
}
|
||||
}
|
||||
|
||||
var parentURN URN
|
||||
|
@ -507,7 +514,7 @@ func (ctx *Context) getOpts(opts ...ResourceOpt) (URN, []URN, bool, string, bool
|
|||
} else {
|
||||
urn, _, err := parent.URN().await(context.TODO())
|
||||
if err != nil {
|
||||
return "", nil, false, "", false, "", err
|
||||
return "", nil, false, "", false, "", nil, err
|
||||
}
|
||||
parentURN = urn
|
||||
}
|
||||
|
@ -518,7 +525,7 @@ func (ctx *Context) getOpts(opts ...ResourceOpt) (URN, []URN, bool, string, bool
|
|||
for i, r := range deps {
|
||||
urn, _, err := r.URN().await(context.TODO())
|
||||
if err != nil {
|
||||
return "", nil, false, "", false, "", err
|
||||
return "", nil, false, "", false, "", nil, err
|
||||
}
|
||||
depURNs[i] = urn
|
||||
}
|
||||
|
@ -528,12 +535,12 @@ func (ctx *Context) getOpts(opts ...ResourceOpt) (URN, []URN, bool, string, bool
|
|||
if provider != nil {
|
||||
pr, err := ctx.resolveProviderReference(provider)
|
||||
if err != nil {
|
||||
return "", nil, false, "", false, "", err
|
||||
return "", nil, false, "", false, "", nil, err
|
||||
}
|
||||
providerRef = pr
|
||||
}
|
||||
|
||||
return parentURN, depURNs, protect, providerRef, false, importID, nil
|
||||
return parentURN, depURNs, protect, providerRef, false, importID, ignoreChanges, nil
|
||||
}
|
||||
|
||||
func (ctx *Context) resolveProviderReference(provider ProviderResource) (string, error) {
|
||||
|
|
|
@ -69,6 +69,8 @@ type ResourceOpt struct {
|
|||
Import ID
|
||||
// CustomTimeouts is an optional configuration block used for CRUD operations
|
||||
CustomTimeouts *CustomTimeouts
|
||||
// Ignore changes to any of the specified properties.
|
||||
IgnoreChanges []string
|
||||
}
|
||||
|
||||
// InvokeOpt contains optional settings that control an invoke's behavior.
|
||||
|
|
Loading…
Reference in a new issue