Compare commits

...

8 commits

Author SHA1 Message Date
Justin Van Patten ec076ee0f4 Update CHANGELOG_PENDING.md 2021-11-12 16:51:30 -08:00
Justin Van Patten 52f3437100 [sdk/dotnet] Don't send deps maps when using output values 2021-11-12 16:13:25 -08:00
Justin Van Patten fca55516e6 [sdk/go] Don't send deps maps when using output values 2021-11-12 16:13:18 -08:00
Justin Van Patten 9a5bd22b4d [sdk/nodejs] Don't send deps maps when using output values 2021-11-12 15:53:04 -08:00
Justin Van Patten 14f03a7b0e [sdk/python] Don't send deps maps when using output values 2021-11-12 15:53:04 -08:00
Justin Van Patten 97daa0a34a [sdk/go] Minor optimization in Go provider
First check for empty deps before checking to see if the gathered dependencies are equivalent to the specified dependencies map.
2021-11-12 15:52:29 -08:00
Justin Van Patten 7487e99d94 Deprecate deps maps when using output values
When output values are being sent to a provider, there's no need to also send the dependencies map, because the output values themselves contain the dependencies. This allows for a simpler implementation in the provider.
2021-11-12 15:13:45 -08:00
Justin Van Patten 7888623aca Add hasOutputs to RegisterRequestRequest
This can be set by an SDK to indicate the inputs were serialized with output values.
2021-11-12 15:13:45 -08:00
15 changed files with 348 additions and 166 deletions

View file

@ -10,6 +10,9 @@
- [sdk/dotnet] - Marshal output values. - [sdk/dotnet] - Marshal output values.
[#8316](https://github.com/pulumi/pulumi/pull/8316) [#8316](https://github.com/pulumi/pulumi/pull/8316)
- Deprecate use of dependencies maps when sending output values.
[#8410](https://github.com/pulumi/pulumi/pull/8410)
### Bug Fixes ### Bug Fixes
- [engine] - Compute dependents correctly during targeted deletes. - [engine] - Compute dependents correctly during targeted deletes.

View file

@ -631,13 +631,16 @@ func (rm *resmon) Call(ctx context.Context, req *pulumirpc.CallRequest) (*pulumi
return nil, errors.Wrapf(err, "failed to unmarshal %v args", tok) return nil, errors.Wrapf(err, "failed to unmarshal %v args", tok)
} }
argDependencies := map[resource.PropertyKey][]resource.URN{} var argDependencies map[resource.PropertyKey][]resource.URN
for name, deps := range req.GetArgDependencies() { if len(req.GetArgDependencies()) > 0 {
urns := make([]resource.URN, len(deps.Urns)) argDependencies = map[resource.PropertyKey][]resource.URN{}
for i, urn := range deps.Urns { for name, deps := range req.GetArgDependencies() {
urns[i] = resource.URN(urn) urns := make([]resource.URN, len(deps.Urns))
for i, urn := range deps.Urns {
urns[i] = resource.URN(urn)
}
argDependencies[resource.PropertyKey(name)] = urns
} }
argDependencies[resource.PropertyKey(name)] = urns
} }
info := plugin.CallInfo{ info := plugin.CallInfo{
@ -853,6 +856,7 @@ func (rm *resmon) RegisterResource(ctx context.Context,
replaceOnChanges := req.GetReplaceOnChanges() replaceOnChanges := req.GetReplaceOnChanges()
id := resource.ID(req.GetImportId()) id := resource.ID(req.GetImportId())
customTimeouts := req.GetCustomTimeouts() customTimeouts := req.GetCustomTimeouts()
hasOutputs := req.GetHasOutputs()
// Custom resources must have a three-part type so that we can 1) identify if they are providers and 2) retrieve the // Custom resources must have a three-part type so that we can 1) identify if they are providers and 2) retrieve the
// provider responsible for managing a particular resource (based on the type's Package). // provider responsible for managing a particular resource (based on the type's Package).
@ -913,7 +917,7 @@ func (rm *resmon) RegisterResource(ctx context.Context,
KeepResources: true, KeepResources: true,
// To initially scope the use of this new feature, we only keep output values when unmarshaling // To initially scope the use of this new feature, we only keep output values when unmarshaling
// properties for RegisterResource (when remote is true for multi-lang components) and Call. // properties for RegisterResource (when remote is true for multi-lang components) and Call.
KeepOutputValues: remote, KeepOutputValues: remote || hasOutputs,
}) })
if err != nil { if err != nil {
return nil, err return nil, err
@ -993,11 +997,14 @@ func (rm *resmon) RegisterResource(ctx context.Context,
// Invoke the provider's Construct RPC method. // Invoke the provider's Construct RPC method.
options := plugin.ConstructOptions{ options := plugin.ConstructOptions{
Aliases: aliases, Aliases: aliases,
Dependencies: dependencies, Dependencies: dependencies,
Protect: protect, Protect: protect,
PropertyDependencies: propertyDependencies, Providers: providerRefs,
Providers: providerRefs, }
if !hasOutputs {
// Only include property dependencies when we don't have output values in the properties.
options.PropertyDependencies = propertyDependencies
} }
constructResult, err := provider.Construct(rm.constructInfo, t, name, parent, props, options) constructResult, err := provider.Construct(rm.constructInfo, t, name, parent, props, options)
if err != nil { if err != nil {

View file

@ -52,11 +52,13 @@ namespace Pulumi
argsDict = argsDict.SetItem("__self__", self); argsDict = argsDict.SetItem("__self__", self);
} }
var keepOutputs = await MonitorSupportsOutputValues().ConfigureAwait(false);
var (serialized, argDependencies) = await SerializeFilteredPropertiesAsync( var (serialized, argDependencies) = await SerializeFilteredPropertiesAsync(
$"call:{token}", $"call:{token}",
argsDict, _ => true, argsDict, _ => true,
keepResources: true, keepResources: true,
keepOutputValues: await MonitorSupportsOutputValues().ConfigureAwait(false)).ConfigureAwait(false); keepOutputValues: keepOutputs).ConfigureAwait(false);
Log.Debug($"Call RPC prepared: token={token}" + Log.Debug($"Call RPC prepared: token={token}" +
(_excessiveDebugOutput ? $", obj={serialized}" : "")); (_excessiveDebugOutput ? $", obj={serialized}" : ""));
@ -84,13 +86,17 @@ namespace Pulumi
Args = serialized, Args = serialized,
}; };
// Add arg dependencies to the request. // Only include the arg dependencies map in the request when *not* keeping output values.
foreach (var (argName, directDependencies) in argDependencies) // When keeping output values, the dependencies will already exist within the args.
if (!keepOutputs)
{ {
var urns = await GetAllTransitivelyReferencedResourceUrnsAsync(directDependencies).ConfigureAwait(false); foreach (var (argName, directDependencies) in argDependencies)
var deps = new CallRequest.Types.ArgumentDependencies(); {
deps.Urns.AddRange(urns); var urns = await GetAllTransitivelyReferencedResourceUrnsAsync(directDependencies).ConfigureAwait(false);
request.ArgDependencies.Add(argName, deps); var deps = new CallRequest.Types.ArgumentDependencies();
deps.Urns.AddRange(urns);
request.ArgDependencies.Add(argName, deps);
}
} }
// Kick off the call. // Kick off the call.

View file

@ -21,7 +21,10 @@ namespace Pulumi
var label = $"resource:{name}[{type}]"; var label = $"resource:{name}[{type}]";
Log.Debug($"Registering resource start: t={type}, name={name}, custom={custom}, remote={remote}"); Log.Debug($"Registering resource start: t={type}, name={name}, custom={custom}, remote={remote}");
var request = CreateRegisterResourceRequest(type, name, custom, remote, options); // Keep track of whether we've kept output values when serializing.
var hasOutputs = remote && await MonitorSupportsOutputValues().ConfigureAwait(false);
var request = CreateRegisterResourceRequest(type, name, custom, remote, options, hasOutputs);
Log.Debug($"Preparing resource: t={type}, name={name}, custom={custom}, remote={remote}"); Log.Debug($"Preparing resource: t={type}, name={name}, custom={custom}, remote={remote}");
var prepareResult = await PrepareResourceAsync(label, resource, custom, remote, args, options).ConfigureAwait(false); var prepareResult = await PrepareResourceAsync(label, resource, custom, remote, args, options).ConfigureAwait(false);
@ -65,7 +68,7 @@ namespace Pulumi
} }
private static RegisterResourceRequest CreateRegisterResourceRequest( private static RegisterResourceRequest CreateRegisterResourceRequest(
string type, string name, bool custom, bool remote, ResourceOptions options) string type, string name, bool custom, bool remote, ResourceOptions options, bool hasOutputs)
{ {
var customOpts = options as CustomResourceOptions; var customOpts = options as CustomResourceOptions;
var deleteBeforeReplace = customOpts?.DeleteBeforeReplace; var deleteBeforeReplace = customOpts?.DeleteBeforeReplace;
@ -89,6 +92,7 @@ namespace Pulumi
Update = TimeoutString(options.CustomTimeouts?.Update), Update = TimeoutString(options.CustomTimeouts?.Update),
}, },
Remote = remote, Remote = remote,
HasOutputs = hasOutputs,
}; };
if (customOpts != null) if (customOpts != null)

View file

@ -20,6 +20,7 @@ import (
"fmt" "fmt"
"io" "io"
"os" "os"
"sort"
"strings" "strings"
"github.com/blang/semver" "github.com/blang/semver"
@ -1125,14 +1126,24 @@ func (p *provider) Construct(info ConstructInfo, typ tokens.Type, name tokens.QN
dependencies[i] = string(dep) dependencies[i] = string(dep)
} }
// Marshal the property dependencies. // If the provider accepts outputs, the marshaled inputs will have output values with dependencies,
inputDependencies := map[string]*pulumirpc.ConstructRequest_PropertyDependencies{} // so there's no need to specify the dependencies map.
for name, dependencies := range options.PropertyDependencies { var inputDependencies map[string]*pulumirpc.ConstructRequest_PropertyDependencies
urns := make([]string, len(dependencies)) if !p.acceptOutputs {
for i, urn := range dependencies { // If the provider doesn't accept outputs, pass along the dependencies map.
urns[i] = string(urn) dependenciesMap := options.PropertyDependencies
if len(dependenciesMap) == 0 {
// If the dependencies map is empty, "polyfill" it based on dependencies gathered from the inputs.
dependenciesMap = gatherDependenciesMap(inputs)
}
inputDependencies = make(map[string]*pulumirpc.ConstructRequest_PropertyDependencies, len(dependenciesMap))
for name, dependencies := range dependenciesMap {
urns := make([]string, len(dependencies))
for i, urn := range dependencies {
urns[i] = string(urn)
}
inputDependencies[string(name)] = &pulumirpc.ConstructRequest_PropertyDependencies{Urns: urns}
} }
inputDependencies[string(name)] = &pulumirpc.ConstructRequest_PropertyDependencies{Urns: urns}
} }
// Marshal the config. // Marshal the config.
@ -1367,14 +1378,24 @@ func (p *provider) Call(tok tokens.ModuleMember, args resource.PropertyMap, info
return CallResult{}, err return CallResult{}, err
} }
// Marshal the arg dependencies. // If the provider accepts outputs, the marshaled args will have output values with dependencies,
argDependencies := map[string]*pulumirpc.CallRequest_ArgumentDependencies{} // so there's no need to specify the dependencies map.
for name, dependencies := range options.ArgDependencies { var argDependencies map[string]*pulumirpc.CallRequest_ArgumentDependencies
urns := make([]string, len(dependencies)) if !p.acceptOutputs {
for i, urn := range dependencies { // If the provider doesn't accept outputs, pass along the dependencies map.
urns[i] = string(urn) dependenciesMap := options.ArgDependencies
if len(dependenciesMap) == 0 {
// If the dependencies map is empty, "polyfill" it based on dependencies gathered from the args.
dependenciesMap = gatherDependenciesMap(args)
}
argDependencies = make(map[string]*pulumirpc.CallRequest_ArgumentDependencies, len(dependenciesMap))
for name, dependencies := range dependenciesMap {
urns := make([]string, len(dependencies))
for i, urn := range dependencies {
urns[i] = string(urn)
}
argDependencies[string(name)] = &pulumirpc.CallRequest_ArgumentDependencies{Urns: urns}
} }
argDependencies[string(name)] = &pulumirpc.CallRequest_ArgumentDependencies{Urns: urns}
} }
// Marshal the config. // Marshal the config.
@ -1613,3 +1634,55 @@ func decorateProviderSpans(span opentracing.Span, method string, req, resp inter
span.SetTag("pulumi-decorator", req.(*pulumirpc.InvokeRequest).Tok) span.SetTag("pulumi-decorator", req.(*pulumirpc.InvokeRequest).Tok)
} }
} }
// gatherDependenciesMap deeply gathers dependencies in the input's output values and resource
// references to "polyfill" a dependencies map for providers that don't accept output values.
func gatherDependenciesMap(inputs resource.PropertyMap) map[resource.PropertyKey][]resource.URN {
type urnSet = map[resource.URN]struct{}
add := func(s urnSet, urn resource.URN) {
s[urn] = struct{}{}
}
sortedValues := func(s urnSet) []resource.URN {
sorted := make([]resource.URN, 0, len(s))
for k := range s {
sorted = append(sorted, k)
}
sort.Slice(sorted, func(i, j int) bool { return sorted[i] < sorted[j] })
return sorted
}
var gatherDeps func(v resource.PropertyValue, deps urnSet)
gatherDeps = func(v resource.PropertyValue, deps urnSet) {
switch {
case v.IsSecret():
gatherDeps(v.SecretValue().Element, deps)
case v.IsComputed():
gatherDeps(v.Input().Element, deps)
case v.IsOutput():
for _, urn := range v.OutputValue().Dependencies {
add(deps, urn)
}
gatherDeps(v.OutputValue().Element, deps)
case v.IsResourceReference():
add(deps, v.ResourceReferenceValue().URN)
case v.IsArray():
for _, e := range v.ArrayValue() {
gatherDeps(e, deps)
}
case v.IsObject():
for _, e := range v.ObjectValue() {
gatherDeps(e, deps)
}
}
}
result := make(map[resource.PropertyKey][]resource.URN, len(inputs))
for k, v := range inputs {
deps := urnSet{}
gatherDeps(v, deps)
result[k] = sortedValues(deps)
}
return result
}

View file

@ -403,21 +403,25 @@ func (ctx *Context) Call(tok string, args Input, output Output, self Resource, o
return nil, fmt.Errorf("marshaling args: %w", err) return nil, fmt.Errorf("marshaling args: %w", err)
} }
// Convert the arg dependencies map for RPC and remove duplicates. // Only include the arg dependencies map in the request when the monitor does *not* support output values.
rpcArgDeps := make(map[string]*pulumirpc.CallRequest_ArgumentDependencies) // When the monitor *does* support output values, the dependencies will already exist within the args.
for k, deps := range argDeps { var rpcArgDeps map[string]*pulumirpc.CallRequest_ArgumentDependencies
sort.Slice(deps, func(i, j int) bool { return deps[i] < deps[j] }) if !ctx.keepOutputValues {
rpcArgDeps = make(map[string]*pulumirpc.CallRequest_ArgumentDependencies, len(argDeps))
for k, deps := range argDeps {
sort.Slice(deps, func(i, j int) bool { return deps[i] < deps[j] })
urns := make([]string, 0, len(deps)) urns := make([]string, 0, len(deps))
for i, d := range deps { for i, d := range deps {
if i > 0 && urns[i-1] == string(d) { if i > 0 && urns[i-1] == string(d) {
continue continue
}
urns = append(urns, string(d))
} }
urns = append(urns, string(d))
}
rpcArgDeps[k] = &pulumirpc.CallRequest_ArgumentDependencies{ rpcArgDeps[k] = &pulumirpc.CallRequest_ArgumentDependencies{
Urns: urns, Urns: urns,
}
} }
} }
@ -822,6 +826,7 @@ func (ctx *Context) registerResource(
Version: inputs.version, Version: inputs.version,
Remote: remote, Remote: remote,
ReplaceOnChanges: inputs.replaceOnChanges, ReplaceOnChanges: inputs.replaceOnChanges,
HasOutputs: inputs.hasOutputs,
}) })
if err != nil { if err != nil {
logging.V(9).Infof("RegisterResource(%s, %s): error: %v", t, name, err) logging.V(9).Infof("RegisterResource(%s, %s): error: %v", t, name, err)
@ -1165,6 +1170,7 @@ type resourceInputs struct {
additionalSecretOutputs []string additionalSecretOutputs []string
version string version string
replaceOnChanges []string replaceOnChanges []string
hasOutputs bool
} }
// prepareResourceInputs prepares the inputs for a resource operation, shared between read and register. // prepareResourceInputs prepares the inputs for a resource operation, shared between read and register.
@ -1184,15 +1190,17 @@ func (ctx *Context) prepareResourceInputs(res Resource, props Input, t string, o
return nil, fmt.Errorf("marshaling properties: %w", err) return nil, fmt.Errorf("marshaling properties: %w", err)
} }
// To initially scope the use of this new feature, we only keep output values when
// remote is true (for multi-lang components).
keepOutputs := remote && ctx.keepOutputValues
// Marshal all properties for the RPC call. // Marshal all properties for the RPC call.
rpcProps, err := plugin.MarshalProperties( rpcProps, err := plugin.MarshalProperties(
resolvedProps, resolvedProps,
ctx.withKeepOrRejectUnknowns(plugin.MarshalOptions{ ctx.withKeepOrRejectUnknowns(plugin.MarshalOptions{
KeepSecrets: true, KeepSecrets: true,
KeepResources: ctx.keepResources, KeepResources: ctx.keepResources,
// To initially scope the use of this new feature, we only keep output values when KeepOutputValues: keepOutputs,
// remote is true (for multi-lang components).
KeepOutputValues: remote && ctx.keepOutputValues,
})) }))
if err != nil { if err != nil {
return nil, fmt.Errorf("marshaling properties: %w", err) return nil, fmt.Errorf("marshaling properties: %w", err)
@ -1250,6 +1258,7 @@ func (ctx *Context) prepareResourceInputs(res Resource, props Input, t string, o
additionalSecretOutputs: resOpts.additionalSecretOutputs, additionalSecretOutputs: resOpts.additionalSecretOutputs,
version: state.version, version: state.version,
replaceOnChanges: resOpts.replaceOnChanges, replaceOnChanges: resOpts.replaceOnChanges,
hasOutputs: keepOutputs,
}, nil }, nil
} }

View file

@ -215,6 +215,13 @@ func (ci constructInput) Dependencies(ctx *Context) []Resource {
return result return result
} }
// HasEquivalentDependencies returns true if the deps are equal to or a subset of the gathered nested dependencies.
func (ci constructInput) HasEquivalentDependencies() bool {
deps := urnSet{}
gatherDeps(ci.value, deps)
return deps.contains(ci.deps)
}
// constructInputsMap returns the inputs as a Map. // constructInputsMap returns the inputs as a Map.
func constructInputsMap(ctx *Context, inputs map[string]interface{}) (Map, error) { func constructInputsMap(ctx *Context, inputs map[string]interface{}) (Map, error) {
result := make(Map, len(inputs)) result := make(Map, len(inputs))
@ -577,13 +584,9 @@ func constructInputsCopyTo(ctx *Context, inputs map[string]interface{}, args int
continue continue
} }
// Find all nested dependencies. // If there aren't any dependencies or the dependencies are equivalent, we don't necessarily
deps := urnSet{} // need to create a top-level output for the property.
gatherDeps(ci.value, deps) if len(ci.deps) == 0 || ci.HasEquivalentDependencies() {
// If the top-level property dependencies are equal to (or a subset of) the gathered nested
// dependencies, we don't necessarily need to create a top-level output for the property.
if deps.contains(ci.deps) {
if err := copyInputTo(ctx, ci.value, fieldV); err != nil { if err := copyInputTo(ctx, ci.value, fieldV); err != nil {
return fmt.Errorf("copying input %q: %w", k, err) return fmt.Errorf("copying input %q: %w", k, err)
} }

View file

@ -1285,7 +1285,8 @@ proto.pulumirpc.RegisterResourceRequest.toObject = function(includeInstance, msg
remote: jspb.Message.getBooleanFieldWithDefault(msg, 20, false), remote: jspb.Message.getBooleanFieldWithDefault(msg, 20, false),
acceptresources: jspb.Message.getBooleanFieldWithDefault(msg, 21, false), acceptresources: jspb.Message.getBooleanFieldWithDefault(msg, 21, false),
providersMap: (f = msg.getProvidersMap()) ? f.toObject(includeInstance, undefined) : [], providersMap: (f = msg.getProvidersMap()) ? f.toObject(includeInstance, undefined) : [],
replaceonchangesList: (f = jspb.Message.getRepeatedField(msg, 23)) == null ? undefined : f replaceonchangesList: (f = jspb.Message.getRepeatedField(msg, 23)) == null ? undefined : f,
hasoutputs: jspb.Message.getBooleanFieldWithDefault(msg, 24, false)
}; };
if (includeInstance) { if (includeInstance) {
@ -1420,6 +1421,10 @@ proto.pulumirpc.RegisterResourceRequest.deserializeBinaryFromReader = function(m
var value = /** @type {string} */ (reader.readString()); var value = /** @type {string} */ (reader.readString());
msg.addReplaceonchanges(value); msg.addReplaceonchanges(value);
break; break;
case 24:
var value = /** @type {boolean} */ (reader.readBool());
msg.setHasoutputs(value);
break;
default: default:
reader.skipField(); reader.skipField();
break; break;
@ -1606,6 +1611,13 @@ proto.pulumirpc.RegisterResourceRequest.serializeBinaryToWriter = function(messa
f f
); );
} }
f = message.getHasoutputs();
if (f) {
writer.writeBool(
24,
f
);
}
}; };
@ -2510,6 +2522,24 @@ proto.pulumirpc.RegisterResourceRequest.prototype.clearReplaceonchangesList = fu
}; };
/**
* optional bool hasOutputs = 24;
* @return {boolean}
*/
proto.pulumirpc.RegisterResourceRequest.prototype.getHasoutputs = function() {
return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 24, false));
};
/**
* @param {boolean} value
* @return {!proto.pulumirpc.RegisterResourceRequest} returns this
*/
proto.pulumirpc.RegisterResourceRequest.prototype.setHasoutputs = function(value) {
return jspb.Message.setProto3BooleanField(this, 24, value);
};
/** /**
* List of repeated fields within this message type. * List of repeated fields within this message type.

View file

@ -29,6 +29,7 @@ import {
getMonitor, getMonitor,
rpcKeepAlive, rpcKeepAlive,
terminateRpcs, terminateRpcs,
monitorSupportsOutputValues,
} from "./settings"; } from "./settings";
import { DependencyResource, ProviderResource, Resource } from "../resource"; import { DependencyResource, ProviderResource, Resource } from "../resource";
@ -400,16 +401,20 @@ async function createCallRequest(tok: string, serialized: Record<string, any>,
req.setProvider(provider); req.setProvider(provider);
req.setVersion(version || ""); req.setVersion(version || "");
const argDependencies = req.getArgdependenciesMap(); // Only include `argDependencies` in the request when the monitor does *not* support output values.
for (const [key, propertyDeps] of serializedDeps) { // When the monitor *does* support output values, the dependencies will already exist within the args.
const urns = new Set<string>(); if (!await monitorSupportsOutputValues()) {
for (const dep of propertyDeps) { const argDependencies = req.getArgdependenciesMap();
const urn = await dep.urn.promise(); for (const [key, propertyDeps] of serializedDeps) {
urns.add(urn); const urns = new Set<string>();
for (const dep of propertyDeps) {
const urn = await dep.urn.promise();
urns.add(urn);
}
const deps = new providerproto.CallRequest.ArgumentDependencies();
deps.setUrnsList(Array.from(urns));
argDependencies.set(key, deps);
} }
const deps = new providerproto.CallRequest.ArgumentDependencies();
deps.setUrnsList(Array.from(urns));
argDependencies.set(key, deps);
} }
return req; return req;

View file

@ -54,6 +54,7 @@ import {
getStack, getStack,
isDryRun, isDryRun,
isLegacyApplyEnabled, isLegacyApplyEnabled,
monitorSupportsOutputValues,
rpcKeepAlive, rpcKeepAlive,
serialize, serialize,
terminateRpcs, terminateRpcs,
@ -89,6 +90,8 @@ interface ResourceResolverOperation {
aliases: URN[]; aliases: URN[];
// An ID to import, if any. // An ID to import, if any.
import: ID | undefined; import: ID | undefined;
// true if the object was serialized with output values.
hasOutputs: boolean;
} }
/** /**
@ -317,6 +320,7 @@ export function registerResource(res: Resource, t: string, name: string, custom:
req.setSupportspartialvalues(true); req.setSupportspartialvalues(true);
req.setRemote(remote); req.setRemote(remote);
req.setReplaceonchangesList(opts.replaceOnChanges || []); req.setReplaceonchangesList(opts.replaceOnChanges || []);
req.setHasoutputs(resop.hasOutputs);
const customTimeouts = new resproto.RegisterResourceRequest.CustomTimeouts(); const customTimeouts = new resproto.RegisterResourceRequest.CustomTimeouts();
if (opts.customTimeouts != null) { if (opts.customTimeouts != null) {
@ -513,9 +517,13 @@ async function prepareResource(label: string, res: Resource, custom: boolean, re
const [serializedProps, propertyToDirectDependencies] = await serializeResourceProperties(label, props, { const [serializedProps, propertyToDirectDependencies] = await serializeResourceProperties(label, props, {
// To initially scope the use of this new feature, we only keep output values when // To initially scope the use of this new feature, we only keep output values when
// remote is true (for multi-lang components). // remote is true (for multi-lang components).
// Note: The serializer will check with the monitor to see if it supports output values.
keepOutputValues: remote, keepOutputValues: remote,
}); });
// Keep track of whether we've kept output values when serializing.
const hasOutputs = remote && await monitorSupportsOutputValues();
// Wait for the parent to complete. // Wait for the parent to complete.
// If no parent was provided, parent to the root resource. // If no parent was provided, parent to the root resource.
const parentURN = opts.parent const parentURN = opts.parent
@ -586,6 +594,7 @@ async function prepareResource(label: string, res: Resource, custom: boolean, re
propertyToDirectDependencyURNs: propertyToDirectDependencyURNs, propertyToDirectDependencyURNs: propertyToDirectDependencyURNs,
aliases: aliases, aliases: aliases,
import: importID, import: importID,
hasOutputs,
}; };
} finally { } finally {

View file

@ -307,6 +307,7 @@ type RegisterResourceRequest struct {
AcceptResources bool `protobuf:"varint,21,opt,name=acceptResources,proto3" json:"acceptResources,omitempty"` AcceptResources bool `protobuf:"varint,21,opt,name=acceptResources,proto3" json:"acceptResources,omitempty"`
Providers map[string]string `protobuf:"bytes,22,rep,name=providers,proto3" json:"providers,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` Providers map[string]string `protobuf:"bytes,22,rep,name=providers,proto3" json:"providers,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
ReplaceOnChanges []string `protobuf:"bytes,23,rep,name=replaceOnChanges,proto3" json:"replaceOnChanges,omitempty"` ReplaceOnChanges []string `protobuf:"bytes,23,rep,name=replaceOnChanges,proto3" json:"replaceOnChanges,omitempty"`
HasOutputs bool `protobuf:"varint,24,opt,name=hasOutputs,proto3" json:"hasOutputs,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"` XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"` XXX_sizecache int32 `json:"-"`
@ -498,6 +499,13 @@ func (m *RegisterResourceRequest) GetReplaceOnChanges() []string {
return nil return nil
} }
func (m *RegisterResourceRequest) GetHasOutputs() bool {
if m != nil {
return m.HasOutputs
}
return false
}
// PropertyDependencies describes the resources that a particular property depends on. // PropertyDependencies describes the resources that a particular property depends on.
type RegisterResourceRequest_PropertyDependencies struct { type RegisterResourceRequest_PropertyDependencies struct {
Urns []string `protobuf:"bytes,1,rep,name=urns,proto3" json:"urns,omitempty"` Urns []string `protobuf:"bytes,1,rep,name=urns,proto3" json:"urns,omitempty"`
@ -792,71 +800,71 @@ func init() {
func init() { proto.RegisterFile("resource.proto", fileDescriptor_d1b72f771c35e3b8) } func init() { proto.RegisterFile("resource.proto", fileDescriptor_d1b72f771c35e3b8) }
var fileDescriptor_d1b72f771c35e3b8 = []byte{ var fileDescriptor_d1b72f771c35e3b8 = []byte{
// 1010 bytes of a gzipped FileDescriptorProto // 1020 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x57, 0x5f, 0x6f, 0x1b, 0x45, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x57, 0x5f, 0x6f, 0x1b, 0x45,
0x10, 0x8f, 0xed, 0xd4, 0xb1, 0x27, 0xa9, 0x13, 0x36, 0xa9, 0xbd, 0x3d, 0x50, 0x08, 0x07, 0x0f, 0x10, 0x8f, 0xed, 0xd4, 0xb1, 0x27, 0xa9, 0x13, 0x36, 0xa9, 0xbd, 0x3d, 0x50, 0x08, 0x07, 0x0f,
0xa6, 0x0f, 0x4e, 0x13, 0x90, 0x9a, 0xa2, 0x02, 0x12, 0x69, 0x41, 0x7d, 0x28, 0x29, 0x17, 0x84, 0xa6, 0x0f, 0x4e, 0x13, 0x90, 0x9a, 0xa2, 0x02, 0x12, 0x69, 0x41, 0x7d, 0x28, 0x29, 0x17, 0x84,
0x00, 0x09, 0xa4, 0x8d, 0x6f, 0x92, 0x1e, 0x39, 0xdf, 0x5e, 0x77, 0xf7, 0x22, 0xf9, 0x0d, 0xbe, 0x00, 0x09, 0xa4, 0x8d, 0x6f, 0x92, 0x1e, 0x39, 0xdf, 0x5e, 0x77, 0xf7, 0x22, 0xf9, 0x0d, 0xbe,
0x07, 0x9f, 0x06, 0xf1, 0xca, 0x77, 0x42, 0xbb, 0x7b, 0xeb, 0xde, 0xf9, 0xce, 0x89, 0xd3, 0xbe, 0x07, 0x9f, 0x06, 0xf1, 0x75, 0xf8, 0x0e, 0x68, 0x77, 0x6f, 0xdd, 0x3b, 0xdf, 0x39, 0x71, 0xda,
0xdd, 0xfc, 0xe6, 0x9f, 0x77, 0xe6, 0x37, 0xb3, 0x6b, 0xe8, 0x09, 0x94, 0x3c, 0x13, 0x63, 0x1c, 0xb7, 0x9b, 0xdf, 0xfc, 0xf3, 0xce, 0xfc, 0x66, 0x76, 0x0d, 0x3d, 0x81, 0x92, 0x67, 0x62, 0x8c,
0xa5, 0x82, 0x2b, 0x4e, 0xba, 0x69, 0x16, 0x67, 0x93, 0x48, 0xa4, 0x63, 0xef, 0xfd, 0x0b, 0xce, 0xa3, 0x54, 0x70, 0xc5, 0x49, 0x37, 0xcd, 0xe2, 0x6c, 0x12, 0x89, 0x74, 0xec, 0xbd, 0x7f, 0xc1,
0x2f, 0x62, 0xdc, 0x37, 0x8a, 0xb3, 0xec, 0x7c, 0x1f, 0x27, 0xa9, 0x9a, 0x5a, 0x3b, 0xef, 0x83, 0xf9, 0x45, 0x8c, 0xfb, 0x46, 0x71, 0x96, 0x9d, 0xef, 0xe3, 0x24, 0x55, 0x53, 0x6b, 0xe7, 0x7d,
0x79, 0xa5, 0x54, 0x22, 0x1b, 0xab, 0x5c, 0xdb, 0x4b, 0x05, 0xbf, 0x8a, 0x42, 0x14, 0x56, 0xf6, 0x30, 0xaf, 0x94, 0x4a, 0x64, 0x63, 0x95, 0x6b, 0x7b, 0xa9, 0xe0, 0x57, 0x51, 0x88, 0xc2, 0xca,
0x87, 0xd0, 0x3f, 0xcd, 0xd2, 0x94, 0x0b, 0x25, 0xbf, 0x45, 0xa6, 0x32, 0x81, 0x01, 0xbe, 0xce, 0xfe, 0x10, 0xfa, 0xa7, 0x59, 0x9a, 0x72, 0xa1, 0xe4, 0xb7, 0xc8, 0x54, 0x26, 0x30, 0xc0, 0xd7,
0x50, 0x2a, 0xd2, 0x83, 0x66, 0x14, 0xd2, 0xc6, 0x5e, 0x63, 0xd8, 0x0d, 0x9a, 0x51, 0xe8, 0x3f, 0x19, 0x4a, 0x45, 0x7a, 0xd0, 0x8c, 0x42, 0xda, 0xd8, 0x6b, 0x0c, 0xbb, 0x41, 0x33, 0x0a, 0xfd,
0x86, 0x41, 0xc5, 0x52, 0xa6, 0x3c, 0x91, 0x48, 0x76, 0x01, 0x5e, 0x31, 0x99, 0x6b, 0x8d, 0x4b, 0xc7, 0x30, 0xa8, 0x58, 0xca, 0x94, 0x27, 0x12, 0xc9, 0x2e, 0xc0, 0x2b, 0x26, 0x73, 0xad, 0x71,
0x27, 0x28, 0x20, 0xfe, 0xdf, 0x2d, 0xd8, 0x0e, 0x90, 0x85, 0x41, 0x7e, 0xa2, 0x05, 0x29, 0x08, 0xe9, 0x04, 0x05, 0xc4, 0xff, 0xbb, 0x05, 0xdb, 0x01, 0xb2, 0x30, 0xc8, 0x4f, 0xb4, 0x20, 0x05,
0x81, 0x55, 0x35, 0x4d, 0x91, 0x36, 0x0d, 0x62, 0xbe, 0x35, 0x96, 0xb0, 0x09, 0xd2, 0x96, 0xc5, 0x21, 0xb0, 0xaa, 0xa6, 0x29, 0xd2, 0xa6, 0x41, 0xcc, 0xb7, 0xc6, 0x12, 0x36, 0x41, 0xda, 0xb2,
0xf4, 0x37, 0xe9, 0x43, 0x3b, 0x65, 0x02, 0x13, 0x45, 0x57, 0x0d, 0x9a, 0x4b, 0xe4, 0x11, 0x40, 0x98, 0xfe, 0x26, 0x7d, 0x68, 0xa7, 0x4c, 0x60, 0xa2, 0xe8, 0xaa, 0x41, 0x73, 0x89, 0x3c, 0x02,
0x2a, 0x78, 0x8a, 0x42, 0x45, 0x28, 0xe9, 0x9d, 0xbd, 0xc6, 0x70, 0xfd, 0x70, 0x30, 0xb2, 0xf5, 0x48, 0x05, 0x4f, 0x51, 0xa8, 0x08, 0x25, 0xbd, 0xb3, 0xd7, 0x18, 0xae, 0x1f, 0x0e, 0x46, 0xb6,
0x18, 0xb9, 0x7a, 0x8c, 0x4e, 0x4d, 0x3d, 0x82, 0x82, 0x29, 0xf1, 0x61, 0x23, 0xc4, 0x14, 0x93, 0x1e, 0x23, 0x57, 0x8f, 0xd1, 0xa9, 0xa9, 0x47, 0x50, 0x30, 0x25, 0x3e, 0x6c, 0x84, 0x98, 0x62,
0x10, 0x93, 0xb1, 0x76, 0x6d, 0xef, 0xb5, 0x86, 0xdd, 0xa0, 0x84, 0x11, 0x0f, 0x3a, 0xae, 0x76, 0x12, 0x62, 0x32, 0xd6, 0xae, 0xed, 0xbd, 0xd6, 0xb0, 0x1b, 0x94, 0x30, 0xe2, 0x41, 0xc7, 0xd5,
0x74, 0xcd, 0xa4, 0x9d, 0xc9, 0x84, 0xc2, 0xda, 0x15, 0x0a, 0x19, 0xf1, 0x84, 0x76, 0x8c, 0xca, 0x8e, 0xae, 0x99, 0xb4, 0x33, 0x99, 0x50, 0x58, 0xbb, 0x42, 0x21, 0x23, 0x9e, 0xd0, 0x8e, 0x51,
0x89, 0xe4, 0x13, 0xb8, 0xcb, 0xc6, 0x63, 0x4c, 0xd5, 0x29, 0x8e, 0x05, 0x2a, 0x49, 0xbb, 0xa6, 0x39, 0x91, 0x7c, 0x02, 0x77, 0xd9, 0x78, 0x8c, 0xa9, 0x3a, 0xc5, 0xb1, 0x40, 0x25, 0x69, 0xd7,
0x3a, 0x65, 0x90, 0x1c, 0xc1, 0x80, 0x85, 0x61, 0xa4, 0x22, 0x9e, 0xb0, 0xd8, 0x82, 0x27, 0x99, 0x54, 0xa7, 0x0c, 0x92, 0x23, 0x18, 0xb0, 0x30, 0x8c, 0x54, 0xc4, 0x13, 0x16, 0x5b, 0xf0, 0x24,
0x4a, 0x33, 0x25, 0x29, 0x98, 0x9f, 0xb2, 0x48, 0xad, 0x33, 0xb3, 0x38, 0x62, 0x12, 0x25, 0x5d, 0x53, 0x69, 0xa6, 0x24, 0x05, 0xf3, 0x53, 0x16, 0xa9, 0x75, 0x66, 0x16, 0x47, 0x4c, 0xa2, 0xa4,
0x37, 0x96, 0x4e, 0x24, 0x43, 0xd8, 0xb4, 0x49, 0x5c, 0xd5, 0x25, 0xdd, 0x30, 0xb9, 0xe7, 0x61, 0xeb, 0xc6, 0xd2, 0x89, 0x64, 0x08, 0x9b, 0x36, 0x89, 0xab, 0xba, 0xa4, 0x1b, 0x26, 0xf7, 0x3c,
0x9f, 0xc1, 0x4e, 0xb9, 0x3b, 0x79, 0x5b, 0xb7, 0xa0, 0x95, 0x89, 0x24, 0xef, 0x8f, 0xfe, 0x9c, 0xec, 0x33, 0xd8, 0x29, 0x77, 0x27, 0x6f, 0xeb, 0x16, 0xb4, 0x32, 0x91, 0xe4, 0xfd, 0xd1, 0x9f,
0x2b, 0x70, 0x73, 0xe9, 0x02, 0xfb, 0xff, 0x01, 0x0c, 0x02, 0xbc, 0x88, 0xa4, 0x42, 0x31, 0xcf, 0x73, 0x05, 0x6e, 0x2e, 0x5d, 0x60, 0xff, 0x3f, 0x80, 0x41, 0x80, 0x17, 0x91, 0x54, 0x28, 0xe6,
0x02, 0xd7, 0xf5, 0x46, 0x4d, 0xd7, 0x9b, 0xb5, 0x5d, 0x6f, 0x95, 0xba, 0xde, 0x87, 0xf6, 0x38, 0x59, 0xe0, 0xba, 0xde, 0xa8, 0xe9, 0x7a, 0xb3, 0xb6, 0xeb, 0xad, 0x52, 0xd7, 0xfb, 0xd0, 0x1e,
0x93, 0x8a, 0x4f, 0x0c, 0x1b, 0x3a, 0x41, 0x2e, 0x91, 0x7d, 0x68, 0xf3, 0xb3, 0x3f, 0x70, 0xac, 0x67, 0x52, 0xf1, 0x89, 0x61, 0x43, 0x27, 0xc8, 0x25, 0xb2, 0x0f, 0x6d, 0x7e, 0xf6, 0x07, 0x8e,
0x6e, 0x62, 0x42, 0x6e, 0xa6, 0x6b, 0xa9, 0x55, 0xda, 0xa3, 0x6d, 0x22, 0x39, 0xb1, 0xc2, 0x8f, 0xd5, 0x4d, 0x4c, 0xc8, 0xcd, 0x74, 0x2d, 0xb5, 0x4a, 0x7b, 0xb4, 0x4d, 0x24, 0x27, 0x56, 0xf8,
0xb5, 0x1b, 0xf8, 0xd1, 0x99, 0xe3, 0x47, 0x0a, 0x3b, 0x79, 0x31, 0xa6, 0x4f, 0x8b, 0x71, 0xba, 0xb1, 0x76, 0x03, 0x3f, 0x3a, 0x73, 0xfc, 0x48, 0x61, 0x27, 0x2f, 0xc6, 0xf4, 0x69, 0x31, 0x4e,
0x7b, 0xad, 0xe1, 0xfa, 0xe1, 0x93, 0xd1, 0x6c, 0xb4, 0x47, 0x0b, 0x8a, 0x34, 0x7a, 0x59, 0xe3, 0x77, 0xaf, 0x35, 0x5c, 0x3f, 0x7c, 0x32, 0x9a, 0x8d, 0xf6, 0x68, 0x41, 0x91, 0x46, 0x2f, 0x6b,
0xfe, 0x2c, 0x51, 0x62, 0x1a, 0xd4, 0x46, 0x26, 0x0f, 0x61, 0x3b, 0xc4, 0x18, 0x15, 0x7e, 0x83, 0xdc, 0x9f, 0x25, 0x4a, 0x4c, 0x83, 0xda, 0xc8, 0xe4, 0x21, 0x6c, 0x87, 0x18, 0xa3, 0xc2, 0x6f,
0xe7, 0x5c, 0x8f, 0x6a, 0x1a, 0xb3, 0x31, 0x52, 0x30, 0xe7, 0xaa, 0x53, 0x15, 0x39, 0xbc, 0x5e, 0xf0, 0x9c, 0xeb, 0x51, 0x4d, 0x63, 0x36, 0x46, 0x0a, 0xe6, 0x5c, 0x75, 0xaa, 0x22, 0x87, 0xd7,
0xe1, 0x70, 0x74, 0x91, 0x70, 0x81, 0xc7, 0xaf, 0x58, 0x72, 0x61, 0x78, 0xa4, 0x8f, 0x5f, 0x06, 0x2b, 0x1c, 0x8e, 0x2e, 0x12, 0x2e, 0xf0, 0xf8, 0x15, 0x4b, 0x2e, 0x0c, 0x8f, 0xf4, 0xf1, 0xcb,
0xab, 0x4c, 0xbf, 0x7b, 0x4b, 0xa6, 0xf7, 0x96, 0x66, 0xfa, 0x66, 0x99, 0xe9, 0x1e, 0x74, 0xa2, 0x60, 0x95, 0xe9, 0x77, 0x6f, 0xc9, 0xf4, 0xde, 0xd2, 0x4c, 0xdf, 0x2c, 0x33, 0xdd, 0x83, 0x4e,
0x89, 0x5e, 0x34, 0xcf, 0x43, 0xba, 0x65, 0x2b, 0xef, 0x64, 0xf2, 0x0b, 0xf4, 0x2c, 0x1d, 0x7e, 0x34, 0xd1, 0x8b, 0xe6, 0x79, 0x48, 0xb7, 0x6c, 0xe5, 0x9d, 0x4c, 0x7e, 0x81, 0x9e, 0xa5, 0xc3,
0x8c, 0x26, 0xc8, 0x75, 0x9a, 0xf7, 0x0c, 0x19, 0x0e, 0x96, 0xa8, 0xf9, 0x71, 0xc9, 0x31, 0x98, 0x8f, 0xd1, 0x04, 0xb9, 0x4e, 0xf3, 0x9e, 0x21, 0xc3, 0xc1, 0x12, 0x35, 0x3f, 0x2e, 0x39, 0x06,
0x0b, 0x44, 0xbe, 0x02, 0xaf, 0xa6, 0x8e, 0x4f, 0xf1, 0x3c, 0x4a, 0x30, 0xa4, 0xc4, 0x9c, 0xfe, 0x73, 0x81, 0xc8, 0x57, 0xe0, 0xd5, 0xd4, 0xf1, 0x29, 0x9e, 0x47, 0x09, 0x86, 0x94, 0x98, 0xd3,
0x1a, 0x0b, 0xf2, 0x39, 0xdc, 0x93, 0xf9, 0x42, 0x7d, 0xc9, 0x84, 0x8a, 0x58, 0xfc, 0x13, 0x8b, 0x5f, 0x63, 0x41, 0x3e, 0x87, 0x7b, 0x32, 0x5f, 0xa8, 0x2f, 0x99, 0x50, 0x11, 0x8b, 0x7f, 0x62,
0x33, 0x94, 0x74, 0xdb, 0xb8, 0xd6, 0x2b, 0x35, 0xdb, 0x05, 0x4e, 0xb8, 0x42, 0xba, 0x63, 0xd9, 0x71, 0x86, 0x92, 0x6e, 0x1b, 0xd7, 0x7a, 0xa5, 0x66, 0xbb, 0xc0, 0x09, 0x57, 0x48, 0x77, 0x2c,
0x6e, 0xa5, 0xba, 0x71, 0xbf, 0x57, 0x3b, 0xee, 0xe4, 0x04, 0xba, 0x8e, 0x98, 0x92, 0xf6, 0x0d, 0xdb, 0xad, 0x54, 0x37, 0xee, 0xf7, 0x6a, 0xc7, 0x9d, 0x9c, 0x40, 0xd7, 0x11, 0x53, 0xd2, 0xbe,
0x03, 0x0f, 0x96, 0x63, 0xa0, 0xf5, 0xb1, 0xb4, 0x7b, 0x13, 0x83, 0x3c, 0x80, 0x2d, 0x61, 0x8f, 0x61, 0xe0, 0xc1, 0x72, 0x0c, 0xb4, 0x3e, 0x96, 0x76, 0x6f, 0x62, 0x90, 0x07, 0xb0, 0x25, 0xec,
0x76, 0x92, 0x38, 0x8a, 0x0c, 0x4c, 0x8b, 0x2a, 0xb8, 0xf7, 0x00, 0x76, 0xea, 0xa8, 0xac, 0x07, 0xd1, 0x4e, 0x12, 0x47, 0x91, 0x81, 0x69, 0x51, 0x05, 0xcf, 0xaf, 0x0a, 0xd7, 0x72, 0x3a, 0xbb,
0x3e, 0x13, 0x89, 0xa4, 0x0d, 0xe3, 0x67, 0xbe, 0xbd, 0x9f, 0xa1, 0x57, 0x6e, 0x81, 0x19, 0x75, 0x2a, 0x72, 0xc4, 0x7b, 0x00, 0x3b, 0x75, 0x54, 0xd7, 0x0b, 0x21, 0x13, 0x89, 0xa4, 0x0d, 0x13,
0x81, 0x4c, 0xb9, 0x65, 0x91, 0x4b, 0x1a, 0xcf, 0xd2, 0x50, 0xe3, 0x76, 0x61, 0xe4, 0x92, 0xc6, 0xd7, 0x7c, 0x7b, 0x3f, 0x43, 0xaf, 0xdc, 0x22, 0xb3, 0x0a, 0x04, 0x32, 0xe5, 0x96, 0x49, 0x2e,
0x6d, 0x03, 0xdc, 0xca, 0xb0, 0x92, 0xf7, 0x67, 0x03, 0xee, 0x2f, 0x9c, 0x28, 0xbd, 0xf7, 0x2e, 0x69, 0x3c, 0x4b, 0x43, 0x8d, 0xdb, 0x85, 0x92, 0x4b, 0x1a, 0xb7, 0x0d, 0x72, 0x2b, 0xc5, 0x4a,
0x71, 0xea, 0xf6, 0xde, 0x25, 0x4e, 0xc9, 0x0b, 0xb8, 0x73, 0xa5, 0xcb, 0x9f, 0xaf, 0xbc, 0x47, 0xde, 0x9f, 0x0d, 0xb8, 0xbf, 0x70, 0xe2, 0xf4, 0x5e, 0xbc, 0xc4, 0xa9, 0xdb, 0x8b, 0x97, 0x38,
0x6f, 0x39, 0xb0, 0x81, 0x8d, 0xf2, 0x45, 0xf3, 0xa8, 0xe1, 0x3d, 0x81, 0x5e, 0xb9, 0xa2, 0x35, 0x25, 0x2f, 0xe0, 0xce, 0x95, 0x6e, 0x4f, 0xbe, 0x12, 0x1f, 0xbd, 0xe5, 0x40, 0x07, 0x36, 0xca,
0x69, 0x77, 0x8a, 0x69, 0xbb, 0x05, 0x6f, 0xff, 0x9f, 0x16, 0xd0, 0x6a, 0xe6, 0x85, 0x7b, 0xdb, 0x17, 0xcd, 0xa3, 0x86, 0xf7, 0x04, 0x7a, 0xe5, 0x8a, 0xd7, 0xa4, 0xdd, 0x29, 0xa6, 0xed, 0x16,
0x5e, 0xb4, 0xcd, 0xd9, 0x45, 0xfb, 0x66, 0x35, 0xb6, 0x96, 0x5b, 0x8d, 0x7d, 0x68, 0x4b, 0xc5, 0xbc, 0xfd, 0x7f, 0x5a, 0x40, 0xab, 0x99, 0x17, 0xee, 0x75, 0x7b, 0x11, 0x37, 0x67, 0x17, 0xf1,
0xce, 0x62, 0x74, 0x3b, 0xd6, 0x4a, 0x7a, 0x28, 0xed, 0x97, 0xbe, 0x6e, 0xcd, 0x50, 0xe6, 0x22, 0x9b, 0xd5, 0xd9, 0x5a, 0x6e, 0x75, 0xf6, 0xa1, 0x2d, 0x15, 0x3b, 0x8b, 0xd1, 0xed, 0x60, 0x2b,
0x79, 0xbd, 0x60, 0xe5, 0xb5, 0x0d, 0xe1, 0xbe, 0xbc, 0xb6, 0x82, 0xf6, 0x1c, 0xb7, 0xdd, 0x79, 0xe9, 0xa1, 0xb5, 0x5f, 0xfa, 0x3a, 0x36, 0x43, 0x9b, 0x8b, 0xe4, 0xf5, 0x82, 0x95, 0xd8, 0x36,
0xb7, 0xe2, 0xd6, 0x5f, 0xb7, 0x64, 0xc0, 0xf7, 0x65, 0x06, 0x1c, 0xbd, 0xed, 0xef, 0x2f, 0x36, 0x84, 0xfc, 0xf2, 0xda, 0x0a, 0xda, 0x73, 0xdc, 0x76, 0x27, 0xde, 0x8a, 0x5b, 0x7f, 0xdd, 0x92,
0x11, 0x61, 0x77, 0xde, 0x37, 0x5f, 0x76, 0xee, 0x6a, 0xac, 0x76, 0xf2, 0x00, 0xd6, 0x78, 0xbe, 0x01, 0xdf, 0x97, 0x19, 0x70, 0xf4, 0xb6, 0xbf, 0xbf, 0xd8, 0x44, 0x84, 0xdd, 0x79, 0xdf, 0x7c,
0x2f, 0x6f, 0xb8, 0x7e, 0x9d, 0xdd, 0xe1, 0xbf, 0xab, 0xb0, 0xe9, 0xe2, 0xbf, 0xe0, 0x49, 0xa4, 0x4c, 0xdc, 0xd5, 0x59, 0xed, 0xe4, 0x01, 0xac, 0xf1, 0x7c, 0xb8, 0x6e, 0xb8, 0x9e, 0x9d, 0xdd,
0xb8, 0x20, 0xbf, 0xc2, 0xe6, 0xdc, 0x63, 0x8e, 0x7c, 0x54, 0x38, 0x52, 0xfd, 0x93, 0xd0, 0xf3, 0xe1, 0xbf, 0xab, 0xb0, 0xe9, 0xe2, 0xbf, 0xe0, 0x49, 0xa4, 0xb8, 0x20, 0xbf, 0xc2, 0xe6, 0xdc,
0xaf, 0x33, 0xb1, 0x87, 0xf6, 0x57, 0xc8, 0xd7, 0xd0, 0x7e, 0x9e, 0x5c, 0xf1, 0x4b, 0x24, 0xb4, 0x63, 0x8f, 0x7c, 0x54, 0x38, 0x52, 0xfd, 0x93, 0xd1, 0xf3, 0xaf, 0x33, 0xb1, 0x87, 0xf6, 0x57,
0x60, 0x6f, 0x21, 0x17, 0xe9, 0x7e, 0x8d, 0x66, 0x16, 0xe0, 0x3b, 0xd8, 0x38, 0x55, 0x02, 0xd9, 0xc8, 0xd7, 0xd0, 0x7e, 0x9e, 0x5c, 0xf1, 0x4b, 0x24, 0xb4, 0x60, 0x6f, 0x21, 0x17, 0xe9, 0x7e,
0xe4, 0x9d, 0xc2, 0x3c, 0x6c, 0x90, 0xc7, 0xb0, 0x7a, 0xcc, 0xe2, 0x98, 0xf4, 0x0b, 0x66, 0x1a, 0x8d, 0x66, 0x16, 0xe0, 0x3b, 0xd8, 0x38, 0x55, 0x02, 0xd9, 0xe4, 0x9d, 0xc2, 0x3c, 0x6c, 0x90,
0x70, 0xee, 0x83, 0x0a, 0x3e, 0xfb, 0x0d, 0x3f, 0xc0, 0x46, 0xf1, 0x4d, 0x44, 0x76, 0x4b, 0x0d, 0xc7, 0xb0, 0x7a, 0xcc, 0xe2, 0x98, 0xf4, 0x0b, 0x66, 0x1a, 0x70, 0xee, 0x83, 0x0a, 0x3e, 0xfb,
0xaf, 0x3c, 0x65, 0xbd, 0x0f, 0x17, 0xea, 0x67, 0x21, 0x7f, 0x83, 0xad, 0xf9, 0x76, 0x13, 0xff, 0x0d, 0x3f, 0xc0, 0x46, 0xf1, 0xcd, 0x44, 0x76, 0x4b, 0x0d, 0xaf, 0x3c, 0x75, 0xbd, 0x0f, 0x17,
0xe6, 0x4d, 0xe2, 0x7d, 0xbc, 0x04, 0xd7, 0xfc, 0x15, 0xf2, 0x7b, 0xf5, 0x85, 0xe5, 0xae, 0xce, 0xea, 0x67, 0x21, 0x7f, 0x83, 0xad, 0xf9, 0x76, 0x13, 0xff, 0xe6, 0x4d, 0xe2, 0x7d, 0xbc, 0x04,
0x4f, 0xaf, 0x89, 0x50, 0x66, 0x9c, 0xd7, 0xaf, 0xd0, 0xe9, 0x99, 0xfe, 0x6f, 0xe1, 0xaf, 0x9c, 0xd7, 0xfc, 0x15, 0xf2, 0x7b, 0xf5, 0x05, 0xe6, 0xae, 0xd6, 0x4f, 0xaf, 0x89, 0x50, 0x66, 0x9c,
0xb5, 0x0d, 0xf2, 0xd9, 0xff, 0x01, 0x00, 0x00, 0xff, 0xff, 0xf1, 0x1f, 0xaf, 0x2d, 0x98, 0x0c, 0xd7, 0xaf, 0xd0, 0xe9, 0x99, 0xfe, 0xef, 0xe1, 0xaf, 0x9c, 0xb5, 0x0d, 0xf2, 0xd9, 0xff, 0x01,
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xa6, 0x36, 0x75, 0xcc, 0xb8, 0x0c, 0x00, 0x00,
} }
// Reference imports to suppress errors if they are not otherwise used. // Reference imports to suppress errors if they are not otherwise used.

View file

@ -105,6 +105,7 @@ message RegisterResourceRequest {
bool acceptResources = 21; // when true operations should return resource references as strongly typed. bool acceptResources = 21; // when true operations should return resource references as strongly typed.
map<string, string> providers = 22; // an optional reference to the provider map to manage this resource's CRUD operations. map<string, string> providers = 22; // an optional reference to the provider map to manage this resource's CRUD operations.
repeated string replaceOnChanges = 23; // a list of properties that if changed should force a replacement. repeated string replaceOnChanges = 23; // a list of properties that if changed should force a replacement.
bool hasOutputs = 24; // true if the object was serialized with output values.
} }
// RegisterResourceResponse is returned by the engine after a resource has finished being initialized. It includes the // RegisterResourceResponse is returned by the engine after a resource has finished being initialized. It includes the

View file

@ -24,7 +24,7 @@ from ..invoke import InvokeOptions
from ..runtime.proto import provider_pb2 from ..runtime.proto import provider_pb2
from . import rpc from . import rpc
from .rpc_manager import RPC_MANAGER from .rpc_manager import RPC_MANAGER
from .settings import get_monitor, grpc_error_to_exception, handle_grpc_error from .settings import get_monitor, grpc_error_to_exception, handle_grpc_error, monitor_supports_output_values
from .sync_await import _sync_await from .sync_await import _sync_await
if TYPE_CHECKING: if TYPE_CHECKING:
@ -182,29 +182,35 @@ def call(tok: str, props: 'Inputs', res: Optional['Resource'] = None, typ: Optio
# Serialize out all props to their final values. In doing so, we'll also collect all the Resources pointed to # Serialize out all props to their final values. In doing so, we'll also collect all the Resources pointed to
# by any Dependency objects we encounter, adding them to 'implicit_dependencies'. # by any Dependency objects we encounter, adding them to 'implicit_dependencies'.
# Note: If the monitor supports output values, we will not pass these collected dependencies as the
# dependencies are implicitly contained within the output values within the inputs.
property_dependencies_resources: Dict[str, List['Resource']] = {} property_dependencies_resources: Dict[str, List['Resource']] = {}
# We keep output values when serializing inputs for call. # We keep output values when serializing inputs for call.
inputs = await rpc.serialize_properties(props, property_dependencies_resources, keep_output_values=True) inputs = await rpc.serialize_properties(props, property_dependencies_resources, keep_output_values=True)
property_dependencies = {} # Prepare the CallRequest arguments.
for key, property_deps in property_dependencies_resources.items(): req_args = {
urns = set() "tok": tok,
for dep in property_deps: "args": inputs,
urn = await dep.urn.future() "provider": provider_ref,
urns.add(urn) "version": version,
property_dependencies[key] = provider_pb2.CallRequest.ArgumentDependencies(urns=list(urns)) }
req = provider_pb2.CallRequest( # Only include `argDependencies` in the request when the monitor does *not* support output values.
tok=tok, # When the monitor *does* support output values, the dependencies will already exist within the inputs.
args=inputs, if not await monitor_supports_output_values():
argDependencies=property_dependencies, arg_dependencies = {}
provider=provider_ref, for key, property_deps in property_dependencies_resources.items():
version=version, urns = set()
) for dep in property_deps:
urn = await dep.urn.future()
urns.add(urn)
arg_dependencies[key] = provider_pb2.CallRequest.ArgumentDependencies(urns=list(urns))
req_args["argDependencies"] = arg_dependencies
def do_rpc_call(): def do_rpc_call():
try: try:
return monitor.Call(req) return monitor.Call(provider_pb2.CallRequest(**req_args))
except grpc.RpcError as exn: except grpc.RpcError as exn:
handle_grpc_error(exn) handle_grpc_error(exn)
return None return None

View file

@ -21,7 +21,7 @@ DESCRIPTOR = _descriptor.FileDescriptor(
package='pulumirpc', package='pulumirpc',
syntax='proto3', syntax='proto3',
serialized_options=None, serialized_options=None,
serialized_pb=b'\n\x0eresource.proto\x12\tpulumirpc\x1a\x1bgoogle/protobuf/empty.proto\x1a\x1cgoogle/protobuf/struct.proto\x1a\x0eprovider.proto\"$\n\x16SupportsFeatureRequest\x12\n\n\x02id\x18\x01 \x01(\t\"-\n\x17SupportsFeatureResponse\x12\x12\n\nhasSupport\x18\x01 \x01(\x08\"\x95\x02\n\x13ReadResourceRequest\x12\n\n\x02id\x18\x01 \x01(\t\x12\x0c\n\x04type\x18\x02 \x01(\t\x12\x0c\n\x04name\x18\x03 \x01(\t\x12\x0e\n\x06parent\x18\x04 \x01(\t\x12+\n\nproperties\x18\x05 \x01(\x0b\x32\x17.google.protobuf.Struct\x12\x14\n\x0c\x64\x65pendencies\x18\x06 \x03(\t\x12\x10\n\x08provider\x18\x07 \x01(\t\x12\x0f\n\x07version\x18\x08 \x01(\t\x12\x15\n\racceptSecrets\x18\t \x01(\x08\x12\x1f\n\x17\x61\x64\x64itionalSecretOutputs\x18\n \x03(\t\x12\x0f\n\x07\x61liases\x18\x0b \x03(\t\x12\x17\n\x0f\x61\x63\x63\x65ptResources\x18\x0c \x01(\x08\"P\n\x14ReadResourceResponse\x12\x0b\n\x03urn\x18\x01 \x01(\t\x12+\n\nproperties\x18\x02 \x01(\x0b\x32\x17.google.protobuf.Struct\"\xda\x07\n\x17RegisterResourceRequest\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x0e\n\x06parent\x18\x03 \x01(\t\x12\x0e\n\x06\x63ustom\x18\x04 \x01(\x08\x12\'\n\x06object\x18\x05 \x01(\x0b\x32\x17.google.protobuf.Struct\x12\x0f\n\x07protect\x18\x06 \x01(\x08\x12\x14\n\x0c\x64\x65pendencies\x18\x07 \x03(\t\x12\x10\n\x08provider\x18\x08 \x01(\t\x12Z\n\x14propertyDependencies\x18\t \x03(\x0b\x32<.pulumirpc.RegisterResourceRequest.PropertyDependenciesEntry\x12\x1b\n\x13\x64\x65leteBeforeReplace\x18\n \x01(\x08\x12\x0f\n\x07version\x18\x0b \x01(\t\x12\x15\n\rignoreChanges\x18\x0c \x03(\t\x12\x15\n\racceptSecrets\x18\r \x01(\x08\x12\x1f\n\x17\x61\x64\x64itionalSecretOutputs\x18\x0e \x03(\t\x12\x0f\n\x07\x61liases\x18\x0f \x03(\t\x12\x10\n\x08importId\x18\x10 \x01(\t\x12I\n\x0e\x63ustomTimeouts\x18\x11 \x01(\x0b\x32\x31.pulumirpc.RegisterResourceRequest.CustomTimeouts\x12\"\n\x1a\x64\x65leteBeforeReplaceDefined\x18\x12 \x01(\x08\x12\x1d\n\x15supportsPartialValues\x18\x13 \x01(\x08\x12\x0e\n\x06remote\x18\x14 \x01(\x08\x12\x17\n\x0f\x61\x63\x63\x65ptResources\x18\x15 \x01(\x08\x12\x44\n\tproviders\x18\x16 \x03(\x0b\x32\x31.pulumirpc.RegisterResourceRequest.ProvidersEntry\x12\x18\n\x10replaceOnChanges\x18\x17 \x03(\t\x1a$\n\x14PropertyDependencies\x12\x0c\n\x04urns\x18\x01 \x03(\t\x1a@\n\x0e\x43ustomTimeouts\x12\x0e\n\x06\x63reate\x18\x01 \x01(\t\x12\x0e\n\x06update\x18\x02 \x01(\t\x12\x0e\n\x06\x64\x65lete\x18\x03 \x01(\t\x1at\n\x19PropertyDependenciesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\x46\n\x05value\x18\x02 \x01(\x0b\x32\x37.pulumirpc.RegisterResourceRequest.PropertyDependencies:\x02\x38\x01\x1a\x30\n\x0eProvidersEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\xf7\x02\n\x18RegisterResourceResponse\x12\x0b\n\x03urn\x18\x01 \x01(\t\x12\n\n\x02id\x18\x02 \x01(\t\x12\'\n\x06object\x18\x03 \x01(\x0b\x32\x17.google.protobuf.Struct\x12\x0e\n\x06stable\x18\x04 \x01(\x08\x12\x0f\n\x07stables\x18\x05 \x03(\t\x12[\n\x14propertyDependencies\x18\x06 \x03(\x0b\x32=.pulumirpc.RegisterResourceResponse.PropertyDependenciesEntry\x1a$\n\x14PropertyDependencies\x12\x0c\n\x04urns\x18\x01 \x03(\t\x1au\n\x19PropertyDependenciesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12G\n\x05value\x18\x02 \x01(\x0b\x32\x38.pulumirpc.RegisterResourceResponse.PropertyDependencies:\x02\x38\x01\"W\n\x1eRegisterResourceOutputsRequest\x12\x0b\n\x03urn\x18\x01 \x01(\t\x12(\n\x07outputs\x18\x02 \x01(\x0b\x32\x17.google.protobuf.Struct2\xc4\x04\n\x0fResourceMonitor\x12Z\n\x0fSupportsFeature\x12!.pulumirpc.SupportsFeatureRequest\x1a\".pulumirpc.SupportsFeatureResponse\"\x00\x12?\n\x06Invoke\x12\x18.pulumirpc.InvokeRequest\x1a\x19.pulumirpc.InvokeResponse\"\x00\x12G\n\x0cStreamInvoke\x12\x18.pulumirpc.InvokeRequest\x1a\x19.pulumirpc.InvokeResponse\"\x00\x30\x01\x12\x39\n\x04\x43\x61ll\x12\x16.pulumirpc.CallRequest\x1a\x17.pulumirpc.CallResponse\"\x00\x12Q\n\x0cReadResource\x12\x1e.pulumirpc.ReadResourceRequest\x1a\x1f.pulumirpc.ReadResourceResponse\"\x00\x12]\n\x10RegisterResource\x12\".pulumirpc.RegisterResourceRequest\x1a#.pulumirpc.RegisterResourceResponse\"\x00\x12^\n\x17RegisterResourceOutputs\x12).pulumirpc.RegisterResourceOutputsRequest\x1a\x16.google.protobuf.Empty\"\x00\x62\x06proto3' serialized_pb=b'\n\x0eresource.proto\x12\tpulumirpc\x1a\x1bgoogle/protobuf/empty.proto\x1a\x1cgoogle/protobuf/struct.proto\x1a\x0eprovider.proto\"$\n\x16SupportsFeatureRequest\x12\n\n\x02id\x18\x01 \x01(\t\"-\n\x17SupportsFeatureResponse\x12\x12\n\nhasSupport\x18\x01 \x01(\x08\"\x95\x02\n\x13ReadResourceRequest\x12\n\n\x02id\x18\x01 \x01(\t\x12\x0c\n\x04type\x18\x02 \x01(\t\x12\x0c\n\x04name\x18\x03 \x01(\t\x12\x0e\n\x06parent\x18\x04 \x01(\t\x12+\n\nproperties\x18\x05 \x01(\x0b\x32\x17.google.protobuf.Struct\x12\x14\n\x0c\x64\x65pendencies\x18\x06 \x03(\t\x12\x10\n\x08provider\x18\x07 \x01(\t\x12\x0f\n\x07version\x18\x08 \x01(\t\x12\x15\n\racceptSecrets\x18\t \x01(\x08\x12\x1f\n\x17\x61\x64\x64itionalSecretOutputs\x18\n \x03(\t\x12\x0f\n\x07\x61liases\x18\x0b \x03(\t\x12\x17\n\x0f\x61\x63\x63\x65ptResources\x18\x0c \x01(\x08\"P\n\x14ReadResourceResponse\x12\x0b\n\x03urn\x18\x01 \x01(\t\x12+\n\nproperties\x18\x02 \x01(\x0b\x32\x17.google.protobuf.Struct\"\xee\x07\n\x17RegisterResourceRequest\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x0e\n\x06parent\x18\x03 \x01(\t\x12\x0e\n\x06\x63ustom\x18\x04 \x01(\x08\x12\'\n\x06object\x18\x05 \x01(\x0b\x32\x17.google.protobuf.Struct\x12\x0f\n\x07protect\x18\x06 \x01(\x08\x12\x14\n\x0c\x64\x65pendencies\x18\x07 \x03(\t\x12\x10\n\x08provider\x18\x08 \x01(\t\x12Z\n\x14propertyDependencies\x18\t \x03(\x0b\x32<.pulumirpc.RegisterResourceRequest.PropertyDependenciesEntry\x12\x1b\n\x13\x64\x65leteBeforeReplace\x18\n \x01(\x08\x12\x0f\n\x07version\x18\x0b \x01(\t\x12\x15\n\rignoreChanges\x18\x0c \x03(\t\x12\x15\n\racceptSecrets\x18\r \x01(\x08\x12\x1f\n\x17\x61\x64\x64itionalSecretOutputs\x18\x0e \x03(\t\x12\x0f\n\x07\x61liases\x18\x0f \x03(\t\x12\x10\n\x08importId\x18\x10 \x01(\t\x12I\n\x0e\x63ustomTimeouts\x18\x11 \x01(\x0b\x32\x31.pulumirpc.RegisterResourceRequest.CustomTimeouts\x12\"\n\x1a\x64\x65leteBeforeReplaceDefined\x18\x12 \x01(\x08\x12\x1d\n\x15supportsPartialValues\x18\x13 \x01(\x08\x12\x0e\n\x06remote\x18\x14 \x01(\x08\x12\x17\n\x0f\x61\x63\x63\x65ptResources\x18\x15 \x01(\x08\x12\x44\n\tproviders\x18\x16 \x03(\x0b\x32\x31.pulumirpc.RegisterResourceRequest.ProvidersEntry\x12\x18\n\x10replaceOnChanges\x18\x17 \x03(\t\x12\x12\n\nhasOutputs\x18\x18 \x01(\x08\x1a$\n\x14PropertyDependencies\x12\x0c\n\x04urns\x18\x01 \x03(\t\x1a@\n\x0e\x43ustomTimeouts\x12\x0e\n\x06\x63reate\x18\x01 \x01(\t\x12\x0e\n\x06update\x18\x02 \x01(\t\x12\x0e\n\x06\x64\x65lete\x18\x03 \x01(\t\x1at\n\x19PropertyDependenciesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\x46\n\x05value\x18\x02 \x01(\x0b\x32\x37.pulumirpc.RegisterResourceRequest.PropertyDependencies:\x02\x38\x01\x1a\x30\n\x0eProvidersEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\xf7\x02\n\x18RegisterResourceResponse\x12\x0b\n\x03urn\x18\x01 \x01(\t\x12\n\n\x02id\x18\x02 \x01(\t\x12\'\n\x06object\x18\x03 \x01(\x0b\x32\x17.google.protobuf.Struct\x12\x0e\n\x06stable\x18\x04 \x01(\x08\x12\x0f\n\x07stables\x18\x05 \x03(\t\x12[\n\x14propertyDependencies\x18\x06 \x03(\x0b\x32=.pulumirpc.RegisterResourceResponse.PropertyDependenciesEntry\x1a$\n\x14PropertyDependencies\x12\x0c\n\x04urns\x18\x01 \x03(\t\x1au\n\x19PropertyDependenciesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12G\n\x05value\x18\x02 \x01(\x0b\x32\x38.pulumirpc.RegisterResourceResponse.PropertyDependencies:\x02\x38\x01\"W\n\x1eRegisterResourceOutputsRequest\x12\x0b\n\x03urn\x18\x01 \x01(\t\x12(\n\x07outputs\x18\x02 \x01(\x0b\x32\x17.google.protobuf.Struct2\xc4\x04\n\x0fResourceMonitor\x12Z\n\x0fSupportsFeature\x12!.pulumirpc.SupportsFeatureRequest\x1a\".pulumirpc.SupportsFeatureResponse\"\x00\x12?\n\x06Invoke\x12\x18.pulumirpc.InvokeRequest\x1a\x19.pulumirpc.InvokeResponse\"\x00\x12G\n\x0cStreamInvoke\x12\x18.pulumirpc.InvokeRequest\x1a\x19.pulumirpc.InvokeResponse\"\x00\x30\x01\x12\x39\n\x04\x43\x61ll\x12\x16.pulumirpc.CallRequest\x1a\x17.pulumirpc.CallResponse\"\x00\x12Q\n\x0cReadResource\x12\x1e.pulumirpc.ReadResourceRequest\x1a\x1f.pulumirpc.ReadResourceResponse\"\x00\x12]\n\x10RegisterResource\x12\".pulumirpc.RegisterResourceRequest\x1a#.pulumirpc.RegisterResourceResponse\"\x00\x12^\n\x17RegisterResourceOutputs\x12).pulumirpc.RegisterResourceOutputsRequest\x1a\x16.google.protobuf.Empty\"\x00\x62\x06proto3'
, ,
dependencies=[google_dot_protobuf_dot_empty__pb2.DESCRIPTOR,google_dot_protobuf_dot_struct__pb2.DESCRIPTOR,provider__pb2.DESCRIPTOR,]) dependencies=[google_dot_protobuf_dot_empty__pb2.DESCRIPTOR,google_dot_protobuf_dot_struct__pb2.DESCRIPTOR,provider__pb2.DESCRIPTOR,])
@ -262,8 +262,8 @@ _REGISTERRESOURCEREQUEST_PROPERTYDEPENDENCIES = _descriptor.Descriptor(
extension_ranges=[], extension_ranges=[],
oneofs=[ oneofs=[
], ],
serialized_start=1268, serialized_start=1288,
serialized_end=1304, serialized_end=1324,
) )
_REGISTERRESOURCEREQUEST_CUSTOMTIMEOUTS = _descriptor.Descriptor( _REGISTERRESOURCEREQUEST_CUSTOMTIMEOUTS = _descriptor.Descriptor(
@ -306,8 +306,8 @@ _REGISTERRESOURCEREQUEST_CUSTOMTIMEOUTS = _descriptor.Descriptor(
extension_ranges=[], extension_ranges=[],
oneofs=[ oneofs=[
], ],
serialized_start=1306, serialized_start=1326,
serialized_end=1370, serialized_end=1390,
) )
_REGISTERRESOURCEREQUEST_PROPERTYDEPENDENCIESENTRY = _descriptor.Descriptor( _REGISTERRESOURCEREQUEST_PROPERTYDEPENDENCIESENTRY = _descriptor.Descriptor(
@ -343,8 +343,8 @@ _REGISTERRESOURCEREQUEST_PROPERTYDEPENDENCIESENTRY = _descriptor.Descriptor(
extension_ranges=[], extension_ranges=[],
oneofs=[ oneofs=[
], ],
serialized_start=1372, serialized_start=1392,
serialized_end=1488, serialized_end=1508,
) )
_REGISTERRESOURCEREQUEST_PROVIDERSENTRY = _descriptor.Descriptor( _REGISTERRESOURCEREQUEST_PROVIDERSENTRY = _descriptor.Descriptor(
@ -380,8 +380,8 @@ _REGISTERRESOURCEREQUEST_PROVIDERSENTRY = _descriptor.Descriptor(
extension_ranges=[], extension_ranges=[],
oneofs=[ oneofs=[
], ],
serialized_start=1490, serialized_start=1510,
serialized_end=1538, serialized_end=1558,
) )
_REGISTERRESOURCEREQUEST = _descriptor.Descriptor( _REGISTERRESOURCEREQUEST = _descriptor.Descriptor(
@ -552,6 +552,13 @@ _REGISTERRESOURCEREQUEST = _descriptor.Descriptor(
message_type=None, enum_type=None, containing_type=None, message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None, is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR), serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='hasOutputs', full_name='pulumirpc.RegisterResourceRequest.hasOutputs', index=23,
number=24, type=8, cpp_type=7, label=1,
has_default_value=False, default_value=False,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
], ],
extensions=[ extensions=[
], ],
@ -565,7 +572,7 @@ _REGISTERRESOURCEREQUEST = _descriptor.Descriptor(
oneofs=[ oneofs=[
], ],
serialized_start=552, serialized_start=552,
serialized_end=1538, serialized_end=1558,
) )
@ -595,8 +602,8 @@ _REGISTERRESOURCERESPONSE_PROPERTYDEPENDENCIES = _descriptor.Descriptor(
extension_ranges=[], extension_ranges=[],
oneofs=[ oneofs=[
], ],
serialized_start=1268, serialized_start=1288,
serialized_end=1304, serialized_end=1324,
) )
_REGISTERRESOURCERESPONSE_PROPERTYDEPENDENCIESENTRY = _descriptor.Descriptor( _REGISTERRESOURCERESPONSE_PROPERTYDEPENDENCIESENTRY = _descriptor.Descriptor(
@ -632,8 +639,8 @@ _REGISTERRESOURCERESPONSE_PROPERTYDEPENDENCIESENTRY = _descriptor.Descriptor(
extension_ranges=[], extension_ranges=[],
oneofs=[ oneofs=[
], ],
serialized_start=1799, serialized_start=1819,
serialized_end=1916, serialized_end=1936,
) )
_REGISTERRESOURCERESPONSE = _descriptor.Descriptor( _REGISTERRESOURCERESPONSE = _descriptor.Descriptor(
@ -697,8 +704,8 @@ _REGISTERRESOURCERESPONSE = _descriptor.Descriptor(
extension_ranges=[], extension_ranges=[],
oneofs=[ oneofs=[
], ],
serialized_start=1541, serialized_start=1561,
serialized_end=1916, serialized_end=1936,
) )
@ -735,8 +742,8 @@ _REGISTERRESOURCEOUTPUTSREQUEST = _descriptor.Descriptor(
extension_ranges=[], extension_ranges=[],
oneofs=[ oneofs=[
], ],
serialized_start=1918, serialized_start=1938,
serialized_end=2005, serialized_end=2025,
) )
_READRESOURCEREQUEST.fields_by_name['properties'].message_type = google_dot_protobuf_dot_struct__pb2._STRUCT _READRESOURCEREQUEST.fields_by_name['properties'].message_type = google_dot_protobuf_dot_struct__pb2._STRUCT
@ -873,8 +880,8 @@ _RESOURCEMONITOR = _descriptor.ServiceDescriptor(
file=DESCRIPTOR, file=DESCRIPTOR,
index=0, index=0,
serialized_options=None, serialized_options=None,
serialized_start=2008, serialized_start=2028,
serialized_end=2588, serialized_end=2608,
methods=[ methods=[
_descriptor.MethodDescriptor( _descriptor.MethodDescriptor(
name='SupportsFeature', name='SupportsFeature',

View file

@ -75,6 +75,11 @@ class ResourceResolverOperations(NamedTuple):
A list of aliases applied to this resource. A list of aliases applied to this resource.
""" """
has_outputs: bool
"""
true if the object was serialized with output values.
"""
# Prepares for an RPC that will manufacture a resource, and hence deals with input and output properties. # Prepares for an RPC that will manufacture a resource, and hence deals with input and output properties.
# pylint: disable=too-many-locals # pylint: disable=too-many-locals
@ -102,9 +107,13 @@ async def prepare_resource(res: 'Resource',
# To initially scope the use of this new feature, we only keep output values when # To initially scope the use of this new feature, we only keep output values when
# remote is true (for multi-lang components). # remote is true (for multi-lang components).
# Note: The serializer will check with the monitor to see if it supports output values.
serialized_props = await rpc.serialize_properties(props, property_dependencies_resources, translate, typ, serialized_props = await rpc.serialize_properties(props, property_dependencies_resources, translate, typ,
keep_output_values=remote) keep_output_values=remote)
# Keep track of whether we've kept output values when serializing.
has_outputs = remote and await settings.monitor_supports_output_values()
# Wait for our parent to resolve # Wait for our parent to resolve
parent_urn: Optional[str] = "" parent_urn: Optional[str] = ""
if opts is not None and opts.parent is not None: if opts is not None and opts.parent is not None:
@ -165,6 +174,7 @@ async def prepare_resource(res: 'Resource',
provider_refs, provider_refs,
property_dependencies, property_dependencies,
aliases, aliases,
has_outputs,
) )
@ -504,6 +514,7 @@ def register_resource(res: 'Resource',
supportsPartialValues=True, supportsPartialValues=True,
remote=remote, remote=remote,
replaceOnChanges=replace_on_changes, replaceOnChanges=replace_on_changes,
hasOutputs=resolver.has_outputs,
) )
from ..resource import create_urn # pylint: disable=import-outside-toplevel from ..resource import create_urn # pylint: disable=import-outside-toplevel