diff --git a/pkg/pulumiyaml/sort.go b/pkg/pulumiyaml/sort.go index d1f4d24d..0a827ad3 100644 --- a/pkg/pulumiyaml/sort.go +++ b/pkg/pulumiyaml/sort.go @@ -139,14 +139,16 @@ func topologicallySortedResources(t *ast.TemplateDecl, externalConfig []configNo } } - var defaultProvider *ast.StringExpr + // Map of package name to default provider resource and it's key. + defaultProviders := map[string]*ast.StringExpr{} for _, kvp := range t.Resources.Entries { rname, r := kvp.Key.Value, kvp.Value node := resourceNode(kvp) // Check if the resource is a default provider if resourceIsDefaultProvider(node) { - defaultProvider = node.key() + pkg := strings.Split(node.Value.Type.Value, ":")[2] + defaultProviders[pkg] = node.key() } cdiags := checkUniqueNode(intermediates, node) @@ -215,14 +217,22 @@ func topologicallySortedResources(t *ast.TemplateDecl, externalConfig []configNo } } - if resourceNodeHasNoExplicitProvider(e) && defaultProvider != name { - // If the resource has no explicit provider and the default provider is not set, then the - // (implicit) dependency is not yet met. - if defaultProvider != nil && !visit(defaultProvider) { - return false + if resNode, ok := e.(resourceNode); ok { + pkg := "" + if resNode.Value.Type != nil { + pkg = strings.Split(resNode.Value.Type.Value, ":")[0] + } + defaultProviderForPackage := defaultProviders[pkg] + isDefaultProvider := resNode.Value.DefaultProvider != nil && resNode.Value.DefaultProvider.Value + if resourceNodeHasNoExplicitProvider(e) && !isDefaultProvider { + // If the resource has no explicit provider and the default provider is not set, then the + // (implicit) dependency is not yet met. + if defaultProviderForPackage != nil && !visit(defaultProviderForPackage) { + return false + } + + // if the defaultProviderForPackage is not set, then it may not be needed. } - - // if the defaultProviderForPackage is not set, then it may not be needed. } visited[name.Value] = true diff --git a/pkg/pulumiyaml/sort_test.go b/pkg/pulumiyaml/sort_test.go index f16a36a0..127012de 100644 --- a/pkg/pulumiyaml/sort_test.go +++ b/pkg/pulumiyaml/sort_test.go @@ -117,6 +117,24 @@ func TestSortUnordered(t *testing.T) { assert.Equal(t, "my-object", names[1]) } +func TestSortMultipleDefaultProviders(t *testing.T) { + t.Parallel() + + tmpl, diags, err := LoadFile("../tests/testdata/resource-ordering/Pulumi.yaml") + requireNoErrors(t, tmpl, diags) + assert.NoError(t, err) + + confNodes := []configNode{} + resources, diags := topologicallySortedResources(tmpl, confNodes) + requireNoErrors(t, tmpl, diags) + names := sortedNames(resources) + assert.Len(t, names, 4) + assert.Equal(t, "provider", names[0]) + assert.Equal(t, "alb", names[1]) + assert.Equal(t, "testProvider", names[2]) + assert.Equal(t, "echo", names[3]) +} + func TestSortErrorCycle(t *testing.T) { t.Parallel() diff --git a/pkg/tests/testdata/resource-ordering/Pulumi.yaml b/pkg/tests/testdata/resource-ordering/Pulumi.yaml index 67bcd7ae..f0ec7075 100644 --- a/pkg/tests/testdata/resource-ordering/Pulumi.yaml +++ b/pkg/tests/testdata/resource-ordering/Pulumi.yaml @@ -1,5 +1,9 @@ name: aws-yaml runtime: yaml +plugins: + providers: + - name: testprovider + path: ../../testprovider resources: alb: type: aws:alb:LoadBalancer @@ -10,8 +14,16 @@ resources: subnets: - subnet-eacf3697 - subnet-939b18f8 + echo: + type: testprovider:index:Echo provider: defaultProvider: true type: pulumi:providers:aws properties: region: us-west-2 + testProvider: + defaultProvider: true + type: pulumi:providers:testprovider + properties: + testInput: ${alb.urn} + diff --git a/pkg/tests/testprovider/main.go b/pkg/tests/testprovider/main.go index a2f737b4..5fad5c0a 100644 --- a/pkg/tests/testprovider/main.go +++ b/pkg/tests/testprovider/main.go @@ -52,7 +52,12 @@ var providerSchema = pschema.PackageSpec{ Description: "The provider type for the testprovider package.", Type: "object", }, - InputProperties: map[string]pschema.PropertySpec{}, + InputProperties: map[string]pschema.PropertySpec{ + "testInput": { + TypeSpec: pschema.TypeSpec{Type: "string"}, + Description: "A test input property.", + }, + }, }, Types: map[string]pschema.ComplexTypeSpec{},