pulumi/pkg/codegen
Zaid Ajaj f146c2e688
[PCL] Implement package descriptor blocks to support parameterized packages (#17589)
### Description

As part of fixing
https://github.com/pulumi/pulumi-converter-terraform/issues/186 we need
to be able to express resources and packages in PCL that are coming from
parameterized providers.

Today in PCL we will extract the package name from the token of a
resource definition and load that package based on the name (using
`LoadReference`) . For parameterized packages, this will not work
because the schema of the parameterized resource is only available after
we figure out which base provider is being parameterized and what the
parameters are.

In this PR we fix this problem by implementing top-level `package`
blocks that are full package descriptors that contain sufficient
information to load both classic resource plugins and parameterized
packages. The block will looks like:
```tf
package <name> {
  baseProviderName = <name>
  baseProviderVersion = <version>
  baseProviderDownloadUrl = <url>
  parameterization {
      name = <name>
      version = <version>
      value = <base64-encoded-value>
  }
}
```
Example of a package descriptors for a `terraform-provider` provider
parameterized with `hashicorp/random`:
```tf
package "random" {
    baseProviderName = "terraform-provider"
    baseProviderVersion = "0.0.27"
    parameterization {
        name = "random"
        version = "3.6.2"
        value = "eyJyZW1vdGUiOnsidXJsIjoicmVnaXN0cnkub3BlbnRvZnUub3JnL2hhc2hpY29ycC9yYW5kb20iLCJ2ZXJzaW9uIjoiMy42LjIifX0="
    }
}

resource "randomPet" "random:index/pet:Pet" { 
    length = 10 
}
``` 
Now when we extract the package name from `random:index/pet:Pet =>
random` we check if there is a package descriptor for it and use that
descriptor to load the package, parameterizing the base provider when
necessary. Otherwise if the package name doesn't have a descriptor, we
fallback to old package loader that expects plugin
`pulumi-resource-<packageName>` to be available in the plugin cache or
PATH.

These blocks are not mapped to specific `Program` nodes, they are read
from the AST after the PCL files have been parsed.
This information can be easily made available to `pcl.Program` if needed
since it has access to the source binder.

### Conformance Tests

With the ability to parameterize packages from a PCL program, we can
support conformance testing parameterized providers! I've implemented a
new test `l2-parameterized-resource` which implements a parameterized
provider that has a schema and runtime behaviour dictated by the values
it was parameterized with.


### Test this locally
You can test this locally with different parameterized providers, you
will need their parameter values which you can retrieve from the schema:
```
pulumi package get-schema terraform-provider hashicorp/random > random-schema.json
```
In `random-schema.json` you will find values you need in
`$.parameterization`

### Converted Code

The program above can be successfully converted to TypeScript for
example and generates the following:
```ts
import * as pulumi from "@pulumi/pulumi";
import * as random from "@pulumi/random";

const randomPet = new random.Pet("randomPet", {length: 10});
```
This program loaded the parameterized schema and used it to generate the
resource definition correctly.

However the following still need to be addressed:
- The `pulumi convert` doesn't generate the local SDKs are part of the
conversion. Doing this might make
https://github.com/pulumi/pulumi-converter-terraform/issues/186 a lot
easier than expected. cc @brandonpollack23
- Program generators do not understand parameterized packages so they
reference them like any of our provider sdk `"@pulumi/random": "3.6.2"`
(this is wrong because there is not such sdk on npm). They should expect
the SDK to be available locally and reference it via a relative path
 - ~We need a good way to (conformance) test these~ DONE 
2024-11-05 00:58:48 +00:00
..
cgstrings Enable goheader rule and add missing license headers (#15473) 2024-09-09 12:05:45 +00:00
convert Have `Host.Provider` accept a `PackageDescriptor` (#17244) 2024-09-12 13:17:30 +00:00
docs Enable some more linting rules (#17456) 2024-10-03 17:37:13 +00:00
dotnet Don't publish test code in `pkg/codegen` (#17517) 2024-10-09 11:09:54 +00:00
gen_program_test Don't publish test code in `pkg/codegen` (#17517) 2024-10-09 11:09:54 +00:00
go Don't publish test code in `pkg/codegen` (#17517) 2024-10-09 11:09:54 +00:00
hcl2 [go/conformance] Fix l2-resource-primitives test (#17332) 2024-09-26 05:15:38 +00:00
nodejs Don't publish test code in `pkg/codegen` (#17517) 2024-10-09 11:09:54 +00:00
pcl [PCL] Implement package descriptor blocks to support parameterized packages (#17589) 2024-11-05 00:58:48 +00:00
python Add a conformance test for preserving map keys (#17350) 2024-10-11 13:34:46 +00:00
report Enable goheader rule and add missing license headers (#15473) 2024-09-09 12:05:45 +00:00
schema [PCL] Implement package descriptor blocks to support parameterized packages (#17589) 2024-11-05 00:58:48 +00:00
testing Add a conformance test for preserving map keys (#17350) 2024-10-11 13:34:46 +00:00
README.md Document code generation concepts (#17162) 2024-09-05 13:12:59 +00:00
docs.go Support "lifting" single-valued method returns to their return type (#8111) 2021-10-01 11:33:02 -07:00
docs_test.go ci: radical idea - what if slow tests & no stdout makes GH consider runner dead? 2022-03-06 14:52:13 -08:00
programs.md Document code generation concepts (#17162) 2024-09-05 13:12:59 +00:00
sdks.md Document code generation concepts (#17162) 2024-09-05 13:12:59 +00:00
utilities.go Use slice.Prealloc instead of make([]T, 0, ...) 2023-06-29 11:27:50 +01:00
utilities_test.go ci: radical idea - what if slow tests & no stdout makes GH consider runner dead? 2022-03-06 14:52:13 -08:00
utilities_types.go Enable goheader rule and add missing license headers (#15473) 2024-09-09 12:05:45 +00:00

README.md

(codegen)= (crosscode)=

Code generation

Code generation is essential to Pulumi's ability to support both a variety of programming languages and a variety of cloud providers. This package defines the core components of Pulumi's code generation functionality (known as Pulumi CrossCode). At a high level, code generation is used to manage three categories of output: SDKs, programs, and documentation. At a lower level, these all make use of a number of shared concepts such as schema and Pulumi Configuration Language (PCL).

:::{toctree} :maxdepth: 1 :titlesonly:

/pkg/codegen/sdks.md /pkg/codegen/programs.md /pkg/codegen/docs/README /pkg/codegen/schema/README /pkg/codegen/pcl/README :::