Skip to content

Commit

Permalink
feat: Package Schema resource-typed properties
Browse files Browse the repository at this point in the history
A new built-in type, `pulumi.json#/Resource` is added to the schema to refer to
any resource. This unblocks schematizing resources like
`kubernetes.yaml/v2.ConfigFile`, which ideally would declare an output like so:

```json
            "properties": {
                "resources": {
                    "type": "array",
                    "items": {
                        "$ref": "pulumi.json#/Resource"
                    },
                    "description": "Resources created by the ConfigFile."
                }
            },
```

This is a small ergonomic improvement over `pulumi.json#/Any`, and fixes #6346.
  • Loading branch information
AaronFriel committed Mar 27, 2024
1 parent 9271ef5 commit 130897d
Show file tree
Hide file tree
Showing 63 changed files with 3,814 additions and 6 deletions.
3 changes: 3 additions & 0 deletions pkg/codegen/docs/constructor_syntax_generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,9 @@ func (g *constructorSyntaxGenerator) writeValue(
write("fileArchive(\"./path/to/archive\")")
case schema.AssetType:
write("stringAsset(\"content\")")
case schema.AnyResourceType:
// Constructors are language specific - just "resource?"
write("resource")
}

switch valueType := valueType.(type) {
Expand Down
2 changes: 2 additions & 0 deletions pkg/codegen/dotnet/gen.go
Original file line number Diff line number Diff line change
Expand Up @@ -473,6 +473,8 @@ func (mod *modContext) typeString(t schema.Type, qualifier string, input, state,
return "AssetOrArchive"
case schema.JSONType:
return "System.Text.Json.JsonElement"
case schema.AnyResourceType:
return "Pulumi.Resource"
case schema.AnyType:
return "object"
}
Expand Down
12 changes: 11 additions & 1 deletion pkg/codegen/go/gen.go
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,7 @@ func isNilType(t schema.Type) bool {
}
default:
switch t {
case schema.ArchiveType, schema.AssetType, schema.JSONType, schema.AnyType:
case schema.ArchiveType, schema.AssetType, schema.JSONType, schema.AnyType, schema.AnyResourceType:
return true
}
}
Expand Down Expand Up @@ -453,6 +453,8 @@ func (pkg *pkgContext) inputType(t schema.Type) (result string) {
fallthrough
case schema.AnyType:
return "pulumi.Input"
case schema.AnyResourceType:
return "pulumi.ResourceInput"
}
}

Expand Down Expand Up @@ -618,6 +620,8 @@ func (pkg *pkgContext) argsTypeImpl(t schema.Type) (result string) {
fallthrough
case schema.AnyType:
return "pulumi.Any"
case schema.AnyResourceType:
return "pulumi.Resource"
}
}

Expand Down Expand Up @@ -712,6 +716,8 @@ func (pkg *pkgContext) typeStringImpl(t schema.Type, argsType bool) string {
fallthrough
case schema.AnyType:
return "interface{}"
case schema.AnyResourceType:
return "pulumi.Resource"
}
}

Expand Down Expand Up @@ -928,6 +934,8 @@ func (pkg *pkgContext) outputTypeImpl(t schema.Type) string {
fallthrough
case schema.AnyType:
return "pulumi.AnyOutput"
case schema.AnyResourceType:
return "pulumi.ResourceOutput"
}
}

Expand Down Expand Up @@ -957,6 +965,8 @@ func (pkg *pkgContext) genericElementType(schemaType schema.Type) (string, bool)
return "pulumi.Archive", true
case schema.AssetType:
return "pulumi.AssetOrArchive", true
case schema.AnyResourceType:
return "pulumi.Resource", true
default:
switch schemaType := schemaType.(type) {
case *schema.ObjectType:
Expand Down
17 changes: 12 additions & 5 deletions pkg/codegen/go/gen_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"github.com/pulumi/pulumi/pkg/v3/codegen/schema"
"github.com/pulumi/pulumi/pkg/v3/codegen/testing/test"
"github.com/pulumi/pulumi/pkg/v3/codegen/testing/utils"
"github.com/pulumi/pulumi/pkg/v3/testing/integration"
"github.com/pulumi/pulumi/sdk/v3/go/common/slice"
"github.com/pulumi/pulumi/sdk/v3/go/common/util/executable"
)
Expand Down Expand Up @@ -144,20 +145,26 @@ func typeCheckGeneratedPackage(t *testing.T, codeDir string) {
if alreadyHaveGoMod {
t.Logf("Found an existing go.mod, leaving as is")
} else {
test.RunCommand(t, "go_mod_init", codeDir, goExe, "mod", "init", inferModuleName(codeDir))
runCommandWithGoWorkOff(t, "go_mod_init", codeDir, goExe, "mod", "init", inferModuleName(codeDir))
replacement := "github.com/pulumi/pulumi/sdk/v3=" + sdk
test.RunCommand(t, "go_mod_edit", codeDir, goExe, "mod", "edit", "-replace", replacement)
runCommandWithGoWorkOff(t, "go_mod_edit", codeDir, goExe, "mod", "edit", "-replace", replacement)
}

test.RunCommand(t, "go_mod_tidy", codeDir, goExe, "mod", "tidy")
test.RunCommand(t, "go_build", codeDir, goExe, "build", "-v", "all")
runCommandWithGoWorkOff(t, "go_mod_tidy", codeDir, goExe, "mod", "tidy")
runCommandWithGoWorkOff(t, "go_build", codeDir, goExe, "build", "-v", "all")
}

func testGeneratedPackage(t *testing.T, codeDir string) {
goExe, err := executable.FindExecutable("go")
require.NoError(t, err)

test.RunCommand(t, "go-test", codeDir, goExe, "test", inferModuleName(codeDir)+"/...")
runCommandWithGoWorkOff(t, "go-test", codeDir, goExe, "test", inferModuleName(codeDir)+"/...")
}

func runCommandWithGoWorkOff(t *testing.T, name string, cwd string, exec string, args ...string) {
test.RunCommandWithOptions(t, &integration.ProgramTestOptions{
Env: []string{"GOWORK=off"},
}, name, cwd, exec, args...)
}

func TestGenerateTypeNames(t *testing.T) {
Expand Down
2 changes: 2 additions & 0 deletions pkg/codegen/nodejs/gen.go
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,8 @@ func (mod *modContext) typeAst(t schema.Type, input bool, constValue interface{}
fallthrough
case schema.AnyType:
return tstypes.Identifier("any")
case schema.AnyResourceType:
return tstypes.Identifier("pulumi.Resource")
}
}
panic(fmt.Errorf("unexpected type %T", t))
Expand Down
2 changes: 2 additions & 0 deletions pkg/codegen/pcl/binder_schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,8 @@ func (b *binder) schemaTypeToType(src schema.Type) model.Type {
fallthrough
case schema.AnyType:
return model.DynamicType
case schema.AnyResourceType:
return ResourceType
default:
return model.NoneType
}
Expand Down
2 changes: 2 additions & 0 deletions pkg/codegen/pcl/type.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,6 @@ var (
ResourcePropertyType model.Type = model.NewOpaqueType("Property")
// AssetOrArchiveType represents the set of Pulumi Archive values.
AssetOrArchiveType model.Type = model.NewUnionType(ArchiveType, AssetType)
// ResourceType represents the set of (untyped) Pulumi Resource values, a generic return type for a resource.
ResourceType model.Type = model.NewOpaqueType("Resource")
)
4 changes: 4 additions & 0 deletions pkg/codegen/python/gen.go
Original file line number Diff line number Diff line change
Expand Up @@ -2422,6 +2422,8 @@ func (mod *modContext) typeString(t schema.Type, input, acceptMapping bool) stri
fallthrough
case schema.AnyType:
return "Any"
case schema.AnyResourceType:
return "pulumi.Resource"
}
}

Expand Down Expand Up @@ -2461,6 +2463,8 @@ func (mod *modContext) pyType(typ schema.Type) string {
return "pulumi.Archive"
case schema.AssetType:
return "Union[pulumi.Asset, pulumi.Archive]"
case schema.AnyResourceType:
return "pulumi.Resource"
default:
return "dict"
}
Expand Down
2 changes: 2 additions & 0 deletions pkg/codegen/schema/bind.go
Original file line number Diff line number Diff line change
Expand Up @@ -747,6 +747,8 @@ func (t *types) bindTypeSpecRef(path string, spec TypeSpec, inputShape bool) (Ty
return JSONType, nil, nil
case "pulumi.json#/Any":
return AnyType, nil, nil
case "pulumi.json#/Resource":
return AnyResourceType, nil, nil
}

ref, refDiags := t.parseTypeSpecRef(path, spec.Ref)
Expand Down
4 changes: 4 additions & 0 deletions pkg/codegen/schema/schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ func (t primitiveType) String() string {
return "pulumi:pulumi:Asset"
case jsonType:
fallthrough
case anyResourceType:
fallthrough
case anyType:
return "pulumi:pulumi:Any"
default:
Expand Down Expand Up @@ -1340,6 +1342,8 @@ func (pkg *Package) marshalType(t Type, plain bool) TypeSpec {
return TypeSpec{Ref: "pulumi.json#/Asset"}
case JSONType:
return TypeSpec{Ref: "pulumi.json#/Json"}
case AnyResourceType:
return TypeSpec{Ref: "pulumi.json#/Resource"}
default:
panic(fmt.Errorf("unexepcted type %v (%T)", t, t))
}
Expand Down
4 changes: 4 additions & 0 deletions pkg/codegen/testing/test/sdk_driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,10 @@ var PulumiPulumiSDKTests = []*SDKTest{
Directory: "assets-and-archives",
Description: "A schema with assets and archives",
},
{
Directory: "any-resource",
Description: "A schema with arbitrary resources",
},
{
Directory: "regress-py-14012",
Description: "Regresses https://github.com/pulumi/pulumi/issues/14012",
Expand Down
34 changes: 34 additions & 0 deletions tests/testdata/codegen/any-resource/docs/_index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
---
title: "example"
title_tag: "example.example"
meta_desc: ""
layout: api
no_edit_this_page: true
---

<!-- WARNING: this file was generated by test. -->
<!-- Do not edit by hand unless you're certain you know what you are doing! -->



<h2 id="resources">Resources</h2>
<ul class="api">
<li><a href="provider/" title="Provider">Provider</a></li>
<li><a href="resourcewithresources/" title="ResourceWithResources">ResourceWithResources</a></li>
</ul>

<h2 id="functions">Functions</h2>
<ul class="api">
<li><a href="getresources/" title="GetResources">GetResources</a></li>
</ul>

<h2 id="package-details">Package Details</h2>
<dl class="package-details">
<dt>Repository</dt>
<dd><a href="">example </a></dd>
<dt>License</dt>
<dd></dd>
<dt>Version</dt>
<dd>0.0.1</dd>
</dl>

Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"emittedFiles": [
"_index.md",
"getresources/_index.md",
"provider/_index.md",
"resourcewithresources/_index.md"
]
}

0 comments on commit 130897d

Please sign in to comment.