These changes add initial support for the construction of remote
components. For now, this support is limited to the NodeJS SDK;
follow-up changes will implement support for the other SDKs.
Remote components are component resources that are constructed and
managed by plugins rather than by Pulumi programs. In this sense, they
are a bit like cloud resources, and are supported by the same
distribution and plugin loading mechanisms and described by the same
schema system.
The construction of a remote component is initiated by a
`RegisterResourceRequest` with the new `remote` field set to `true`.
When the resource monitor receives such a request, it loads the plugin
that implements the component resource and calls the `Construct`
method added to the resource provider interface as part of these
changes. This method accepts the information necessary to construct the
component and its children: the component's name, type, resource
options, inputs, and input dependencies. It is responsible for
dispatching to the appropriate component factory to create the
component, then returning its URN, resolved output properties, and
output property dependencies. The dependency information is necessary to
support features such as delete-before-replace, which rely on precise
dependency information for custom resources.
These changes also add initial support for more conveniently
implementing resource providers in NodeJS. The interface used to
implement such a provider is similar to the dynamic provider interface
(and may be unified with that interface in the future).
An example of a NodeJS program constructing a remote component resource
also implemented in NodeJS can be found in
`tests/construct_component/nodejs`.
This is the core of #2430.
`Output<T>` now tracks if an output represents secret data or
not. When secret, it is marshalled as a secret value and we signal to
the resource monitor that it is safe to return secret values to us.
The `pulumi` module exports a new functiion, `secret<T>` which works
in the same was a `output<T>` except that it marks the underlying
output as a secret.
This secret bit flows as you would expect across `all`'s and
`apply`'s.
Note that in process memory, the raw value is still present, when you
run an `apply` for a secret output, you are able to see the raw
value. In addition, if you capture a secret output with a lambda, the
raw value will be present in the captured source text.
This update includes several changes to core `@pulumi/pulumi` constructs that will not play nicely
in side-by-side applications that pull in prior versions of this package. As such, we are rev'ing
the minor version of the package from 0.16 to 0.17. Recent version of `pulumi` will now detect,
and warn, if different versions of `@pulumi/pulumi` are loaded into the same application. If you
encounter this warning, it is recommended you move to versions of the `@pulumi/...` packages that
are compatible. i.e. keep everything on 0.16.x until you are ready to move everything to 0.17.x.
### Improvements
- `Output<T>` now 'lifts' property members from the value it wraps, simplifying common coding patterns. Note: this wrapping only happens for POJO values, not `Output<Resource>`s.
- Depending on a **Component** Resource will now depend on all other Resources parented by that
Resource. This will help out the programming model for Component Resources as your consumers can
just depend on a Component and have that automatically depend on all the child Resources created
by that Component. Note: this does not apply to a **Custom** resource. Depending on a
CustomResource will still only wait on that single resource being created, not any other Resources
that consider that CustomResource to be a parent.
Suppose you have `pulumi.output(o).apply(foo)`, with `o` being type `O`
and `foo` taking type `O` as an argument. If `O` is a type with methods,
this will fail to type check.
The reason is that `UnwrappedObject<T>` (as well as the other
`Unwrapped*` types) will recursively wrap the types of field values
whose type was `Function`. Since `UnwrappedObject<Function>` is not the
same as `Function`, we fail to type check. Note that this does not
result in an actual "boxed" object -- this is purely at the type level.
This commit resolves this by considering `Function` a primitive type,
which will cause us to not wrap the types of field values, instead
leaving them as `Function`.