pulumi/tests
Justin Van Patten 472e6bdd50
Allow Python dynamic providers to capture secrets (#15864)
As of https://github.com/pulumi/pulumi/pull/13315 (which shipped in
[v3.75.0](https://github.com/pulumi/pulumi/releases/tag/v3.75.0)),
`__provider` (the serialized provider string) is _always_ set to a
secret in the state. This can lead to poor performance when there are a
lot of dynamic resources and the serialized provider does not actually
have any secrets.

This change does two things:
1. Provides a way to opt-out of always serializing the provider as a
secret.
2. Allows Outputs to be captured during serialization of the provider,
which wasn't previously possible.

## 1. Opt-out of always serializing as secret

A new attribute, `serialize_as_secret_always`, can be set on a subclass
of `ResourceProvider` to opt-out of always serializing the provider as a
secret. If you know you don't have any secrets being serialized into the
provider and want to avoid the encryption overhead, you can set this
attribute to `False`.

```python
class MyProvider(ResourceProvider):
    serialize_as_secret_always = False

    def create(self, props):
        # Doesn't have any secrets that need encrypting
        ...
```

## 2. Allow Outputs to be captured

If you currently try to capture an `Output`, it fails when serializing
the provider with:

```
TypeError: cannot pickle '_asyncio.Future' object
```

This change allows Outputs to be captured/serialized for dynamic
providers, including secret Outputs.

This aligns Python dynamic providers with
[Node.js](https://github.com/pulumi/pulumi/pull/13329).

```python
import pulumi
from pulumi.dynamic import CreateResult, Resource, ResourceProvider

config = pulumi.Config()
password = config.require_secret("password")

class SimpleProvider(ResourceProvider):
    def create(self, props):
        # Need to use `password.get()` to get the underlying value of the secret from within the serialized code.
        # This simulates using this as a credential to talk to an external system.
        return CreateResult("0", { "authenticated": "200" if password.get() == "s3cret" else "401" })

class SimpleResource(Resource):
    authenticated: pulumi.Output[str]

    def __init__(self, name):
        super().__init__(SimpleProvider(), name, { "authenticated": None })


r = SimpleResource("foo")
pulumi.export("out", r.authenticated)
```

Note: In the above example, we didn't have to specify
`serialize_as_secret_always` since the default behavior is to always
serialize the provider as a secret. If we wanted to, we could have
specified `serialize_as_secret_always = False` and it still would have
serialized the provider as a secret, since it captured `password` which
is a secret Output. If `serialize_as_secret_always = False` was
specified and no secrets were captured, then the provider would not be
serialized as a secret.

We plan to recommend this approach to capturing secrets for both Node.js
and Python dynamic providers after this change.

Fixes #15539
2024-08-02 23:51:52 +00:00
..
benchmarks/go-alias-norm Bump go modules (#16051) 2024-04-25 14:30:00 +00:00
examples Update node sdk to use typescript definitions for grpc and protobufs. (#14415) 2023-12-04 15:22:44 +00:00
integration Allow Python dynamic providers to capture secrets (#15864) 2024-08-02 23:51:52 +00:00
testdata Use pulumi.Sprintf in program gen (#16852) 2024-08-01 09:24:25 +00:00
testprovider Add support for parameterized invokes in Python (#16832) 2024-07-29 14:51:07 +00:00
.gitignore ci: Use reduced smoke testing on Windows & macOS targets 2022-09-21 09:55:06 -07:00
README.md Rename "Smoke" test to "Acceptance" tests 2023-01-30 15:38:37 -05:00
about_test.go Run Environment.DeleteIfNotFailed after tests complete (#16730) 2024-07-23 10:37:01 +00:00
config_test.go [config] Re-enable TestConfigCommandsUsingEnvironments (#16817) 2024-07-30 21:34:14 +00:00
go.mod Changelog and go.mod updates for v3.127.0 (#16805) 2024-07-25 23:47:22 +00:00
go.sum Update Pulumi YAML to 1.9.1 (#16636) 2024-07-11 22:33:05 +00:00
history_test.go all: Reformat with gofumpt 2023-03-03 09:00:24 -08:00
login_test.go ci: radical idea - what if slow tests & no stdout makes GH consider runner dead? 2022-03-06 14:52:13 -08:00
main_test.go Rename filestate to DIY (#15314) 2024-01-30 15:53:10 +00:00
policy_new_test.go Revert "[policy] support premium policies (#13898)" (#14114) 2023-10-06 09:49:40 +00:00
preview_only_test.go Run Environment.DeleteIfNotFailed after tests complete (#16730) 2024-07-23 10:37:01 +00:00
remote_test.go Use new API for deployments (#15684) 2024-04-16 23:23:56 +00:00
roundtrip_test.go Run Environment.DeleteIfNotFailed after tests complete (#16730) 2024-07-23 10:37:01 +00:00
smoke_test.go Fix plugin run to pickup binary path correctly (#16249) 2024-05-22 14:39:13 +00:00
stack_test.go Run Environment.DeleteIfNotFailed after tests complete (#16730) 2024-07-23 10:37:01 +00:00

README.md

Integration Tests

This module provides integration tests for the Pulumi CLI.

The tests can be run via:

make test_all

Usage of Go build tags

In order to speed up integration tests in GitHub actions, Go build tags are used to conditionally compile the desired test cases.

// integration_nodejs_test.go
//go:build (nodejs || all) && !xplatform-acceptance

// integration_nodejs_acceptance_test.go
//go:build nodejs || all