pulumi/pkg
bors[bot] 480454009c
Merge #12804
12804: [pcl/python] Support range expressions that are of type output r=Zaid-Ajaj a=Zaid-Ajaj

# Description

This PR implements python program-gen support for range expressions that are of type Output<T> where T is a collection that should be iterated inside an apply call. 

It generates intermediate helper functions that contain the loop to create the resources, then references those functions in the apply call. (see code below)

I had to change/fix `rewriteTraversal` where it type-checked a traversal expression (i.e. `value.something`) after the casing of a member has changed to snake case (i.e. `someValue` -> `some_value`) and failed the program generation. Now it no longer type checks the resulting expression, since we rely on the bind phase to do the type checking.

<details>
    <summary>Example PCL</summary>

```terraform
resource "root" "range:index:Root" {}

// creating resources by iterating a property of type array(string) of another resource
resource "fromListOfStrings" "range:index:Example" {
  options {
    range = root.arrayOfString
  }

  someString = range.value
}

// creating resources by iterating a property of type map(string) of another resource
resource "fromMapOfStrings" "range:index:Example" {
  options {
    range = root.mapOfString
  }

  someString = "${range.key} ${range.value}"
}

// computed range list expression to create instances of range:index:Example resource
resource "fromComputedListOfStrings" "range:index:Example" {
  options {
    range = [
        root.mapOfString["hello"],
        root.mapOfString["world"]
    ]
  }

  someString = "${range.key} ${range.value}"
}

// computed range for expression to create instances of range:index:Example resource
resource "fromComputedForExpression" "range:index:Example" {
  options {
    range = [for value in root.arrayOfString : root.mapOfString[value]]
  }

  someString = "${range.key} ${range.value}"
}

```

</details>

<details>
<summary>Generated python code</summary>

```python
import pulumi
import pulumi_range as range

root = range.Root("root")
# creating resources by iterating a property of type array(string) of another resource
from_list_of_strings = []
def create_from_list_of_strings(range_body):
    for range in [{"key": k, "value": v} for [k, v] in enumerate(range_body)]:
        from_list_of_strings.append(range.Example(f"fromListOfStrings-{range['key']}", some_string=range["value"]))

root.array_of_string.apply(create_from_list_of_strings)
# creating resources by iterating a property of type map(string) of another resource
from_map_of_strings = []
def create_from_map_of_strings(range_body):
    for range in [{"key": k, "value": v} for [k, v] in enumerate(range_body)]:
        from_map_of_strings.append(range.Example(f"fromMapOfStrings-{range['key']}", some_string=f"{range['key']} {range['value']}"))

root.map_of_string.apply(create_from_map_of_strings)
# computed range list expression to create instances of range:index:Example resource
from_computed_list_of_strings = []
def create_from_computed_list_of_strings(range_body):
    for range in [{"key": k, "value": v} for [k, v] in enumerate(range_body)]:
        from_computed_list_of_strings.append(range.Example(f"fromComputedListOfStrings-{range['key']}", some_string=f"{range['key']} {range['value']}"))

pulumi.Output.all(
    root.map_of_string["hello"],
    root.map_of_string["world"]
).apply(create_from_computed_list_of_strings)
# computed range for expression to create instances of range:index:Example resource
from_computed_for_expression = []
def create_from_computed_for_expression(range_body):
    for range in [{"key": k, "value": v} for [k, v] in enumerate(range_body)]:
        from_computed_for_expression.append(range.Example(f"fromComputedForExpression-{range['key']}", some_string=f"{range['key']} {range['value']}"))

pulumi.Output.all(
    array_of_string=root.array_of_string,
    map_of_string=root.map_of_string
).apply(lambda resolved_outputs: create_from_computed_for_expression([resolved_outputs["map_of_string"][value] for value in resolved_outputs["array_of_string"]]))

```

</details>

## Checklist

<!--- Please provide details if the checkbox below is to be left unchecked. -->
- [x] I have added tests that prove my fix is effective or that my feature works
<!--- 
User-facing changes require a CHANGELOG entry.
-->
- [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change
<!--
If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud,
then the service should honor older versions of the CLI where this change would not exist.
You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add
it to the service.
-->
- [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version
  <!-- `@Pulumi` employees: If yes, you must submit corresponding changes in the service repo. -->


Co-authored-by: Zaid Ajaj <zaid.naom@gmail.com>
2023-05-03 17:17:28 +00:00
..
authhelpers make linter happy 2023-02-08 10:30:10 -08:00
backend Merge #12798 2023-05-03 00:19:27 +00:00
cmd/pulumi Fix parse diagnostics returning as diagnostics not error 2023-05-03 16:40:25 +01:00
codegen lint 2023-05-02 16:15:22 +02:00
engine mark default providers as always targeted 2023-05-02 11:37:30 -07:00
graph all: Assert => Assertf 2023-03-03 14:37:43 -08:00
importer all: Reformat with gofumpt 2023-03-03 09:00:24 -08:00
operations all: Reformat with gofumpt 2023-03-03 09:00:24 -08:00
resource Merge #12628 2023-05-02 21:34:11 +00:00
secrets all: Assert => Assertf 2023-03-03 14:37:43 -08:00
testing/integration Fix failure to load Pulumi.yaml when RelativeWorkDir provided. 2023-04-26 16:14:46 -04:00
util Fix convert pcl copy 2023-04-14 22:04:50 +01:00
version duplicate version to ensure linking is properly handled 2020-03-19 12:49:34 -07:00
README.md export codegen tests for internal use (#8928) 2022-02-07 12:10:04 +01:00
go.mod chore: post-release go.mod updates 2023-04-27 02:34:44 +00:00
go.sum feat(go/host): Support vendored dependencies 2023-04-24 09:49:16 -07: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.