pulumi/pkg
Zaid Ajaj b3546c9fa4
[cli/import] Fix undefined variable errors in code generation when imported resources use a parent or provider (#16786)
Fixes #15410 Fixes #13339

## Problem Context

When using `pulumi import` we generate code snippets for the resources
that were imported. Sometimes the user specifies `--parent
parentName=URN` or `--provider providerName=URN` which tweak the parent
or provider that the imported resources uses. When using `--parent` or
`--provider` the generated code emits a resource option `parent =
parentName` (in case of using `--parent`) where `parentName` is an
unbound variable.

Usually unbound variables would result in a _bind_ error such as `error:
undefined variable parentName` when type-checking the program however in
the import code generation we specify the bind option
`pcl.AllowMissingVariables` which turns that unbound variable errors
into warnings and code generation can continue to emit code.

This is all good and works as expected. However in the issues linked
above, we do get an _error_ for unbound variables in generated code even
though we specified `AllowMissingVariables`.

The problem as it turns out is when we are trying to generate code via
dynamically loaded `LangaugeRuntime` plugins. Specifically for NodeJS
and Python, we load `pulumi-language-nodejs` or `pulumi-language-python`
and call `GenerateProgram` to get the generated program. That function
`GenerateProgram` takes the text _SOURCE_ of the a bound program (one
that was bound using option `AllowMissingVariables`) and re-binds again
inside the implementation of the language plugin. The second time we
bind the program, we don't pass it the option `AllowMissingVariables`
and so it fails with `unboud variable` error.

I've verified that the issue above don't repro when doing an import for
dotnet (probably same for java/yaml) because we use the statically
linked function `codegen/{lang}/gen_program.go -> GenerateProgram`

## Solution

The problem can be solved by propagating the bind options from the CLI
to the language hosts during import so that they know how to bind the
program. I've extended the gRPC interface in `GenerateProgramRequest`
with a property `Strict` which follows the same logic from `pulumi
convert --strict` and made it such that the import command sends
`strict=false` to the language plugins when doing `GenerateProgram`.
This is consistent with `GenerateProject` that uses the same flag. When
`strict=false` we use `pcl.NonStrictBindOptions()` which includes
`AllowMissingVariables` .

## Repro

Once can test the before and after behaviour by running `pulumi up
--yes` on the following TypeScript program:
```ts
import * as pulumi from "@pulumi/pulumi";
import * as random from "@pulumi/random";

export class MyComponent extends pulumi.ComponentResource {
    public readonly randomPetId: pulumi.Output<string>;
    constructor(name: string, opts?: pulumi.ComponentResourceOptions) {
        super("example:index:MyComponent", name, {}, opts);

        const randomPet = new random.RandomPet("randomPet", {}, { 
            parent: this 
        });

        this.randomPetId = randomPet.id;
        this.registerOutputs({
            randomPetId: randomPet.id,
        });
    }
}

const example = new MyComponent("example");
export const randomPetId = example.randomPetId;
``` 
Then running `pulumi import -f import.json` where `import.json` contains
a resource to be imported under the created component (stack=`dev`,
project=`importerrors`)
```ts
{
    "nameTable": {
        "parentComponent": "urn:pulumi:dev::importerrors::example:index:MyComponent::example"
    },
    "resources": [
        {
            "type": "random:index/randomPassword:RandomPassword",
            "name": "randomPassword",
            "id": "supersecret",
            "parent": "parentComponent"
        }
    ]
}
```
Running this locally I get the following generated code (which
previously failed to generate)
```ts
import * as pulumi from "@pulumi/pulumi";
import * as random from "@pulumi/random";

const randomPassword = new random.RandomPassword("randomPassword", {
    length: 11,
    lower: true,
    number: true,
    numeric: true,
    special: true,
    upper: true,
}, {
    parent: parentComponent,
});
```
2024-07-25 13:53:44 +00:00
..
asset Move some asset code to pkg (#15162) 2024-01-17 11:30:37 +00:00
authhelpers Add tests for gcpauth pkg (#13926) 2023-09-13 11:27:03 +00:00
backend Don't set `PendingReplacement` until `Delete` succeeds (#16699) 2024-07-18 12:27:06 +00:00
cmd/pulumi [cli/import] Fix undefined variable errors in code generation when imported resources use a parent or provider (#16786) 2024-07-25 13:53:44 +00:00
codegen [cli/import] Fix undefined variable errors in code generation when imported resources use a parent or provider (#16786) 2024-07-25 13:53:44 +00:00
display Move sdk/go/common/display to /pkg/display (#13954) 2023-09-18 11:01:28 +00:00
engine Fix default provider names for parameterized providers (#16785) 2024-07-25 12:56:17 +00:00
graph Adds a flag to graph command to insert fragment (#14858) 2024-01-08 22:03:08 +00:00
importer [cli/import] Fix undefined variable errors in code generation when imported resources use a parent or provider (#16786) 2024-07-25 13:53:44 +00:00
operations Move resource.URN to urn.URN (#15689) 2024-03-14 15:28:32 +00:00
resource [cli/import] Fix undefined variable errors in code generation when imported resources use a parent or provider (#16786) 2024-07-25 13:53:44 +00:00
secrets cloud backend test: retry creating secrets manager (#16494) 2024-06-27 04:33:56 +00:00
testing/integration Clean up PULUMI_HOME after program test (#16663) 2024-07-15 13:03:27 +00:00
util [cli/plugin] Fix plugin install command when plugin type is tool (#16407) 2024-06-17 13:25:57 +00:00
version duplicate version to ensure linking is properly handled 2020-03-19 12:49:34 -07:00
workspace Refactor: move plugin kind to apitype (#15946) 2024-04-25 17:30:30 +00:00
README.md export codegen tests for internal use (#8928) 2022-02-07 12:10:04 +01:00
go.mod Changelog and go.mod updates for v3.126.0 (#16761) 2024-07-23 04:38:13 +00:00
go.sum Update Pulumi YAML to 1.9.1 (#16636) 2024-07-11 22:33:05 +00:00

README.md

pulumi/pkg

While pulumi/sdk maintains strict backwards compatibility guarantees, code under pkg/ is handled more informally: while breaking changes are still discouraged they may happen when they make sense.