Add support for serialized resource references. (#5041)
Resources are serialized as their URN, ID, and package version. Each Pulumi package is expected to register itself with the SDK. The package will be invoked to construct appropriate instances of rehydrated resources. Packages are distinguished by their name and their version. This is the foundation of cross-process resources. Related to #2430. Co-authored-by: Mikhail Shilkov <github@mikhail.io> Co-authored-by: Luke Hoban <luke@pulumi.com> Co-authored-by: Levi Blackstone <levi@pulumi.com>
This commit is contained in:
parent
83f2aa613b
commit
3d2e31289a
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -22,6 +22,7 @@ coverage.cov
|
|||
# By default, we don't check in yarn.lock files
|
||||
**/yarn.lock
|
||||
|
||||
# Turning on MyPy in VSCode creates this workspace local folder
|
||||
.mypy_cache
|
||||
|
||||
# for goreleaser
|
||||
|
|
|
@ -414,6 +414,12 @@ func filterPropertyMap(propertyMap resource.PropertyMap, debug bool) resource.Pr
|
|||
return resource.Output{
|
||||
Element: filterPropertyValue(t.Element),
|
||||
}
|
||||
case resource.ResourceReference:
|
||||
return resource.ResourceReference{
|
||||
URN: resource.URN(filterValue(string(t.URN)).(string)),
|
||||
ID: resource.ID(filterValue(string(t.ID)).(string)),
|
||||
PackageVersion: filterValue(t.PackageVersion).(string),
|
||||
}
|
||||
}
|
||||
|
||||
// Next, see if it's an array, slice, pointer or struct, and handle each accordingly.
|
||||
|
|
|
@ -5527,6 +5527,57 @@ func TestSingleComponentDefaultProviderLifecycle(t *testing.T) {
|
|||
p.Run(t, nil)
|
||||
}
|
||||
|
||||
func TestResourceReferences(t *testing.T) {
|
||||
var urnA resource.URN
|
||||
var idA resource.ID
|
||||
|
||||
loaders := []*deploytest.ProviderLoader{
|
||||
deploytest.NewProviderLoader("pkgA", semver.MustParse("1.0.0"), func() (plugin.Provider, error) {
|
||||
v := &deploytest.Provider{
|
||||
CreateF: func(urn resource.URN, news resource.PropertyMap,
|
||||
timeout float64, preview bool) (resource.ID, resource.PropertyMap, resource.Status, error) {
|
||||
|
||||
if urn.Name() == "resB" {
|
||||
propA, ok := news["resA"]
|
||||
assert.True(t, ok)
|
||||
assert.Equal(t, resource.MakeResourceReference(urnA, idA, ""), propA)
|
||||
}
|
||||
|
||||
return "created-id", news, resource.StatusOK, nil
|
||||
},
|
||||
ReadF: func(urn resource.URN, id resource.ID,
|
||||
inputs, state resource.PropertyMap) (plugin.ReadResult, resource.Status, error) {
|
||||
return plugin.ReadResult{Inputs: inputs, Outputs: state}, resource.StatusOK, nil
|
||||
},
|
||||
}
|
||||
return v, nil
|
||||
}),
|
||||
}
|
||||
|
||||
program := deploytest.NewLanguageRuntime(func(_ plugin.RunInfo, monitor *deploytest.ResourceMonitor) error {
|
||||
var err error
|
||||
urnA, idA, _, err = monitor.RegisterResource("pkgA:m:typA", "resA", true)
|
||||
assert.NoError(t, err)
|
||||
|
||||
ins := resource.PropertyMap{
|
||||
"resA": resource.MakeResourceReference(urnA, idA, ""),
|
||||
}
|
||||
_, _, props, err := monitor.RegisterResource("pkgA:m:typA", "resB", true, deploytest.ResourceOptions{
|
||||
Inputs: ins,
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, ins, props)
|
||||
return nil
|
||||
})
|
||||
host := deploytest.NewPluginHost(nil, nil, program, loaders...)
|
||||
|
||||
p := &TestPlan{
|
||||
Options: UpdateOptions{Host: host},
|
||||
Steps: MakeBasicLifecycleSteps(t, 3),
|
||||
}
|
||||
p.Run(t, nil)
|
||||
}
|
||||
|
||||
type updateContext struct {
|
||||
*deploytest.ResourceMonitor
|
||||
|
||||
|
|
|
@ -88,7 +88,8 @@ func (rm *ResourceMonitor) RegisterResource(t tokens.Type, name string, custom b
|
|||
|
||||
// marshal inputs
|
||||
ins, err := plugin.MarshalProperties(opts.Inputs, plugin.MarshalOptions{
|
||||
KeepUnknowns: true,
|
||||
KeepUnknowns: true,
|
||||
KeepResources: true,
|
||||
})
|
||||
if err != nil {
|
||||
return "", "", nil, err
|
||||
|
@ -146,6 +147,7 @@ func (rm *ResourceMonitor) RegisterResource(t tokens.Type, name string, custom b
|
|||
DeleteBeforeReplaceDefined: opts.DeleteBeforeReplace != nil,
|
||||
IgnoreChanges: opts.IgnoreChanges,
|
||||
AcceptSecrets: true,
|
||||
AcceptResources: true,
|
||||
Version: opts.Version,
|
||||
Aliases: aliasStrings,
|
||||
ImportId: string(opts.ImportID),
|
||||
|
@ -161,7 +163,8 @@ func (rm *ResourceMonitor) RegisterResource(t tokens.Type, name string, custom b
|
|||
}
|
||||
// unmarshal outputs
|
||||
outs, err := plugin.UnmarshalProperties(resp.Object, plugin.MarshalOptions{
|
||||
KeepUnknowns: true,
|
||||
KeepUnknowns: true,
|
||||
KeepResources: true,
|
||||
})
|
||||
if err != nil {
|
||||
return "", "", nil, err
|
||||
|
@ -192,7 +195,8 @@ func (rm *ResourceMonitor) ReadResource(t tokens.Type, name string, id resource.
|
|||
|
||||
// marshal inputs
|
||||
ins, err := plugin.MarshalProperties(inputs, plugin.MarshalOptions{
|
||||
KeepUnknowns: true,
|
||||
KeepUnknowns: true,
|
||||
KeepResources: true,
|
||||
})
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
|
@ -214,7 +218,8 @@ func (rm *ResourceMonitor) ReadResource(t tokens.Type, name string, id resource.
|
|||
|
||||
// unmarshal outputs
|
||||
outs, err := plugin.UnmarshalProperties(resp.Properties, plugin.MarshalOptions{
|
||||
KeepUnknowns: true,
|
||||
KeepUnknowns: true,
|
||||
KeepResources: true,
|
||||
})
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
|
@ -228,7 +233,8 @@ func (rm *ResourceMonitor) Invoke(tok tokens.ModuleMember, inputs resource.Prope
|
|||
|
||||
// marshal inputs
|
||||
ins, err := plugin.MarshalProperties(inputs, plugin.MarshalOptions{
|
||||
KeepUnknowns: true,
|
||||
KeepUnknowns: true,
|
||||
KeepResources: true,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
|
@ -252,7 +258,8 @@ func (rm *ResourceMonitor) Invoke(tok tokens.ModuleMember, inputs resource.Prope
|
|||
|
||||
// unmarshal outputs
|
||||
outs, err := plugin.UnmarshalProperties(resp.Return, plugin.MarshalOptions{
|
||||
KeepUnknowns: true,
|
||||
KeepUnknowns: true,
|
||||
KeepResources: true,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
|
|
|
@ -532,7 +532,7 @@ func (rm *resmon) SupportsFeature(ctx context.Context,
|
|||
hasSupport := false
|
||||
|
||||
switch req.Id {
|
||||
case "secrets":
|
||||
case "secrets", "resourceReferences":
|
||||
hasSupport = true
|
||||
}
|
||||
|
||||
|
@ -560,9 +560,10 @@ func (rm *resmon) Invoke(ctx context.Context, req *pulumirpc.InvokeRequest) (*pu
|
|||
|
||||
args, err := plugin.UnmarshalProperties(
|
||||
req.GetArgs(), plugin.MarshalOptions{
|
||||
Label: label,
|
||||
KeepUnknowns: true,
|
||||
KeepSecrets: true,
|
||||
Label: label,
|
||||
KeepUnknowns: true,
|
||||
KeepSecrets: true,
|
||||
KeepResources: true,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to unmarshal %v args", tok)
|
||||
|
@ -575,8 +576,9 @@ func (rm *resmon) Invoke(ctx context.Context, req *pulumirpc.InvokeRequest) (*pu
|
|||
return nil, errors.Wrapf(err, "invocation of %v returned an error", tok)
|
||||
}
|
||||
mret, err := plugin.MarshalProperties(ret, plugin.MarshalOptions{
|
||||
Label: label,
|
||||
KeepUnknowns: true,
|
||||
Label: label,
|
||||
KeepUnknowns: true,
|
||||
KeepResources: true,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to marshal %v return", tok)
|
||||
|
@ -608,9 +610,10 @@ func (rm *resmon) StreamInvoke(
|
|||
|
||||
args, err := plugin.UnmarshalProperties(
|
||||
req.GetArgs(), plugin.MarshalOptions{
|
||||
Label: label,
|
||||
KeepUnknowns: true,
|
||||
KeepSecrets: true,
|
||||
Label: label,
|
||||
KeepUnknowns: true,
|
||||
KeepSecrets: true,
|
||||
KeepResources: true,
|
||||
})
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to unmarshal %v args", tok)
|
||||
|
@ -621,8 +624,9 @@ func (rm *resmon) StreamInvoke(
|
|||
logging.V(5).Infof("ResourceMonitor.StreamInvoke received: tok=%v #args=%v", tok, len(args))
|
||||
failures, err := prov.StreamInvoke(tok, args, func(event resource.PropertyMap) error {
|
||||
mret, err := plugin.MarshalProperties(event, plugin.MarshalOptions{
|
||||
Label: label,
|
||||
KeepUnknowns: true,
|
||||
Label: label,
|
||||
KeepUnknowns: true,
|
||||
KeepResources: req.GetAcceptResources(),
|
||||
})
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to marshal return")
|
||||
|
@ -681,9 +685,10 @@ func (rm *resmon) ReadResource(ctx context.Context,
|
|||
}
|
||||
|
||||
props, err := plugin.UnmarshalProperties(req.GetProperties(), plugin.MarshalOptions{
|
||||
Label: label,
|
||||
KeepUnknowns: true,
|
||||
KeepSecrets: true,
|
||||
Label: label,
|
||||
KeepUnknowns: true,
|
||||
KeepSecrets: true,
|
||||
KeepResources: true,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -723,9 +728,10 @@ func (rm *resmon) ReadResource(ctx context.Context,
|
|||
|
||||
contract.Assert(result != nil)
|
||||
marshaled, err := plugin.MarshalProperties(result.State.Outputs, plugin.MarshalOptions{
|
||||
Label: label,
|
||||
KeepUnknowns: true,
|
||||
KeepSecrets: req.GetAcceptSecrets(),
|
||||
Label: label,
|
||||
KeepUnknowns: true,
|
||||
KeepSecrets: req.GetAcceptSecrets(),
|
||||
KeepResources: req.GetAcceptResources(),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to marshal %s return state", result.State.URN)
|
||||
|
@ -804,6 +810,7 @@ func (rm *resmon) RegisterResource(ctx context.Context,
|
|||
KeepUnknowns: true,
|
||||
ComputeAssetHashes: true,
|
||||
KeepSecrets: true,
|
||||
KeepResources: true,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -942,9 +949,10 @@ func (rm *resmon) RegisterResource(ctx context.Context,
|
|||
// Finally, unpack the response into properties that we can return to the language runtime. This mostly includes
|
||||
// an ID, URN, and defaults and output properties that will all be blitted back onto the runtime object.
|
||||
obj, err := plugin.MarshalProperties(outputs, plugin.MarshalOptions{
|
||||
Label: label,
|
||||
KeepUnknowns: true,
|
||||
KeepSecrets: req.GetAcceptSecrets(),
|
||||
Label: label,
|
||||
KeepUnknowns: true,
|
||||
KeepSecrets: req.GetAcceptSecrets(),
|
||||
KeepResources: req.GetAcceptResources(),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -974,6 +982,7 @@ func (rm *resmon) RegisterResourceOutputs(ctx context.Context,
|
|||
KeepUnknowns: true,
|
||||
ComputeAssetHashes: true,
|
||||
KeepSecrets: true,
|
||||
KeepResources: true,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "cannot unmarshal output properties")
|
||||
|
|
|
@ -313,7 +313,12 @@ func (rm *queryResmon) Invoke(ctx context.Context, req *pulumirpc.InvokeRequest)
|
|||
}
|
||||
|
||||
args, err := plugin.UnmarshalProperties(
|
||||
req.GetArgs(), plugin.MarshalOptions{Label: label, KeepUnknowns: true})
|
||||
req.GetArgs(), plugin.MarshalOptions{
|
||||
Label: label,
|
||||
KeepUnknowns: true,
|
||||
KeepSecrets: true,
|
||||
KeepResources: true,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to unmarshal %v args", tok)
|
||||
}
|
||||
|
@ -324,7 +329,11 @@ func (rm *queryResmon) Invoke(ctx context.Context, req *pulumirpc.InvokeRequest)
|
|||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "invocation of %v returned an error", tok)
|
||||
}
|
||||
mret, err := plugin.MarshalProperties(ret, plugin.MarshalOptions{Label: label, KeepUnknowns: true})
|
||||
mret, err := plugin.MarshalProperties(ret, plugin.MarshalOptions{
|
||||
Label: label,
|
||||
KeepUnknowns: true,
|
||||
KeepResources: req.GetAcceptResources(),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to marshal return")
|
||||
}
|
||||
|
|
|
@ -370,6 +370,17 @@ func SerializePropertyValue(prop resource.PropertyValue, enc config.Encrypter,
|
|||
return prop.ArchiveValue().Serialize(), nil
|
||||
}
|
||||
|
||||
// We serialize resource references using a map-based representation similar to assets, archives, and secrets.
|
||||
if prop.IsResourceReference() {
|
||||
ref := prop.ResourceReferenceValue()
|
||||
return map[string]interface{}{
|
||||
resource.SigKey: resource.ResourceReferenceSig,
|
||||
"urn": ref.URN,
|
||||
"id": ref.ID,
|
||||
"packageVersion": ref.PackageVersion,
|
||||
}, nil
|
||||
}
|
||||
|
||||
if prop.IsSecret() {
|
||||
// Since we are going to encrypt property value, we can elide encrypting sub-elements. We'll mark them as
|
||||
// "secret" so we retain that information when deserializaing the overall structure, but there is no
|
||||
|
@ -543,6 +554,32 @@ func DeserializePropertyValue(v interface{}, dec config.Decrypter,
|
|||
cachingCrypter.insert(prop.SecretValue(), plaintext, ciphertext)
|
||||
}
|
||||
return prop, nil
|
||||
case resource.ResourceReferenceSig:
|
||||
urnStr, ok := objmap["urn"].(string)
|
||||
if !ok {
|
||||
return resource.PropertyValue{}, errors.New("malformed resource value: missing urn")
|
||||
}
|
||||
urn := resource.URN(urnStr)
|
||||
|
||||
var id resource.ID
|
||||
if idV, ok := objmap["id"]; ok {
|
||||
idStr, ok := idV.(string)
|
||||
if !ok {
|
||||
return resource.PropertyValue{}, errors.New("malformed resource value: id must be a string")
|
||||
}
|
||||
id = resource.ID(idStr)
|
||||
}
|
||||
|
||||
var packageVersion string
|
||||
if packageVersionV, ok := objmap["packageVersion"]; ok {
|
||||
packageVersion, ok = packageVersionV.(string)
|
||||
if !ok {
|
||||
return resource.PropertyValue{},
|
||||
errors.New("malformed resource value: packageVersion must be a string")
|
||||
}
|
||||
}
|
||||
|
||||
return resource.MakeResourceReference(urn, id, packageVersion), nil
|
||||
default:
|
||||
return resource.PropertyValue{}, errors.Errorf("unrecognized signature '%v' in property map", sig)
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ namespace Pulumi.Tests.Serialization
|
|||
{
|
||||
var serializer = new Serializer(excessiveDebugOutput: false);
|
||||
return Serializer.CreateValue(
|
||||
await serializer.SerializeAsync(ctx: "", value).ConfigureAwait(false));
|
||||
await serializer.SerializeAsync(ctx: "", value, true).ConfigureAwait(false));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// Copyright 2016-2019, Pulumi Corporation
|
||||
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Pulumi.Testing;
|
||||
|
@ -51,6 +52,7 @@ namespace Pulumi
|
|||
private readonly string _projectName;
|
||||
private readonly string _stackName;
|
||||
private readonly bool _isDryRun;
|
||||
private readonly ConcurrentDictionary<string, bool> _featureSupport = new ConcurrentDictionary<string, bool>();
|
||||
|
||||
private readonly ILogger _logger;
|
||||
private readonly IRunner _runner;
|
||||
|
@ -131,5 +133,21 @@ namespace Pulumi
|
|||
get => Stack;
|
||||
set => Stack = value;
|
||||
}
|
||||
|
||||
private async Task<bool> MonitorSupportsFeature(string feature)
|
||||
{
|
||||
if (!this._featureSupport.ContainsKey(feature))
|
||||
{
|
||||
var request = new Pulumirpc.SupportsFeatureRequest {Id = feature };
|
||||
var response = await this.Monitor.SupportsFeatureAsync(request).ConfigureAwait(false);
|
||||
this._featureSupport[feature] = response.HasSupport;
|
||||
}
|
||||
return this._featureSupport[feature];
|
||||
}
|
||||
|
||||
internal Task<bool> MonitorSupportsResourceReferences()
|
||||
{
|
||||
return MonitorSupportsFeature("resourceReferences");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,7 +27,9 @@ namespace Pulumi
|
|||
|
||||
// Wait for all values to be available, and then perform the RPC.
|
||||
var argsDict = await args.ToDictionaryAsync().ConfigureAwait(false);
|
||||
var serialized = await SerializeAllPropertiesAsync($"invoke:{token}", argsDict);
|
||||
var serialized = await SerializeAllPropertiesAsync(
|
||||
$"invoke:{token}",
|
||||
argsDict, await this.MonitorSupportsResourceReferences().ConfigureAwait(false)).ConfigureAwait(false);
|
||||
Log.Debug($"Invoke RPC prepared: token={token}" +
|
||||
(_excessiveDebugOutput ? $", obj={serialized}" : ""));
|
||||
|
||||
|
|
|
@ -31,7 +31,10 @@ namespace Pulumi
|
|||
LogExcessive($"Serializing properties: t={type}, name={name}, custom={custom}");
|
||||
var dictionary = await args.ToDictionaryAsync().ConfigureAwait(false);
|
||||
var (serializedProps, propertyToDirectDependencies) =
|
||||
await SerializeResourcePropertiesAsync(label, dictionary).ConfigureAwait(false);
|
||||
await SerializeResourcePropertiesAsync(
|
||||
label,
|
||||
dictionary,
|
||||
await this.MonitorSupportsResourceReferences().ConfigureAwait(false)).ConfigureAwait(false);
|
||||
LogExcessive($"Serialized properties: t={type}, name={name}, custom={custom}");
|
||||
|
||||
// Wait for the parent to complete.
|
||||
|
|
|
@ -29,7 +29,7 @@ namespace Pulumi
|
|||
var urn = await resource.Urn.GetValueAsync().ConfigureAwait(false);
|
||||
var props = await outputs.GetValueAsync().ConfigureAwait(false);
|
||||
|
||||
var serialized = await SerializeAllPropertiesAsync(opLabel, props).ConfigureAwait(false);
|
||||
var serialized = await SerializeAllPropertiesAsync(opLabel, props, true).ConfigureAwait(false);
|
||||
Log.Debug($"RegisterResourceOutputs RPC prepared: urn={urn}" +
|
||||
(_excessiveDebugOutput ? $", outputs ={JsonFormatter.Default.Format(serialized)}" : ""));
|
||||
|
||||
|
|
15
sdk/dotnet/Pulumi/Deployment/Deployment_ResourcePackages.cs
Normal file
15
sdk/dotnet/Pulumi/Deployment/Deployment_ResourcePackages.cs
Normal file
|
@ -0,0 +1,15 @@
|
|||
// Copyright 2016-2020, Pulumi Corporation
|
||||
|
||||
using System;
|
||||
using Pulumi.Serialization;
|
||||
|
||||
namespace Pulumi
|
||||
{
|
||||
public partial class Deployment
|
||||
{
|
||||
public static void RegisterResourcePackage(string name, string version, IResourcePackage package)
|
||||
{
|
||||
ResourcePackages.RegisterResourcePackage(name, version, package);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -21,16 +21,16 @@ namespace Pulumi
|
|||
/// to registerResource.
|
||||
/// </summary>
|
||||
private static Task<SerializationResult> SerializeResourcePropertiesAsync(
|
||||
string label, IDictionary<string, object?> args)
|
||||
string label, IDictionary<string, object?> args, bool keepResources)
|
||||
{
|
||||
return SerializeFilteredPropertiesAsync(
|
||||
label, args, key => key != Constants.IdPropertyName && key != Constants.UrnPropertyName);
|
||||
label, args, key => key != Constants.IdPropertyName && key != Constants.UrnPropertyName, keepResources);
|
||||
}
|
||||
|
||||
private static async Task<Struct> SerializeAllPropertiesAsync(
|
||||
string label, IDictionary<string, object?> args)
|
||||
string label, IDictionary<string, object?> args, bool keepResources)
|
||||
{
|
||||
var result = await SerializeFilteredPropertiesAsync(label, args, _ => true).ConfigureAwait(false);
|
||||
var result = await SerializeFilteredPropertiesAsync(label, args, _ => true, keepResources).ConfigureAwait(false);
|
||||
return result.Serialized;
|
||||
}
|
||||
|
||||
|
@ -40,7 +40,7 @@ namespace Pulumi
|
|||
/// creating a reasonable POCO object that can be remoted over to registerResource.
|
||||
/// </summary>
|
||||
private static async Task<SerializationResult> SerializeFilteredPropertiesAsync(
|
||||
string label, IDictionary<string, object?> args, Predicate<string> acceptKey)
|
||||
string label, IDictionary<string, object?> args, Predicate<string> acceptKey, bool keepResources)
|
||||
{
|
||||
var propertyToDependentResources = ImmutableDictionary.CreateBuilder<string, HashSet<Resource>>();
|
||||
var result = ImmutableDictionary.CreateBuilder<string, object>();
|
||||
|
@ -51,7 +51,7 @@ namespace Pulumi
|
|||
{
|
||||
// We treat properties with null values as if they do not exist.
|
||||
var serializer = new Serializer(_excessiveDebugOutput);
|
||||
var v = await serializer.SerializeAsync($"{label}.{key}", val).ConfigureAwait(false);
|
||||
var v = await serializer.SerializeAsync($"{label}.{key}", val, keepResources).ConfigureAwait(false);
|
||||
if (v != null)
|
||||
{
|
||||
result[key] = v;
|
||||
|
|
|
@ -19,6 +19,9 @@ namespace Pulumi
|
|||
this._client = new ResourceMonitor.ResourceMonitorClient(new Channel(monitor, ChannelCredentials.Insecure, grpcChannelOptions));
|
||||
}
|
||||
|
||||
public async Task<SupportsFeatureResponse> SupportsFeatureAsync(SupportsFeatureRequest request)
|
||||
=> await this._client.SupportsFeatureAsync(request);
|
||||
|
||||
public async Task<InvokeResponse> InvokeAsync(InvokeRequest request)
|
||||
=> await this._client.InvokeAsync(request);
|
||||
|
||||
|
|
|
@ -7,6 +7,8 @@ namespace Pulumi
|
|||
{
|
||||
internal interface IMonitor
|
||||
{
|
||||
Task<SupportsFeatureResponse> SupportsFeatureAsync(SupportsFeatureRequest request);
|
||||
|
||||
Task<InvokeResponse> InvokeAsync(InvokeRequest request);
|
||||
|
||||
Task<ReadResourceResponse> ReadResourceAsync(Resource resource, ReadResourceRequest request);
|
||||
|
|
|
@ -173,6 +173,9 @@ Pulumi.ResourceTransformationResult
|
|||
Pulumi.ResourceTransformationResult.Args.get -> Pulumi.ResourceArgs
|
||||
Pulumi.ResourceTransformationResult.Options.get -> Pulumi.ResourceOptions
|
||||
Pulumi.ResourceTransformationResult.ResourceTransformationResult(Pulumi.ResourceArgs args, Pulumi.ResourceOptions options) -> void
|
||||
Pulumi.IResourcePackage
|
||||
Pulumi.IResourcePackage.Construct(string name, string type, System.Collections.Generic.IDictionary<string, object> args, string urn) -> Pulumi.Resource
|
||||
Pulumi.IResourcePackage.ConstructProvider(string name, string type, System.Collections.Generic.IDictionary<string, object> args, string urn) -> Pulumi.ProviderResource
|
||||
Pulumi.Stack
|
||||
Pulumi.Stack.Stack(Pulumi.StackOptions options = null) -> void
|
||||
Pulumi.StackOptions
|
||||
|
@ -226,6 +229,7 @@ override Pulumi.Union<T0, T1>.ToString() -> string
|
|||
static Pulumi.ComponentResourceOptions.Merge(Pulumi.ComponentResourceOptions options1, Pulumi.ComponentResourceOptions options2) -> Pulumi.ComponentResourceOptions
|
||||
static Pulumi.CustomResourceOptions.Merge(Pulumi.CustomResourceOptions options1, Pulumi.CustomResourceOptions options2) -> Pulumi.CustomResourceOptions
|
||||
static Pulumi.Deployment.Instance.get -> Pulumi.DeploymentInstance
|
||||
static Pulumi.Deployment.RegisterResourcePackage(string name, string version, Pulumi.IResourcePackage package) -> void
|
||||
static Pulumi.Deployment.RunAsync(System.Action action) -> System.Threading.Tasks.Task<int>
|
||||
static Pulumi.Deployment.RunAsync(System.Func<System.Collections.Generic.IDictionary<string, object>> func) -> System.Threading.Tasks.Task<int>
|
||||
static Pulumi.Deployment.RunAsync(System.Func<System.Threading.Tasks.Task> func) -> System.Threading.Tasks.Task<int>
|
||||
|
|
|
@ -75,7 +75,7 @@ namespace Pulumi
|
|||
return null;
|
||||
|
||||
var serializer = new Serializer(excessiveDebugOutput: false);
|
||||
var obj = await serializer.SerializeAsync(context, input).ConfigureAwait(false);
|
||||
var obj = await serializer.SerializeAsync(context, input, false).ConfigureAwait(false);
|
||||
var value = Serializer.CreateValue(obj);
|
||||
return JsonFormatter.Default.Format(value);
|
||||
}
|
||||
|
|
|
@ -10,25 +10,30 @@ namespace Pulumi.Serialization
|
|||
public const string UnknownValue = "04da6b54-80e4-46f7-96ec-b56ff0331ba9";
|
||||
|
||||
/// <summary>
|
||||
/// SpecialSigKey is sometimes used to encode type identity inside of a map. See pkg/resource/properties.go.
|
||||
/// SpecialSigKey is sometimes used to encode type identity inside of a map. See sdk/go/common/resource/properties.go.
|
||||
/// </summary>
|
||||
public const string SpecialSigKey = "4dabf18193072939515e22adb298388d";
|
||||
|
||||
/// <summary>
|
||||
/// SpecialAssetSig is a randomly assigned hash used to identify assets in maps. See pkg/resource/asset.go.
|
||||
/// SpecialAssetSig is a randomly assigned hash used to identify assets in maps. See sdk/go/common/resource/asset.go.
|
||||
/// </summary>
|
||||
public const string SpecialAssetSig = "c44067f5952c0a294b673a41bacd8c17";
|
||||
|
||||
/// <summary>
|
||||
/// SpecialArchiveSig is a randomly assigned hash used to identify archives in maps. See pkg/resource/asset.go.
|
||||
/// SpecialArchiveSig is a randomly assigned hash used to identify archives in maps. See sdk/go/common/resource/asset.go.
|
||||
/// </summary>
|
||||
public const string SpecialArchiveSig = "0def7320c3a5731c473e5ecbe6d01bc7";
|
||||
|
||||
/// <summary>
|
||||
/// SpecialSecretSig is a randomly assigned hash used to identify secrets in maps. See pkg/resource/properties.go.
|
||||
/// SpecialSecretSig is a randomly assigned hash used to identify secrets in maps. See sdk/go/common/resource/properties.go.
|
||||
/// </summary>
|
||||
public const string SpecialSecretSig = "1b47061264138c4ac30d75fd1eb44270";
|
||||
|
||||
/// <summary>
|
||||
/// SpecialResourceSig is a randomly assigned hash used to identify resources in maps. See sdk/go/common/resource/properties.go.
|
||||
/// </summary>
|
||||
public const string SpecialResourceSig = "5cf8f73096256a8f31e491e813e4eb8e";
|
||||
|
||||
public const string SecretValueName = "value";
|
||||
|
||||
public const string AssetTextName = "text";
|
||||
|
@ -37,6 +42,9 @@ namespace Pulumi.Serialization
|
|||
public const string AssetOrArchivePathName = "path";
|
||||
public const string AssetOrArchiveUriName = "uri";
|
||||
|
||||
public const string ResourceUrnName = "urn";
|
||||
public const string ResourceVersionName = "version";
|
||||
|
||||
public const string IdPropertyName = "id";
|
||||
public const string UrnPropertyName = "urn";
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// Copyright 2016-2019, Pulumi Corporation
|
||||
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Immutable;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Google.Protobuf.Collections;
|
||||
|
@ -26,6 +27,10 @@ namespace Pulumi.Serialization
|
|||
{
|
||||
return new OutputData<T>(ImmutableHashSet<Resource>.Empty, (T)(object)assetOrArchive, isKnown: true, isSecret);
|
||||
}
|
||||
else if (TryDeserializeResource(value, out var resource))
|
||||
{
|
||||
return new OutputData<T>(ImmutableHashSet<Resource>.Empty, (T)(object)resource, isKnown: true, isSecret);
|
||||
}
|
||||
|
||||
var innerData = func(value);
|
||||
return OutputData.Create(innerData.Resources, innerData.Value, innerData.IsKnown, isSecret || innerData.IsSecret);
|
||||
|
@ -204,6 +209,53 @@ namespace Pulumi.Serialization
|
|||
throw new InvalidOperationException("Value was marked as Asset, but did not conform to required shape.");
|
||||
}
|
||||
|
||||
private static bool TryDeserializeResource(
|
||||
Value value, [NotNullWhen(true)] out Resource? resource)
|
||||
{
|
||||
if (!IsSpecialStruct(value, out var sig) || sig != Constants.SpecialResourceSig)
|
||||
{
|
||||
resource = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
string? urn;
|
||||
if (!TryGetStringValue(value.StructValue.Fields, Constants.ResourceUrnName, out urn))
|
||||
{
|
||||
throw new InvalidOperationException("Value was marked as a Resource, but did not conform to required shape.");
|
||||
}
|
||||
|
||||
string? version;
|
||||
if (!TryGetStringValue(value.StructValue.Fields, Constants.ResourceVersionName, out version))
|
||||
{
|
||||
throw new InvalidOperationException("Value was marked as a Resource, but did not conform to required shape.");
|
||||
}
|
||||
|
||||
var urnParts = urn.Split("::");
|
||||
var qualifiedType = urnParts[2];
|
||||
var qualifiedTypeParts = qualifiedType.Split('$');
|
||||
var type = qualifiedTypeParts[qualifiedTypeParts.Length-1];
|
||||
|
||||
var typeParts = type.Split(':');
|
||||
var pkgName = typeParts[0];
|
||||
var modName = typeParts.Length > 1 ? typeParts[1] : "";
|
||||
var typeName = typeParts.Length > 2 ? typeParts[2] : "";
|
||||
var isProvider = pkgName == "pulumi" && modName == "providers";
|
||||
if (isProvider) {
|
||||
pkgName = typeName;
|
||||
}
|
||||
|
||||
IResourcePackage? package;
|
||||
if (!ResourcePackages.TryGetResourcePackage(pkgName, version, out package))
|
||||
{
|
||||
throw new InvalidOperationException($"Unable to deserialize resource URN {urn}, no resource package is registered for type {type}.");
|
||||
}
|
||||
var urnName = urnParts[3];
|
||||
resource = !isProvider ?
|
||||
package.Construct(urnName, type, null, urn) :
|
||||
package.ConstructProvider(urnName, type, null, urn);
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool TryGetStringValue(
|
||||
MapField<string, Value> fields, string keyName, [NotNullWhen(true)] out string? result)
|
||||
{
|
||||
|
|
41
sdk/dotnet/Pulumi/Serialization/ResourcePackages.cs
Normal file
41
sdk/dotnet/Pulumi/Serialization/ResourcePackages.cs
Normal file
|
@ -0,0 +1,41 @@
|
|||
// Copyright 2016-2019, Pulumi Corporation
|
||||
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Google.Protobuf.Collections;
|
||||
using Google.Protobuf.WellKnownTypes;
|
||||
|
||||
namespace Pulumi
|
||||
{
|
||||
public interface IResourcePackage
|
||||
{
|
||||
Resource Construct(string name, string type, IDictionary<string, object?>? args, string urn);
|
||||
ProviderResource ConstructProvider(string name, string type, IDictionary<string, object?>? args, string urn);
|
||||
}
|
||||
|
||||
internal static class ResourcePackages
|
||||
{
|
||||
internal static ConcurrentDictionary<string, IResourcePackage> _resourcePackages = new ConcurrentDictionary<string, IResourcePackage>();
|
||||
|
||||
private static string PackageKey(string name, string version)
|
||||
{
|
||||
return $"{name}@{version}";
|
||||
}
|
||||
|
||||
internal static bool TryGetResourcePackage(string name, string version, [NotNullWhen(true)] out IResourcePackage? package)
|
||||
{
|
||||
return _resourcePackages.TryGetValue(PackageKey(name, version), out package);
|
||||
}
|
||||
|
||||
public static void RegisterResourcePackage(string name, string version, IResourcePackage package)
|
||||
{
|
||||
var key = PackageKey(name, version);
|
||||
if (!_resourcePackages.TryAdd(key, package))
|
||||
{
|
||||
throw new InvalidOperationException($"Cannot re-register package {key}.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -65,7 +65,7 @@ namespace Pulumi.Serialization
|
|||
/// </list>
|
||||
/// No other result type are allowed to be returned.
|
||||
/// </summary>
|
||||
public async Task<object?> SerializeAsync(string ctx, object? prop)
|
||||
public async Task<object?> SerializeAsync(string ctx, object? prop, bool keepResources)
|
||||
{
|
||||
// IMPORTANT:
|
||||
// IMPORTANT: Keep this in sync with serializesPropertiesSync in invoke.ts
|
||||
|
@ -85,10 +85,10 @@ namespace Pulumi.Serialization
|
|||
}
|
||||
|
||||
if (prop is InputArgs args)
|
||||
return await SerializeInputArgsAsync(ctx, args).ConfigureAwait(false);
|
||||
return await SerializeInputArgsAsync(ctx, args, keepResources).ConfigureAwait(false);
|
||||
|
||||
if (prop is AssetOrArchive assetOrArchive)
|
||||
return await SerializeAssetOrArchiveAsync(ctx, assetOrArchive).ConfigureAwait(false);
|
||||
return await SerializeAssetOrArchiveAsync(ctx, assetOrArchive, keepResources).ConfigureAwait(false);
|
||||
|
||||
if (prop is Task)
|
||||
{
|
||||
|
@ -103,7 +103,7 @@ $"Tasks are not allowed inside ResourceArgs. Please wrap your Task in an Output:
|
|||
Log.Debug($"Serialize property[{ctx}]: Recursing into IInput");
|
||||
}
|
||||
|
||||
return await SerializeAsync(ctx, input.ToOutput()).ConfigureAwait(false);
|
||||
return await SerializeAsync(ctx, input.ToOutput(), keepResources).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
if (prop is IUnion union)
|
||||
|
@ -113,7 +113,7 @@ $"Tasks are not allowed inside ResourceArgs. Please wrap your Task in an Output:
|
|||
Log.Debug($"Serialize property[{ctx}]: Recursing into IUnion");
|
||||
}
|
||||
|
||||
return await SerializeAsync(ctx, union.Value).ConfigureAwait(false);
|
||||
return await SerializeAsync(ctx, union.Value, keepResources).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
if (prop is JsonElement element)
|
||||
|
@ -145,7 +145,7 @@ $"Tasks are not allowed inside ResourceArgs. Please wrap your Task in an Output:
|
|||
if (!isKnown)
|
||||
return Constants.UnknownValue;
|
||||
|
||||
var value = await SerializeAsync($"{ctx}.id", data.Value).ConfigureAwait(false);
|
||||
var value = await SerializeAsync($"{ctx}.id", data.Value, keepResources).ConfigureAwait(false);
|
||||
if (isSecret)
|
||||
{
|
||||
var builder = ImmutableDictionary.CreateBuilder<string, object?>();
|
||||
|
@ -166,7 +166,15 @@ $"Tasks are not allowed inside ResourceArgs. Please wrap your Task in an Output:
|
|||
}
|
||||
|
||||
this.DependentResources.Add(customResource);
|
||||
return await SerializeAsync($"{ctx}.id", customResource.Id).ConfigureAwait(false);
|
||||
if (keepResources)
|
||||
{
|
||||
var urn = await SerializeAsync($"{ctx}.urn", customResource.Urn, keepResources).ConfigureAwait(false);
|
||||
var builder = ImmutableDictionary.CreateBuilder<string, object?>();
|
||||
builder.Add(Constants.SpecialSigKey, Constants.SpecialResourceSig);
|
||||
builder.Add(Constants.ResourceUrnName, urn);
|
||||
return builder.ToImmutable();
|
||||
}
|
||||
return await SerializeAsync($"{ctx}.id", customResource.Id, keepResources).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
if (prop is ComponentResource componentResource)
|
||||
|
@ -193,14 +201,22 @@ $"Tasks are not allowed inside ResourceArgs. Please wrap your Task in an Output:
|
|||
Log.Debug($"Serialize property[{ctx}]: Encountered ComponentResource");
|
||||
}
|
||||
|
||||
return await SerializeAsync($"{ctx}.urn", componentResource.Urn).ConfigureAwait(false);
|
||||
var urn = await SerializeAsync($"{ctx}.urn", componentResource.Urn, keepResources).ConfigureAwait(false);
|
||||
if (keepResources)
|
||||
{
|
||||
var builder = ImmutableDictionary.CreateBuilder<string, object?>();
|
||||
builder.Add(Constants.SpecialSigKey, Constants.SpecialResourceSig);
|
||||
builder.Add(Constants.ResourceUrnName, urn);
|
||||
return builder.ToImmutable();
|
||||
}
|
||||
return urn;
|
||||
}
|
||||
|
||||
if (prop is IDictionary dictionary)
|
||||
return await SerializeDictionaryAsync(ctx, dictionary).ConfigureAwait(false);
|
||||
return await SerializeDictionaryAsync(ctx, dictionary, keepResources).ConfigureAwait(false);
|
||||
|
||||
if (prop is IList list)
|
||||
return await SerializeListAsync(ctx, list).ConfigureAwait(false);
|
||||
return await SerializeListAsync(ctx, list, keepResources).ConfigureAwait(false);
|
||||
|
||||
throw new InvalidOperationException($"{prop.GetType().FullName} is not a supported argument type.\n\t{ctx}");
|
||||
}
|
||||
|
@ -246,7 +262,7 @@ $"Tasks are not allowed inside ResourceArgs. Please wrap your Task in an Output:
|
|||
}
|
||||
}
|
||||
|
||||
private async Task<ImmutableDictionary<string, object>> SerializeAssetOrArchiveAsync(string ctx, AssetOrArchive assetOrArchive)
|
||||
private async Task<ImmutableDictionary<string, object>> SerializeAssetOrArchiveAsync(string ctx, AssetOrArchive assetOrArchive, bool keepResources)
|
||||
{
|
||||
if (_excessiveDebugOutput)
|
||||
{
|
||||
|
@ -254,7 +270,7 @@ $"Tasks are not allowed inside ResourceArgs. Please wrap your Task in an Output:
|
|||
}
|
||||
|
||||
var propName = assetOrArchive.PropName;
|
||||
var value = await SerializeAsync(ctx + "." + propName, assetOrArchive.Value).ConfigureAwait(false);
|
||||
var value = await SerializeAsync(ctx + "." + propName, assetOrArchive.Value, keepResources).ConfigureAwait(false);
|
||||
|
||||
var builder = ImmutableDictionary.CreateBuilder<string, object>();
|
||||
builder.Add(Constants.SpecialSigKey, assetOrArchive.SigKey);
|
||||
|
@ -262,7 +278,7 @@ $"Tasks are not allowed inside ResourceArgs. Please wrap your Task in an Output:
|
|||
return builder.ToImmutable();
|
||||
}
|
||||
|
||||
private async Task<ImmutableDictionary<string, object>> SerializeInputArgsAsync(string ctx, InputArgs args)
|
||||
private async Task<ImmutableDictionary<string, object>> SerializeInputArgsAsync(string ctx, InputArgs args, bool keepResources)
|
||||
{
|
||||
if (_excessiveDebugOutput)
|
||||
{
|
||||
|
@ -270,10 +286,10 @@ $"Tasks are not allowed inside ResourceArgs. Please wrap your Task in an Output:
|
|||
}
|
||||
|
||||
var dictionary = await args.ToDictionaryAsync().ConfigureAwait(false);
|
||||
return await SerializeDictionaryAsync(ctx, dictionary).ConfigureAwait(false);
|
||||
return await SerializeDictionaryAsync(ctx, dictionary, keepResources).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private async Task<ImmutableArray<object?>> SerializeListAsync(string ctx, IList list)
|
||||
private async Task<ImmutableArray<object?>> SerializeListAsync(string ctx, IList list, bool keepResources)
|
||||
{
|
||||
if (_excessiveDebugOutput)
|
||||
{
|
||||
|
@ -288,13 +304,13 @@ $"Tasks are not allowed inside ResourceArgs. Please wrap your Task in an Output:
|
|||
Log.Debug($"Serialize property[{ctx}]: array[{i}] element");
|
||||
}
|
||||
|
||||
result.Add(await SerializeAsync($"{ctx}[{i}]", list[i]).ConfigureAwait(false));
|
||||
result.Add(await SerializeAsync($"{ctx}[{i}]", list[i], keepResources).ConfigureAwait(false));
|
||||
}
|
||||
|
||||
return result.MoveToImmutable();
|
||||
}
|
||||
|
||||
private async Task<ImmutableDictionary<string, object>> SerializeDictionaryAsync(string ctx, IDictionary dictionary)
|
||||
private async Task<ImmutableDictionary<string, object>> SerializeDictionaryAsync(string ctx, IDictionary dictionary, bool keepResources)
|
||||
{
|
||||
if (_excessiveDebugOutput)
|
||||
{
|
||||
|
@ -317,7 +333,7 @@ $"Tasks are not allowed inside ResourceArgs. Please wrap your Task in an Output:
|
|||
|
||||
// When serializing an object, we omit any keys with null values. This matches
|
||||
// JSON semantics.
|
||||
var v = await SerializeAsync($"{ctx}.{stringKey}", dictionary[stringKey]).ConfigureAwait(false);
|
||||
var v = await SerializeAsync($"{ctx}.{stringKey}", dictionary[stringKey], keepResources).ConfigureAwait(false);
|
||||
if (v != null)
|
||||
{
|
||||
result[stringKey] = v;
|
||||
|
|
|
@ -23,6 +23,12 @@ namespace Pulumi.Testing
|
|||
_mocks = mocks;
|
||||
}
|
||||
|
||||
public Task<SupportsFeatureResponse> SupportsFeatureAsync(SupportsFeatureRequest request)
|
||||
{
|
||||
var hasSupport = request.Id == "secrets" || request.Id == "resourceReferences";
|
||||
return Task.FromResult(new SupportsFeatureResponse { HasSupport = hasSupport });
|
||||
}
|
||||
|
||||
public async Task<InvokeResponse> InvokeAsync(InvokeRequest request)
|
||||
{
|
||||
var result = await _mocks.CallAsync(request.Tok, ToDictionary(request.Args), request.Provider)
|
||||
|
@ -104,7 +110,7 @@ namespace Pulumi.Testing
|
|||
private async Task<Struct> SerializeAsync(object o)
|
||||
{
|
||||
var dict = (o as IDictionary<string, object>)?.ToImmutableDictionary()
|
||||
?? await _serializer.SerializeAsync("", o).ConfigureAwait(false) as ImmutableDictionary<string, object>
|
||||
?? await _serializer.SerializeAsync("", o, true).ConfigureAwait(false) as ImmutableDictionary<string, object>
|
||||
?? throw new InvalidOperationException($"{o.GetType().FullName} is not a supported argument type");
|
||||
return Serializer.CreateStruct(dict);
|
||||
}
|
||||
|
|
|
@ -60,7 +60,8 @@ type provider struct {
|
|||
cfgerr error // non-nil if a configure call fails.
|
||||
cfgknown bool // true if all configuration values are known.
|
||||
cfgdone chan bool // closed when configuration has completed.
|
||||
acceptSecrets bool // true if this plugin can consume strongly-typed secrets.
|
||||
acceptSecrets bool // true if this plugin accepts strongly-typed secrets.
|
||||
acceptResources bool // true if this plugin accepts strongly-typed resource refs.
|
||||
supportsPreview bool // true if this plugin supports previews for Create and Update.
|
||||
disableProviderPreview bool // true if previews for Create and Update are disabled.
|
||||
}
|
||||
|
@ -155,18 +156,20 @@ func (p *provider) CheckConfig(urn resource.URN, olds,
|
|||
logging.V(7).Infof("%s executing (#olds=%d,#news=%d)", label, len(olds), len(news))
|
||||
|
||||
molds, err := MarshalProperties(olds, MarshalOptions{
|
||||
Label: fmt.Sprintf("%s.olds", label),
|
||||
KeepUnknowns: allowUnknowns,
|
||||
KeepSecrets: p.acceptSecrets,
|
||||
Label: fmt.Sprintf("%s.olds", label),
|
||||
KeepUnknowns: allowUnknowns,
|
||||
KeepSecrets: p.acceptSecrets,
|
||||
KeepResources: p.acceptResources,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
mnews, err := MarshalProperties(news, MarshalOptions{
|
||||
Label: fmt.Sprintf("%s.news", label),
|
||||
KeepUnknowns: allowUnknowns,
|
||||
KeepSecrets: p.acceptSecrets,
|
||||
Label: fmt.Sprintf("%s.news", label),
|
||||
KeepUnknowns: allowUnknowns,
|
||||
KeepSecrets: p.acceptSecrets,
|
||||
KeepResources: p.acceptResources,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
|
@ -198,6 +201,7 @@ func (p *provider) CheckConfig(urn resource.URN, olds,
|
|||
KeepUnknowns: allowUnknowns,
|
||||
RejectUnknowns: !allowUnknowns,
|
||||
KeepSecrets: true,
|
||||
KeepResources: true,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
|
@ -256,18 +260,20 @@ func (p *provider) DiffConfig(urn resource.URN, olds, news resource.PropertyMap,
|
|||
label := fmt.Sprintf("%s.DiffConfig(%s)", p.label(), urn)
|
||||
logging.V(7).Infof("%s executing (#olds=%d,#news=%d)", label, len(olds), len(news))
|
||||
molds, err := MarshalProperties(olds, MarshalOptions{
|
||||
Label: fmt.Sprintf("%s.olds", label),
|
||||
KeepUnknowns: true,
|
||||
KeepSecrets: p.acceptSecrets,
|
||||
Label: fmt.Sprintf("%s.olds", label),
|
||||
KeepUnknowns: true,
|
||||
KeepSecrets: p.acceptSecrets,
|
||||
KeepResources: p.acceptResources,
|
||||
})
|
||||
if err != nil {
|
||||
return DiffResult{}, err
|
||||
}
|
||||
|
||||
mnews, err := MarshalProperties(news, MarshalOptions{
|
||||
Label: fmt.Sprintf("%s.news", label),
|
||||
KeepUnknowns: true,
|
||||
KeepSecrets: p.acceptSecrets,
|
||||
Label: fmt.Sprintf("%s.news", label),
|
||||
KeepUnknowns: true,
|
||||
KeepSecrets: p.acceptSecrets,
|
||||
KeepResources: p.acceptResources,
|
||||
})
|
||||
if err != nil {
|
||||
return DiffResult{}, err
|
||||
|
@ -430,7 +436,7 @@ func (p *provider) Configure(inputs resource.PropertyMap) error {
|
|||
}
|
||||
|
||||
if v.ContainsUnknowns() {
|
||||
p.cfgknown, p.acceptSecrets = false, false
|
||||
p.cfgknown, p.acceptSecrets, p.acceptResources = false, false, false
|
||||
close(p.cfgdone)
|
||||
return nil
|
||||
}
|
||||
|
@ -452,9 +458,10 @@ func (p *provider) Configure(inputs resource.PropertyMap) error {
|
|||
}
|
||||
|
||||
minputs, err := MarshalProperties(inputs, MarshalOptions{
|
||||
Label: fmt.Sprintf("%s.inputs", label),
|
||||
KeepUnknowns: true,
|
||||
KeepSecrets: true,
|
||||
Label: fmt.Sprintf("%s.inputs", label),
|
||||
KeepUnknowns: true,
|
||||
KeepSecrets: true,
|
||||
KeepResources: true,
|
||||
})
|
||||
if err != nil {
|
||||
p.cfgerr = errors.Wrapf(err, "marshaling provider inputs")
|
||||
|
@ -466,9 +473,10 @@ func (p *provider) Configure(inputs resource.PropertyMap) error {
|
|||
// want to make forward progress, even as the configure call is happening.
|
||||
go func() {
|
||||
resp, err := p.clientRaw.Configure(p.ctx.Request(), &pulumirpc.ConfigureRequest{
|
||||
AcceptSecrets: true,
|
||||
Variables: config,
|
||||
Args: minputs,
|
||||
AcceptSecrets: true,
|
||||
AcceptResources: true,
|
||||
Variables: config,
|
||||
Args: minputs,
|
||||
})
|
||||
if err != nil {
|
||||
rpcError := rpcerror.Convert(err)
|
||||
|
@ -476,7 +484,10 @@ func (p *provider) Configure(inputs resource.PropertyMap) error {
|
|||
err = createConfigureError(rpcError)
|
||||
}
|
||||
// Acquire the lock, publish the results, and notify any waiters.
|
||||
p.acceptSecrets, p.supportsPreview = resp.GetAcceptSecrets(), resp.GetSupportsPreview()
|
||||
p.acceptSecrets = resp.GetAcceptSecrets()
|
||||
p.acceptResources = resp.GetAcceptResources()
|
||||
p.supportsPreview = resp.GetSupportsPreview()
|
||||
|
||||
p.cfgknown, p.cfgerr = true, err
|
||||
close(p.cfgdone)
|
||||
}()
|
||||
|
@ -503,17 +514,19 @@ func (p *provider) Check(urn resource.URN,
|
|||
}
|
||||
|
||||
molds, err := MarshalProperties(olds, MarshalOptions{
|
||||
Label: fmt.Sprintf("%s.olds", label),
|
||||
KeepUnknowns: allowUnknowns,
|
||||
KeepSecrets: p.acceptSecrets,
|
||||
Label: fmt.Sprintf("%s.olds", label),
|
||||
KeepUnknowns: allowUnknowns,
|
||||
KeepSecrets: p.acceptSecrets,
|
||||
KeepResources: p.acceptResources,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
mnews, err := MarshalProperties(news, MarshalOptions{
|
||||
Label: fmt.Sprintf("%s.news", label),
|
||||
KeepUnknowns: allowUnknowns,
|
||||
KeepSecrets: p.acceptSecrets,
|
||||
Label: fmt.Sprintf("%s.news", label),
|
||||
KeepUnknowns: allowUnknowns,
|
||||
KeepSecrets: p.acceptSecrets,
|
||||
KeepResources: p.acceptResources,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
|
@ -538,6 +551,7 @@ func (p *provider) Check(urn resource.URN,
|
|||
KeepUnknowns: allowUnknowns,
|
||||
RejectUnknowns: !allowUnknowns,
|
||||
KeepSecrets: true,
|
||||
KeepResources: true,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
|
@ -595,14 +609,16 @@ func (p *provider) Diff(urn resource.URN, id resource.ID,
|
|||
ElideAssetContents: true,
|
||||
KeepUnknowns: allowUnknowns,
|
||||
KeepSecrets: p.acceptSecrets,
|
||||
KeepResources: p.acceptResources,
|
||||
})
|
||||
if err != nil {
|
||||
return DiffResult{}, err
|
||||
}
|
||||
mnews, err := MarshalProperties(news, MarshalOptions{
|
||||
Label: fmt.Sprintf("%s.news", label),
|
||||
KeepUnknowns: allowUnknowns,
|
||||
KeepSecrets: p.acceptSecrets,
|
||||
Label: fmt.Sprintf("%s.news", label),
|
||||
KeepUnknowns: allowUnknowns,
|
||||
KeepSecrets: p.acceptSecrets,
|
||||
KeepResources: p.acceptResources,
|
||||
})
|
||||
if err != nil {
|
||||
return DiffResult{}, err
|
||||
|
@ -677,9 +693,10 @@ func (p *provider) Create(urn resource.URN, props resource.PropertyMap, timeout
|
|||
contract.Assert(p.cfgknown)
|
||||
|
||||
mprops, err := MarshalProperties(props, MarshalOptions{
|
||||
Label: fmt.Sprintf("%s.inputs", label),
|
||||
KeepUnknowns: preview,
|
||||
KeepSecrets: p.acceptSecrets,
|
||||
Label: fmt.Sprintf("%s.inputs", label),
|
||||
KeepUnknowns: preview,
|
||||
KeepSecrets: p.acceptSecrets,
|
||||
KeepResources: p.acceptResources,
|
||||
})
|
||||
if err != nil {
|
||||
return "", nil, resource.StatusOK, err
|
||||
|
@ -714,9 +731,10 @@ func (p *provider) Create(urn resource.URN, props resource.PropertyMap, timeout
|
|||
}
|
||||
|
||||
outs, err := UnmarshalProperties(liveObject, MarshalOptions{
|
||||
Label: fmt.Sprintf("%s.outputs", label),
|
||||
RejectUnknowns: true,
|
||||
KeepSecrets: true,
|
||||
Label: fmt.Sprintf("%s.outputs", label),
|
||||
KeepUnknowns: preview,
|
||||
KeepSecrets: true,
|
||||
KeepResources: true,
|
||||
})
|
||||
if err != nil {
|
||||
return "", nil, resourceStatus, err
|
||||
|
@ -768,6 +786,7 @@ func (p *provider) Read(urn resource.URN, id resource.ID,
|
|||
Label: label,
|
||||
ElideAssetContents: true,
|
||||
KeepSecrets: p.acceptSecrets,
|
||||
KeepResources: p.acceptResources,
|
||||
})
|
||||
if err != nil {
|
||||
return ReadResult{}, resource.StatusUnknown, err
|
||||
|
@ -778,6 +797,7 @@ func (p *provider) Read(urn resource.URN, id resource.ID,
|
|||
Label: label,
|
||||
ElideAssetContents: true,
|
||||
KeepSecrets: p.acceptSecrets,
|
||||
KeepResources: p.acceptResources,
|
||||
})
|
||||
if err != nil {
|
||||
return ReadResult{}, resource.StatusUnknown, err
|
||||
|
@ -819,6 +839,7 @@ func (p *provider) Read(urn resource.URN, id resource.ID,
|
|||
Label: fmt.Sprintf("%s.outputs", label),
|
||||
RejectUnknowns: true,
|
||||
KeepSecrets: true,
|
||||
KeepResources: true,
|
||||
})
|
||||
if err != nil {
|
||||
return ReadResult{}, resourceStatus, err
|
||||
|
@ -830,6 +851,7 @@ func (p *provider) Read(urn resource.URN, id resource.ID,
|
|||
Label: label + ".inputs",
|
||||
RejectUnknowns: true,
|
||||
KeepSecrets: true,
|
||||
KeepResources: true,
|
||||
})
|
||||
if err != nil {
|
||||
return ReadResult{}, resourceStatus, err
|
||||
|
@ -887,14 +909,16 @@ func (p *provider) Update(urn resource.URN, id resource.ID,
|
|||
Label: fmt.Sprintf("%s.olds", label),
|
||||
ElideAssetContents: true,
|
||||
KeepSecrets: p.acceptSecrets,
|
||||
KeepResources: p.acceptResources,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, resource.StatusOK, err
|
||||
}
|
||||
mnews, err := MarshalProperties(news, MarshalOptions{
|
||||
Label: fmt.Sprintf("%s.news", label),
|
||||
KeepUnknowns: preview,
|
||||
KeepSecrets: p.acceptSecrets,
|
||||
Label: fmt.Sprintf("%s.news", label),
|
||||
KeepUnknowns: preview,
|
||||
KeepSecrets: p.acceptSecrets,
|
||||
KeepResources: p.acceptResources,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, resource.StatusOK, err
|
||||
|
@ -928,6 +952,7 @@ func (p *provider) Update(urn resource.URN, id resource.ID,
|
|||
Label: fmt.Sprintf("%s.outputs", label),
|
||||
RejectUnknowns: true,
|
||||
KeepSecrets: true,
|
||||
KeepResources: true,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, resourceStatus, err
|
||||
|
@ -960,6 +985,7 @@ func (p *provider) Delete(urn resource.URN, id resource.ID, props resource.Prope
|
|||
Label: label,
|
||||
ElideAssetContents: true,
|
||||
KeepSecrets: p.acceptSecrets,
|
||||
KeepResources: p.acceptResources,
|
||||
})
|
||||
if err != nil {
|
||||
return resource.StatusOK, err
|
||||
|
@ -1119,8 +1145,9 @@ func (p *provider) Invoke(tok tokens.ModuleMember, args resource.PropertyMap) (r
|
|||
}
|
||||
|
||||
margs, err := MarshalProperties(args, MarshalOptions{
|
||||
Label: fmt.Sprintf("%s.args", label),
|
||||
KeepSecrets: p.acceptSecrets,
|
||||
Label: fmt.Sprintf("%s.args", label),
|
||||
KeepSecrets: p.acceptSecrets,
|
||||
KeepResources: p.acceptResources,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
|
@ -1138,6 +1165,7 @@ func (p *provider) Invoke(tok tokens.ModuleMember, args resource.PropertyMap) (r
|
|||
Label: fmt.Sprintf("%s.returns", label),
|
||||
RejectUnknowns: true,
|
||||
KeepSecrets: true,
|
||||
KeepResources: true,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
|
@ -1177,8 +1205,9 @@ func (p *provider) StreamInvoke(
|
|||
}
|
||||
|
||||
margs, err := MarshalProperties(args, MarshalOptions{
|
||||
Label: fmt.Sprintf("%s.args", label),
|
||||
KeepSecrets: p.acceptSecrets,
|
||||
Label: fmt.Sprintf("%s.args", label),
|
||||
KeepSecrets: p.acceptSecrets,
|
||||
KeepResources: p.acceptResources,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -1206,6 +1235,7 @@ func (p *provider) StreamInvoke(
|
|||
Label: fmt.Sprintf("%s.returns", label),
|
||||
RejectUnknowns: true,
|
||||
KeepSecrets: true,
|
||||
KeepResources: true,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
|
@ -36,6 +36,7 @@ type MarshalOptions struct {
|
|||
ComputeAssetHashes bool // true if we are computing missing asset hashes on the fly.
|
||||
KeepSecrets bool // true if we are keeping secrets (otherwise we replace them with their underlying value).
|
||||
RejectAssets bool // true if we should return errors on Asset and Archive values.
|
||||
KeepResources bool // true if we are keeping resoures (otherwise we return raw urn).
|
||||
SkipInternalKeys bool // true to skip internal property keys (keys that start with "__") in the resulting map.
|
||||
}
|
||||
|
||||
|
@ -161,6 +162,27 @@ func MarshalPropertyValue(v resource.PropertyValue, opts MarshalOptions) (*struc
|
|||
"value": v.SecretValue().Element,
|
||||
})
|
||||
return MarshalPropertyValue(secret, opts)
|
||||
} else if v.IsResourceReference() {
|
||||
ref := v.ResourceReferenceValue()
|
||||
if !opts.KeepResources {
|
||||
val := string(ref.URN)
|
||||
if ref.ID != "" {
|
||||
val = string(ref.ID)
|
||||
}
|
||||
logging.V(5).Infof("marshalling resource value as raw URN or ID as opts.KeepResources is false")
|
||||
return MarshalString(val, opts), nil
|
||||
}
|
||||
m := resource.PropertyMap{
|
||||
resource.SigKey: resource.NewStringProperty(resource.ResourceReferenceSig),
|
||||
"urn": resource.NewStringProperty(string(ref.URN)),
|
||||
}
|
||||
if ref.ID != "" {
|
||||
m["id"] = resource.NewStringProperty(string(ref.ID))
|
||||
}
|
||||
if ref.PackageVersion != "" {
|
||||
m["packageVersion"] = resource.NewStringProperty(ref.PackageVersion)
|
||||
}
|
||||
return MarshalPropertyValue(resource.NewObjectProperty(m), opts)
|
||||
}
|
||||
|
||||
contract.Failf("Unrecognized property value in RPC[%s]: %v (type=%v)", opts.Label, v.V, reflect.TypeOf(v.V))
|
||||
|
@ -345,6 +367,42 @@ func UnmarshalPropertyValue(v *structpb.Value, opts MarshalOptions) (*resource.P
|
|||
}
|
||||
s := resource.MakeSecret(value)
|
||||
return &s, nil
|
||||
case resource.ResourceReferenceSig:
|
||||
urn, ok := obj["urn"]
|
||||
if !ok {
|
||||
return nil, errors.New("malformed resource reference: missing urn")
|
||||
}
|
||||
if !urn.IsString() {
|
||||
return nil, errors.New("malformed resource reference: urn not a string")
|
||||
}
|
||||
|
||||
var id string
|
||||
if idProp, ok := obj["id"]; ok {
|
||||
if !idProp.IsString() {
|
||||
return nil, errors.New("malformed resource reference: id not a string")
|
||||
}
|
||||
id = idProp.StringValue()
|
||||
}
|
||||
|
||||
var packageVersion string
|
||||
if packageVersionProp, ok := obj["packageVersion"]; ok {
|
||||
if !packageVersionProp.IsString() {
|
||||
return nil, errors.New("malformed resource reference: packageVersion not a string")
|
||||
}
|
||||
packageVersion = packageVersionProp.StringValue()
|
||||
}
|
||||
|
||||
if !opts.KeepResources {
|
||||
value := urn.StringValue()
|
||||
if id != "" {
|
||||
value = id
|
||||
}
|
||||
r := resource.NewStringProperty(value)
|
||||
return &r, nil
|
||||
}
|
||||
|
||||
r := resource.MakeResourceReference(resource.URN(urn.StringValue()), resource.ID(id), packageVersion)
|
||||
return &r, nil
|
||||
default:
|
||||
return nil, errors.Errorf("unrecognized signature '%v' in property map", sig)
|
||||
}
|
||||
|
|
|
@ -285,3 +285,45 @@ func TestSkipInternalKeys(t *testing.T) {
|
|||
assert.NoError(t, err)
|
||||
assert.Equal(t, expected, actual)
|
||||
}
|
||||
|
||||
func TestResourceReference(t *testing.T) {
|
||||
// Test round-trip
|
||||
opts := MarshalOptions{KeepResources: true}
|
||||
rawProp := resource.MakeResourceReference("fakeURN", "fakeID", "fakeVersion")
|
||||
prop, err := MarshalPropertyValue(rawProp, opts)
|
||||
assert.NoError(t, err)
|
||||
actual, err := UnmarshalPropertyValue(prop, opts)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, rawProp, *actual)
|
||||
|
||||
// Test unmarshaling as an ID
|
||||
opts.KeepResources = false
|
||||
actual, err = UnmarshalPropertyValue(prop, opts)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, resource.NewStringProperty(string(rawProp.ResourceReferenceValue().ID)), *actual)
|
||||
|
||||
// Test marshaling as an ID
|
||||
prop, err = MarshalPropertyValue(rawProp, opts)
|
||||
assert.NoError(t, err)
|
||||
opts.KeepResources = true
|
||||
actual, err = UnmarshalPropertyValue(prop, opts)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, resource.NewStringProperty(string(rawProp.ResourceReferenceValue().ID)), *actual)
|
||||
|
||||
// Test unmarshaling as a URN
|
||||
rawProp = resource.MakeResourceReference("fakeURN", "", "fakeVersion")
|
||||
prop, err = MarshalPropertyValue(rawProp, opts)
|
||||
assert.NoError(t, err)
|
||||
opts.KeepResources = false
|
||||
actual, err = UnmarshalPropertyValue(prop, opts)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, resource.NewStringProperty(string(rawProp.ResourceReferenceValue().URN)), *actual)
|
||||
|
||||
// Test marshaling as a URN
|
||||
prop, err = MarshalPropertyValue(rawProp, opts)
|
||||
assert.NoError(t, err)
|
||||
opts.KeepResources = true
|
||||
actual, err = UnmarshalPropertyValue(prop, opts)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, resource.NewStringProperty(string(rawProp.ResourceReferenceValue().URN)), *actual)
|
||||
}
|
||||
|
|
|
@ -96,6 +96,16 @@ type Secret struct {
|
|||
Element PropertyValue
|
||||
}
|
||||
|
||||
// ResourceReference is a property value that represents a reference to a Resource. The reference captures the
|
||||
// resource's URN, ID, and the version of its containing package.
|
||||
//
|
||||
//nolint: golint
|
||||
type ResourceReference struct {
|
||||
URN URN
|
||||
ID ID
|
||||
PackageVersion string
|
||||
}
|
||||
|
||||
type ReqError struct {
|
||||
K PropertyKey
|
||||
}
|
||||
|
@ -178,17 +188,18 @@ func (m PropertyMap) StableKeys() []PropertyKey {
|
|||
return sorted
|
||||
}
|
||||
|
||||
func NewNullProperty() PropertyValue { return PropertyValue{nil} }
|
||||
func NewBoolProperty(v bool) PropertyValue { return PropertyValue{v} }
|
||||
func NewNumberProperty(v float64) PropertyValue { return PropertyValue{v} }
|
||||
func NewStringProperty(v string) PropertyValue { return PropertyValue{v} }
|
||||
func NewArrayProperty(v []PropertyValue) PropertyValue { return PropertyValue{v} }
|
||||
func NewAssetProperty(v *Asset) PropertyValue { return PropertyValue{v} }
|
||||
func NewArchiveProperty(v *Archive) PropertyValue { return PropertyValue{v} }
|
||||
func NewObjectProperty(v PropertyMap) PropertyValue { return PropertyValue{v} }
|
||||
func NewComputedProperty(v Computed) PropertyValue { return PropertyValue{v} }
|
||||
func NewOutputProperty(v Output) PropertyValue { return PropertyValue{v} }
|
||||
func NewSecretProperty(v *Secret) PropertyValue { return PropertyValue{v} }
|
||||
func NewNullProperty() PropertyValue { return PropertyValue{nil} }
|
||||
func NewBoolProperty(v bool) PropertyValue { return PropertyValue{v} }
|
||||
func NewNumberProperty(v float64) PropertyValue { return PropertyValue{v} }
|
||||
func NewStringProperty(v string) PropertyValue { return PropertyValue{v} }
|
||||
func NewArrayProperty(v []PropertyValue) PropertyValue { return PropertyValue{v} }
|
||||
func NewAssetProperty(v *Asset) PropertyValue { return PropertyValue{v} }
|
||||
func NewArchiveProperty(v *Archive) PropertyValue { return PropertyValue{v} }
|
||||
func NewObjectProperty(v PropertyMap) PropertyValue { return PropertyValue{v} }
|
||||
func NewComputedProperty(v Computed) PropertyValue { return PropertyValue{v} }
|
||||
func NewOutputProperty(v Output) PropertyValue { return PropertyValue{v} }
|
||||
func NewSecretProperty(v *Secret) PropertyValue { return PropertyValue{v} }
|
||||
func NewResourceReferenceProperty(v ResourceReference) PropertyValue { return PropertyValue{v} }
|
||||
|
||||
func MakeComputed(v PropertyValue) PropertyValue {
|
||||
return NewComputedProperty(Computed{Element: v})
|
||||
|
@ -202,6 +213,10 @@ func MakeSecret(v PropertyValue) PropertyValue {
|
|||
return NewSecretProperty(&Secret{Element: v})
|
||||
}
|
||||
|
||||
func MakeResourceReference(urn URN, id ID, packageVersion string) PropertyValue {
|
||||
return NewResourceReferenceProperty(ResourceReference{URN: urn, ID: id, PackageVersion: packageVersion})
|
||||
}
|
||||
|
||||
// NewPropertyValue turns a value into a property value, provided it is of a legal "JSON-like" kind.
|
||||
func NewPropertyValue(v interface{}) PropertyValue {
|
||||
return NewPropertyValueRepl(v, nil, nil)
|
||||
|
@ -255,6 +270,8 @@ func NewPropertyValueRepl(v interface{},
|
|||
return NewOutputProperty(t)
|
||||
case *Secret:
|
||||
return NewSecretProperty(t)
|
||||
case ResourceReference:
|
||||
return NewResourceReferenceProperty(t)
|
||||
}
|
||||
|
||||
// Next, see if it's an array, slice, pointer or struct, and handle each accordingly.
|
||||
|
@ -382,6 +399,9 @@ func (v PropertyValue) OutputValue() Output { return v.V.(Output) }
|
|||
// SecretValue fetches the underlying secret value (panicking if it isn't a secret).
|
||||
func (v PropertyValue) SecretValue() *Secret { return v.V.(*Secret) }
|
||||
|
||||
// ResourceReferenceValue fetches the underlying resource reference value (panicking if it isn't a resource reference).
|
||||
func (v PropertyValue) ResourceReferenceValue() ResourceReference { return v.V.(ResourceReference) }
|
||||
|
||||
// IsNull returns true if the underlying value is a null.
|
||||
func (v PropertyValue) IsNull() bool {
|
||||
return v.V == nil
|
||||
|
@ -447,6 +467,12 @@ func (v PropertyValue) IsSecret() bool {
|
|||
return is
|
||||
}
|
||||
|
||||
// IsResourceReference returns true if the underlying value is a resource reference value.
|
||||
func (v PropertyValue) IsResourceReference() bool {
|
||||
_, is := v.V.(ResourceReference)
|
||||
return is
|
||||
}
|
||||
|
||||
// TypeString returns a type representation of the property value's holder type.
|
||||
func (v PropertyValue) TypeString() string {
|
||||
if v.IsNull() {
|
||||
|
@ -471,6 +497,9 @@ func (v PropertyValue) TypeString() string {
|
|||
return "output<" + v.OutputValue().Element.TypeString() + ">"
|
||||
} else if v.IsSecret() {
|
||||
return "secret<" + v.SecretValue().Element.TypeString() + ">"
|
||||
} else if v.IsResourceReference() {
|
||||
ref := v.ResourceReferenceValue()
|
||||
return fmt.Sprintf("resourceReference(%q, %q, %q)", ref.URN, ref.ID, ref.PackageVersion)
|
||||
}
|
||||
contract.Failf("Unrecognized PropertyValue type")
|
||||
return ""
|
||||
|
@ -514,6 +543,8 @@ func (v PropertyValue) MapRepl(replk func(string) (string, bool),
|
|||
return v.OutputValue()
|
||||
} else if v.IsSecret() {
|
||||
return v.SecretValue()
|
||||
} else if v.IsResourceReference() {
|
||||
return v.ResourceReferenceValue()
|
||||
}
|
||||
contract.Assertf(v.IsObject(), "v is not Object '%v' instead", v.TypeString())
|
||||
return v.ObjectValue().MapRepl(replk, replv)
|
||||
|
@ -550,6 +581,9 @@ func HasSig(obj PropertyMap, match string) bool {
|
|||
// SecretSig is the unique secret signature.
|
||||
const SecretSig = "1b47061264138c4ac30d75fd1eb44270"
|
||||
|
||||
// ResourceReferenceSig is the unique resource reference signature.
|
||||
const ResourceReferenceSig = "5cf8f73096256a8f31e491e813e4eb8e"
|
||||
|
||||
// IsInternalPropertyKey returns true if the given property key is an internal key that should not be displayed to
|
||||
// users.
|
||||
func IsInternalPropertyKey(key PropertyKey) bool {
|
||||
|
|
|
@ -323,6 +323,17 @@ func (v PropertyValue) DeepEquals(other PropertyValue) bool {
|
|||
return vs.Element.DeepEquals(os.Element)
|
||||
}
|
||||
|
||||
// Resource references are equal if they refer to the same resource. The package version is ignored.
|
||||
if v.IsResourceReference() {
|
||||
if !other.IsResourceReference() {
|
||||
return false
|
||||
}
|
||||
vr := v.ResourceReferenceValue()
|
||||
or := other.ResourceReferenceValue()
|
||||
|
||||
return vr.URN == or.URN && vr.ID == or.ID
|
||||
}
|
||||
|
||||
// For all other cases, primitives are equal if their values are equal.
|
||||
return v.V == other.V
|
||||
}
|
||||
|
|
|
@ -39,18 +39,19 @@ import (
|
|||
|
||||
// Context handles registration of resources and exposes metadata about the current deployment context.
|
||||
type Context struct {
|
||||
ctx context.Context
|
||||
info RunInfo
|
||||
stack Resource
|
||||
exports map[string]Input
|
||||
monitor pulumirpc.ResourceMonitorClient
|
||||
monitorConn *grpc.ClientConn
|
||||
engine pulumirpc.EngineClient
|
||||
engineConn *grpc.ClientConn
|
||||
rpcs int // the number of outstanding RPC requests.
|
||||
rpcsDone *sync.Cond // an event signaling completion of RPCs.
|
||||
rpcsLock *sync.Mutex // a lock protecting the RPC count and event.
|
||||
rpcError error // the first error (if any) encountered during an RPC.
|
||||
ctx context.Context
|
||||
info RunInfo
|
||||
stack Resource
|
||||
exports map[string]Input
|
||||
monitor pulumirpc.ResourceMonitorClient
|
||||
monitorConn *grpc.ClientConn
|
||||
engine pulumirpc.EngineClient
|
||||
engineConn *grpc.ClientConn
|
||||
keepResources bool // true if resources should be marshaled as strongly-typed references.
|
||||
rpcs int // the number of outstanding RPC requests.
|
||||
rpcsDone *sync.Cond // an event signaling completion of RPCs.
|
||||
rpcsLock *sync.Mutex // a lock protecting the RPC count and event.
|
||||
rpcError error // the first error (if any) encountered during an RPC.
|
||||
|
||||
Log Log // the logging interface for the Pulumi log stream.
|
||||
}
|
||||
|
@ -93,23 +94,35 @@ func NewContext(ctx context.Context, info RunInfo) (*Context, error) {
|
|||
engine = &mockEngine{}
|
||||
}
|
||||
|
||||
var keepResources bool
|
||||
if monitor != nil {
|
||||
supportsFeatureResp, err := monitor.SupportsFeature(ctx, &pulumirpc.SupportsFeatureRequest{
|
||||
Id: "resourceReferences",
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("checking monitor features: %w", err)
|
||||
}
|
||||
keepResources = supportsFeatureResp.GetHasSupport()
|
||||
}
|
||||
|
||||
mutex := &sync.Mutex{}
|
||||
log := &logState{
|
||||
engine: engine,
|
||||
ctx: ctx,
|
||||
}
|
||||
return &Context{
|
||||
ctx: ctx,
|
||||
info: info,
|
||||
exports: make(map[string]Input),
|
||||
monitorConn: monitorConn,
|
||||
monitor: monitor,
|
||||
engineConn: engineConn,
|
||||
engine: engine,
|
||||
rpcs: 0,
|
||||
rpcsLock: mutex,
|
||||
rpcsDone: sync.NewCond(mutex),
|
||||
Log: log,
|
||||
ctx: ctx,
|
||||
info: info,
|
||||
exports: make(map[string]Input),
|
||||
monitorConn: monitorConn,
|
||||
monitor: monitor,
|
||||
engineConn: engineConn,
|
||||
engine: engine,
|
||||
keepResources: keepResources,
|
||||
rpcs: 0,
|
||||
rpcsLock: mutex,
|
||||
rpcsDone: sync.NewCond(mutex),
|
||||
Log: log,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
@ -192,7 +205,7 @@ func (ctx *Context) Invoke(tok string, args interface{}, result interface{}, opt
|
|||
keepUnknowns := ctx.DryRun()
|
||||
rpcArgs, err := plugin.MarshalProperties(
|
||||
resolvedArgsMap,
|
||||
plugin.MarshalOptions{KeepUnknowns: keepUnknowns, KeepSecrets: true},
|
||||
plugin.MarshalOptions{KeepUnknowns: keepUnknowns, KeepSecrets: true, KeepResources: ctx.keepResources},
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("marshaling arguments: %w", err)
|
||||
|
@ -228,10 +241,10 @@ func (ctx *Context) Invoke(tok string, args interface{}, result interface{}, opt
|
|||
return ferr
|
||||
}
|
||||
|
||||
// Otherwsie, simply unmarshal the output properties and return the result.
|
||||
// Otherwise, simply unmarshal the output properties and return the result.
|
||||
outProps, err := plugin.UnmarshalProperties(
|
||||
resp.Return,
|
||||
plugin.MarshalOptions{KeepSecrets: true, KeepUnknowns: keepUnknowns},
|
||||
plugin.MarshalOptions{KeepSecrets: true, KeepResources: true, KeepUnknowns: keepUnknowns},
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -718,7 +731,7 @@ func (state *resourceState) resolve(dryrun bool, err error, inputs *resourceInpu
|
|||
if err == nil {
|
||||
outprops, err = plugin.UnmarshalProperties(
|
||||
result,
|
||||
plugin.MarshalOptions{KeepSecrets: true, KeepUnknowns: dryrun},
|
||||
plugin.MarshalOptions{KeepSecrets: true, KeepResources: true, KeepUnknowns: dryrun},
|
||||
)
|
||||
}
|
||||
if err != nil {
|
||||
|
@ -818,7 +831,7 @@ func (ctx *Context) prepareResourceInputs(props Input, t string,
|
|||
keepUnknowns := ctx.DryRun()
|
||||
rpcProps, err := plugin.MarshalProperties(
|
||||
resolvedProps,
|
||||
plugin.MarshalOptions{KeepUnknowns: keepUnknowns, KeepSecrets: true})
|
||||
plugin.MarshalOptions{KeepSecrets: true, KeepUnknowns: keepUnknowns, KeepResources: ctx.keepResources})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("marshaling properties: %w", err)
|
||||
}
|
||||
|
@ -1036,7 +1049,7 @@ func (ctx *Context) RegisterResourceOutputs(resource Resource, outs Map) error {
|
|||
keepUnknowns := ctx.DryRun()
|
||||
outsMarshalled, err := plugin.MarshalProperties(
|
||||
outsResolved.ObjectValue(),
|
||||
plugin.MarshalOptions{KeepUnknowns: keepUnknowns, KeepSecrets: true})
|
||||
plugin.MarshalOptions{KeepSecrets: true, KeepUnknowns: keepUnknowns, KeepResources: ctx.keepResources})
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
|
|
@ -52,7 +52,10 @@ func (m *mockMonitor) SupportsFeature(ctx context.Context, in *pulumirpc.Support
|
|||
func (m *mockMonitor) Invoke(ctx context.Context, in *pulumirpc.InvokeRequest,
|
||||
opts ...grpc.CallOption) (*pulumirpc.InvokeResponse, error) {
|
||||
|
||||
args, err := plugin.UnmarshalProperties(in.GetArgs(), plugin.MarshalOptions{KeepSecrets: true})
|
||||
args, err := plugin.UnmarshalProperties(in.GetArgs(), plugin.MarshalOptions{
|
||||
KeepSecrets: true,
|
||||
KeepResources: true,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -62,7 +65,10 @@ func (m *mockMonitor) Invoke(ctx context.Context, in *pulumirpc.InvokeRequest,
|
|||
return nil, err
|
||||
}
|
||||
|
||||
result, err := plugin.MarshalProperties(resultV, plugin.MarshalOptions{KeepSecrets: true})
|
||||
result, err := plugin.MarshalProperties(resultV, plugin.MarshalOptions{
|
||||
KeepSecrets: true,
|
||||
KeepResources: true,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -81,7 +87,10 @@ func (m *mockMonitor) StreamInvoke(ctx context.Context, in *pulumirpc.InvokeRequ
|
|||
func (m *mockMonitor) ReadResource(ctx context.Context, in *pulumirpc.ReadResourceRequest,
|
||||
opts ...grpc.CallOption) (*pulumirpc.ReadResourceResponse, error) {
|
||||
|
||||
stateIn, err := plugin.UnmarshalProperties(in.GetProperties(), plugin.MarshalOptions{KeepSecrets: true})
|
||||
stateIn, err := plugin.UnmarshalProperties(in.GetProperties(), plugin.MarshalOptions{
|
||||
KeepSecrets: true,
|
||||
KeepResources: true,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -91,7 +100,10 @@ func (m *mockMonitor) ReadResource(ctx context.Context, in *pulumirpc.ReadResour
|
|||
return nil, err
|
||||
}
|
||||
|
||||
stateOut, err := plugin.MarshalProperties(state, plugin.MarshalOptions{KeepSecrets: true})
|
||||
stateOut, err := plugin.MarshalProperties(state, plugin.MarshalOptions{
|
||||
KeepSecrets: true,
|
||||
KeepResources: true,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -111,7 +123,10 @@ func (m *mockMonitor) RegisterResource(ctx context.Context, in *pulumirpc.Regist
|
|||
}, nil
|
||||
}
|
||||
|
||||
inputs, err := plugin.UnmarshalProperties(in.GetObject(), plugin.MarshalOptions{KeepSecrets: true})
|
||||
inputs, err := plugin.UnmarshalProperties(in.GetObject(), plugin.MarshalOptions{
|
||||
KeepSecrets: true,
|
||||
KeepResources: true,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -121,7 +136,10 @@ func (m *mockMonitor) RegisterResource(ctx context.Context, in *pulumirpc.Regist
|
|||
return nil, err
|
||||
}
|
||||
|
||||
stateOut, err := plugin.MarshalProperties(state, plugin.MarshalOptions{KeepSecrets: true})
|
||||
stateOut, err := plugin.MarshalProperties(state, plugin.MarshalOptions{
|
||||
KeepSecrets: true,
|
||||
KeepResources: true,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -19,10 +19,12 @@ import (
|
|||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
|
||||
"github.com/pulumi/pulumi/sdk/v2/go/common/resource"
|
||||
"github.com/pulumi/pulumi/sdk/v2/go/common/tokens"
|
||||
"github.com/pulumi/pulumi/sdk/v2/go/common/util/contract"
|
||||
)
|
||||
|
||||
|
@ -254,15 +256,30 @@ func marshalInputAndDetermineSecret(v interface{},
|
|||
Path: v.Path(),
|
||||
URI: v.URI(),
|
||||
}), deps, secret, nil
|
||||
case CustomResource:
|
||||
case Resource:
|
||||
deps = append(deps, v)
|
||||
|
||||
// Resources aren't serializable; instead, serialize a reference to ID, tracking as a dependency.
|
||||
e, d, err := marshalInput(v.ID(), idType, await)
|
||||
urn, known, secretURN, err := v.URN().awaitURN(context.Background())
|
||||
if err != nil {
|
||||
return resource.PropertyValue{}, nil, false, err
|
||||
}
|
||||
return e, append(deps, d...), secret, nil
|
||||
contract.Assert(known)
|
||||
contract.Assert(!secretURN)
|
||||
|
||||
var id ID
|
||||
if custom, ok := v.(CustomResource); ok {
|
||||
resID, known, secretID, err := custom.ID().awaitID(context.Background())
|
||||
if err != nil {
|
||||
return resource.PropertyValue{}, nil, false, err
|
||||
}
|
||||
contract.Assert(!secretID)
|
||||
if !known {
|
||||
return resource.MakeComputed(resource.NewStringProperty("")), deps, secret, nil
|
||||
}
|
||||
id = resID
|
||||
}
|
||||
|
||||
return resource.MakeResourceReference(resource.URN(urn), resource.ID(id), ""), deps, secret, nil
|
||||
}
|
||||
|
||||
contract.Assertf(valueType.AssignableTo(destType) || valueType.ConvertibleTo(destType),
|
||||
|
@ -437,9 +454,39 @@ func unmarshalPropertyValue(v resource.PropertyValue) (interface{}, bool, error)
|
|||
return NewFileArchive(archive.Path), secret, nil
|
||||
case archive.IsURI():
|
||||
return NewRemoteArchive(archive.URI), secret, nil
|
||||
default:
|
||||
}
|
||||
return nil, false, errors.New("expected asset to be one of File, String, or Remote; got none")
|
||||
case v.IsResourceReference():
|
||||
ref := v.ResourceReferenceValue()
|
||||
|
||||
resName := ref.URN.Name()
|
||||
resType := ref.URN.Type()
|
||||
pkgName := resType.Package()
|
||||
|
||||
isProvider := false
|
||||
if tokens.Token(resType).HasModuleMember() && resType.Module() == "pulumi:providers" {
|
||||
pkgName, isProvider = tokens.Package(resType.Name()), true
|
||||
}
|
||||
|
||||
resourcePackageV, ok := resourcePackages.Load(packageKey(string(pkgName), ref.PackageVersion))
|
||||
if !ok {
|
||||
err := fmt.Errorf("unable to deserialize resource URN %v, no resource package is registered for type %v",
|
||||
ref.URN, pkgName)
|
||||
return nil, false, err
|
||||
}
|
||||
resourcePackage := resourcePackageV.(ResourcePackage)
|
||||
|
||||
var resource Resource
|
||||
var err error
|
||||
if !isProvider {
|
||||
resource, err = resourcePackage.Construct(string(resName), string(resType), nil, string(ref.URN))
|
||||
} else {
|
||||
resource, err = resourcePackage.ConstructProvider(string(resName), string(resType), nil, string(ref.URN))
|
||||
}
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
return resource, false, nil
|
||||
default:
|
||||
return v.V, false, nil
|
||||
}
|
||||
|
@ -491,6 +538,17 @@ func unmarshalOutput(v resource.PropertyValue, dest reflect.Value) (bool, error)
|
|||
return false, err
|
||||
}
|
||||
return true, nil
|
||||
case v.IsResourceReference():
|
||||
res, secret, err := unmarshalPropertyValue(v)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
resV := reflect.ValueOf(res).Elem()
|
||||
if !resV.Type().AssignableTo(dest.Type()) {
|
||||
return false, fmt.Errorf("expected a %s, got a resource of type %s", dest.Type(), resV.Type())
|
||||
}
|
||||
dest.Set(resV)
|
||||
return secret, nil
|
||||
}
|
||||
|
||||
// Unmarshal based on the desired type.
|
||||
|
@ -619,3 +677,23 @@ func unmarshalOutput(v resource.PropertyValue, dest reflect.Value) (bool, error)
|
|||
return false, fmt.Errorf("cannot unmarshal into type %v", dest.Type())
|
||||
}
|
||||
}
|
||||
|
||||
type ResourcePackage interface {
|
||||
Construct(name, typ string, args map[string]interface{}, urn string) (Resource, error)
|
||||
ConstructProvider(name, typ string, args map[string]interface{}, urn string) (ProviderResource, error)
|
||||
}
|
||||
|
||||
var resourcePackages sync.Map // map[string]ResourcePackage
|
||||
|
||||
func packageKey(name, version string) string {
|
||||
return fmt.Sprintf("%s@%s", name, version)
|
||||
}
|
||||
|
||||
// RegisterResourcePackage register a resource package with the Pulumi runtime.
|
||||
func RegisterResourcePackage(name, version string, pkg ResourcePackage) {
|
||||
key := packageKey(name, version)
|
||||
existing, hasExisting := resourcePackages.LoadOrStore(key, pkg)
|
||||
if hasExisting {
|
||||
panic(fmt.Errorf("a resource package for %v is already registered: %v", key, existing))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -886,7 +886,8 @@ proto.pulumirpc.ConfigureRequest.toObject = function(includeInstance, msg) {
|
|||
var f, obj = {
|
||||
variablesMap: (f = msg.getVariablesMap()) ? f.toObject(includeInstance, undefined) : [],
|
||||
args: (f = msg.getArgs()) && google_protobuf_struct_pb.Struct.toObject(includeInstance, f),
|
||||
acceptsecrets: jspb.Message.getBooleanFieldWithDefault(msg, 3, false)
|
||||
acceptsecrets: jspb.Message.getBooleanFieldWithDefault(msg, 3, false),
|
||||
acceptresources: jspb.Message.getBooleanFieldWithDefault(msg, 4, false)
|
||||
};
|
||||
|
||||
if (includeInstance) {
|
||||
|
@ -938,6 +939,10 @@ proto.pulumirpc.ConfigureRequest.deserializeBinaryFromReader = function(msg, rea
|
|||
var value = /** @type {boolean} */ (reader.readBool());
|
||||
msg.setAcceptsecrets(value);
|
||||
break;
|
||||
case 4:
|
||||
var value = /** @type {boolean} */ (reader.readBool());
|
||||
msg.setAcceptresources(value);
|
||||
break;
|
||||
default:
|
||||
reader.skipField();
|
||||
break;
|
||||
|
@ -986,6 +991,13 @@ proto.pulumirpc.ConfigureRequest.serializeBinaryToWriter = function(message, wri
|
|||
f
|
||||
);
|
||||
}
|
||||
f = message.getAcceptresources();
|
||||
if (f) {
|
||||
writer.writeBool(
|
||||
4,
|
||||
f
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
@ -1066,6 +1078,24 @@ proto.pulumirpc.ConfigureRequest.prototype.setAcceptsecrets = function(value) {
|
|||
};
|
||||
|
||||
|
||||
/**
|
||||
* optional bool acceptResources = 4;
|
||||
* @return {boolean}
|
||||
*/
|
||||
proto.pulumirpc.ConfigureRequest.prototype.getAcceptresources = function() {
|
||||
return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 4, false));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {boolean} value
|
||||
* @return {!proto.pulumirpc.ConfigureRequest} returns this
|
||||
*/
|
||||
proto.pulumirpc.ConfigureRequest.prototype.setAcceptresources = function(value) {
|
||||
return jspb.Message.setProto3BooleanField(this, 4, value);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1099,7 +1129,8 @@ proto.pulumirpc.ConfigureResponse.prototype.toObject = function(opt_includeInsta
|
|||
proto.pulumirpc.ConfigureResponse.toObject = function(includeInstance, msg) {
|
||||
var f, obj = {
|
||||
acceptsecrets: jspb.Message.getBooleanFieldWithDefault(msg, 1, false),
|
||||
supportspreview: jspb.Message.getBooleanFieldWithDefault(msg, 2, false)
|
||||
supportspreview: jspb.Message.getBooleanFieldWithDefault(msg, 2, false),
|
||||
acceptresources: jspb.Message.getBooleanFieldWithDefault(msg, 3, false)
|
||||
};
|
||||
|
||||
if (includeInstance) {
|
||||
|
@ -1144,6 +1175,10 @@ proto.pulumirpc.ConfigureResponse.deserializeBinaryFromReader = function(msg, re
|
|||
var value = /** @type {boolean} */ (reader.readBool());
|
||||
msg.setSupportspreview(value);
|
||||
break;
|
||||
case 3:
|
||||
var value = /** @type {boolean} */ (reader.readBool());
|
||||
msg.setAcceptresources(value);
|
||||
break;
|
||||
default:
|
||||
reader.skipField();
|
||||
break;
|
||||
|
@ -1187,6 +1222,13 @@ proto.pulumirpc.ConfigureResponse.serializeBinaryToWriter = function(message, wr
|
|||
f
|
||||
);
|
||||
}
|
||||
f = message.getAcceptresources();
|
||||
if (f) {
|
||||
writer.writeBool(
|
||||
3,
|
||||
f
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
@ -1226,6 +1268,24 @@ proto.pulumirpc.ConfigureResponse.prototype.setSupportspreview = function(value)
|
|||
};
|
||||
|
||||
|
||||
/**
|
||||
* optional bool acceptResources = 3;
|
||||
* @return {boolean}
|
||||
*/
|
||||
proto.pulumirpc.ConfigureResponse.prototype.getAcceptresources = function() {
|
||||
return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 3, false));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {boolean} value
|
||||
* @return {!proto.pulumirpc.ConfigureResponse} returns this
|
||||
*/
|
||||
proto.pulumirpc.ConfigureResponse.prototype.setAcceptresources = function(value) {
|
||||
return jspb.Message.setProto3BooleanField(this, 3, value);
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* List of repeated fields within this message type.
|
||||
|
@ -1581,7 +1641,8 @@ proto.pulumirpc.InvokeRequest.toObject = function(includeInstance, msg) {
|
|||
tok: jspb.Message.getFieldWithDefault(msg, 1, ""),
|
||||
args: (f = msg.getArgs()) && google_protobuf_struct_pb.Struct.toObject(includeInstance, f),
|
||||
provider: jspb.Message.getFieldWithDefault(msg, 3, ""),
|
||||
version: jspb.Message.getFieldWithDefault(msg, 4, "")
|
||||
version: jspb.Message.getFieldWithDefault(msg, 4, ""),
|
||||
acceptresources: jspb.Message.getBooleanFieldWithDefault(msg, 5, false)
|
||||
};
|
||||
|
||||
if (includeInstance) {
|
||||
|
@ -1635,6 +1696,10 @@ proto.pulumirpc.InvokeRequest.deserializeBinaryFromReader = function(msg, reader
|
|||
var value = /** @type {string} */ (reader.readString());
|
||||
msg.setVersion(value);
|
||||
break;
|
||||
case 5:
|
||||
var value = /** @type {boolean} */ (reader.readBool());
|
||||
msg.setAcceptresources(value);
|
||||
break;
|
||||
default:
|
||||
reader.skipField();
|
||||
break;
|
||||
|
@ -1693,6 +1758,13 @@ proto.pulumirpc.InvokeRequest.serializeBinaryToWriter = function(message, writer
|
|||
f
|
||||
);
|
||||
}
|
||||
f = message.getAcceptresources();
|
||||
if (f) {
|
||||
writer.writeBool(
|
||||
5,
|
||||
f
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
@ -1787,6 +1859,24 @@ proto.pulumirpc.InvokeRequest.prototype.setVersion = function(value) {
|
|||
};
|
||||
|
||||
|
||||
/**
|
||||
* optional bool acceptResources = 5;
|
||||
* @return {boolean}
|
||||
*/
|
||||
proto.pulumirpc.InvokeRequest.prototype.getAcceptresources = function() {
|
||||
return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 5, false));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {boolean} value
|
||||
* @return {!proto.pulumirpc.InvokeRequest} returns this
|
||||
*/
|
||||
proto.pulumirpc.InvokeRequest.prototype.setAcceptresources = function(value) {
|
||||
return jspb.Message.setProto3BooleanField(this, 5, value);
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* List of repeated fields within this message type.
|
||||
|
|
|
@ -547,7 +547,8 @@ proto.pulumirpc.ReadResourceRequest.toObject = function(includeInstance, msg) {
|
|||
version: jspb.Message.getFieldWithDefault(msg, 8, ""),
|
||||
acceptsecrets: jspb.Message.getBooleanFieldWithDefault(msg, 9, false),
|
||||
additionalsecretoutputsList: (f = jspb.Message.getRepeatedField(msg, 10)) == null ? undefined : f,
|
||||
aliasesList: (f = jspb.Message.getRepeatedField(msg, 11)) == null ? undefined : f
|
||||
aliasesList: (f = jspb.Message.getRepeatedField(msg, 11)) == null ? undefined : f,
|
||||
acceptresources: jspb.Message.getBooleanFieldWithDefault(msg, 12, false)
|
||||
};
|
||||
|
||||
if (includeInstance) {
|
||||
|
@ -629,6 +630,10 @@ proto.pulumirpc.ReadResourceRequest.deserializeBinaryFromReader = function(msg,
|
|||
var value = /** @type {string} */ (reader.readString());
|
||||
msg.addAliases(value);
|
||||
break;
|
||||
case 12:
|
||||
var value = /** @type {boolean} */ (reader.readBool());
|
||||
msg.setAcceptresources(value);
|
||||
break;
|
||||
default:
|
||||
reader.skipField();
|
||||
break;
|
||||
|
@ -736,6 +741,13 @@ proto.pulumirpc.ReadResourceRequest.serializeBinaryToWriter = function(message,
|
|||
f
|
||||
);
|
||||
}
|
||||
f = message.getAcceptresources();
|
||||
if (f) {
|
||||
writer.writeBool(
|
||||
12,
|
||||
f
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
@ -1013,6 +1025,24 @@ proto.pulumirpc.ReadResourceRequest.prototype.clearAliasesList = function() {
|
|||
};
|
||||
|
||||
|
||||
/**
|
||||
* optional bool acceptResources = 12;
|
||||
* @return {boolean}
|
||||
*/
|
||||
proto.pulumirpc.ReadResourceRequest.prototype.getAcceptresources = function() {
|
||||
return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 12, false));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {boolean} value
|
||||
* @return {!proto.pulumirpc.ReadResourceRequest} returns this
|
||||
*/
|
||||
proto.pulumirpc.ReadResourceRequest.prototype.setAcceptresources = function(value) {
|
||||
return jspb.Message.setProto3BooleanField(this, 12, value);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1252,7 +1282,8 @@ proto.pulumirpc.RegisterResourceRequest.toObject = function(includeInstance, msg
|
|||
customtimeouts: (f = msg.getCustomtimeouts()) && proto.pulumirpc.RegisterResourceRequest.CustomTimeouts.toObject(includeInstance, f),
|
||||
deletebeforereplacedefined: jspb.Message.getBooleanFieldWithDefault(msg, 18, false),
|
||||
supportspartialvalues: jspb.Message.getBooleanFieldWithDefault(msg, 19, false),
|
||||
remote: jspb.Message.getBooleanFieldWithDefault(msg, 20, false)
|
||||
remote: jspb.Message.getBooleanFieldWithDefault(msg, 20, false),
|
||||
acceptresources: jspb.Message.getBooleanFieldWithDefault(msg, 21, false)
|
||||
};
|
||||
|
||||
if (includeInstance) {
|
||||
|
@ -1373,6 +1404,10 @@ proto.pulumirpc.RegisterResourceRequest.deserializeBinaryFromReader = function(m
|
|||
var value = /** @type {boolean} */ (reader.readBool());
|
||||
msg.setRemote(value);
|
||||
break;
|
||||
case 21:
|
||||
var value = /** @type {boolean} */ (reader.readBool());
|
||||
msg.setAcceptresources(value);
|
||||
break;
|
||||
default:
|
||||
reader.skipField();
|
||||
break;
|
||||
|
@ -1541,6 +1576,13 @@ proto.pulumirpc.RegisterResourceRequest.serializeBinaryToWriter = function(messa
|
|||
f
|
||||
);
|
||||
}
|
||||
f = message.getAcceptresources();
|
||||
if (f) {
|
||||
writer.writeBool(
|
||||
21,
|
||||
f
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
@ -2368,6 +2410,24 @@ proto.pulumirpc.RegisterResourceRequest.prototype.setRemote = function(value) {
|
|||
};
|
||||
|
||||
|
||||
/**
|
||||
* optional bool acceptResources = 21;
|
||||
* @return {boolean}
|
||||
*/
|
||||
proto.pulumirpc.RegisterResourceRequest.prototype.getAcceptresources = function() {
|
||||
return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 21, false));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {boolean} value
|
||||
* @return {!proto.pulumirpc.RegisterResourceRequest} returns this
|
||||
*/
|
||||
proto.pulumirpc.RegisterResourceRequest.prototype.setAcceptresources = function(value) {
|
||||
return jspb.Message.setProto3BooleanField(this, 21, value);
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* List of repeated fields within this message type.
|
||||
|
|
|
@ -16,9 +16,9 @@ import * as asset from "../asset";
|
|||
import { isGrpcError } from "../errors";
|
||||
import * as log from "../log";
|
||||
import { getAllResources, Input, Inputs, isUnknown, Output, unknown } from "../output";
|
||||
import { ComponentResource, CustomResource, Resource, URN } from "../resource";
|
||||
import { ComponentResource, CustomResource, ProviderResource, Resource, URN } from "../resource";
|
||||
import { debuggablePromise, errorString, promiseDebugString } from "./debuggable";
|
||||
import { excessiveDebugOutput, isDryRun, monitorSupportsSecrets } from "./settings";
|
||||
import { excessiveDebugOutput, isDryRun, monitorSupportsResourceReferences, monitorSupportsSecrets } from "./settings";
|
||||
|
||||
const gstruct = require("google-protobuf/google/protobuf/struct_pb.js");
|
||||
|
||||
|
@ -87,7 +87,10 @@ export function transferProperties(onto: Resource, label: string, props: Inputs)
|
|||
* be remoted over to registerResource.
|
||||
*/
|
||||
async function serializeFilteredProperties(
|
||||
label: string, props: Inputs, acceptKey: (k: string) => boolean): Promise<[Record<string, any>, Map<string, Set<Resource>>]> {
|
||||
label: string,
|
||||
props: Inputs,
|
||||
acceptKey: (k: string) => boolean,
|
||||
): Promise<[Record<string, any>, Map<string, Set<Resource>>]> {
|
||||
|
||||
const propertyToDependentResources = new Map<string, Set<Resource>>();
|
||||
|
||||
|
@ -236,6 +239,10 @@ export const specialArchiveSig = "0def7320c3a5731c473e5ecbe6d01bc7";
|
|||
* specialSecretSig is a randomly assigned hash used to identify secrets in maps. See pkg/resource/properties.go.
|
||||
*/
|
||||
export const specialSecretSig = "1b47061264138c4ac30d75fd1eb44270";
|
||||
/**
|
||||
* specialResourceSig is a randomly assigned hash used to identify resources in maps. See pkg/resource/properties.go.
|
||||
*/
|
||||
export const specialResourceSig = "5cf8f73096256a8f31e491e813e4eb8e";
|
||||
|
||||
/**
|
||||
* serializeProperty serializes properties deeply. This understands how to wait on any unresolved promises, as
|
||||
|
@ -243,7 +250,7 @@ export const specialSecretSig = "1b47061264138c4ac30d75fd1eb44270";
|
|||
*/
|
||||
export async function serializeProperty(ctx: string, prop: Input<any>, dependentResources: Set<Resource>): Promise<any> {
|
||||
// IMPORTANT:
|
||||
// IMPORTANT: Keep this in sync with serializesPropertiesSync in invoke.ts
|
||||
// IMPORTANT: Keep this in sync with serializePropertiesSync in invoke.ts
|
||||
// IMPORTANT:
|
||||
|
||||
if (prop === undefined ||
|
||||
|
@ -323,13 +330,24 @@ export async function serializeProperty(ctx: string, prop: Input<any>, dependent
|
|||
}
|
||||
|
||||
if (CustomResource.isInstance(prop)) {
|
||||
// Resources aren't serializable; instead, we serialize them as references to the ID property.
|
||||
if (excessiveDebugOutput) {
|
||||
log.debug(`Serialize property [${ctx}]: custom resource id`);
|
||||
log.debug(`Serialize property [${ctx}]: custom resource urn`);
|
||||
}
|
||||
|
||||
dependentResources.add(prop);
|
||||
return serializeProperty(`${ctx}.id`, prop.id, dependentResources);
|
||||
const id = await serializeProperty(`${ctx}.id`, prop.id, dependentResources);
|
||||
|
||||
if (await monitorSupportsResourceReferences()) {
|
||||
// If we are keeping resources, emit a stronly typed wrapper over the URN
|
||||
const urn = await serializeProperty(`${ctx}.urn`, prop.urn, dependentResources);
|
||||
return {
|
||||
[specialSigKey]: specialResourceSig,
|
||||
urn: urn,
|
||||
id: id,
|
||||
};
|
||||
}
|
||||
// Else, return the id for backward compatibility.
|
||||
return id;
|
||||
}
|
||||
|
||||
if (ComponentResource.isInstance(prop)) {
|
||||
|
@ -348,9 +366,18 @@ export async function serializeProperty(ctx: string, prop: Input<any>, dependent
|
|||
// and tracked in a reasonable manner, while not causing us to compute or embed information
|
||||
// about it that is not needed, and which can lead to deadlocks.
|
||||
if (excessiveDebugOutput) {
|
||||
log.debug(`Serialize property [${ctx}]: component resource urnid`);
|
||||
log.debug(`Serialize property [${ctx}]: component resource urn`);
|
||||
}
|
||||
|
||||
if (await monitorSupportsResourceReferences()) {
|
||||
// If we are keeping resources, emit a strongly typed wrapper over the URN
|
||||
const urn = await serializeProperty(`${ctx}.urn`, prop.urn, dependentResources);
|
||||
return {
|
||||
[specialSigKey]: specialResourceSig,
|
||||
urn: urn,
|
||||
};
|
||||
}
|
||||
// Else, return the urn for backward compatibility.
|
||||
return serializeProperty(`${ctx}.urn`, prop.urn, dependentResources);
|
||||
}
|
||||
|
||||
|
@ -482,6 +509,32 @@ export function deserializeProperty(prop: any): any {
|
|||
[specialSigKey]: specialSecretSig,
|
||||
value: deserializeProperty(prop["value"]),
|
||||
};
|
||||
case specialResourceSig:
|
||||
// Deserialize the resource into a live Resource reference
|
||||
const urn = prop["urn"];
|
||||
const version = prop["version"];
|
||||
|
||||
const urnParts = urn.split("::");
|
||||
const qualifiedType = urnParts[2];
|
||||
|
||||
const type = qualifiedType.split("$").pop()!;
|
||||
const typeParts = type.split(":");
|
||||
let pkgName = typeParts[0];
|
||||
const modName = typeParts.length > 1 ? typeParts[1] : "";
|
||||
const typName = typeParts.length > 2 ? typeParts[2] : "";
|
||||
const isProvider = pkgName === "pulumi" && modName === "providers";
|
||||
if (isProvider) {
|
||||
pkgName = typName;
|
||||
}
|
||||
|
||||
const resourcePackage = resourcePackages.get(packageKey(pkgName, version || ""));
|
||||
if (!resourcePackage) {
|
||||
throw new Error(`Unable to deserialize resource URN ${urn}, no resource package is registered for type ${type}.`);
|
||||
}
|
||||
const urnName = urnParts[3];
|
||||
return !isProvider ?
|
||||
resourcePackage.construct(urnName, type, {}, { urn }) :
|
||||
resourcePackage.constructProvider(urnName, type, {}, { urn });
|
||||
default:
|
||||
throw new Error(`Unrecognized signature '${sig}' when unmarshaling resource property`);
|
||||
}
|
||||
|
@ -521,3 +574,30 @@ export function suppressUnhandledGrpcRejections<T>(p: Promise<T>): Promise<T> {
|
|||
});
|
||||
return p;
|
||||
}
|
||||
|
||||
/**
|
||||
* A ResourcePackage is a package that understands how to construct resources given a name, type, args, and URN.
|
||||
*/
|
||||
export type ResourcePackage = {
|
||||
construct(name: string, type: string, args: any, opts: { urn: string }): Resource;
|
||||
constructProvider(name: string, type: string, args: any, opts: { urn: string }): ProviderResource;
|
||||
};
|
||||
|
||||
const resourcePackages = new Map<string, ResourcePackage>();
|
||||
|
||||
function packageKey(name: string, version: string): string {
|
||||
return `${name}@${version}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* registerResourcePackage registers a resource package that will be used to construct resources for any URNs matching
|
||||
* the package name and version that are deserialized by the current instance of the Pulumi JavaScript SDK.
|
||||
*/
|
||||
export function registerResourcePackage(pkgName: string, version: string, pkg: ResourcePackage) {
|
||||
const key = packageKey(pkgName, version);
|
||||
const existing = resourcePackages.get(key);
|
||||
if (existing) {
|
||||
throw new Error(`Cannot re-register package ${key}. Previous registration was ${existing}, new registration was ${pkg}.`);
|
||||
}
|
||||
resourcePackages.set(key, pkg);
|
||||
}
|
||||
|
|
|
@ -490,3 +490,12 @@ export async function monitorSupportsFeature(feature: string): Promise<boolean>
|
|||
export function monitorSupportsSecrets(): Promise<boolean> {
|
||||
return monitorSupportsFeature("secrets");
|
||||
}
|
||||
|
||||
/**
|
||||
* monitorSupportsResourceReferences returns a promise that when resolved tells you if the resource monitor we are
|
||||
* connected to is able to support resouece references aross its RPC interface. When it does, we marshal resources
|
||||
* in a special way.
|
||||
*/
|
||||
export async function monitorSupportsResourceReferences(): Promise<boolean> {
|
||||
return monitorSupportsFeature("resourceReferences");
|
||||
}
|
||||
|
|
|
@ -92,6 +92,7 @@
|
|||
"tests/runtime/tsClosureCases.ts",
|
||||
"tests/runtime/props.spec.ts",
|
||||
"tests/runtime/langhost/run.spec.ts",
|
||||
|
||||
"tests/automation/localWorkspace.spec.ts"
|
||||
]
|
||||
}
|
||||
|
|
|
@ -173,6 +173,7 @@ type ConfigureRequest struct {
|
|||
Variables map[string]string `protobuf:"bytes,1,rep,name=variables,proto3" json:"variables,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
|
||||
Args *_struct.Struct `protobuf:"bytes,2,opt,name=args,proto3" json:"args,omitempty"`
|
||||
AcceptSecrets bool `protobuf:"varint,3,opt,name=acceptSecrets,proto3" json:"acceptSecrets,omitempty"`
|
||||
AcceptResources bool `protobuf:"varint,4,opt,name=acceptResources,proto3" json:"acceptResources,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
|
@ -224,9 +225,17 @@ func (m *ConfigureRequest) GetAcceptSecrets() bool {
|
|||
return false
|
||||
}
|
||||
|
||||
func (m *ConfigureRequest) GetAcceptResources() bool {
|
||||
if m != nil {
|
||||
return m.AcceptResources
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type ConfigureResponse struct {
|
||||
AcceptSecrets bool `protobuf:"varint,1,opt,name=acceptSecrets,proto3" json:"acceptSecrets,omitempty"`
|
||||
SupportsPreview bool `protobuf:"varint,2,opt,name=supportsPreview,proto3" json:"supportsPreview,omitempty"`
|
||||
AcceptResources bool `protobuf:"varint,3,opt,name=acceptResources,proto3" json:"acceptResources,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
|
@ -271,6 +280,13 @@ func (m *ConfigureResponse) GetSupportsPreview() bool {
|
|||
return false
|
||||
}
|
||||
|
||||
func (m *ConfigureResponse) GetAcceptResources() bool {
|
||||
if m != nil {
|
||||
return m.AcceptResources
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// ConfigureErrorMissingKeys is sent as a Detail on an error returned from `ResourceProvider.Configure`.
|
||||
type ConfigureErrorMissingKeys struct {
|
||||
MissingKeys []*ConfigureErrorMissingKeys_MissingKey `protobuf:"bytes,1,rep,name=missingKeys,proto3" json:"missingKeys,omitempty"`
|
||||
|
@ -363,6 +379,7 @@ type InvokeRequest struct {
|
|||
Args *_struct.Struct `protobuf:"bytes,2,opt,name=args,proto3" json:"args,omitempty"`
|
||||
Provider string `protobuf:"bytes,3,opt,name=provider,proto3" json:"provider,omitempty"`
|
||||
Version string `protobuf:"bytes,4,opt,name=version,proto3" json:"version,omitempty"`
|
||||
AcceptResources bool `protobuf:"varint,5,opt,name=acceptResources,proto3" json:"acceptResources,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
|
@ -421,6 +438,13 @@ func (m *InvokeRequest) GetVersion() string {
|
|||
return ""
|
||||
}
|
||||
|
||||
func (m *InvokeRequest) GetAcceptResources() bool {
|
||||
if m != nil {
|
||||
return m.AcceptResources
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type InvokeResponse struct {
|
||||
Return *_struct.Struct `protobuf:"bytes,1,opt,name=return,proto3" json:"return,omitempty"`
|
||||
Failures []*CheckFailure `protobuf:"bytes,2,rep,name=failures,proto3" json:"failures,omitempty"`
|
||||
|
@ -1662,111 +1686,112 @@ func init() {
|
|||
func init() { proto.RegisterFile("provider.proto", fileDescriptor_c6a9f3c02af3d1c8) }
|
||||
|
||||
var fileDescriptor_c6a9f3c02af3d1c8 = []byte{
|
||||
// 1651 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x58, 0x4b, 0x73, 0x1b, 0x37,
|
||||
0x12, 0xd6, 0x90, 0x14, 0x25, 0x36, 0x1f, 0xa6, 0xb0, 0x5e, 0x99, 0xa6, 0x75, 0x50, 0xcd, 0x6e,
|
||||
0xd5, 0x6a, 0xed, 0x35, 0xa5, 0x95, 0x0f, 0xbb, 0x76, 0xc9, 0xe5, 0x95, 0x44, 0x4a, 0xab, 0xb2,
|
||||
0x2d, 0x2b, 0x23, 0x3b, 0x8f, 0x93, 0x3d, 0x9e, 0x01, 0xa9, 0x89, 0x86, 0x33, 0x13, 0x0c, 0x86,
|
||||
0x2e, 0xe5, 0x9c, 0x43, 0x4e, 0xb9, 0xe7, 0x47, 0xa4, 0x52, 0x95, 0x5f, 0x90, 0x1f, 0x92, 0x1c,
|
||||
0x73, 0xcc, 0x21, 0x95, 0x3f, 0x90, 0xc2, 0x6b, 0x04, 0x90, 0xd4, 0x33, 0xae, 0xe4, 0x86, 0x46,
|
||||
0x37, 0xfa, 0xf1, 0xa1, 0xd1, 0x68, 0x00, 0x1a, 0x09, 0x89, 0x47, 0x81, 0x8f, 0x49, 0x27, 0x21,
|
||||
0x31, 0x8d, 0x51, 0x25, 0xc9, 0xc2, 0x6c, 0x18, 0x90, 0xc4, 0x6b, 0xd7, 0x92, 0x30, 0x1b, 0x04,
|
||||
0x91, 0x60, 0xb4, 0xef, 0x0c, 0xe2, 0x78, 0x10, 0xe2, 0x55, 0x4e, 0xbd, 0xcd, 0xfa, 0xab, 0x78,
|
||||
0x98, 0xd0, 0x13, 0xc9, 0x5c, 0x1a, 0x67, 0xa6, 0x94, 0x64, 0x1e, 0x15, 0x5c, 0xfb, 0x5f, 0xd0,
|
||||
0xdc, 0xc5, 0xf4, 0xd0, 0x3b, 0xc2, 0x43, 0xd7, 0xc1, 0x9f, 0x65, 0x38, 0xa5, 0xa8, 0x05, 0x73,
|
||||
0x23, 0x4c, 0xd2, 0x20, 0x8e, 0x5a, 0xd6, 0xb2, 0xb5, 0x32, 0xeb, 0x28, 0xd2, 0xbe, 0x07, 0x0b,
|
||||
0x9a, 0x74, 0x9a, 0xc4, 0x51, 0x8a, 0xd1, 0x22, 0x94, 0x53, 0x3e, 0xc3, 0xa5, 0x2b, 0x8e, 0xa4,
|
||||
0xec, 0x9f, 0x2d, 0x68, 0x6e, 0xc7, 0x51, 0x3f, 0x18, 0x64, 0x04, 0x2b, 0xdd, 0xff, 0x87, 0xca,
|
||||
0xc8, 0x25, 0x81, 0xfb, 0x36, 0xc4, 0x69, 0xcb, 0x5a, 0x2e, 0xae, 0x54, 0xd7, 0xef, 0x76, 0xf2,
|
||||
0xb8, 0x3a, 0xe3, 0xf2, 0x9d, 0x0f, 0x95, 0x70, 0x2f, 0xa2, 0xe4, 0xc4, 0x39, 0x5d, 0x8c, 0xee,
|
||||
0x41, 0xc9, 0x25, 0x83, 0xb4, 0x55, 0x58, 0xb6, 0x56, 0xaa, 0xeb, 0xb7, 0x3a, 0x22, 0xcc, 0x8e,
|
||||
0x0a, 0xb3, 0x73, 0xc8, 0xc3, 0x74, 0xb8, 0x10, 0xfa, 0x3b, 0xd4, 0x5d, 0xcf, 0xc3, 0x09, 0x3d,
|
||||
0xc4, 0x1e, 0xc1, 0x34, 0x6d, 0x15, 0x97, 0xad, 0x95, 0x79, 0xc7, 0x9c, 0x6c, 0x6f, 0x40, 0xc3,
|
||||
0xb4, 0x87, 0x9a, 0x50, 0x3c, 0xc6, 0x27, 0x32, 0x30, 0x36, 0x44, 0x37, 0x61, 0x76, 0xe4, 0x86,
|
||||
0x19, 0xe6, 0x76, 0x2b, 0x8e, 0x20, 0x1e, 0x15, 0xfe, 0x6b, 0xd9, 0x1e, 0x2c, 0x68, 0xee, 0x4b,
|
||||
0x70, 0x26, 0x0c, 0x5b, 0x53, 0x0c, 0xa3, 0x15, 0xb8, 0x91, 0x66, 0x49, 0x12, 0x13, 0x9a, 0x1e,
|
||||
0x10, 0x3c, 0x0a, 0xf0, 0x3b, 0xae, 0x7e, 0xde, 0x19, 0x9f, 0xb6, 0xbf, 0xb3, 0xe0, 0x76, 0x6e,
|
||||
0xa5, 0x47, 0x48, 0x4c, 0x9e, 0x07, 0x69, 0x1a, 0x44, 0x83, 0xa7, 0xf8, 0x24, 0x45, 0x1f, 0x40,
|
||||
0x75, 0x78, 0x4a, 0x4a, 0x7c, 0x57, 0xa7, 0xe1, 0x3b, 0xbe, 0xb4, 0x73, 0x3a, 0x76, 0x74, 0x1d,
|
||||
0xed, 0x2d, 0x80, 0x53, 0x16, 0x42, 0x50, 0x8a, 0xdc, 0x21, 0x96, 0x80, 0xf0, 0x31, 0x5a, 0x86,
|
||||
0xaa, 0x8f, 0x53, 0x8f, 0x04, 0x09, 0x65, 0x29, 0x23, 0x70, 0xd1, 0xa7, 0xec, 0x2f, 0x2c, 0xa8,
|
||||
0xef, 0x45, 0xa3, 0xf8, 0x38, 0x4f, 0x83, 0x26, 0x14, 0x69, 0x7c, 0xac, 0x70, 0xa5, 0xf1, 0xf1,
|
||||
0xd5, 0xb6, 0xb3, 0x0d, 0xf3, 0xea, 0x6c, 0xf0, 0x9d, 0xac, 0x38, 0x39, 0xad, 0x67, 0x6f, 0x89,
|
||||
0xb3, 0xf2, 0xec, 0x1d, 0x41, 0x43, 0x79, 0x21, 0x77, 0x67, 0x15, 0xca, 0x04, 0xd3, 0x8c, 0x88,
|
||||
0x44, 0x3f, 0xc7, 0xac, 0x14, 0x43, 0x0f, 0x60, 0xbe, 0xef, 0x06, 0x61, 0x46, 0x30, 0xf3, 0xb4,
|
||||
0xc8, 0x97, 0x68, 0xe8, 0x1e, 0x61, 0xef, 0x78, 0x47, 0xf0, 0x9d, 0x5c, 0xd0, 0xfe, 0x1c, 0x6a,
|
||||
0x9c, 0xa3, 0x05, 0xaf, 0x4c, 0x56, 0x1c, 0x36, 0x64, 0xc1, 0xc7, 0xa1, 0x7f, 0x71, 0xf0, 0x4c,
|
||||
0x88, 0x09, 0x47, 0xf8, 0x9d, 0x48, 0xe1, 0xf3, 0x84, 0x99, 0x90, 0x9d, 0x41, 0x5d, 0xda, 0x3e,
|
||||
0x0d, 0x39, 0x88, 0x92, 0x4c, 0x66, 0xe2, 0x79, 0x21, 0x0b, 0xb1, 0xeb, 0x85, 0xbc, 0x25, 0x43,
|
||||
0x96, 0x1c, 0xb9, 0x61, 0x09, 0x26, 0x54, 0x1d, 0xa6, 0x9c, 0x66, 0xf5, 0x83, 0x60, 0x37, 0xcd,
|
||||
0x53, 0x47, 0x52, 0xf6, 0xb7, 0x16, 0x54, 0xbb, 0x41, 0xbf, 0xaf, 0x60, 0x6b, 0x40, 0x21, 0xf0,
|
||||
0xe5, 0xea, 0x42, 0xe0, 0x2b, 0x18, 0x0b, 0x93, 0x30, 0x16, 0xaf, 0x02, 0x63, 0xe9, 0x12, 0x30,
|
||||
0xb2, 0x63, 0x1c, 0x0c, 0xa2, 0x98, 0xe0, 0xed, 0x23, 0x37, 0x1a, 0xe0, 0xb4, 0x35, 0xbb, 0x5c,
|
||||
0x5c, 0xa9, 0x38, 0xe6, 0xa4, 0xfd, 0xbd, 0x05, 0xb5, 0x03, 0x19, 0x16, 0xf3, 0x1c, 0xad, 0x41,
|
||||
0xe9, 0x38, 0x88, 0x84, 0xd3, 0x8d, 0xf5, 0x25, 0x0d, 0x37, 0x5d, 0xac, 0xf3, 0x34, 0x88, 0x7c,
|
||||
0x87, 0x4b, 0xa2, 0x25, 0xa8, 0x70, 0xdc, 0xd9, 0xbc, 0xac, 0x01, 0xa7, 0x13, 0xf6, 0x1b, 0x28,
|
||||
0x31, 0x59, 0x34, 0x07, 0xc5, 0xcd, 0x6e, 0xb7, 0x39, 0x83, 0x6e, 0x40, 0x75, 0xb3, 0xdb, 0x7d,
|
||||
0xed, 0xf4, 0x0e, 0x9e, 0x6d, 0x6e, 0xf7, 0x9a, 0x16, 0x02, 0x28, 0x77, 0x7b, 0xcf, 0x7a, 0x2f,
|
||||
0x7b, 0xcd, 0x02, 0x42, 0xd0, 0x10, 0xe3, 0x9c, 0x5f, 0x64, 0xfc, 0x57, 0x07, 0xdd, 0xcd, 0x97,
|
||||
0xbd, 0x66, 0x89, 0xf1, 0xc5, 0x38, 0xe7, 0xcf, 0xda, 0x3f, 0x16, 0xa1, 0x26, 0x40, 0x97, 0xf9,
|
||||
0xd2, 0x86, 0x79, 0x82, 0x93, 0xd0, 0xf5, 0x64, 0xbd, 0xae, 0x38, 0x39, 0xcd, 0x8e, 0x5a, 0x4a,
|
||||
0x45, 0x29, 0x2f, 0x70, 0x96, 0x22, 0xd1, 0x1a, 0xfc, 0xc5, 0xc7, 0x21, 0xa6, 0x78, 0x0b, 0xf7,
|
||||
0x63, 0x56, 0x0e, 0xf9, 0x0a, 0x59, 0x75, 0xa7, 0xb1, 0xd0, 0x63, 0x98, 0xf3, 0x24, 0xb6, 0x25,
|
||||
0x8e, 0xd6, 0xdf, 0x34, 0xb4, 0x74, 0x8f, 0x38, 0x21, 0x11, 0x77, 0xd4, 0x1a, 0x56, 0x96, 0xfd,
|
||||
0xa0, 0xdf, 0x57, 0x1b, 0x23, 0x08, 0xf4, 0x1c, 0x6a, 0x3e, 0xa6, 0x6e, 0x10, 0x62, 0x9f, 0x03,
|
||||
0x5a, 0xe6, 0xf9, 0xfb, 0xcf, 0x33, 0x35, 0x6b, 0xb2, 0xe2, 0xbe, 0x31, 0x96, 0xb3, 0x32, 0x7d,
|
||||
0xe4, 0xa6, 0xba, 0x54, 0x6b, 0x4e, 0x94, 0xe9, 0xb1, 0xe9, 0xf6, 0xc7, 0xb0, 0x30, 0xa1, 0x6c,
|
||||
0xca, 0x65, 0x72, 0x5f, 0xbf, 0x4c, 0xcc, 0x83, 0xa5, 0x27, 0x88, 0x7e, 0xcb, 0x3c, 0x16, 0x87,
|
||||
0x42, 0x02, 0x80, 0x9a, 0x50, 0xeb, 0xee, 0xed, 0xec, 0xbc, 0x7e, 0xb5, 0xff, 0x74, 0xff, 0xc5,
|
||||
0x47, 0xfb, 0xcd, 0x19, 0x54, 0x87, 0x0a, 0x9f, 0xd9, 0x7f, 0xb1, 0xcf, 0x12, 0x42, 0x91, 0x87,
|
||||
0x2f, 0x9e, 0xf7, 0x9a, 0x05, 0xfb, 0x2b, 0x0b, 0xea, 0xdb, 0x04, 0xbb, 0x14, 0x9f, 0x5d, 0x8d,
|
||||
0xfe, 0x03, 0x20, 0x0f, 0x67, 0x80, 0x2f, 0xac, 0x49, 0x9a, 0x28, 0xcb, 0x07, 0x1a, 0x0c, 0x71,
|
||||
0x9c, 0x51, 0xbe, 0xd3, 0x96, 0xa3, 0x48, 0xc6, 0x49, 0xe4, 0xc5, 0x56, 0xe2, 0x88, 0x29, 0xd2,
|
||||
0xfe, 0x04, 0x1a, 0xca, 0x1f, 0x99, 0x71, 0xe3, 0xe7, 0xfc, 0xba, 0xee, 0xd8, 0x5f, 0x5b, 0x50,
|
||||
0x75, 0xb0, 0xeb, 0x5f, 0xbe, 0x80, 0x98, 0xa6, 0x8a, 0x97, 0x8f, 0xfc, 0xb4, 0xaa, 0x96, 0x2e,
|
||||
0x55, 0x55, 0xed, 0x2f, 0x2d, 0xa8, 0x09, 0xdf, 0xde, 0x73, 0xd4, 0x9a, 0x2b, 0xc5, 0xcb, 0xb9,
|
||||
0xf2, 0x93, 0x05, 0xf5, 0x57, 0x89, 0xaf, 0xa5, 0xc4, 0x9f, 0x59, 0x69, 0xb5, 0x1c, 0x9a, 0x35,
|
||||
0x73, 0x68, 0xa2, 0x06, 0x97, 0xa7, 0xd4, 0x60, 0x3d, 0xd3, 0xe6, 0xcc, 0x4c, 0xdb, 0x83, 0x86,
|
||||
0x0a, 0x53, 0x62, 0x6e, 0x62, 0x6c, 0x5d, 0x3e, 0xb3, 0x58, 0x43, 0xd3, 0xe5, 0x45, 0xec, 0x0f,
|
||||
0xc8, 0x2d, 0x0d, 0x91, 0x92, 0x81, 0x88, 0xfd, 0x6b, 0x99, 0x77, 0xd8, 0xa2, 0xa1, 0xd7, 0xba,
|
||||
0xf7, 0x84, 0xc4, 0x9f, 0x62, 0x8f, 0x4a, 0x77, 0x14, 0xc9, 0x6a, 0x64, 0x4a, 0x5d, 0xef, 0x58,
|
||||
0xb5, 0xae, 0x9c, 0x40, 0x4f, 0xa0, 0xec, 0xf1, 0xae, 0xb0, 0x55, 0xe4, 0xd5, 0xf1, 0x1f, 0x66,
|
||||
0xbb, 0x68, 0x28, 0x97, 0xfd, 0xa3, 0xa8, 0x8d, 0x72, 0x19, 0xbb, 0xbf, 0x7d, 0x72, 0xe2, 0x64,
|
||||
0x91, 0x3c, 0xda, 0x92, 0xe2, 0x77, 0xbe, 0x4b, 0xdc, 0x30, 0xc4, 0x21, 0xdf, 0xca, 0x59, 0x27,
|
||||
0xa7, 0x59, 0x25, 0x1d, 0xc6, 0x51, 0x40, 0x63, 0xd2, 0x8b, 0xfc, 0x24, 0x0e, 0x22, 0xda, 0x2a,
|
||||
0x73, 0xa7, 0xc6, 0xa7, 0x59, 0xc7, 0x49, 0x4f, 0x12, 0xcc, 0x37, 0xb3, 0xe2, 0xf0, 0x71, 0xde,
|
||||
0x85, 0xce, 0x6b, 0x5d, 0xe8, 0x22, 0x94, 0x13, 0x97, 0xe0, 0x88, 0xb6, 0x2a, 0xa2, 0x8b, 0x10,
|
||||
0x94, 0x76, 0x1c, 0xe0, 0x72, 0xfd, 0xce, 0x1b, 0x58, 0x10, 0x17, 0x2e, 0x4e, 0x70, 0xe4, 0xe3,
|
||||
0xc8, 0x63, 0xdb, 0x55, 0xe5, 0xd0, 0xac, 0x9f, 0x07, 0xcd, 0xde, 0xf8, 0x22, 0x81, 0xd2, 0xa4,
|
||||
0x32, 0xb9, 0x43, 0x94, 0xed, 0x50, 0x4d, 0xa5, 0x28, 0x27, 0xd9, 0xeb, 0x48, 0xf5, 0xb1, 0x69,
|
||||
0xab, 0x3e, 0xed, 0x75, 0x64, 0xda, 0x3c, 0x50, 0xc2, 0xf2, 0x75, 0x94, 0x2f, 0x66, 0x36, 0xdc,
|
||||
0x30, 0x70, 0x53, 0x9c, 0xb6, 0x1a, 0xe2, 0x6a, 0x96, 0x24, 0xb2, 0xd9, 0x9d, 0xa8, 0x85, 0x76,
|
||||
0x83, 0xb3, 0x8d, 0xb9, 0xf6, 0x5d, 0xb8, 0x99, 0xdf, 0x3f, 0xba, 0xe7, 0x08, 0x4a, 0x19, 0x89,
|
||||
0x54, 0x23, 0xc0, 0xc7, 0xed, 0x87, 0x50, 0xd5, 0xb2, 0xe2, 0x2a, 0x2f, 0xa6, 0xf6, 0x08, 0x16,
|
||||
0xa7, 0xa3, 0x36, 0x45, 0xcb, 0x8e, 0x79, 0x55, 0xae, 0x5d, 0x00, 0xcb, 0x84, 0xef, 0xba, 0xdd,
|
||||
0x0d, 0x68, 0x98, 0xc8, 0x5d, 0xe9, 0x9d, 0xf7, 0x43, 0x81, 0x3f, 0xf4, 0x94, 0x49, 0x59, 0x4b,
|
||||
0x26, 0xaf, 0xd1, 0xfb, 0xfc, 0xb8, 0x51, 0x7c, 0x51, 0xf1, 0x16, 0x52, 0xc8, 0x85, 0x05, 0x3e,
|
||||
0x30, 0xf2, 0x4e, 0x1c, 0xc9, 0x07, 0xd3, 0x83, 0x95, 0x5d, 0xcb, 0xe1, 0xf8, 0x2a, 0x99, 0x78,
|
||||
0x13, 0xda, 0xae, 0xb4, 0xad, 0xef, 0x60, 0x71, 0xba, 0xe2, 0x29, 0x58, 0xed, 0x9a, 0x7b, 0xf3,
|
||||
0xef, 0x73, 0xdd, 0xbd, 0x60, 0x73, 0xec, 0x6f, 0x2c, 0xb8, 0xc5, 0x5f, 0xa7, 0x0e, 0x4e, 0xe3,
|
||||
0x8c, 0x78, 0x78, 0x2f, 0x0a, 0xe8, 0x0e, 0x6f, 0xa5, 0xde, 0xdf, 0x25, 0xd9, 0x82, 0x39, 0xf1,
|
||||
0xca, 0x10, 0x10, 0x57, 0x1c, 0x45, 0x5e, 0xf9, 0x26, 0x5f, 0xff, 0x65, 0x0e, 0x9a, 0xca, 0x55,
|
||||
0x95, 0x55, 0xec, 0x20, 0xe7, 0x1f, 0x25, 0xe8, 0x8e, 0x86, 0xc7, 0xf8, 0x67, 0x4b, 0x7b, 0x69,
|
||||
0x3a, 0x53, 0x80, 0x65, 0xcf, 0xa0, 0x2d, 0xa8, 0xf2, 0x97, 0x94, 0x38, 0x63, 0x68, 0xe2, 0xed,
|
||||
0xa5, 0xf4, 0xb4, 0x26, 0x19, 0xb9, 0x8e, 0x27, 0x00, 0xbc, 0x67, 0x94, 0xf5, 0x7a, 0xa2, 0xfd,
|
||||
0x15, 0x1a, 0x6e, 0x9d, 0xd1, 0x16, 0xdb, 0x33, 0x2c, 0x9c, 0xfc, 0xe7, 0xc0, 0x08, 0x67, 0xfc,
|
||||
0xbf, 0xc6, 0x08, 0x67, 0xe2, 0x37, 0x84, 0xbb, 0x52, 0x16, 0x6f, 0x70, 0xa4, 0x3b, 0x6c, 0x7c,
|
||||
0x0e, 0xb4, 0x6f, 0x4f, 0xe1, 0xe4, 0x0a, 0x76, 0xa1, 0x76, 0x48, 0x09, 0x76, 0x87, 0xbf, 0x4b,
|
||||
0xcd, 0x9a, 0x85, 0x36, 0x60, 0x96, 0xe3, 0x74, 0x3d, 0x48, 0x1f, 0x42, 0x89, 0x3f, 0x09, 0xae,
|
||||
0x01, 0xe6, 0x13, 0x28, 0x8b, 0x8e, 0xd7, 0xf0, 0xdd, 0x68, 0xca, 0x0d, 0xdf, 0xcd, 0xf6, 0x58,
|
||||
0xd8, 0x66, 0xad, 0xa3, 0x61, 0x5b, 0xeb, 0x73, 0x0d, 0xdb, 0x7a, 0x8f, 0x29, 0x6c, 0x8b, 0x1e,
|
||||
0xc8, 0xb0, 0x6d, 0x74, 0x7f, 0x86, 0x6d, 0xb3, 0x61, 0xb2, 0x67, 0xd0, 0x06, 0x94, 0x45, 0xe3,
|
||||
0x63, 0x28, 0x30, 0x7a, 0xa1, 0xf6, 0xe2, 0xc4, 0x91, 0xe9, 0x0d, 0x13, 0x7a, 0x92, 0xe7, 0x91,
|
||||
0x28, 0x08, 0xe3, 0x79, 0x64, 0x94, 0xf0, 0xf1, 0x3c, 0x32, 0x6b, 0x88, 0x3d, 0x83, 0x1e, 0x41,
|
||||
0x79, 0xdb, 0x8d, 0x3c, 0x1c, 0xa2, 0x33, 0xac, 0x9d, 0xe3, 0xc5, 0xff, 0xa0, 0xbe, 0x8b, 0xe9,
|
||||
0x01, 0xff, 0x41, 0xdd, 0x8b, 0xfa, 0xf1, 0x99, 0x2a, 0xfe, 0xaa, 0xbf, 0xc7, 0x72, 0x71, 0x7b,
|
||||
0xe6, 0x6d, 0x99, 0x0b, 0x3e, 0xf8, 0x2d, 0x00, 0x00, 0xff, 0xff, 0xb4, 0x49, 0xd0, 0x38, 0xa2,
|
||||
0x15, 0x00, 0x00,
|
||||
// 1670 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x58, 0xcd, 0x72, 0x1b, 0x45,
|
||||
0x10, 0xf6, 0x4a, 0xb2, 0x6c, 0xb5, 0x7e, 0x22, 0x0f, 0xc1, 0x51, 0x14, 0x1f, 0x5c, 0x0b, 0x55,
|
||||
0x98, 0x84, 0xc8, 0xc6, 0x39, 0x40, 0x52, 0x4e, 0x05, 0xdb, 0x92, 0x8d, 0x2b, 0x89, 0x63, 0xd6,
|
||||
0x09, 0x3f, 0xa7, 0x64, 0xb3, 0x1a, 0xc9, 0x8b, 0xa5, 0xdd, 0x65, 0x76, 0x56, 0x29, 0x73, 0xe6,
|
||||
0xc0, 0x05, 0xae, 0x14, 0x0f, 0x01, 0x54, 0xf1, 0x04, 0x3c, 0x08, 0x1c, 0x79, 0x00, 0x8a, 0x17,
|
||||
0xa0, 0xe6, 0x6f, 0x3d, 0x23, 0xad, 0x7f, 0x49, 0xc1, 0x6d, 0x7b, 0xba, 0xa7, 0xa7, 0xfb, 0x9b,
|
||||
0x9e, 0xfe, 0x59, 0xa8, 0x45, 0x24, 0x1c, 0xf9, 0x5d, 0x4c, 0x5a, 0x11, 0x09, 0x69, 0x88, 0x4a,
|
||||
0x51, 0x32, 0x48, 0x86, 0x3e, 0x89, 0xbc, 0x66, 0x25, 0x1a, 0x24, 0x7d, 0x3f, 0x10, 0x8c, 0xe6,
|
||||
0x8d, 0x7e, 0x18, 0xf6, 0x07, 0x78, 0x99, 0x53, 0x2f, 0x93, 0xde, 0x32, 0x1e, 0x46, 0xf4, 0x48,
|
||||
0x32, 0x17, 0xc6, 0x99, 0x31, 0x25, 0x89, 0x47, 0x05, 0xd7, 0x7e, 0x0f, 0xea, 0xdb, 0x98, 0xee,
|
||||
0x7b, 0x07, 0x78, 0xe8, 0x3a, 0xf8, 0xab, 0x04, 0xc7, 0x14, 0x35, 0x60, 0x66, 0x84, 0x49, 0xec,
|
||||
0x87, 0x41, 0xc3, 0x5a, 0xb4, 0x96, 0xa6, 0x1d, 0x45, 0xda, 0xb7, 0x60, 0x4e, 0x93, 0x8e, 0xa3,
|
||||
0x30, 0x88, 0x31, 0x9a, 0x87, 0x62, 0xcc, 0x57, 0xb8, 0x74, 0xc9, 0x91, 0x94, 0xfd, 0x43, 0x0e,
|
||||
0xea, 0x9b, 0x61, 0xd0, 0xf3, 0xfb, 0x09, 0xc1, 0x4a, 0xf7, 0xc7, 0x50, 0x1a, 0xb9, 0xc4, 0x77,
|
||||
0x5f, 0x0e, 0x70, 0xdc, 0xb0, 0x16, 0xf3, 0x4b, 0xe5, 0xd5, 0x9b, 0xad, 0xd4, 0xaf, 0xd6, 0xb8,
|
||||
0x7c, 0xeb, 0x53, 0x25, 0xdc, 0x09, 0x28, 0x39, 0x72, 0x8e, 0x37, 0xa3, 0x5b, 0x50, 0x70, 0x49,
|
||||
0x3f, 0x6e, 0xe4, 0x16, 0xad, 0xa5, 0xf2, 0xea, 0xb5, 0x96, 0x70, 0xb3, 0xa5, 0xdc, 0x6c, 0xed,
|
||||
0x73, 0x37, 0x1d, 0x2e, 0x84, 0xde, 0x86, 0xaa, 0xeb, 0x79, 0x38, 0xa2, 0xfb, 0xd8, 0x23, 0x98,
|
||||
0xc6, 0x8d, 0xfc, 0xa2, 0xb5, 0x34, 0xeb, 0x98, 0x8b, 0x68, 0x09, 0xae, 0x88, 0x05, 0x07, 0xc7,
|
||||
0x61, 0x42, 0x3c, 0x1c, 0x37, 0x0a, 0x5c, 0x6e, 0x7c, 0xb9, 0xb9, 0x06, 0x35, 0xd3, 0x32, 0x54,
|
||||
0x87, 0xfc, 0x21, 0x3e, 0x92, 0x10, 0xb0, 0x4f, 0x74, 0x15, 0xa6, 0x47, 0xee, 0x20, 0xc1, 0xdc,
|
||||
0xc2, 0x92, 0x23, 0x88, 0x7b, 0xb9, 0x0f, 0x2d, 0xfb, 0x3b, 0x0b, 0xe6, 0x34, 0x4f, 0x25, 0x8e,
|
||||
0x13, 0x36, 0x5a, 0x27, 0xd8, 0x18, 0x27, 0x51, 0x14, 0x12, 0x1a, 0xef, 0x11, 0x3c, 0xf2, 0xf1,
|
||||
0x2b, 0xae, 0x7f, 0xd6, 0x19, 0x5f, 0xce, 0xf2, 0x26, 0x9f, 0xe9, 0x8d, 0xfd, 0xab, 0x05, 0xd7,
|
||||
0x53, 0x7b, 0x3a, 0x84, 0x84, 0xe4, 0xb1, 0x1f, 0xc7, 0x7e, 0xd0, 0x7f, 0x88, 0x8f, 0x62, 0xf4,
|
||||
0x09, 0x94, 0x87, 0xc7, 0xa4, 0xbc, 0xb4, 0xe5, 0xac, 0x4b, 0x1b, 0xdf, 0xda, 0x3a, 0xfe, 0x76,
|
||||
0x74, 0x1d, 0xcd, 0x0d, 0x80, 0x63, 0x16, 0x42, 0x50, 0x08, 0xdc, 0x21, 0x96, 0xd8, 0xf1, 0x6f,
|
||||
0xb4, 0x08, 0xe5, 0x2e, 0x8e, 0x3d, 0xe2, 0x47, 0x94, 0xc5, 0xa1, 0x80, 0x50, 0x5f, 0xb2, 0x7f,
|
||||
0xb6, 0xa0, 0xba, 0x13, 0x8c, 0xc2, 0xc3, 0x34, 0xb6, 0xea, 0x90, 0xa7, 0xe1, 0xa1, 0xba, 0x02,
|
||||
0x1a, 0x1e, 0x5e, 0x2c, 0x46, 0x9a, 0x30, 0xab, 0x1e, 0x1c, 0x07, 0xaa, 0xe4, 0xa4, 0xb4, 0xfe,
|
||||
0x24, 0x0a, 0x9c, 0xa5, 0xc8, 0x2c, 0x94, 0xa7, 0xb3, 0x51, 0x1e, 0x41, 0x4d, 0xd9, 0x2b, 0x6f,
|
||||
0x7c, 0x19, 0x8a, 0x04, 0xd3, 0x84, 0x88, 0x77, 0x76, 0x8a, 0x81, 0x52, 0x0c, 0xdd, 0x81, 0xd9,
|
||||
0x9e, 0xeb, 0x0f, 0x12, 0x82, 0x99, 0x4f, 0x79, 0xbe, 0x45, 0xbb, 0x87, 0x03, 0xec, 0x1d, 0x6e,
|
||||
0x09, 0xbe, 0x93, 0x0a, 0xda, 0x5f, 0x43, 0x85, 0x73, 0x34, 0x98, 0xd4, 0x91, 0x25, 0x87, 0x7d,
|
||||
0x32, 0x98, 0xc2, 0x41, 0xf7, 0x6c, 0x98, 0x98, 0x10, 0x13, 0x0e, 0xf0, 0x2b, 0x11, 0x4b, 0xa7,
|
||||
0x09, 0x33, 0x21, 0x3b, 0x81, 0xaa, 0x3c, 0xfb, 0xd8, 0x65, 0x3f, 0x88, 0x12, 0x19, 0xdd, 0xa7,
|
||||
0xb9, 0x2c, 0xc4, 0x2e, 0xe7, 0xf2, 0x86, 0x74, 0x59, 0x72, 0xe4, 0xd5, 0x46, 0x98, 0x50, 0xf5,
|
||||
0x42, 0x53, 0x9a, 0xa5, 0x2f, 0x82, 0xdd, 0x38, 0x0d, 0x32, 0x49, 0xd9, 0xbf, 0x58, 0x50, 0x6e,
|
||||
0xfb, 0xbd, 0x9e, 0x82, 0xad, 0x06, 0x39, 0xbf, 0x2b, 0x77, 0xe7, 0xfc, 0xae, 0x82, 0x31, 0x37,
|
||||
0x09, 0x63, 0xfe, 0x22, 0x30, 0x16, 0xce, 0x01, 0x23, 0x4b, 0x0d, 0x7e, 0x3f, 0x08, 0x09, 0xde,
|
||||
0x3c, 0x70, 0x83, 0x3e, 0x0f, 0xb1, 0xfc, 0x52, 0xc9, 0x31, 0x17, 0xed, 0xdf, 0x2c, 0xa8, 0xec,
|
||||
0x49, 0xb7, 0x98, 0xe5, 0x68, 0x05, 0x0a, 0x87, 0x7e, 0x20, 0x8c, 0xae, 0xad, 0x2e, 0x68, 0xb8,
|
||||
0xe9, 0x62, 0xad, 0x87, 0x7e, 0xd0, 0x75, 0xb8, 0x24, 0x5a, 0x80, 0x12, 0xc7, 0x9d, 0xad, 0xcb,
|
||||
0xbc, 0x72, 0xbc, 0x60, 0xbf, 0x80, 0x02, 0x93, 0x45, 0x33, 0x90, 0x5f, 0x6f, 0xb7, 0xeb, 0x53,
|
||||
0xe8, 0x0a, 0x94, 0xd7, 0xdb, 0xed, 0xe7, 0x4e, 0x67, 0xef, 0xd1, 0xfa, 0x66, 0xa7, 0x6e, 0x21,
|
||||
0x80, 0x62, 0xbb, 0xf3, 0xa8, 0xf3, 0xb4, 0x53, 0xcf, 0x21, 0x04, 0x35, 0xf1, 0x9d, 0xf2, 0xf3,
|
||||
0x8c, 0xff, 0x6c, 0xaf, 0xbd, 0xfe, 0xb4, 0x53, 0x2f, 0x30, 0xbe, 0xf8, 0x4e, 0xf9, 0xd3, 0xf6,
|
||||
0x1f, 0x79, 0xa8, 0x08, 0xd0, 0x65, 0xbc, 0x34, 0x61, 0x96, 0xe0, 0x68, 0xe0, 0x7a, 0xb2, 0x5c,
|
||||
0x94, 0x9c, 0x94, 0x66, 0x8f, 0x32, 0xa6, 0xa2, 0x92, 0xe4, 0x38, 0x4b, 0x91, 0x68, 0x05, 0xde,
|
||||
0xe8, 0xe2, 0x01, 0xa6, 0x78, 0x03, 0xf7, 0x42, 0x96, 0x62, 0xf9, 0x0e, 0x99, 0xfe, 0xb2, 0x58,
|
||||
0xe8, 0x3e, 0xcc, 0x78, 0x12, 0xdb, 0x02, 0x47, 0xeb, 0x2d, 0x0d, 0x2d, 0xdd, 0x22, 0x4e, 0x48,
|
||||
0xc4, 0x1d, 0xb5, 0x87, 0xe5, 0xfa, 0xae, 0xdf, 0xeb, 0xa9, 0x8b, 0x11, 0x04, 0x7a, 0x0c, 0x95,
|
||||
0x2e, 0xa6, 0xae, 0x3f, 0xc0, 0x5d, 0x0e, 0x68, 0x91, 0xc7, 0xef, 0xbb, 0x27, 0x6a, 0xd6, 0x64,
|
||||
0x45, 0xb9, 0x33, 0xb6, 0xb3, 0x54, 0x73, 0xe0, 0xc6, 0xba, 0x54, 0x63, 0x46, 0xa4, 0x9a, 0xb1,
|
||||
0xe5, 0xe6, 0xe7, 0x30, 0x37, 0xa1, 0x2c, 0xa3, 0x42, 0xdd, 0xd6, 0x2b, 0x94, 0xf9, 0xb0, 0xf4,
|
||||
0x00, 0xd1, 0x4b, 0xd7, 0x7d, 0xf1, 0x28, 0x24, 0x00, 0xa8, 0x0e, 0x95, 0xf6, 0xce, 0xd6, 0xd6,
|
||||
0xf3, 0x67, 0xbb, 0x0f, 0x77, 0x9f, 0x7c, 0xb6, 0x5b, 0x9f, 0x42, 0x55, 0x28, 0xf1, 0x95, 0xdd,
|
||||
0x27, 0xbb, 0x2c, 0x20, 0x14, 0xb9, 0xff, 0xe4, 0x71, 0xa7, 0x9e, 0xb3, 0xbf, 0xb7, 0xa0, 0xba,
|
||||
0x49, 0xb0, 0x4b, 0xf1, 0xc9, 0xd9, 0xe8, 0x03, 0x00, 0xf9, 0x38, 0x7d, 0x7c, 0x66, 0x4e, 0xd2,
|
||||
0x44, 0x59, 0x3c, 0x50, 0x7f, 0x88, 0xc3, 0x84, 0xf2, 0x9b, 0xb6, 0x1c, 0x45, 0x32, 0x4e, 0x24,
|
||||
0x8b, 0xa5, 0x28, 0xe8, 0x8a, 0xb4, 0xbf, 0x80, 0x9a, 0xb2, 0x47, 0x46, 0xdc, 0xf8, 0x3b, 0xbf,
|
||||
0xac, 0x39, 0xf6, 0x8f, 0x16, 0x94, 0x1d, 0xec, 0x76, 0xcf, 0x9f, 0x40, 0xcc, 0xa3, 0xf2, 0xe7,
|
||||
0xf7, 0xfc, 0x38, 0xab, 0x16, 0xce, 0x95, 0x55, 0xed, 0x6f, 0x2d, 0xa8, 0x08, 0xdb, 0x5e, 0xb3,
|
||||
0xd7, 0x9a, 0x29, 0xf9, 0xf3, 0x99, 0xf2, 0xa7, 0x05, 0xd5, 0x67, 0x51, 0x57, 0x0b, 0x89, 0xff,
|
||||
0x33, 0xd3, 0x6a, 0x31, 0x34, 0x6d, 0xc6, 0xd0, 0x44, 0x0e, 0x2e, 0x66, 0xe4, 0x60, 0x3d, 0xd2,
|
||||
0x66, 0xcc, 0x48, 0xdb, 0x81, 0x9a, 0x72, 0x53, 0x62, 0x6e, 0x62, 0x6c, 0x9d, 0x3f, 0xb2, 0xbe,
|
||||
0xb1, 0xa0, 0xda, 0xe6, 0x49, 0xec, 0x3f, 0x88, 0x2d, 0x0d, 0x91, 0x82, 0x81, 0x88, 0xfd, 0x77,
|
||||
0x91, 0x37, 0xf8, 0x62, 0x9e, 0xd0, 0x86, 0x87, 0x88, 0x84, 0x5f, 0x62, 0x8f, 0x4a, 0x73, 0x14,
|
||||
0xc9, 0x72, 0x64, 0x4c, 0x5d, 0xef, 0x50, 0xf5, 0xc3, 0x9c, 0x40, 0x0f, 0xa0, 0xe8, 0xf1, 0xfe,
|
||||
0xb1, 0x91, 0xe7, 0xd9, 0xf1, 0x1d, 0xb3, 0xb1, 0x34, 0x94, 0xcb, 0x4e, 0x53, 0xe4, 0x46, 0xb9,
|
||||
0x8d, 0xd5, 0xef, 0x2e, 0x39, 0x72, 0x92, 0x40, 0x3e, 0x6d, 0x49, 0xf1, 0x9a, 0xef, 0x12, 0x77,
|
||||
0x30, 0xc0, 0x03, 0x7e, 0x95, 0xd3, 0x4e, 0x4a, 0xb3, 0x4c, 0x3a, 0x0c, 0x03, 0x9f, 0x86, 0xa4,
|
||||
0x13, 0x74, 0xa3, 0xd0, 0x0f, 0x68, 0xa3, 0xc8, 0x8d, 0x1a, 0x5f, 0x66, 0xbd, 0x29, 0x3d, 0x8a,
|
||||
0x30, 0xbf, 0xcc, 0x92, 0xc3, 0xbf, 0xd3, 0x7e, 0x75, 0x56, 0xeb, 0x57, 0xe7, 0xa1, 0x18, 0xb9,
|
||||
0x04, 0x07, 0xb4, 0x51, 0x12, 0x5d, 0x84, 0xa0, 0xb4, 0xe7, 0x00, 0xe7, 0xeb, 0x77, 0x5e, 0xc0,
|
||||
0x9c, 0x28, 0xb8, 0x38, 0xc2, 0x41, 0x17, 0x07, 0x1e, 0xbb, 0xae, 0x32, 0x87, 0x66, 0xf5, 0x34,
|
||||
0x68, 0x76, 0xc6, 0x37, 0x09, 0x94, 0x26, 0x95, 0xc9, 0x1b, 0xa2, 0xec, 0x86, 0x2a, 0x2a, 0x44,
|
||||
0x39, 0xc9, 0x86, 0x33, 0xd5, 0xf1, 0xc6, 0x8d, 0x6a, 0xd6, 0x70, 0x66, 0x9e, 0xb9, 0xa7, 0x84,
|
||||
0xe5, 0x70, 0x96, 0x6e, 0x66, 0x67, 0xb8, 0x03, 0xdf, 0x8d, 0x71, 0xdc, 0xa8, 0x89, 0xd2, 0x2c,
|
||||
0x49, 0x64, 0xb3, 0x9a, 0xa8, 0xb9, 0x76, 0x85, 0xb3, 0x8d, 0xb5, 0xe6, 0x4d, 0xb8, 0x9a, 0xd6,
|
||||
0x1f, 0xdd, 0x72, 0x04, 0x85, 0x84, 0x04, 0xaa, 0x11, 0xe0, 0xdf, 0xcd, 0xbb, 0x50, 0xd6, 0xa2,
|
||||
0xe2, 0x22, 0x63, 0x58, 0x73, 0x04, 0xf3, 0xd9, 0xa8, 0x65, 0x68, 0xd9, 0x32, 0x4b, 0xe5, 0xca,
|
||||
0x19, 0xb0, 0x4c, 0xd8, 0xae, 0x9f, 0xbb, 0x06, 0x35, 0x13, 0xb9, 0x0b, 0x0d, 0x8f, 0xbf, 0xe7,
|
||||
0xf8, 0xf0, 0xa8, 0x8e, 0x94, 0xb9, 0x64, 0xb2, 0x8c, 0xde, 0xe6, 0xcf, 0x8d, 0xe2, 0xb3, 0x92,
|
||||
0xb7, 0x90, 0x42, 0x2e, 0xcc, 0xf1, 0x0f, 0x23, 0xee, 0xc4, 0x93, 0xbc, 0x93, 0xed, 0xac, 0xec,
|
||||
0x5a, 0xf6, 0xc7, 0x77, 0xc9, 0xc0, 0x9b, 0xd0, 0x76, 0xa1, 0x6b, 0x7d, 0x05, 0xf3, 0xd9, 0x8a,
|
||||
0x33, 0xb0, 0xda, 0x36, 0xef, 0xe6, 0xfd, 0x53, 0xcd, 0x3d, 0xe3, 0x72, 0xec, 0x9f, 0x2c, 0xb8,
|
||||
0xc6, 0xe7, 0x58, 0x35, 0xb8, 0xed, 0x04, 0x3e, 0xdd, 0xe2, 0xad, 0xd4, 0xeb, 0x2b, 0x92, 0x0d,
|
||||
0x98, 0x11, 0x53, 0x86, 0x80, 0xb8, 0xe4, 0x28, 0xf2, 0xc2, 0x95, 0x7c, 0xf5, 0xaf, 0x19, 0xa8,
|
||||
0x2b, 0x53, 0x55, 0x54, 0xb1, 0x87, 0x9c, 0xfe, 0xa7, 0x41, 0x37, 0x34, 0x3c, 0xc6, 0xff, 0xf5,
|
||||
0x34, 0x17, 0xb2, 0x99, 0x02, 0x2c, 0x7b, 0x0a, 0x6d, 0x40, 0x99, 0x4f, 0x52, 0xe2, 0x8d, 0xa1,
|
||||
0x89, 0xd9, 0x4b, 0xe9, 0x69, 0x4c, 0x32, 0x52, 0x1d, 0x0f, 0x00, 0x78, 0xcf, 0x28, 0xf3, 0xf5,
|
||||
0x44, 0xfb, 0x2b, 0x34, 0x5c, 0x3b, 0xa1, 0x2d, 0xb6, 0xa7, 0x98, 0x3b, 0xe9, 0x3f, 0x06, 0xc3,
|
||||
0x9d, 0xf1, 0xdf, 0x45, 0x86, 0x3b, 0x13, 0x7f, 0x58, 0xb8, 0x29, 0x45, 0x31, 0x83, 0x23, 0xdd,
|
||||
0x60, 0xe3, 0x37, 0x42, 0xf3, 0x7a, 0x06, 0x27, 0x55, 0xb0, 0x0d, 0x95, 0x7d, 0x4a, 0xb0, 0x3b,
|
||||
0xfc, 0x57, 0x6a, 0x56, 0x2c, 0xb4, 0x06, 0xd3, 0x1c, 0xa7, 0xcb, 0x41, 0x7a, 0x17, 0x0a, 0x7c,
|
||||
0x24, 0xb8, 0x04, 0x98, 0x0f, 0xa0, 0x28, 0x3a, 0x5e, 0xc3, 0x76, 0xa3, 0x29, 0x37, 0x6c, 0x37,
|
||||
0xdb, 0x63, 0x71, 0x36, 0x6b, 0x1d, 0x8d, 0xb3, 0xb5, 0x3e, 0xd7, 0x38, 0x5b, 0xef, 0x31, 0xc5,
|
||||
0xd9, 0xa2, 0x07, 0x32, 0xce, 0x36, 0xba, 0x3f, 0xe3, 0x6c, 0xb3, 0x61, 0xb2, 0xa7, 0xd0, 0x1a,
|
||||
0x14, 0x45, 0xe3, 0x63, 0x28, 0x30, 0x7a, 0xa1, 0xe6, 0xfc, 0xc4, 0x93, 0xe9, 0x0c, 0x23, 0x7a,
|
||||
0x94, 0xc6, 0x91, 0x48, 0x08, 0xe3, 0x71, 0x64, 0xa4, 0xf0, 0xf1, 0x38, 0x32, 0x73, 0x88, 0x3d,
|
||||
0x85, 0xee, 0x41, 0x71, 0xd3, 0x0d, 0x3c, 0x3c, 0x40, 0x27, 0x9c, 0x76, 0x8a, 0x15, 0x1f, 0x41,
|
||||
0x75, 0x1b, 0xd3, 0x3d, 0xfe, 0x03, 0x77, 0x27, 0xe8, 0x85, 0x27, 0xaa, 0x78, 0x53, 0x9f, 0xc7,
|
||||
0x52, 0x71, 0x7b, 0xea, 0x65, 0x91, 0x0b, 0xde, 0xf9, 0x27, 0x00, 0x00, 0xff, 0xff, 0xac, 0xa3,
|
||||
0xd1, 0x1f, 0x21, 0x16, 0x00, 0x00,
|
||||
}
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
|
|
|
@ -119,6 +119,7 @@ type ReadResourceRequest struct {
|
|||
AcceptSecrets bool `protobuf:"varint,9,opt,name=acceptSecrets,proto3" json:"acceptSecrets,omitempty"`
|
||||
AdditionalSecretOutputs []string `protobuf:"bytes,10,rep,name=additionalSecretOutputs,proto3" json:"additionalSecretOutputs,omitempty"`
|
||||
Aliases []string `protobuf:"bytes,11,rep,name=aliases,proto3" json:"aliases,omitempty"`
|
||||
AcceptResources bool `protobuf:"varint,12,opt,name=acceptResources,proto3" json:"acceptResources,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
|
@ -226,6 +227,13 @@ func (m *ReadResourceRequest) GetAliases() []string {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (m *ReadResourceRequest) GetAcceptResources() bool {
|
||||
if m != nil {
|
||||
return m.AcceptResources
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// ReadResourceResponse contains the result of reading a resource's state.
|
||||
type ReadResourceResponse struct {
|
||||
Urn string `protobuf:"bytes,1,opt,name=urn,proto3" json:"urn,omitempty"`
|
||||
|
@ -296,6 +304,7 @@ type RegisterResourceRequest struct {
|
|||
DeleteBeforeReplaceDefined bool `protobuf:"varint,18,opt,name=deleteBeforeReplaceDefined,proto3" json:"deleteBeforeReplaceDefined,omitempty"`
|
||||
SupportsPartialValues bool `protobuf:"varint,19,opt,name=supportsPartialValues,proto3" json:"supportsPartialValues,omitempty"`
|
||||
Remote bool `protobuf:"varint,20,opt,name=remote,proto3" json:"remote,omitempty"`
|
||||
AcceptResources bool `protobuf:"varint,21,opt,name=acceptResources,proto3" json:"acceptResources,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
|
@ -466,6 +475,13 @@ func (m *RegisterResourceRequest) GetRemote() bool {
|
|||
return false
|
||||
}
|
||||
|
||||
func (m *RegisterResourceRequest) GetAcceptResources() bool {
|
||||
if m != nil {
|
||||
return m.AcceptResources
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// PropertyDependencies describes the resources that a particular property depends on.
|
||||
type RegisterResourceRequest_PropertyDependencies struct {
|
||||
Urns []string `protobuf:"bytes,1,rep,name=urns,proto3" json:"urns,omitempty"`
|
||||
|
@ -759,65 +775,66 @@ func init() {
|
|||
func init() { proto.RegisterFile("resource.proto", fileDescriptor_d1b72f771c35e3b8) }
|
||||
|
||||
var fileDescriptor_d1b72f771c35e3b8 = []byte{
|
||||
// 927 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x56, 0x5f, 0x73, 0xdb, 0x44,
|
||||
0x10, 0x8f, 0xed, 0x54, 0xb1, 0x37, 0xa9, 0x13, 0x2e, 0xc1, 0xb9, 0x0a, 0x26, 0x04, 0xc1, 0x83,
|
||||
0xe1, 0xc1, 0x69, 0x03, 0x33, 0x0d, 0x0c, 0x7f, 0x66, 0x68, 0x0b, 0xd3, 0x87, 0x42, 0x51, 0x18,
|
||||
0x06, 0x98, 0x81, 0x99, 0x8b, 0xb4, 0x71, 0x45, 0x64, 0xdd, 0xf5, 0xee, 0x94, 0x19, 0xbf, 0xc1,
|
||||
0x23, 0x5f, 0x8b, 0x4f, 0xc3, 0x33, 0x9f, 0x80, 0xb9, 0x3b, 0xc9, 0x58, 0x96, 0x9c, 0xd8, 0xed,
|
||||
0xdb, 0xed, 0xee, 0xdd, 0x4a, 0xfb, 0xfb, 0xfd, 0x76, 0xef, 0xa0, 0x2f, 0x51, 0xf1, 0x5c, 0x46,
|
||||
0x38, 0x12, 0x92, 0x6b, 0x4e, 0x7a, 0x22, 0x4f, 0xf3, 0x49, 0x22, 0x45, 0xe4, 0xbf, 0x35, 0xe6,
|
||||
0x7c, 0x9c, 0xe2, 0x89, 0x0d, 0x5c, 0xe4, 0x97, 0x27, 0x38, 0x11, 0x7a, 0xea, 0xf6, 0xf9, 0x6f,
|
||||
0x2f, 0x06, 0x95, 0x96, 0x79, 0xa4, 0x8b, 0x68, 0x5f, 0x48, 0x7e, 0x9d, 0xc4, 0x28, 0x9d, 0x1d,
|
||||
0x0c, 0x61, 0x70, 0x9e, 0x0b, 0xc1, 0xa5, 0x56, 0x5f, 0x23, 0xd3, 0xb9, 0xc4, 0x10, 0x5f, 0xe6,
|
||||
0xa8, 0x34, 0xe9, 0x43, 0x3b, 0x89, 0x69, 0xeb, 0xb8, 0x35, 0xec, 0x85, 0xed, 0x24, 0x0e, 0x3e,
|
||||
0x81, 0xc3, 0xda, 0x4e, 0x25, 0x78, 0xa6, 0x90, 0x1c, 0x01, 0xbc, 0x60, 0xaa, 0x88, 0xda, 0x23,
|
||||
0xdd, 0x70, 0xce, 0x13, 0xfc, 0xdb, 0x86, 0xfd, 0x10, 0x59, 0x1c, 0x16, 0x15, 0x2d, 0xf9, 0x04,
|
||||
0x21, 0xb0, 0xa9, 0xa7, 0x02, 0x69, 0xdb, 0x7a, 0xec, 0xda, 0xf8, 0x32, 0x36, 0x41, 0xda, 0x71,
|
||||
0x3e, 0xb3, 0x26, 0x03, 0xf0, 0x04, 0x93, 0x98, 0x69, 0xba, 0x69, 0xbd, 0x85, 0x45, 0x1e, 0x02,
|
||||
0x08, 0xc9, 0x05, 0x4a, 0x9d, 0xa0, 0xa2, 0x77, 0x8e, 0x5b, 0xc3, 0xed, 0xd3, 0xc3, 0x91, 0xc3,
|
||||
0x63, 0x54, 0xe2, 0x31, 0x3a, 0xb7, 0x78, 0x84, 0x73, 0x5b, 0x49, 0x00, 0x3b, 0x31, 0x0a, 0xcc,
|
||||
0x62, 0xcc, 0x22, 0x73, 0xd4, 0x3b, 0xee, 0x0c, 0x7b, 0x61, 0xc5, 0x47, 0x7c, 0xe8, 0x96, 0xd8,
|
||||
0xd1, 0x2d, 0xfb, 0xd9, 0x99, 0x4d, 0x28, 0x6c, 0x5d, 0xa3, 0x54, 0x09, 0xcf, 0x68, 0xd7, 0x86,
|
||||
0x4a, 0x93, 0xbc, 0x0f, 0x77, 0x59, 0x14, 0xa1, 0xd0, 0xe7, 0x18, 0x49, 0xd4, 0x8a, 0xf6, 0x2c,
|
||||
0x3a, 0x55, 0x27, 0x39, 0x83, 0x43, 0x16, 0xc7, 0x89, 0x4e, 0x78, 0xc6, 0x52, 0xe7, 0xfc, 0x2e,
|
||||
0xd7, 0x22, 0xd7, 0x8a, 0x82, 0xfd, 0x95, 0x65, 0x61, 0xf3, 0x65, 0x96, 0x26, 0x4c, 0xa1, 0xa2,
|
||||
0xdb, 0x76, 0x67, 0x69, 0x06, 0x0c, 0x0e, 0xaa, 0x98, 0x17, 0x64, 0xed, 0x41, 0x27, 0x97, 0x59,
|
||||
0x81, 0xba, 0x59, 0x2e, 0xc0, 0xd6, 0x5e, 0x19, 0xb6, 0xe0, 0x9f, 0x2e, 0x1c, 0x86, 0x38, 0x4e,
|
||||
0x94, 0x46, 0xb9, 0xc8, 0x6d, 0xc9, 0x65, 0xab, 0x81, 0xcb, 0x76, 0x23, 0x97, 0x9d, 0x0a, 0x97,
|
||||
0x03, 0xf0, 0xa2, 0x5c, 0x69, 0x3e, 0xb1, 0x1c, 0x77, 0xc3, 0xc2, 0x22, 0x27, 0xe0, 0xf1, 0x8b,
|
||||
0xdf, 0x31, 0xd2, 0xb7, 0xf1, 0x5b, 0x6c, 0x33, 0x08, 0x99, 0x90, 0x39, 0xe1, 0xd9, 0x4c, 0xa5,
|
||||
0x59, 0x63, 0x7d, 0xeb, 0x16, 0xd6, 0xbb, 0x0b, 0xac, 0x0b, 0x38, 0x28, 0xc0, 0x98, 0x3e, 0x9e,
|
||||
0xcf, 0xd3, 0x3b, 0xee, 0x0c, 0xb7, 0x4f, 0x3f, 0x1b, 0xcd, 0x1a, 0x76, 0xb4, 0x04, 0xa4, 0xd1,
|
||||
0xf3, 0x86, 0xe3, 0x4f, 0x32, 0x2d, 0xa7, 0x61, 0x63, 0x66, 0x72, 0x1f, 0xf6, 0x63, 0x4c, 0x51,
|
||||
0xe3, 0x57, 0x78, 0xc9, 0x4d, 0x03, 0x8a, 0x94, 0x45, 0x48, 0xc1, 0xd6, 0xd5, 0x14, 0x9a, 0x57,
|
||||
0xe6, 0x76, 0x4d, 0x99, 0xc9, 0x38, 0xe3, 0x12, 0x1f, 0xbd, 0x60, 0xd9, 0x18, 0x15, 0xdd, 0xb1,
|
||||
0xe5, 0x57, 0x9d, 0x75, 0xfd, 0xde, 0x5d, 0x53, 0xbf, 0xfd, 0x95, 0xf5, 0xbb, 0x5b, 0xd1, 0xaf,
|
||||
0x41, 0x3e, 0x99, 0x98, 0xf1, 0xf1, 0x34, 0xa6, 0x7b, 0x0e, 0xf9, 0xd2, 0x26, 0x3f, 0x43, 0xdf,
|
||||
0xc9, 0xe1, 0x87, 0x64, 0x82, 0xdc, 0x7c, 0xe6, 0x0d, 0x2b, 0x86, 0x07, 0x2b, 0x60, 0xfe, 0xa8,
|
||||
0x72, 0x30, 0x5c, 0x48, 0x44, 0xbe, 0x00, 0xbf, 0x01, 0xc7, 0xc7, 0x78, 0x99, 0x64, 0x18, 0x53,
|
||||
0x62, 0xab, 0xbf, 0x61, 0x07, 0xf9, 0x18, 0xde, 0x54, 0xc5, 0x98, 0x7c, 0xce, 0xa4, 0x4e, 0x58,
|
||||
0xfa, 0x23, 0x4b, 0x73, 0x54, 0x74, 0xdf, 0x1e, 0x6d, 0x0e, 0x1a, 0xb5, 0x4b, 0x9c, 0x70, 0x8d,
|
||||
0xf4, 0xc0, 0xa9, 0xdd, 0x59, 0xfe, 0x87, 0x70, 0xd0, 0xa4, 0x11, 0xd3, 0x49, 0xb9, 0xcc, 0x14,
|
||||
0x6d, 0x59, 0xcc, 0xec, 0xda, 0xff, 0x09, 0xfa, 0xd5, 0xda, 0x6c, 0x0f, 0x49, 0x64, 0xba, 0xec,
|
||||
0xc2, 0xc2, 0x32, 0xfe, 0x5c, 0xc4, 0xc6, 0xef, 0x3a, 0xb1, 0xb0, 0x8c, 0xdf, 0x55, 0x56, 0xf6,
|
||||
0xa2, 0xb3, 0xfc, 0x3f, 0x5a, 0x70, 0x6f, 0xa9, 0x54, 0xcd, 0x40, 0xb9, 0xc2, 0x69, 0x39, 0x50,
|
||||
0xae, 0x70, 0x4a, 0x9e, 0xc1, 0x9d, 0x6b, 0x53, 0x57, 0x31, 0x4b, 0x1e, 0xbe, 0x62, 0x27, 0x84,
|
||||
0x2e, 0xcb, 0xa7, 0xed, 0xb3, 0x56, 0xf0, 0x77, 0x07, 0x68, 0xfd, 0xec, 0xd2, 0x91, 0xe6, 0x6e,
|
||||
0x96, 0xf6, 0xec, 0x66, 0xf9, 0x7f, 0x6a, 0x74, 0x56, 0x9b, 0x1a, 0x03, 0xf0, 0x94, 0x66, 0x17,
|
||||
0x29, 0x96, 0xe3, 0xc7, 0x59, 0x46, 0xaf, 0x6e, 0x65, 0xee, 0x17, 0xab, 0xd7, 0xc2, 0x24, 0x2f,
|
||||
0x97, 0x4c, 0x03, 0xcf, 0x4e, 0x83, 0xcf, 0x6f, 0xc4, 0xc0, 0xd5, 0xb1, 0xee, 0x38, 0x58, 0x4b,
|
||||
0x1d, 0x7f, 0xae, 0xc9, 0xe1, 0xb7, 0x55, 0x0e, 0xcf, 0x5e, 0xf5, 0xff, 0xe7, 0x49, 0x44, 0x38,
|
||||
0x5a, 0x3c, 0x5b, 0xcc, 0x81, 0xf2, 0xd6, 0xa8, 0x33, 0xf9, 0x00, 0xb6, 0x78, 0x31, 0x4a, 0x6e,
|
||||
0xb9, 0x99, 0xca, 0x7d, 0xa7, 0x7f, 0x6d, 0xc2, 0x6e, 0x99, 0xff, 0x19, 0xcf, 0x12, 0xcd, 0x25,
|
||||
0xf9, 0x05, 0x76, 0x17, 0x5e, 0x2f, 0xe4, 0xdd, 0xb9, 0x92, 0x9a, 0xdf, 0x40, 0x7e, 0x70, 0xd3,
|
||||
0x16, 0x57, 0x74, 0xb0, 0x41, 0xbe, 0x04, 0xef, 0x69, 0x76, 0xcd, 0xaf, 0x90, 0xd0, 0xb9, 0xfd,
|
||||
0xce, 0x55, 0x66, 0xba, 0xd7, 0x10, 0x99, 0x25, 0xf8, 0x06, 0x76, 0xce, 0xb5, 0x44, 0x36, 0x79,
|
||||
0xad, 0x34, 0xf7, 0x5b, 0xe4, 0x7b, 0xd8, 0x99, 0xbf, 0xf3, 0xc9, 0x51, 0x85, 0xb5, 0xda, 0x03,
|
||||
0xcc, 0x7f, 0x67, 0x69, 0x7c, 0xf6, 0x6f, 0xbf, 0xc2, 0xde, 0x22, 0x67, 0x24, 0xb8, 0xbd, 0xa1,
|
||||
0xfd, 0xf7, 0x56, 0x10, 0x4c, 0xb0, 0x41, 0x7e, 0xab, 0xbf, 0x20, 0xca, 0xab, 0xe1, 0x83, 0x1b,
|
||||
0x32, 0x54, 0x65, 0xe3, 0x0f, 0x6a, 0x9a, 0x78, 0x62, 0x5e, 0xc4, 0xc1, 0xc6, 0x85, 0x67, 0x3d,
|
||||
0x1f, 0xfd, 0x17, 0x00, 0x00, 0xff, 0xff, 0xfe, 0xbf, 0x6d, 0x72, 0x4e, 0x0b, 0x00, 0x00,
|
||||
// 943 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x56, 0xcd, 0x6f, 0x1c, 0x35,
|
||||
0x14, 0xcf, 0xee, 0xa6, 0x93, 0xdd, 0x97, 0x74, 0x13, 0x9c, 0x34, 0x71, 0x07, 0x14, 0xc2, 0xc0,
|
||||
0x61, 0xe1, 0xb0, 0x69, 0x03, 0x52, 0x03, 0xe2, 0x43, 0xa2, 0x2d, 0xa8, 0x87, 0x42, 0x99, 0x20,
|
||||
0x04, 0x48, 0x20, 0x39, 0x33, 0x2f, 0xdb, 0x21, 0xb3, 0x63, 0xd7, 0xf6, 0x44, 0xda, 0x1b, 0x1c,
|
||||
0xb9, 0x72, 0xe6, 0xaf, 0xe1, 0x2f, 0x43, 0xb6, 0x67, 0x96, 0x9d, 0x8f, 0x4d, 0x36, 0xe5, 0xe6,
|
||||
0xf7, 0x69, 0xfb, 0xf7, 0x7e, 0xef, 0xd9, 0x30, 0x94, 0xa8, 0x78, 0x2e, 0x23, 0x1c, 0x0b, 0xc9,
|
||||
0x35, 0x27, 0x03, 0x91, 0xa7, 0xf9, 0x34, 0x91, 0x22, 0xf2, 0xdf, 0x9c, 0x70, 0x3e, 0x49, 0xf1,
|
||||
0xd8, 0x1a, 0xce, 0xf3, 0x8b, 0x63, 0x9c, 0x0a, 0x3d, 0x73, 0x7e, 0xfe, 0x5b, 0x75, 0xa3, 0xd2,
|
||||
0x32, 0x8f, 0x74, 0x61, 0x1d, 0x0a, 0xc9, 0xaf, 0x92, 0x18, 0xa5, 0x93, 0x83, 0x11, 0xec, 0x9f,
|
||||
0xe5, 0x42, 0x70, 0xa9, 0xd5, 0x57, 0xc8, 0x74, 0x2e, 0x31, 0xc4, 0x57, 0x39, 0x2a, 0x4d, 0x86,
|
||||
0xd0, 0x4d, 0x62, 0xda, 0x39, 0xea, 0x8c, 0x06, 0x61, 0x37, 0x89, 0x83, 0x8f, 0xe1, 0xa0, 0xe1,
|
||||
0xa9, 0x04, 0xcf, 0x14, 0x92, 0x43, 0x80, 0x97, 0x4c, 0x15, 0x56, 0x1b, 0xd2, 0x0f, 0x17, 0x34,
|
||||
0xc1, 0xdf, 0x3d, 0xd8, 0x0d, 0x91, 0xc5, 0x61, 0x71, 0xa3, 0x25, 0x5b, 0x10, 0x02, 0xeb, 0x7a,
|
||||
0x26, 0x90, 0x76, 0xad, 0xc6, 0xae, 0x8d, 0x2e, 0x63, 0x53, 0xa4, 0x3d, 0xa7, 0x33, 0x6b, 0xb2,
|
||||
0x0f, 0x9e, 0x60, 0x12, 0x33, 0x4d, 0xd7, 0xad, 0xb6, 0x90, 0xc8, 0x23, 0x00, 0x21, 0xb9, 0x40,
|
||||
0xa9, 0x13, 0x54, 0xf4, 0xce, 0x51, 0x67, 0xb4, 0x79, 0x72, 0x30, 0x76, 0x78, 0x8c, 0x4b, 0x3c,
|
||||
0xc6, 0x67, 0x16, 0x8f, 0x70, 0xc1, 0x95, 0x04, 0xb0, 0x15, 0xa3, 0xc0, 0x2c, 0xc6, 0x2c, 0x32,
|
||||
0xa1, 0xde, 0x51, 0x6f, 0x34, 0x08, 0x2b, 0x3a, 0xe2, 0x43, 0xbf, 0xc4, 0x8e, 0x6e, 0xd8, 0x6d,
|
||||
0xe7, 0x32, 0xa1, 0xb0, 0x71, 0x85, 0x52, 0x25, 0x3c, 0xa3, 0x7d, 0x6b, 0x2a, 0x45, 0xf2, 0x1e,
|
||||
0xdc, 0x65, 0x51, 0x84, 0x42, 0x9f, 0x61, 0x24, 0x51, 0x2b, 0x3a, 0xb0, 0xe8, 0x54, 0x95, 0xe4,
|
||||
0x14, 0x0e, 0x58, 0x1c, 0x27, 0x3a, 0xe1, 0x19, 0x4b, 0x9d, 0xf2, 0xdb, 0x5c, 0x8b, 0x5c, 0x2b,
|
||||
0x0a, 0xf6, 0x28, 0xcb, 0xcc, 0x66, 0x67, 0x96, 0x26, 0x4c, 0xa1, 0xa2, 0x9b, 0xd6, 0xb3, 0x14,
|
||||
0xc9, 0x08, 0xb6, 0xdd, 0x26, 0x25, 0xea, 0x8a, 0x6e, 0xd9, 0xbd, 0xeb, 0xea, 0x80, 0xc1, 0x5e,
|
||||
0xb5, 0x3a, 0x45, 0x59, 0x77, 0xa0, 0x97, 0xcb, 0xac, 0xa8, 0x8f, 0x59, 0xd6, 0x00, 0xee, 0xae,
|
||||
0x0c, 0x70, 0xf0, 0xd7, 0x00, 0x0e, 0x42, 0x9c, 0x24, 0x4a, 0xa3, 0xac, 0xb3, 0xa0, 0xac, 0x7a,
|
||||
0xa7, 0xa5, 0xea, 0xdd, 0xd6, 0xaa, 0xf7, 0x2a, 0x55, 0xdf, 0x07, 0x2f, 0xca, 0x95, 0xe6, 0x53,
|
||||
0xcb, 0x86, 0x7e, 0x58, 0x48, 0xe4, 0x18, 0x3c, 0x7e, 0xfe, 0x1b, 0x46, 0xfa, 0x26, 0x26, 0x14,
|
||||
0x6e, 0x06, 0x4b, 0x63, 0x32, 0x11, 0x9e, 0xcd, 0x54, 0x8a, 0x0d, 0x7e, 0x6c, 0xdc, 0xc0, 0x8f,
|
||||
0x7e, 0x8d, 0x1f, 0x02, 0xf6, 0x0a, 0x30, 0x66, 0x4f, 0x16, 0xf3, 0x0c, 0x8e, 0x7a, 0xa3, 0xcd,
|
||||
0x93, 0x4f, 0xc7, 0xf3, 0xd6, 0x1e, 0x2f, 0x01, 0x69, 0xfc, 0xa2, 0x25, 0xfc, 0x69, 0xa6, 0xe5,
|
||||
0x2c, 0x6c, 0xcd, 0x4c, 0x1e, 0xc0, 0x6e, 0x8c, 0x29, 0x6a, 0xfc, 0x12, 0x2f, 0xb8, 0x69, 0x55,
|
||||
0x91, 0xb2, 0x08, 0x29, 0xd8, 0x7b, 0xb5, 0x99, 0x16, 0x39, 0xbc, 0xd9, 0xe0, 0x70, 0x32, 0xc9,
|
||||
0xb8, 0xc4, 0xc7, 0x2f, 0x59, 0x36, 0xb1, 0x3c, 0x32, 0xd7, 0xaf, 0x2a, 0x9b, 0x4c, 0xbf, 0x7b,
|
||||
0x4b, 0xa6, 0x0f, 0x57, 0x66, 0xfa, 0x76, 0x95, 0xe9, 0x3e, 0xf4, 0x93, 0xa9, 0x19, 0x34, 0xcf,
|
||||
0x62, 0xba, 0xe3, 0x90, 0x2f, 0x65, 0xf2, 0x13, 0x0c, 0x1d, 0x1d, 0xbe, 0x4f, 0xa6, 0xc8, 0xcd,
|
||||
0x36, 0x6f, 0x58, 0x32, 0x3c, 0x5c, 0x01, 0xf3, 0xc7, 0x95, 0xc0, 0xb0, 0x96, 0x88, 0x7c, 0x0e,
|
||||
0x7e, 0x0b, 0x8e, 0x4f, 0xf0, 0x22, 0xc9, 0x30, 0xa6, 0xc4, 0xde, 0xfe, 0x1a, 0x0f, 0xf2, 0x11,
|
||||
0xdc, 0x53, 0xc5, 0x40, 0x7d, 0xc1, 0xa4, 0x4e, 0x58, 0xfa, 0x03, 0x4b, 0x73, 0x54, 0x74, 0xd7,
|
||||
0x86, 0xb6, 0x1b, 0x0d, 0xdb, 0x25, 0x4e, 0xb9, 0x46, 0xba, 0xe7, 0xd8, 0xee, 0xa4, 0xb6, 0x76,
|
||||
0xbf, 0xd7, 0xda, 0xee, 0xfe, 0x07, 0xb0, 0xd7, 0xc6, 0x26, 0xd3, 0x73, 0xb9, 0xcc, 0x14, 0xed,
|
||||
0x58, 0x74, 0xed, 0xda, 0xff, 0x11, 0x86, 0x55, 0x14, 0x6c, 0xb7, 0x49, 0x64, 0xba, 0xec, 0xd7,
|
||||
0x42, 0x32, 0xfa, 0x5c, 0xc4, 0x46, 0xef, 0x7a, 0xb6, 0x90, 0x8c, 0xde, 0x61, 0x50, 0x76, 0xad,
|
||||
0x93, 0xfc, 0xdf, 0x3b, 0x70, 0x7f, 0x29, 0xa9, 0xcd, 0xe8, 0xb9, 0xc4, 0x59, 0x39, 0x7a, 0x2e,
|
||||
0x71, 0x46, 0x9e, 0xc3, 0x9d, 0x2b, 0x83, 0x40, 0x31, 0x75, 0x1e, 0xbd, 0x66, 0xcf, 0x84, 0x2e,
|
||||
0xcb, 0x27, 0xdd, 0xd3, 0x4e, 0xf0, 0x4f, 0x0f, 0x68, 0x33, 0x76, 0xe9, 0xf0, 0x73, 0xaf, 0x55,
|
||||
0x77, 0xfe, 0x5a, 0xfd, 0x37, 0x5f, 0x7a, 0xab, 0xcd, 0x97, 0x7d, 0xf0, 0x94, 0x66, 0xe7, 0x29,
|
||||
0x96, 0x83, 0xca, 0x49, 0x86, 0xd9, 0x6e, 0x65, 0xde, 0x2c, 0xcb, 0xec, 0x42, 0x24, 0xaf, 0x96,
|
||||
0xcc, 0x0d, 0xcf, 0xce, 0x8d, 0xcf, 0xae, 0xc5, 0xc0, 0xdd, 0xe3, 0xb6, 0x83, 0xe3, 0x56, 0xec,
|
||||
0xf8, 0xe3, 0x96, 0x35, 0xfc, 0xa6, 0x5a, 0xc3, 0xd3, 0xd7, 0x3d, 0xff, 0x62, 0x11, 0x11, 0x0e,
|
||||
0xeb, 0xb1, 0xc5, 0xc4, 0x28, 0xdf, 0x97, 0x66, 0x25, 0x1f, 0xc2, 0x06, 0x2f, 0x86, 0xce, 0x0d,
|
||||
0x6f, 0x58, 0xe9, 0x77, 0xf2, 0xe7, 0x3a, 0x6c, 0x97, 0xf9, 0x9f, 0xf3, 0x2c, 0xd1, 0x5c, 0x92,
|
||||
0x9f, 0x61, 0xbb, 0xf6, 0x23, 0x22, 0xef, 0x2c, 0x5c, 0xa9, 0xfd, 0x5f, 0xe5, 0x07, 0xd7, 0xb9,
|
||||
0xb8, 0x4b, 0x07, 0x6b, 0xe4, 0x0b, 0xf0, 0x9e, 0x65, 0x57, 0xfc, 0x12, 0x09, 0x5d, 0xf0, 0x77,
|
||||
0xaa, 0x32, 0xd3, 0xfd, 0x16, 0xcb, 0x3c, 0xc1, 0xd7, 0xb0, 0x75, 0xa6, 0x25, 0xb2, 0xe9, 0xff,
|
||||
0x4a, 0xf3, 0xa0, 0x43, 0xbe, 0x83, 0xad, 0xc5, 0xdf, 0x01, 0x39, 0xac, 0x54, 0xad, 0xf1, 0xa9,
|
||||
0xf3, 0xdf, 0x5e, 0x6a, 0x9f, 0x9f, 0xed, 0x17, 0xd8, 0xa9, 0xd7, 0x8c, 0x04, 0x37, 0x37, 0xb4,
|
||||
0xff, 0xee, 0x0a, 0x84, 0x09, 0xd6, 0xc8, 0xaf, 0xcd, 0xbf, 0x46, 0xf9, 0x88, 0xbc, 0x7f, 0x4d,
|
||||
0x86, 0x2a, 0x6d, 0xfc, 0xfd, 0x06, 0x27, 0x9e, 0x9a, 0x5f, 0x76, 0xb0, 0x76, 0xee, 0x59, 0xcd,
|
||||
0x87, 0xff, 0x06, 0x00, 0x00, 0xff, 0xff, 0x70, 0x3e, 0x80, 0x35, 0xa2, 0x0b, 0x00, 0x00,
|
||||
}
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
|
|
|
@ -80,11 +80,13 @@ message ConfigureRequest {
|
|||
map<string, string> variables = 1; // a map of configuration keys to values.
|
||||
google.protobuf.Struct args = 2; // the input properties for the provider. Only filled in for newer providers.
|
||||
bool acceptSecrets = 3; // when true, operations should return secrets as strongly typed.
|
||||
bool acceptResources = 4; // when true, operations should return resources as strongly typed values to the provider.
|
||||
}
|
||||
|
||||
message ConfigureResponse {
|
||||
bool acceptSecrets = 1; // when true, the engine should pass secrets as strongly typed values to the provider.
|
||||
bool supportsPreview = 2; // when true, the engine should invoke create and update with preview=true during previews.
|
||||
bool acceptResources = 3; // when true, the engine should pass resources as strongly typed values to the provider.
|
||||
}
|
||||
|
||||
// ConfigureErrorMissingKeys is sent as a Detail on an error returned from `ResourceProvider.Configure`.
|
||||
|
@ -102,6 +104,7 @@ message InvokeRequest {
|
|||
google.protobuf.Struct args = 2; // the arguments for the function invocation.
|
||||
string provider = 3; // an optional reference to the provider to use for this invoke.
|
||||
string version = 4; // the version of the provider to use when servicing this request.
|
||||
bool acceptResources = 5; // when true operations should return resource references as strongly typed.
|
||||
}
|
||||
|
||||
message InvokeResponse {
|
||||
|
|
|
@ -59,6 +59,7 @@ message ReadResourceRequest {
|
|||
bool acceptSecrets = 9; // when true operations should return secrets as strongly typed.
|
||||
repeated string additionalSecretOutputs = 10; // a list of output properties that should also be treated as secret, in addition to ones we detect.
|
||||
repeated string aliases = 11; // a list of additional URNs that shoud be considered the same.
|
||||
bool acceptResources = 12; // when true operations should return resource references as strongly typed.
|
||||
}
|
||||
|
||||
// ReadResourceResponse contains the result of reading a resource's state.
|
||||
|
@ -100,6 +101,7 @@ message RegisterResourceRequest {
|
|||
bool deleteBeforeReplaceDefined = 18; // true if the deleteBeforeReplace property should be treated as defined even if it is false.
|
||||
bool supportsPartialValues = 19; // true if the request is from an SDK that supports partially-known properties during preview.
|
||||
bool remote = 20; // true if the resource is a plugin-managed component resource.
|
||||
bool acceptResources = 21; // when true operations should return resource references as strongly typed.
|
||||
}
|
||||
|
||||
// RegisterResourceResponse is returned by the engine after a resource has finished being initialized. It includes the
|
||||
|
|
|
@ -48,3 +48,7 @@ from .invoke import (
|
|||
from ._json import (
|
||||
to_json,
|
||||
)
|
||||
|
||||
from .rpc import (
|
||||
register_resource_package,
|
||||
)
|
||||
|
|
|
@ -27,12 +27,6 @@ within the functions themselves.
|
|||
from typing import Any, Optional
|
||||
|
||||
|
||||
# We override this global in test/test_next_serialize.py to stub the CustomResource type.
|
||||
# TODO: Rework the test to remove the need for this global. https://github.com/pulumi/pulumi/issues/5000
|
||||
_custom_resource_type: Optional[type] = None
|
||||
"""The type of CustomResource."""
|
||||
|
||||
|
||||
def is_asset(obj: Any) -> bool:
|
||||
"""
|
||||
Returns true if the given type is an Asset, false otherwise.
|
||||
|
@ -49,12 +43,20 @@ def is_archive(obj: Any) -> bool:
|
|||
return isinstance(obj, Archive)
|
||||
|
||||
|
||||
def is_resource(obj: Any) -> bool:
|
||||
"""
|
||||
Returns true if the given type is a Resource, false otherwise.
|
||||
"""
|
||||
from .. import Resource # pylint: disable=import-outside-toplevel
|
||||
return isinstance(obj, Resource)
|
||||
|
||||
|
||||
def is_custom_resource(obj: Any) -> bool:
|
||||
"""
|
||||
Returns true if the given type is a CustomResource, false otherwise.
|
||||
"""
|
||||
from .. import CustomResource # pylint: disable=import-outside-toplevel
|
||||
return isinstance(obj, _custom_resource_type or CustomResource)
|
||||
return isinstance(obj, CustomResource)
|
||||
|
||||
|
||||
def is_custom_timeouts(obj: Any) -> bool:
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -21,7 +21,7 @@ DESCRIPTOR = _descriptor.FileDescriptor(
|
|||
package='pulumirpc',
|
||||
syntax='proto3',
|
||||
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\"\xfc\x01\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\"P\n\x14ReadResourceResponse\x12\x0b\n\x03urn\x18\x01 \x01(\t\x12+\n\nproperties\x18\x02 \x01(\x0b\x32\x17.google.protobuf.Struct\"\xaf\x06\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\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\"\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\x89\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\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\"\xc8\x06\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\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\"\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\x89\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\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,])
|
||||
|
||||
|
@ -174,6 +174,13 @@ _READRESOURCEREQUEST = _descriptor.Descriptor(
|
|||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='acceptResources', full_name='pulumirpc.ReadResourceRequest.acceptResources', index=11,
|
||||
number=12, 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=[
|
||||
],
|
||||
|
@ -187,7 +194,7 @@ _READRESOURCEREQUEST = _descriptor.Descriptor(
|
|||
oneofs=[
|
||||
],
|
||||
serialized_start=190,
|
||||
serialized_end=442,
|
||||
serialized_end=467,
|
||||
)
|
||||
|
||||
|
||||
|
@ -224,8 +231,8 @@ _READRESOURCERESPONSE = _descriptor.Descriptor(
|
|||
extension_ranges=[],
|
||||
oneofs=[
|
||||
],
|
||||
serialized_start=444,
|
||||
serialized_end=524,
|
||||
serialized_start=469,
|
||||
serialized_end=549,
|
||||
)
|
||||
|
||||
|
||||
|
@ -255,8 +262,8 @@ _REGISTERRESOURCEREQUEST_PROPERTYDEPENDENCIES = _descriptor.Descriptor(
|
|||
extension_ranges=[],
|
||||
oneofs=[
|
||||
],
|
||||
serialized_start=1122,
|
||||
serialized_end=1158,
|
||||
serialized_start=1172,
|
||||
serialized_end=1208,
|
||||
)
|
||||
|
||||
_REGISTERRESOURCEREQUEST_CUSTOMTIMEOUTS = _descriptor.Descriptor(
|
||||
|
@ -299,8 +306,8 @@ _REGISTERRESOURCEREQUEST_CUSTOMTIMEOUTS = _descriptor.Descriptor(
|
|||
extension_ranges=[],
|
||||
oneofs=[
|
||||
],
|
||||
serialized_start=1160,
|
||||
serialized_end=1224,
|
||||
serialized_start=1210,
|
||||
serialized_end=1274,
|
||||
)
|
||||
|
||||
_REGISTERRESOURCEREQUEST_PROPERTYDEPENDENCIESENTRY = _descriptor.Descriptor(
|
||||
|
@ -336,8 +343,8 @@ _REGISTERRESOURCEREQUEST_PROPERTYDEPENDENCIESENTRY = _descriptor.Descriptor(
|
|||
extension_ranges=[],
|
||||
oneofs=[
|
||||
],
|
||||
serialized_start=1226,
|
||||
serialized_end=1342,
|
||||
serialized_start=1276,
|
||||
serialized_end=1392,
|
||||
)
|
||||
|
||||
_REGISTERRESOURCEREQUEST = _descriptor.Descriptor(
|
||||
|
@ -487,6 +494,13 @@ _REGISTERRESOURCEREQUEST = _descriptor.Descriptor(
|
|||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='acceptResources', full_name='pulumirpc.RegisterResourceRequest.acceptResources', index=20,
|
||||
number=21, 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=[
|
||||
],
|
||||
|
@ -499,8 +513,8 @@ _REGISTERRESOURCEREQUEST = _descriptor.Descriptor(
|
|||
extension_ranges=[],
|
||||
oneofs=[
|
||||
],
|
||||
serialized_start=527,
|
||||
serialized_end=1342,
|
||||
serialized_start=552,
|
||||
serialized_end=1392,
|
||||
)
|
||||
|
||||
|
||||
|
@ -530,8 +544,8 @@ _REGISTERRESOURCERESPONSE_PROPERTYDEPENDENCIES = _descriptor.Descriptor(
|
|||
extension_ranges=[],
|
||||
oneofs=[
|
||||
],
|
||||
serialized_start=1122,
|
||||
serialized_end=1158,
|
||||
serialized_start=1172,
|
||||
serialized_end=1208,
|
||||
)
|
||||
|
||||
_REGISTERRESOURCERESPONSE_PROPERTYDEPENDENCIESENTRY = _descriptor.Descriptor(
|
||||
|
@ -567,8 +581,8 @@ _REGISTERRESOURCERESPONSE_PROPERTYDEPENDENCIESENTRY = _descriptor.Descriptor(
|
|||
extension_ranges=[],
|
||||
oneofs=[
|
||||
],
|
||||
serialized_start=1603,
|
||||
serialized_end=1720,
|
||||
serialized_start=1653,
|
||||
serialized_end=1770,
|
||||
)
|
||||
|
||||
_REGISTERRESOURCERESPONSE = _descriptor.Descriptor(
|
||||
|
@ -632,8 +646,8 @@ _REGISTERRESOURCERESPONSE = _descriptor.Descriptor(
|
|||
extension_ranges=[],
|
||||
oneofs=[
|
||||
],
|
||||
serialized_start=1345,
|
||||
serialized_end=1720,
|
||||
serialized_start=1395,
|
||||
serialized_end=1770,
|
||||
)
|
||||
|
||||
|
||||
|
@ -670,8 +684,8 @@ _REGISTERRESOURCEOUTPUTSREQUEST = _descriptor.Descriptor(
|
|||
extension_ranges=[],
|
||||
oneofs=[
|
||||
],
|
||||
serialized_start=1722,
|
||||
serialized_end=1809,
|
||||
serialized_start=1772,
|
||||
serialized_end=1859,
|
||||
)
|
||||
|
||||
_READRESOURCEREQUEST.fields_by_name['properties'].message_type = google_dot_protobuf_dot_struct__pb2._STRUCT
|
||||
|
@ -797,8 +811,8 @@ _RESOURCEMONITOR = _descriptor.ServiceDescriptor(
|
|||
file=DESCRIPTOR,
|
||||
index=0,
|
||||
serialized_options=None,
|
||||
serialized_start=1812,
|
||||
serialized_end=2333,
|
||||
serialized_start=1862,
|
||||
serialized_end=2383,
|
||||
methods=[
|
||||
_descriptor.MethodDescriptor(
|
||||
name='SupportsFeature',
|
||||
|
|
|
@ -48,6 +48,9 @@ _special_archive_sig = "0def7320c3a5731c473e5ecbe6d01bc7"
|
|||
_special_secret_sig = "1b47061264138c4ac30d75fd1eb44270"
|
||||
"""special_secret_sig is a randomly assigned hash used to identify secrets in maps. See pkg/resource/properties.go"""
|
||||
|
||||
_special_resource_sig = "5cf8f73096256a8f31e491e813e4eb8e"
|
||||
"""special_resource_sig is a randomly assigned hash used to identify resources in maps. See pkg/resource/properties.go"""
|
||||
|
||||
_INT_OR_FLOAT = six.integer_types + (float,)
|
||||
|
||||
def isLegalProtobufValue(value: Any) -> bool:
|
||||
|
@ -104,10 +107,25 @@ async def serialize_property(value: 'Input[Any]',
|
|||
if known_types.is_unknown(value):
|
||||
return UNKNOWN
|
||||
|
||||
if known_types.is_custom_resource(value):
|
||||
resource = cast('CustomResource', value)
|
||||
if known_types.is_resource(value):
|
||||
resource = cast('Resource', value)
|
||||
deps.append(resource)
|
||||
return await serialize_property(resource.id, deps, input_transformer)
|
||||
|
||||
is_custom = known_types.is_custom_resource(value)
|
||||
resource_id = cast('CustomResource', value).id if is_custom else None
|
||||
|
||||
# If we're retaining resources, serialize the resource as a reference.
|
||||
if await settings.monitor_supports_resource_references():
|
||||
res = {
|
||||
_special_sig_key: _special_resource_sig,
|
||||
"urn": await serialize_property(resource.urn, deps, input_transformer)
|
||||
}
|
||||
if is_custom:
|
||||
res["id"] = await serialize_property(resource_id, deps, input_transformer)
|
||||
return res
|
||||
|
||||
# Otherwise, serialize the resource as either its ID (for custom resources) or its URN (for component resources)
|
||||
return await serialize_property(resource_id if is_custom else resource.urn, deps, input_transformer)
|
||||
|
||||
if known_types.is_asset(value):
|
||||
# Serializing an asset requires the use of a magical signature key, since otherwise it would
|
||||
|
@ -246,6 +264,28 @@ def deserialize_properties(props_struct: struct_pb2.Struct, keep_unknowns: Optio
|
|||
raise AssertionError("Invalid archive encountered when unmarshalling resource property")
|
||||
if props_struct[_special_sig_key] == _special_secret_sig:
|
||||
return wrap_rpc_secret(deserialize_property(props_struct["value"]))
|
||||
if props_struct[_special_sig_key] == _special_resource_sig:
|
||||
urn = props_struct["urn"]
|
||||
version = props_struct["version"]
|
||||
|
||||
urn_parts = urn.split("::")
|
||||
qualified_type = urn_parts[2]
|
||||
typ = qualified_type.split("$")[-1]
|
||||
typ_parts = typ.split(":")
|
||||
pkg_name = typ_parts[0]
|
||||
mod_name = typ_parts[1] if len(typ_parts) > 1 else ""
|
||||
typ_name = typ_parts[2] if len(typ_parts) > 2 else ""
|
||||
is_provider = pkg_name == "pulumi" and mod_name == "providers"
|
||||
if is_provider:
|
||||
pkg_name = typ_name
|
||||
|
||||
resource_package = RESOURCE_PACKAGES.get(package_key(pkg_name, version))
|
||||
if resource_package is None:
|
||||
raise Exception(f"Unable to deserialize resource URN {urn}, no resource package is registered for type {typ}.")
|
||||
urn_name = urn_parts[3]
|
||||
resource = resource_package.construct(urn_name, typ, {}, {"urn": urn}) if not is_provider \
|
||||
else resource_package.construct_provider(urn_name, typ, {}, {"urn": urn})
|
||||
return cast('Resource', resource)
|
||||
|
||||
raise AssertionError("Unrecognized signature when unmarshalling resource property")
|
||||
|
||||
|
@ -538,6 +578,10 @@ async def resolve_outputs(res: 'Resource',
|
|||
# the user.
|
||||
all_properties[translated_key] = translate_output_properties(deserialize_property(value), res.translate_output_property, types.get(key))
|
||||
|
||||
await resolve_properties(resolvers, all_properties, deps)
|
||||
|
||||
async def resolve_properties(resolvers: Dict[str, Resolver], all_properties: Dict[str, Any], deps: Mapping[str, Set['Resource']]):
|
||||
|
||||
for key, value in all_properties.items():
|
||||
# Skip "id" and "urn", since we handle those specially.
|
||||
if key in ["id", "urn"]:
|
||||
|
@ -598,3 +642,15 @@ def resolve_outputs_due_to_exception(resolvers: Dict[str, Resolver], exn: Except
|
|||
for key, resolve in resolvers.items():
|
||||
log.debug(f"sending exception to resolver for {key}")
|
||||
resolve(None, False, False, None, exn)
|
||||
|
||||
RESOURCE_PACKAGES: Dict[str, Any] = dict()
|
||||
|
||||
def package_key(typ: str, version: str) -> str:
|
||||
return f"{typ}@{version}"
|
||||
|
||||
def register_resource_package(typ: str, version: str, package):
|
||||
key = package_key(typ, version)
|
||||
existing = RESOURCE_PACKAGES.get(key, None)
|
||||
if existing is not None:
|
||||
raise ValueError(f"Cannot re-register package {key}. Previous registration was {existing}, new registration was {package}.")
|
||||
RESOURCE_PACKAGES[key] = package
|
||||
|
|
|
@ -40,6 +40,7 @@ class Settings:
|
|||
dry_run: Optional[bool]
|
||||
test_mode_enabled: Optional[bool]
|
||||
legacy_apply_enabled: Optional[bool]
|
||||
feature_support: dict
|
||||
|
||||
"""
|
||||
A bag of properties for configuring the Pulumi Python language runtime.
|
||||
|
@ -60,6 +61,7 @@ class Settings:
|
|||
self.dry_run = dry_run
|
||||
self.test_mode_enabled = test_mode_enabled
|
||||
self.legacy_apply_enabled = legacy_apply_enabled
|
||||
self.feature_support = {}
|
||||
|
||||
if self.test_mode_enabled is None:
|
||||
self.test_mode_enabled = os.getenv("PULUMI_TEST_MODE", "false") == "true"
|
||||
|
@ -203,25 +205,35 @@ def set_root_resource(root: 'Resource'):
|
|||
ROOT = root
|
||||
|
||||
|
||||
async def monitor_supports_feature(feature: str) -> bool:
|
||||
if feature not in SETTINGS.feature_support:
|
||||
monitor = SETTINGS.monitor
|
||||
if not monitor:
|
||||
return False
|
||||
|
||||
req = resource_pb2.SupportsFeatureRequest(id="secrets")
|
||||
def do_rpc_call():
|
||||
try:
|
||||
resp = monitor.SupportsFeature(req)
|
||||
return resp.hasSupport
|
||||
except grpc.RpcError as exn:
|
||||
# See the comment on invoke for the justification for disabling
|
||||
# this warning
|
||||
# pylint: disable=no-member
|
||||
if exn.code() == grpc.StatusCode.UNAVAILABLE:
|
||||
sys.exit(0)
|
||||
if exn.code() == grpc.StatusCode.UNIMPLEMENTED:
|
||||
return False
|
||||
details = exn.details()
|
||||
raise Exception(details)
|
||||
|
||||
result = await asyncio.get_event_loop().run_in_executor(None, do_rpc_call)
|
||||
SETTINGS.feature_support[feature] = result
|
||||
|
||||
return SETTINGS.feature_support[feature]
|
||||
|
||||
async def monitor_supports_secrets() -> bool:
|
||||
monitor = SETTINGS.monitor
|
||||
if not monitor:
|
||||
return False
|
||||
return await monitor_supports_feature("secrets")
|
||||
|
||||
req = resource_pb2.SupportsFeatureRequest(id="secrets")
|
||||
def do_rpc_call():
|
||||
try:
|
||||
resp = monitor.SupportsFeature(req)
|
||||
return resp.hasSupport
|
||||
except grpc.RpcError as exn:
|
||||
# See the comment on invoke for the justification for disabling
|
||||
# this warning
|
||||
# pylint: disable=no-member
|
||||
if exn.code() == grpc.StatusCode.UNAVAILABLE:
|
||||
sys.exit(0)
|
||||
if exn.code() == grpc.StatusCode.UNIMPLEMENTED:
|
||||
return False
|
||||
details = exn.details()
|
||||
raise Exception(details)
|
||||
|
||||
return await asyncio.get_event_loop().run_in_executor(None, do_rpc_call)
|
||||
async def monitor_supports_resource_references() -> bool:
|
||||
return await monitor_supports_feature("resourceReferences")
|
||||
|
|
|
@ -16,7 +16,7 @@ import unittest
|
|||
from typing import Any, Dict, List, Mapping, Optional, Sequence
|
||||
|
||||
from google.protobuf import struct_pb2
|
||||
from pulumi.resource import CustomResource
|
||||
from pulumi.resource import ComponentResource, CustomResource
|
||||
from pulumi.runtime import rpc, known_types, settings
|
||||
from pulumi import Input, Output, UNKNOWN, input_type
|
||||
from pulumi.asset import (
|
||||
|
@ -30,14 +30,14 @@ from pulumi.asset import (
|
|||
import pulumi
|
||||
|
||||
|
||||
class FakeCustomResource:
|
||||
"""
|
||||
Fake CustomResource class that duck-types to the real CustomResource.
|
||||
This class is substituted for the real CustomResource for the below test.
|
||||
"""
|
||||
def __init__(self, id):
|
||||
self.id = id
|
||||
class TestCustomResource(CustomResource):
|
||||
def __init__(self, urn):
|
||||
self.__dict__["urn"] = Output.from_input(urn)
|
||||
self.__dict__["id"] = Output.from_input("id")
|
||||
|
||||
class TestComponentResource(ComponentResource):
|
||||
def __init__(self, urn):
|
||||
self.__dict__["urn"] = Output.from_input(urn)
|
||||
|
||||
def async_test(coro):
|
||||
def wrapper(*args, **kwargs):
|
||||
|
@ -48,12 +48,6 @@ def async_test(coro):
|
|||
|
||||
|
||||
class NextSerializationTests(unittest.TestCase):
|
||||
def setUp(self):
|
||||
known_types._custom_resource_type = FakeCustomResource
|
||||
|
||||
def tearDown(self):
|
||||
known_types._custom_resource_type = CustomResource
|
||||
|
||||
@async_test
|
||||
async def test_list(self):
|
||||
test_list = [1, 2, 3]
|
||||
|
@ -86,11 +80,40 @@ class NextSerializationTests(unittest.TestCase):
|
|||
|
||||
@async_test
|
||||
async def test_custom_resource(self):
|
||||
res = FakeCustomResource("some-id")
|
||||
fake_urn = "urn:pulumi:mystack::myproject::my:mod:Fake::fake"
|
||||
res = TestCustomResource(fake_urn)
|
||||
|
||||
settings.SETTINGS.feature_support["resourceReferences"] = False
|
||||
deps = []
|
||||
prop = await rpc.serialize_property(res, deps)
|
||||
self.assertListEqual([res], deps)
|
||||
self.assertEqual("some-id", prop)
|
||||
self.assertEqual("id", prop)
|
||||
|
||||
settings.SETTINGS.feature_support["resourceReferences"] = True
|
||||
deps = []
|
||||
prop = await rpc.serialize_property(res, deps)
|
||||
self.assertListEqual([res], deps)
|
||||
self.assertEqual(rpc._special_resource_sig, prop[rpc._special_sig_key])
|
||||
self.assertEqual(fake_urn, prop["urn"])
|
||||
self.assertEqual("id", prop["id"])
|
||||
|
||||
@async_test
|
||||
async def test_component_resource(self):
|
||||
fake_urn = "urn:pulumi:mystack::myproject::my:mod:Fake::fake"
|
||||
res = TestComponentResource(fake_urn)
|
||||
|
||||
settings.SETTINGS.feature_support["resourceReferences"] = False
|
||||
deps = []
|
||||
prop = await rpc.serialize_property(res, deps)
|
||||
self.assertListEqual([res], deps)
|
||||
self.assertEqual(fake_urn, prop)
|
||||
|
||||
settings.SETTINGS.feature_support["resourceReferences"] = True
|
||||
deps = []
|
||||
prop = await rpc.serialize_property(res, deps)
|
||||
self.assertListEqual([res], deps)
|
||||
self.assertEqual(rpc._special_resource_sig, prop[rpc._special_sig_key])
|
||||
self.assertEqual(fake_urn, prop["urn"])
|
||||
|
||||
@async_test
|
||||
async def test_string_asset(self):
|
||||
|
@ -115,8 +138,8 @@ class NextSerializationTests(unittest.TestCase):
|
|||
|
||||
@async_test
|
||||
async def test_output(self):
|
||||
existing = FakeCustomResource("existing-dependency")
|
||||
res = FakeCustomResource("some-dependency")
|
||||
existing = TestCustomResource("existing-dependency")
|
||||
res = TestCustomResource("some-dependency")
|
||||
fut = asyncio.Future()
|
||||
fut.set_result(42)
|
||||
known_fut = asyncio.Future()
|
||||
|
@ -152,7 +175,7 @@ class NextSerializationTests(unittest.TestCase):
|
|||
|
||||
@async_test
|
||||
async def test_output_all(self):
|
||||
res = FakeCustomResource("some-resource")
|
||||
res = TestCustomResource("some-resource")
|
||||
fut = asyncio.Future()
|
||||
fut.set_result(42)
|
||||
known_fut = asyncio.Future()
|
||||
|
@ -168,14 +191,14 @@ class NextSerializationTests(unittest.TestCase):
|
|||
|
||||
@async_test
|
||||
async def test_output_all_composes_dependencies(self):
|
||||
res = FakeCustomResource("some-resource")
|
||||
res = TestCustomResource("some-resource")
|
||||
fut = asyncio.Future()
|
||||
fut.set_result(42)
|
||||
known_fut = asyncio.Future()
|
||||
known_fut.set_result(True)
|
||||
out = Output({res}, fut, known_fut)
|
||||
|
||||
other = FakeCustomResource("some-other-resource")
|
||||
other = TestCustomResource("some-other-resource")
|
||||
other_fut = asyncio.Future()
|
||||
other_fut.set_result(99)
|
||||
other_known_fut = asyncio.Future()
|
||||
|
@ -190,14 +213,14 @@ class NextSerializationTests(unittest.TestCase):
|
|||
|
||||
@async_test
|
||||
async def test_output_all_known_if_all_are_known(self):
|
||||
res = FakeCustomResource("some-resource")
|
||||
res = TestCustomResource("some-resource")
|
||||
fut = asyncio.Future()
|
||||
fut.set_result(42)
|
||||
known_fut = asyncio.Future()
|
||||
known_fut.set_result(True)
|
||||
out = Output({res}, fut, known_fut)
|
||||
|
||||
other = FakeCustomResource("some-other-resource")
|
||||
other = TestCustomResource("some-other-resource")
|
||||
other_fut = asyncio.Future()
|
||||
other_fut.set_result(UNKNOWN) # <- not known
|
||||
other_known_fut = asyncio.Future()
|
||||
|
@ -216,7 +239,7 @@ class NextSerializationTests(unittest.TestCase):
|
|||
|
||||
@async_test
|
||||
async def test_unknown_output(self):
|
||||
res = FakeCustomResource("some-dependency")
|
||||
res = TestCustomResource("some-dependency")
|
||||
fut = asyncio.Future()
|
||||
fut.set_result(None)
|
||||
known_fut = asyncio.Future()
|
||||
|
|
|
@ -337,6 +337,14 @@ func getBaseOptions() integration.ProgramTestOptions {
|
|||
}
|
||||
}
|
||||
|
||||
func getPythonBaseOptions() integration.ProgramTestOptions {
|
||||
return integration.ProgramTestOptions{
|
||||
Dependencies: []string{
|
||||
filepath.Join("..", "sdk", "python", "env", "src"),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func skipIfNotNode610(t *testing.T) {
|
||||
nodeVer, err := getNodeVersion()
|
||||
if err != nil && nodeVer.Major == 6 && nodeVer.Minor == 10 {
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
"align": [
|
||||
true,
|
||||
"parameters",
|
||||
"arguments",
|
||||
"statements"
|
||||
],
|
||||
"ban": false,
|
||||
|
|
Loading…
Reference in a new issue