Do not parse version from resource providers

Until we can come up with a solution for #2753, just ignore the
version that comes in as part of a resource monitor RPC.
This commit is contained in:
Matt Ellis 2019-05-21 18:14:20 -07:00
parent d5b45ac5ad
commit 61bff0c3a4
3 changed files with 178 additions and 168 deletions

View file

@ -1,4 +1,8 @@
## 0.17.13 (unreleased)
## 0.17.14 (Unreleased)
### Improvements
## 0.17.13 (Released May 21, 2019)
### Improvements
@ -12,6 +16,7 @@
- Signature of `Pulumi.all` has been made more accurate. Calling `.all` on `Output`s that may
be `undefined` will properly encode and pass along that `undefined` information.
- Fix an issue where some operations would fail with `error: could not deserialize deployment: unknown secrets provider type`.
- Fix an issue where pulumi might try to replace existing resources when upgrading to the newest version of some resource providers.
## 0.17.12 (Released May 15, 2019)

View file

@ -494,18 +494,21 @@ func (rm *resmon) getProvider(req providers.ProviderRequest, rawProviderRef stri
}
func (rm *resmon) parseProviderRequest(pkg tokens.Package, version string) (providers.ProviderRequest, error) {
if version == "" {
logging.V(5).Infof("parseProviderRequest(%s): semver version is the empty string", pkg)
return providers.NewProviderRequest(nil, pkg), nil
}
return providers.NewProviderRequest(nil, pkg), nil
parsedVersion, err := semver.Parse(version)
if err != nil {
logging.V(5).Infof("parseProviderRequest(%s, %s): semver version string is invalid: %v", pkg, version, err)
return providers.ProviderRequest{}, err
}
// TODO[pulumi/pulumi#2753]: We should re-enable this code once we have a solution for #2753.
// if version == "" {
// logging.V(5).Infof("parseProviderRequest(%s): semver version is the empty string", pkg)
// return providers.NewProviderRequest(nil, pkg), nil
// }
return providers.NewProviderRequest(&parsedVersion, pkg), nil
// parsedVersion, err := semver.Parse(version)
// if err != nil {
// logging.V(5).Infof("parseProviderRequest(%s, %s): semver version string is invalid: %v", pkg, version, err)
// return providers.ProviderRequest{}, err
// }
// return providers.NewProviderRequest(&parsedVersion, pkg), nil
}
func (rm *resmon) SupportsFeature(ctx context.Context,

View file

@ -485,190 +485,192 @@ func TestReadInvokeDefaultProviders(t *testing.T) {
assert.Equal(t, expectedInvokes, int(invokes))
}
func TestReadResourceAndInvokeVersion(t *testing.T) {
runInfo := &EvalRunInfo{
Proj: &workspace.Project{Name: "test"},
Target: &Target{Name: "test"},
}
// TODO[pulumi/pulumi#2753]: We should re-enable these tests (and fix them up as needed) once we have a solution
// for #2753.
// func TestReadResourceAndInvokeVersion(t *testing.T) {
// runInfo := &EvalRunInfo{
// Proj: &workspace.Project{Name: "test"},
// Target: &Target{Name: "test"},
// }
newURN := func(t tokens.Type, name string, parent resource.URN) resource.URN {
var pt tokens.Type
if parent != "" {
pt = parent.Type()
}
return resource.NewURN(runInfo.Target.Name, runInfo.Proj.Name, pt, t, tokens.QName(name))
}
// newURN := func(t tokens.Type, name string, parent resource.URN) resource.URN {
// var pt tokens.Type
// if parent != "" {
// pt = parent.Type()
// }
// return resource.NewURN(runInfo.Target.Name, runInfo.Proj.Name, pt, t, tokens.QName(name))
// }
invokes := int32(0)
noopProvider := &deploytest.Provider{
InvokeF: func(tokens.ModuleMember, resource.PropertyMap) (resource.PropertyMap, []plugin.CheckFailure, error) {
atomic.AddInt32(&invokes, 1)
return resource.PropertyMap{}, nil, nil
},
}
// invokes := int32(0)
// noopProvider := &deploytest.Provider{
// InvokeF: func(tokens.ModuleMember, resource.PropertyMap) (resource.PropertyMap, []plugin.CheckFailure, error) {
// atomic.AddInt32(&invokes, 1)
// return resource.PropertyMap{}, nil, nil
// },
// }
// This program is designed to trigger the instantiation of two default providers:
// 1. Provider pkgA, version 0.18.0
// 2. Provider pkgC, version 0.18.0
program := func(_ plugin.RunInfo, resmon *deploytest.ResourceMonitor) error {
// Triggers pkgA, v0.18.0.
_, _, err := resmon.ReadResource("pkgA:m:typA", "resA", "id1", "", nil, "", "0.18.0")
assert.NoError(t, err)
// Uses pkgA's already-instantiated provider.
_, _, err = resmon.ReadResource("pkgA:m:typB", "resB", "id1", "", nil, "", "0.18.0")
assert.NoError(t, err)
// // This program is designed to trigger the instantiation of two default providers:
// // 1. Provider pkgA, version 0.18.0
// // 2. Provider pkgC, version 0.18.0
// program := func(_ plugin.RunInfo, resmon *deploytest.ResourceMonitor) error {
// // Triggers pkgA, v0.18.0.
// _, _, err := resmon.ReadResource("pkgA:m:typA", "resA", "id1", "", nil, "", "0.18.0")
// assert.NoError(t, err)
// // Uses pkgA's already-instantiated provider.
// _, _, err = resmon.ReadResource("pkgA:m:typB", "resB", "id1", "", nil, "", "0.18.0")
// assert.NoError(t, err)
// Triggers pkgC, v0.18.0.
_, _, err = resmon.ReadResource("pkgC:m:typC", "resC", "id1", "", nil, "", "0.18.0")
assert.NoError(t, err)
// // Triggers pkgC, v0.18.0.
// _, _, err = resmon.ReadResource("pkgC:m:typC", "resC", "id1", "", nil, "", "0.18.0")
// assert.NoError(t, err)
// Uses pkgA and pkgC's already-instantiated provider.
_, _, err = resmon.Invoke("pkgA:m:funcA", nil, "", "0.18.0")
assert.NoError(t, err)
_, _, err = resmon.Invoke("pkgA:m:funcB", nil, "", "0.18.0")
assert.NoError(t, err)
_, _, err = resmon.Invoke("pkgC:m:funcC", nil, "", "0.18.0")
assert.NoError(t, err)
// // Uses pkgA and pkgC's already-instantiated provider.
// _, _, err = resmon.Invoke("pkgA:m:funcA", nil, "", "0.18.0")
// assert.NoError(t, err)
// _, _, err = resmon.Invoke("pkgA:m:funcB", nil, "", "0.18.0")
// assert.NoError(t, err)
// _, _, err = resmon.Invoke("pkgC:m:funcC", nil, "", "0.18.0")
// assert.NoError(t, err)
return nil
}
// return nil
// }
ctx, err := newTestPluginContext(program)
assert.NoError(t, err)
// ctx, err := newTestPluginContext(program)
// assert.NoError(t, err)
providerSource := &testProviderSource{providers: make(map[providers.Reference]plugin.Provider)}
// providerSource := &testProviderSource{providers: make(map[providers.Reference]plugin.Provider)}
iter, res := NewEvalSource(ctx, runInfo, nil, false).Iterate(context.Background(), Options{}, providerSource)
assert.Nil(t, res)
registrations, reads := 0, 0
for {
event, res := iter.Next()
assert.Nil(t, res)
// iter, res := NewEvalSource(ctx, runInfo, nil, false).Iterate(context.Background(), Options{}, providerSource)
// assert.Nil(t, res)
// registrations, reads := 0, 0
// for {
// event, res := iter.Next()
// assert.Nil(t, res)
if event == nil {
break
}
// if event == nil {
// break
// }
switch e := event.(type) {
case RegisterResourceEvent:
goal := e.Goal()
urn, id := newURN(goal.Type, string(goal.Name), goal.Parent), resource.ID("id")
// switch e := event.(type) {
// case RegisterResourceEvent:
// goal := e.Goal()
// urn, id := newURN(goal.Type, string(goal.Name), goal.Parent), resource.ID("id")
assert.True(t, providers.IsProviderType(goal.Type))
// The name of the provider resource is derived from the version requested.
assert.Equal(t, "default_0_18_0", string(goal.Name))
ref, err := providers.NewReference(urn, id)
assert.NoError(t, err)
_, ok := providerSource.GetProvider(ref)
assert.False(t, ok)
providerSource.registerProvider(ref, noopProvider)
// assert.True(t, providers.IsProviderType(goal.Type))
// // The name of the provider resource is derived from the version requested.
// assert.Equal(t, "default_0_18_0", string(goal.Name))
// ref, err := providers.NewReference(urn, id)
// assert.NoError(t, err)
// _, ok := providerSource.GetProvider(ref)
// assert.False(t, ok)
// providerSource.registerProvider(ref, noopProvider)
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),
})
registrations++
// 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),
// })
// registrations++
case ReadResourceEvent:
urn := newURN(e.Type(), string(e.Name()), e.Parent())
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),
})
reads++
}
}
// case ReadResourceEvent:
// urn := newURN(e.Type(), string(e.Name()), e.Parent())
// 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),
// })
// reads++
// }
// }
assert.Equal(t, 2, registrations)
assert.Equal(t, 3, reads)
assert.Equal(t, int32(3), invokes)
}
// assert.Equal(t, 2, registrations)
// assert.Equal(t, 3, reads)
// assert.Equal(t, int32(3), invokes)
// }
func TestRegisterResourceWithVersion(t *testing.T) {
runInfo := &EvalRunInfo{
Proj: &workspace.Project{Name: "test"},
Target: &Target{Name: "test"},
}
// func TestRegisterResourceWithVersion(t *testing.T) {
// runInfo := &EvalRunInfo{
// Proj: &workspace.Project{Name: "test"},
// Target: &Target{Name: "test"},
// }
newURN := func(t tokens.Type, name string, parent resource.URN) resource.URN {
var pt tokens.Type
if parent != "" {
pt = parent.Type()
}
return resource.NewURN(runInfo.Target.Name, runInfo.Proj.Name, pt, t, tokens.QName(name))
}
// newURN := func(t tokens.Type, name string, parent resource.URN) resource.URN {
// var pt tokens.Type
// if parent != "" {
// pt = parent.Type()
// }
// return resource.NewURN(runInfo.Target.Name, runInfo.Proj.Name, pt, t, tokens.QName(name))
// }
noopProvider := &deploytest.Provider{}
// noopProvider := &deploytest.Provider{}
// This program is designed to trigger the instantiation of two default providers:
// 1. Provider pkgA, version 0.18.0
// 2. Provider pkgC, version 0.18.0
program := func(_ plugin.RunInfo, resmon *deploytest.ResourceMonitor) error {
// Triggers pkgA, v0.18.1.
_, _, _, err := resmon.RegisterResource("pkgA:m:typA", "resA", true, "", false, nil, "",
resource.PropertyMap{}, nil, false, "0.18.1", nil)
assert.NoError(t, err)
// // This program is designed to trigger the instantiation of two default providers:
// // 1. Provider pkgA, version 0.18.0
// // 2. Provider pkgC, version 0.18.0
// program := func(_ plugin.RunInfo, resmon *deploytest.ResourceMonitor) error {
// // Triggers pkgA, v0.18.1.
// _, _, _, err := resmon.RegisterResource("pkgA:m:typA", "resA", true, "", false, nil, "",
// resource.PropertyMap{}, nil, false, "0.18.1", nil)
// assert.NoError(t, err)
// Re-uses pkgA's already-instantiated provider.
_, _, _, err = resmon.RegisterResource("pkgA:m:typA", "resB", true, "", false, nil, "",
resource.PropertyMap{}, nil, false, "0.18.1", nil)
assert.NoError(t, err)
// // Re-uses pkgA's already-instantiated provider.
// _, _, _, err = resmon.RegisterResource("pkgA:m:typA", "resB", true, "", false, nil, "",
// resource.PropertyMap{}, nil, false, "0.18.1", nil)
// assert.NoError(t, err)
// Triggers pkgA, v0.18.2
_, _, _, err = resmon.RegisterResource("pkgA:m:typA", "resB", true, "", false, nil, "",
resource.PropertyMap{}, nil, false, "0.18.2", nil)
assert.NoError(t, err)
return nil
}
// // Triggers pkgA, v0.18.2
// _, _, _, err = resmon.RegisterResource("pkgA:m:typA", "resB", true, "", false, nil, "",
// resource.PropertyMap{}, nil, false, "0.18.2", nil)
// assert.NoError(t, err)
// return nil
// }
ctx, err := newTestPluginContext(program)
assert.NoError(t, err)
// ctx, err := newTestPluginContext(program)
// assert.NoError(t, err)
providerSource := &testProviderSource{providers: make(map[providers.Reference]plugin.Provider)}
// providerSource := &testProviderSource{providers: make(map[providers.Reference]plugin.Provider)}
iter, res := NewEvalSource(ctx, runInfo, nil, false).Iterate(context.Background(), Options{}, providerSource)
assert.Nil(t, res)
registered181, registered182 := false, false
for {
event, res := iter.Next()
assert.Nil(t, res)
// iter, res := NewEvalSource(ctx, runInfo, nil, false).Iterate(context.Background(), Options{}, providerSource)
// assert.Nil(t, res)
// registered181, registered182 := false, false
// for {
// event, res := iter.Next()
// assert.Nil(t, res)
if event == nil {
break
}
// if event == nil {
// break
// }
switch e := event.(type) {
case RegisterResourceEvent:
goal := e.Goal()
urn, id := newURN(goal.Type, string(goal.Name), goal.Parent), resource.ID("id")
// switch e := event.(type) {
// case RegisterResourceEvent:
// goal := e.Goal()
// urn, id := newURN(goal.Type, string(goal.Name), goal.Parent), resource.ID("id")
if providers.IsProviderType(goal.Type) {
switch goal.Name {
case "default_0_18_1":
assert.False(t, registered181)
registered181 = true
case "default_0_18_2":
assert.False(t, registered182)
registered182 = true
}
// if providers.IsProviderType(goal.Type) {
// switch goal.Name {
// case "default_0_18_1":
// assert.False(t, registered181)
// registered181 = true
// case "default_0_18_2":
// assert.False(t, registered182)
// registered182 = true
// }
ref, err := providers.NewReference(urn, id)
assert.NoError(t, err)
_, ok := providerSource.GetProvider(ref)
assert.False(t, ok)
providerSource.registerProvider(ref, noopProvider)
}
// ref, err := providers.NewReference(urn, id)
// assert.NoError(t, err)
// _, ok := providerSource.GetProvider(ref)
// assert.False(t, ok)
// providerSource.registerProvider(ref, noopProvider)
// }
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),
})
}
}
// 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),
// })
// }
// }
assert.True(t, registered181)
assert.True(t, registered182)
}
// assert.True(t, registered181)
// assert.True(t, registered182)
// }