diff --git a/sdk/dotnet/Pulumi.Automation/Pulumi.Automation.xml b/sdk/dotnet/Pulumi.Automation/Pulumi.Automation.xml
index 51ef5e23705a..56aa04345b1b 100644
--- a/sdk/dotnet/Pulumi.Automation/Pulumi.Automation.xml
+++ b/sdk/dotnet/Pulumi.Automation/Pulumi.Automation.xml
@@ -924,6 +924,31 @@
Colorize output. Choices are: always, never, raw, auto (default "auto")
+
+
+ Flow log settings to child processes (like plugins)
+
+
+
+
+ Enable verbose logging (e.g., v=3); anything >3 is very verbose
+
+
+
+
+ Log to stderr instead of to files
+
+
+
+
+ Emit tracing to the specified endpoint. Use the file: scheme to write tracing data to a local file
+
+
+
+
+ Print detailed debugging output during resource operations
+
+
Options controlling the behavior of an operation.
diff --git a/sdk/dotnet/Pulumi/Provider/Provider.cs b/sdk/dotnet/Pulumi/Provider/Provider.cs
new file mode 100644
index 000000000000..0bc56fd4dd8a
--- /dev/null
+++ b/sdk/dotnet/Pulumi/Provider/Provider.cs
@@ -0,0 +1,1502 @@
+using Pulumirpc;
+using Pulumi.Serialization;
+using Grpc.Core;
+using Google.Protobuf.WellKnownTypes;
+using System;
+using System.Linq;
+using System.Threading.Tasks;
+using System.Collections.Generic;
+using System.Collections.Immutable;
+using Microsoft.Extensions.Hosting;
+using Microsoft.AspNetCore.Hosting;
+using System.Net;
+using Microsoft.AspNetCore.Server.Kestrel.Core;
+using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Hosting.Server;
+using Microsoft.AspNetCore.Hosting.Server.Features;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Logging;
+using System.Diagnostics;
+using System.Threading;
+
+namespace Pulumi.Provider
+{
+
+ public readonly struct ResourceReference
+ {
+ public readonly string URN;
+ public readonly PropertyValue ID;
+ public readonly string PackageVersion;
+
+ public ResourceReference(string urn, PropertyValue id, string version)
+ {
+ URN = urn;
+ ID = id;
+ PackageVersion = version;
+ }
+ }
+
+ public readonly struct OutputReference
+ {
+ public readonly PropertyValue? Value;
+ public readonly ImmutableArray Dependencies;
+
+ public OutputReference(PropertyValue? value, ImmutableArray dependencies)
+ {
+ Value = value;
+ Dependencies = dependencies;
+ }
+ }
+
+ public sealed class PropertyValue
+ {
+ private bool IsNull
+ {
+ get
+ {
+ // Null if all the other properties aren't set
+ return
+ BoolValue == null &&
+ NumberValue == null &&
+ StringValue == null &&
+ ArrayValue == null &&
+ ObjectValue == null &&
+ AssetValue == null &&
+ ArchiveValue == null &&
+ SecretValue == null &&
+ ResourceValue == null &&
+ !IsComputed;
+ }
+ }
+
+ private readonly bool? BoolValue;
+ private readonly double? NumberValue;
+ private readonly string? StringValue;
+ private readonly ImmutableArray? ArrayValue;
+ private readonly ImmutableDictionary? ObjectValue;
+ private readonly Asset? AssetValue;
+ private readonly Archive? ArchiveValue;
+ private readonly PropertyValue? SecretValue;
+ private readonly ResourceReference? ResourceValue;
+ private readonly OutputReference? OutputValue;
+ private readonly bool IsComputed;
+
+ public T Match(
+ Func nullCase,
+ Func boolCase,
+ Func numberCase,
+ Func stringCase,
+ Func, T> arrayCase,
+ Func, T> objectCase,
+ Func assetCase,
+ Func archiveCase,
+ Func secretCase,
+ Func resourceCase,
+ Func outputCase,
+ Func computedCase)
+ {
+ if (BoolValue != null) return boolCase(BoolValue.Value);
+ if (NumberValue != null) return numberCase(NumberValue.Value);
+ if (StringValue != null) return stringCase(StringValue);
+ if (ArrayValue != null) return arrayCase(ArrayValue.Value);
+ if (ObjectValue != null) return objectCase(ObjectValue);
+ if (AssetValue != null) return assetCase(AssetValue);
+ if (ArchiveValue != null) return archiveCase(ArchiveValue);
+ if (SecretValue != null) return secretCase(SecretValue);
+ if (ResourceValue != null) return resourceCase(ResourceValue.Value);
+ if (OutputValue != null) return outputCase(OutputValue.Value);
+ if (IsComputed) return computedCase();
+ return nullCase();
+ }
+
+ private enum SpecialType
+ {
+ IsNull,
+ IsComputed,
+ }
+
+ public static PropertyValue Null = new PropertyValue(SpecialType.IsComputed);
+ public static PropertyValue Computed = new PropertyValue(SpecialType.IsNull);
+
+ public PropertyValue(bool value)
+ {
+ BoolValue = value;
+ }
+ public PropertyValue(double value)
+ {
+ NumberValue = value;
+ }
+ public PropertyValue(string value)
+ {
+ StringValue = value;
+ }
+ public PropertyValue(ImmutableArray value)
+ {
+ ArrayValue = value;
+ }
+ public PropertyValue(ImmutableDictionary value)
+ {
+ ObjectValue = value;
+ }
+ public PropertyValue(Asset value)
+ {
+ AssetValue = value;
+ }
+ public PropertyValue(Archive value)
+ {
+ ArchiveValue = value;
+ }
+ public PropertyValue(PropertyValue value)
+ {
+ SecretValue = value;
+ }
+ public PropertyValue(ResourceReference value)
+ {
+ ResourceValue = value;
+ }
+ public PropertyValue(OutputReference value)
+ {
+ OutputValue = value;
+ }
+
+ private PropertyValue(SpecialType type)
+ {
+ if (type == SpecialType.IsComputed)
+ {
+ IsComputed = true;
+ }
+ }
+
+ static bool TryGetStringValue(Google.Protobuf.Collections.MapField fields, string key, [System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out string? result)
+ {
+ if (fields.TryGetValue(key, out var value) && value.KindCase == Value.KindOneofCase.StringValue)
+ {
+ result = value.StringValue;
+ return true;
+ }
+ result = null;
+ return false;
+ }
+
+ internal static ImmutableDictionary Marshal(Struct properties)
+ {
+ var builder = ImmutableDictionary.CreateBuilder();
+ foreach (var item in properties.Fields)
+ {
+ builder.Add(item.Key, Marshal(item.Value));
+ }
+ return builder.ToImmutable();
+ }
+
+ internal static PropertyValue Marshal(Value value)
+ {
+ switch (value.KindCase)
+ {
+ case Value.KindOneofCase.NullValue:
+ return PropertyValue.Null;
+ case Value.KindOneofCase.BoolValue:
+ return new PropertyValue(value.BoolValue);
+ case Value.KindOneofCase.NumberValue:
+ return new PropertyValue(value.NumberValue);
+ case Value.KindOneofCase.StringValue:
+ {
+ // This could be the special unknown value
+ if (value.StringValue == Constants.UnknownValue)
+ {
+ return PropertyValue.Computed;
+ }
+ return new PropertyValue(value.StringValue);
+ }
+ case Value.KindOneofCase.ListValue:
+ {
+ var listValue = value.ListValue;
+ var builder = ImmutableArray.CreateBuilder(listValue.Values.Count);
+ foreach (var item in listValue.Values)
+ {
+ builder.Add(Marshal(item));
+ }
+ return new PropertyValue(builder.ToImmutable());
+ }
+ case Value.KindOneofCase.StructValue:
+ {
+ // This could be a plain object, or one of our specials
+ var structValue = value.StructValue;
+
+ if (TryGetStringValue(structValue.Fields, Constants.SpecialSigKey, out var sig))
+ {
+ switch (sig)
+ {
+ case Constants.SpecialSecretSig:
+ {
+ if (!structValue.Fields.TryGetValue(Constants.ValueName, out var secretValue))
+ throw new InvalidOperationException("Secrets must have a field called 'value'");
+
+ return new PropertyValue(Marshal(secretValue));
+ }
+ case Constants.SpecialAssetSig:
+ {
+ if (TryGetStringValue(structValue.Fields, Constants.AssetOrArchivePathName, out var path))
+ return new PropertyValue(new FileAsset(path));
+
+ if (TryGetStringValue(structValue.Fields, Constants.AssetOrArchiveUriName, out var uri))
+ return new PropertyValue(new RemoteAsset(uri));
+
+ if (TryGetStringValue(structValue.Fields, Constants.AssetTextName, out var text))
+ return new PropertyValue(new StringAsset(text));
+
+ throw new InvalidOperationException("Value was marked as Asset, but did not conform to required shape.");
+ }
+ case Constants.SpecialArchiveSig:
+ {
+ if (TryGetStringValue(structValue.Fields, Constants.AssetOrArchivePathName, out var path))
+ return new PropertyValue(new FileArchive(path));
+
+ if (TryGetStringValue(structValue.Fields, Constants.AssetOrArchiveUriName, out var uri))
+ return new PropertyValue(new RemoteArchive(uri));
+
+ if (structValue.Fields.TryGetValue(Constants.ArchiveAssetsName, out var assetsValue))
+ {
+ if (assetsValue.KindCase == Value.KindOneofCase.StructValue)
+ {
+ var assets = ImmutableDictionary.CreateBuilder();
+ foreach (var (name, val) in assetsValue.StructValue.Fields)
+ {
+ var innerAssetOrArchive = Marshal(val);
+ if (innerAssetOrArchive.AssetValue != null)
+ {
+ assets[name] = innerAssetOrArchive.AssetValue;
+ }
+ else if (innerAssetOrArchive.ArchiveValue != null)
+ {
+ assets[name] = innerAssetOrArchive.ArchiveValue;
+ }
+ else
+ {
+ throw new InvalidOperationException("AssetArchive contained an element that wasn't itself an Asset or Archive.");
+ }
+ }
+
+ return new PropertyValue(new AssetArchive(assets.ToImmutable()));
+ }
+ }
+
+ throw new InvalidOperationException("Value was marked as Archive, but did not conform to required shape.");
+ }
+ case Constants.SpecialResourceSig:
+ {
+ if (!TryGetStringValue(structValue.Fields, Constants.UrnPropertyName, out var urn))
+ {
+ throw new InvalidOperationException("Value was marked as a Resource, but did not conform to required shape.");
+ }
+
+ if (!TryGetStringValue(structValue.Fields, Constants.ResourceVersionName, out var version))
+ {
+ version = "";
+ }
+
+ if (!structValue.Fields.TryGetValue(Constants.IdPropertyName, out var id))
+ {
+ throw new InvalidOperationException("Value was marked as a Resource, but did not conform to required shape.");
+ }
+
+ return new PropertyValue(new ResourceReference(urn, Marshal(id), version));
+ }
+ case Constants.SpecialOutputValueSig:
+ {
+ PropertyValue? element = null;
+ if (structValue.Fields.TryGetValue(Constants.ValueName, out var knownElement))
+ {
+ element = Marshal(knownElement);
+ }
+ var secret = false;
+ if (structValue.Fields.TryGetValue(Constants.SecretName, out var v))
+ {
+ if (v.KindCase == Value.KindOneofCase.BoolValue)
+ {
+ secret = v.BoolValue;
+ }
+ else
+ {
+ throw new InvalidOperationException("Value was marked as an Output, but did not conform to required shape.");
+ }
+ }
+
+ var dependenciesBuilder = ImmutableArray.CreateBuilder();
+ if (structValue.Fields.TryGetValue(Constants.DependenciesName, out var dependencies))
+ {
+ if (dependencies.KindCase == Value.KindOneofCase.ListValue)
+ {
+ foreach (var dependency in dependencies.ListValue.Values)
+ {
+ if (dependency.KindCase == Value.KindOneofCase.StringValue)
+ {
+ dependenciesBuilder.Add(dependency.StringValue);
+ }
+ else
+ {
+ throw new InvalidOperationException("Value was marked as an Output, but did not conform to required shape.");
+ }
+ }
+ }
+ else
+ {
+ throw new InvalidOperationException("Value was marked as an Output, but did not conform to required shape.");
+ }
+ }
+
+ var output = new OutputReference(element, dependenciesBuilder.ToImmutable());
+
+ if (secret)
+ {
+ return new PropertyValue(new PropertyValue(output));
+ }
+ else
+ {
+ return new PropertyValue(output);
+ }
+ }
+
+ default:
+ throw new InvalidOperationException($"Unrecognized special signature: {sig}");
+ }
+ }
+ else
+ {
+ // Just a plain object
+ var builder = ImmutableDictionary.CreateBuilder();
+ foreach (var item in structValue.Fields)
+ {
+ builder.Add(item.Key, Marshal(item.Value));
+ }
+ return new PropertyValue(builder.ToImmutable());
+ }
+ }
+
+ case Value.KindOneofCase.None:
+ default:
+ throw new InvalidOperationException($"Unexpected grpc value: {value}");
+ }
+ }
+
+ internal static Struct Unmarshal(IDictionary properties)
+ {
+ var result = new Struct();
+ foreach (var item in properties)
+ {
+ result.Fields[item.Key] = Unmarshal(item.Value);
+ }
+ return result;
+ }
+
+ private static Value UnmarshalAsset(Asset asset)
+ {
+ var result = new Struct();
+ result.Fields[Constants.SpecialSigKey] = Value.ForString(Constants.SpecialAssetSig);
+ result.Fields[asset.PropName] = Value.ForString((string)asset.Value);
+ return Value.ForStruct(result);
+ }
+
+ private static Value UnmarshalArchive(Archive archive)
+ {
+ var result = new Struct();
+ result.Fields[Constants.SpecialSigKey] = Value.ForString(Constants.SpecialAssetSig);
+
+ if (archive.Value is string str)
+ {
+ result.Fields[archive.PropName] = Value.ForString(str);
+ }
+ else
+ {
+ var inner = (ImmutableDictionary)archive.Value;
+ var innerStruct = new Struct();
+ foreach (var item in inner)
+ {
+ innerStruct.Fields[item.Key] = UnmarshalAssetOrArchive(item.Value);
+ }
+ result.Fields[archive.PropName] = Value.ForStruct(innerStruct);
+ }
+ return Value.ForStruct(result);
+ }
+
+ private static Value UnmarshalAssetOrArchive(AssetOrArchive assetOrArchive)
+ {
+ if (assetOrArchive is Asset asset)
+ {
+ return UnmarshalAsset(asset);
+ }
+ else if (assetOrArchive is Archive archive)
+ {
+ return UnmarshalArchive(archive);
+ }
+ throw new InvalidOperationException("Internal error, AssetOrArchive was neither an Asset or Archive");
+ }
+
+ private static Value UnmarshalOutput(OutputReference output, bool secret)
+ {
+ var result = new Struct();
+ result.Fields[Constants.SpecialSigKey] = Value.ForString(Constants.SpecialOutputValueSig);
+ if (output.Value != null)
+ {
+ result.Fields[Constants.ValueName] = Unmarshal(output.Value);
+ }
+
+ var dependencies = new Value[output.Dependencies.Length];
+ var i = 0;
+ foreach (var dependency in output.Dependencies)
+ {
+ dependencies[i++] = Value.ForString(dependency);
+ }
+ result.Fields[Constants.DependenciesName] = Value.ForList(dependencies);
+ result.Fields[Constants.SecretName] = Value.ForBool(secret);
+
+ return Value.ForStruct(result);
+ }
+
+ internal static Value Unmarshal(PropertyValue value)
+ {
+ return value.Match(
+ () => Value.ForNull(),
+ b => Value.ForBool(b),
+ n => Value.ForNumber(n),
+ s => Value.ForString(s),
+ a =>
+ {
+ var result = new Value[a.Length];
+ for (int i = 0; i < a.Length; ++i)
+ {
+ result[i] = Unmarshal(a[i]);
+ }
+ return Value.ForList(result);
+ },
+ o =>
+ {
+ var result = new Struct();
+ foreach (var item in o)
+ {
+ result.Fields[item.Key] = Unmarshal(item.Value);
+ }
+ return Value.ForStruct(result);
+ },
+ asset => UnmarshalAsset(asset),
+ archive => UnmarshalArchive(archive),
+ secret =>
+ {
+ // Special case if our secret value is an output
+ if (secret.OutputValue != null)
+ {
+ return UnmarshalOutput(secret.OutputValue.Value, true);
+ }
+ var result = new Struct();
+ result.Fields[Constants.SpecialSigKey] = Value.ForString(Constants.SpecialSecretSig);
+ result.Fields[Constants.ValueName] = Unmarshal(secret);
+ return Value.ForStruct(result);
+ },
+ resource =>
+ {
+ var result = new Struct();
+ result.Fields[Constants.SpecialSigKey] = Value.ForString(Constants.SpecialResourceSig);
+ result.Fields[Constants.UrnPropertyName] = Value.ForString(resource.URN);
+ result.Fields[Constants.IdPropertyName] = Unmarshal(resource.ID);
+ if (resource.PackageVersion != "")
+ {
+ result.Fields[Constants.ResourceVersionName] = Value.ForString(resource.PackageVersion);
+ }
+ return Value.ForStruct(result);
+ },
+ output => UnmarshalOutput(output, false),
+ () => Value.ForString(Constants.UnknownValue)
+ );
+ }
+ }
+
+ public sealed class CheckRequest
+ {
+ public readonly string Urn;
+ public readonly ImmutableDictionary Olds;
+ public readonly ImmutableDictionary News;
+ public readonly ImmutableArray RandomSeed;
+
+ public CheckRequest(string urn, ImmutableDictionary olds, ImmutableDictionary news, ImmutableArray randomSeed)
+ {
+ Urn = urn;
+ Olds = olds;
+ News = news;
+ RandomSeed = randomSeed;
+ }
+ }
+
+ public sealed class CheckFailure
+ {
+ public string Property { get; set; }
+ public string Reason { get; set; }
+
+ public CheckFailure(string property, string reason)
+ {
+ Property = property;
+ Reason = reason;
+ }
+ }
+
+ public sealed class CheckResponse
+ {
+ public IDictionary? Inputs { get; set; }
+ public IList? Failures { get; set; }
+ }
+
+
+ public sealed class DiffRequest
+ {
+ public readonly string Urn;
+ public readonly string ID;
+ public readonly ImmutableDictionary Olds;
+ public readonly ImmutableDictionary News;
+ public readonly ImmutableArray IgnoreChanges;
+
+ public DiffRequest(string urn, string id, ImmutableDictionary olds, ImmutableDictionary news, ImmutableArray ignoreChanges)
+ {
+ Urn = urn;
+ ID = id;
+ Olds = olds;
+ News = news;
+ IgnoreChanges = ignoreChanges;
+ }
+ }
+
+ public enum PropertyDiffKind
+ {
+ Add = 0,
+ AddReplace = 1,
+ Delete = 2,
+ DeleteReplace = 3,
+ Update = 4,
+ UpdateReplace = 5,
+ }
+
+ public sealed class PropertyDiff
+ {
+ public PropertyDiffKind Kind { get; set; }
+ public bool InputDiff { get; set; }
+ }
+
+ public sealed class DiffResponse
+ {
+ public bool? Changes { get; set; }
+
+ public IList? Replaces { get; set; }
+
+ public IList? Stables { get; set; }
+
+ public bool DeleteBeforeReplace { get; set; }
+ public IList? Diffs { get; set; }
+
+ public IDictionary? DetailedDiff { get; set; }
+ }
+
+ public sealed class InvokeRequest
+ {
+ public readonly string Tok;
+ public readonly ImmutableDictionary Args;
+
+ public InvokeRequest(string tok, ImmutableDictionary args)
+ {
+ Tok = tok;
+ Args = args;
+ }
+ }
+
+ public sealed class InvokeResponse
+ {
+
+ public IDictionary? Return { get; set; }
+ public IList? Failures { get; set; }
+ }
+
+ public sealed class GetSchemaRequest
+ {
+ public readonly int Version;
+
+ public GetSchemaRequest(int version)
+ {
+ Version = version;
+ }
+ }
+
+ public sealed class GetSchemaResponse
+ {
+ public string? Schema { get; set; }
+ }
+
+ public sealed class ConfigureRequest
+ {
+ public readonly ImmutableDictionary Variables;
+ public readonly ImmutableDictionary Args;
+ public readonly bool AcceptSecrets;
+ public readonly bool AcceptResources;
+
+ public ConfigureRequest(ImmutableDictionary variables, ImmutableDictionary args, bool acceptSecrets, bool acceptResources)
+ {
+ Variables = variables;
+ Args = args;
+ AcceptSecrets = acceptSecrets;
+ AcceptResources = acceptResources;
+ }
+ }
+
+ public sealed class ConfigureResponse
+ {
+ public bool AcceptSecrets { get; set; }
+ public bool SupportsPreview { get; set; }
+ public bool AcceptResources { get; set; }
+ public bool AcceptOutputs { get; set; }
+ }
+
+ public sealed class GetPluginInfoResponse
+ {
+ public string? Version { get; set; }
+ }
+
+ public sealed class CreateRequest
+ {
+ public readonly string URN;
+ public readonly ImmutableDictionary Properties;
+ public readonly TimeSpan Timeout;
+ public readonly bool Preview;
+
+ public CreateRequest(string urn, ImmutableDictionary properties, TimeSpan timeout, bool preview)
+ {
+ URN = urn;
+ Properties = properties;
+ Timeout = timeout;
+ Preview = preview;
+ }
+ }
+
+ public sealed class CreateResponse
+ {
+ public string? ID { get; set; }
+ public IDictionary? Properties { get; set; }
+ }
+
+ public sealed class ReadRequest {
+ public readonly string ID;
+ public readonly string URN;
+ public readonly ImmutableDictionary Properties;
+ public readonly ImmutableDictionary Inputs;
+
+ public ReadRequest(string id, string urn, ImmutableDictionary properties, ImmutableDictionary inputs) {
+ ID = id;
+ URN = urn;
+ Properties = properties;
+ Inputs = inputs;
+ }
+ }
+
+ public sealed class ReadResponse {
+ public string? ID {get;set;}
+ public IDictionary? Properties {get;set;}
+ public IDictionary? Inputs{get;set;}
+ }
+
+ public sealed class UpdateRequest {
+ public readonly string ID;
+ public readonly string URN;
+ public readonly ImmutableDictionary Olds;
+ public readonly ImmutableDictionary News;
+ public readonly TimeSpan Timeout;
+ public readonly ImmutableArray IgnoreChanges;
+ public readonly bool Preview;
+
+ public UpdateRequest(string id, string urn, ImmutableDictionary olds, ImmutableDictionary news, TimeSpan timeout, ImmutableArray ignoreChanges, bool preview) {
+ ID = id;
+ URN = urn;
+ Olds = olds;
+ News = news;
+ Timeout = timeout;
+ IgnoreChanges = ignoreChanges;
+ Preview = preview;
+ }
+ }
+
+ public sealed class UpdateResponse {
+ public IDictionary? Properties {get;set;}
+ }
+
+ public sealed class DeleteRequest {
+ public readonly string ID;
+ public readonly string URN;
+ public readonly ImmutableDictionary Properties;
+ public readonly TimeSpan Timeout;
+
+ public DeleteRequest(string id, string urn, ImmutableDictionary properties, TimeSpan timeout) {
+ ID = id;
+ URN = urn;
+ Properties = properties;
+ Timeout = timeout;
+ }
+ }
+
+ public sealed class ConstructRequest {
+ public readonly string Name;
+ public readonly string Type;
+ public readonly ImmutableDictionary Inputs;
+ public readonly ComponentResourceOptions Options;
+
+ public ConstructRequest(string name, string type, ImmutableDictionary inputs, ComponentResourceOptions options) {
+ Name = name;
+ Type = type;
+ Inputs = inputs;
+ Options = options;
+ }
+ }
+
+ public sealed class ConstructResponse {
+ public string? Urn {get;set;}
+ public IDictionary? Properties {get;set;}
+ }
+
+ public sealed class CallRequest {
+ public readonly string Tok;
+ public readonly ImmutableDictionary Args;
+
+ public CallRequest(string tok, ImmutableDictionary args)
+ {
+ Tok = tok;
+ Args = args;
+ }
+ }
+
+ public sealed class CallResponse {
+ public IDictionary? Properties {get;set;}
+ }
+
+ public abstract class Provider
+ {
+ public virtual Task CheckConfig(CheckRequest request, CancellationToken ct)
+ {
+ throw new NotImplementedException();
+ }
+
+ public virtual Task DiffConfig(DiffRequest request, CancellationToken ct)
+ {
+ throw new NotImplementedException();
+ }
+
+ public virtual Task Invoke(InvokeRequest request, CancellationToken ct)
+ {
+ throw new NotImplementedException();
+ }
+
+ public virtual Task GetSchema(GetSchemaRequest request, CancellationToken ct)
+ {
+ throw new NotImplementedException();
+ }
+
+ public virtual Task Configure(ConfigureRequest request, CancellationToken ct)
+ {
+ throw new NotImplementedException();
+ }
+
+ public virtual Task GetPluginInfo(CancellationToken ct)
+ {
+ throw new NotImplementedException();
+ }
+
+ public virtual Task Cancel(CancellationToken ct)
+ {
+ throw new NotImplementedException();
+ }
+
+ public virtual Task Create(CreateRequest request, CancellationToken ct)
+ {
+ throw new NotImplementedException();
+ }
+
+ public virtual Task Read(ReadRequest request, CancellationToken ct)
+ {
+ throw new NotImplementedException();
+ }
+
+ public virtual Task Check(CheckRequest request, CancellationToken ct)
+ {
+ throw new NotImplementedException();
+ }
+
+ public virtual Task Diff(DiffRequest request, CancellationToken ct)
+ {
+ throw new NotImplementedException();
+ }
+
+ public virtual Task Update(UpdateRequest request, CancellationToken ct)
+ {
+ throw new NotImplementedException();
+ }
+
+ public virtual Task Delete(DeleteRequest request, CancellationToken ct)
+ {
+ throw new NotImplementedException();
+ }
+
+ public virtual Task Construct(ConstructRequest request, CancellationToken ct)
+ {
+ throw new NotImplementedException();
+ }
+
+ public virtual Task Call(CallRequest request, CancellationToken ct)
+ {
+ throw new NotImplementedException();
+ }
+
+ public async Task Serve(string[] args, System.Threading.CancellationToken cancellationToken)
+ {
+ // maxRpcMessageSize raises the gRPC Max message size from `4194304` (4mb) to `419430400` (400mb)
+ var maxRpcMessageSize = 400 * 1024 * 1024;
+
+ var host = Host.CreateDefaultBuilder()
+ .ConfigureWebHostDefaults(webBuilder =>
+ {
+ webBuilder
+ .ConfigureKestrel(kestrelOptions =>
+ {
+ kestrelOptions.Listen(IPAddress.Any, 0, listenOptions =>
+ {
+ listenOptions.Protocols = HttpProtocols.Http2;
+ });
+ })
+ .ConfigureAppConfiguration((context, config) =>
+ {
+ // clear so we don't read appsettings.json
+ // note that we also won't read environment variables for config
+ config.Sources.Clear();
+ })
+ .ConfigureLogging(loggingBuilder =>
+ {
+ // disable default logging
+ loggingBuilder.ClearProviders();
+ })
+ .ConfigureServices(services =>
+ {
+ // to be injected into ResourceProviderService
+ services.AddSingleton(this);
+
+ services.AddGrpc(grpcOptions =>
+ {
+ grpcOptions.MaxReceiveMessageSize = maxRpcMessageSize;
+ grpcOptions.MaxSendMessageSize = maxRpcMessageSize;
+ });
+ })
+ .Configure(app =>
+ {
+ app.UseRouting();
+ app.UseEndpoints(endpoints =>
+ {
+ endpoints.MapGrpcService();
+ });
+ });
+ })
+ .Build();
+
+ // before starting the host, set up this callback to tell us what port was selected
+ var portTcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
+ var portRegistration = host.Services.GetRequiredService().ApplicationStarted.Register(() =>
+ {
+ try
+ {
+ var serverFeatures = host.Services.GetRequiredService().Features;
+ var addresses = serverFeatures.Get().Addresses.ToList();
+ Debug.Assert(addresses.Count == 1, "Server should only be listening on one address");
+ var uri = new Uri(addresses[0]);
+ portTcs.TrySetResult(uri.Port);
+ }
+ catch (Exception ex)
+ {
+ portTcs.TrySetException(ex);
+ }
+ });
+
+ await host.StartAsync(cancellationToken);
+
+ var port = await portTcs.Task;
+ System.Console.WriteLine(port.ToString());
+
+ await host.WaitForShutdownAsync(cancellationToken);
+
+ host.Dispose();
+ }
+ }
+
+ class ResourceProviderService : ResourceProvider.ResourceProviderBase
+ {
+ readonly Provider implementation;
+
+ public ResourceProviderService(Provider implementation)
+ {
+ this.implementation = implementation;
+ }
+
+ public override async Task CheckConfig(Pulumirpc.CheckRequest request, ServerCallContext context)
+ {
+ try
+ {
+ var domRequest = new CheckRequest(request.Urn, PropertyValue.Marshal(request.Olds), PropertyValue.Marshal(request.News), ImmutableArray.ToImmutableArray(request.RandomSeed));
+ var domResponse = await this.implementation.CheckConfig(domRequest, context.CancellationToken);
+ var grpcResponse = new Pulumirpc.CheckResponse();
+ grpcResponse.Inputs = domResponse.Inputs == null ? null : PropertyValue.Unmarshal(domResponse.Inputs);
+ if (domResponse.Failures != null)
+ {
+ foreach (var domFailure in domResponse.Failures)
+ {
+ var grpcFailure = new Pulumirpc.CheckFailure();
+ grpcFailure.Property = domFailure.Property;
+ grpcFailure.Reason = domFailure.Reason;
+ grpcResponse.Failures.Add(grpcFailure);
+ }
+ }
+ return grpcResponse;
+ }
+ catch (NotImplementedException ex)
+ {
+ throw new RpcException(new Status(StatusCode.Unimplemented, ex.Message));
+ }
+ catch (System.Threading.Tasks.TaskCanceledException ex)
+ {
+ throw new RpcException(new Status(StatusCode.Cancelled, ex.Message));
+ }
+ catch (Exception ex)
+ {
+ throw new RpcException(new Status(StatusCode.Internal, ex.Message));
+ }
+ }
+
+ public override async Task DiffConfig(Pulumirpc.DiffRequest request, ServerCallContext context)
+ {
+ try
+ {
+ var domRequest = new DiffRequest(request.Urn, request.Id, PropertyValue.Marshal(request.Olds), PropertyValue.Marshal(request.News), request.IgnoreChanges.ToImmutableArray());
+ var domResponse = await this.implementation.DiffConfig(domRequest, context.CancellationToken);
+ var grpcResponse = new Pulumirpc.DiffResponse();
+ if (domResponse.Changes.HasValue)
+ {
+ grpcResponse.Changes = domResponse.Changes.Value ? Pulumirpc.DiffResponse.Types.DiffChanges.DiffSome : Pulumirpc.DiffResponse.Types.DiffChanges.DiffNone;
+ }
+ if (domResponse.Stables != null)
+ {
+ grpcResponse.Stables.AddRange(domResponse.Stables);
+ }
+ if (domResponse.Replaces != null)
+ {
+ grpcResponse.Replaces.AddRange(domResponse.Replaces);
+ }
+ grpcResponse.DeleteBeforeReplace = domResponse.DeleteBeforeReplace;
+ if (domResponse.Diffs != null)
+ {
+ grpcResponse.Diffs.AddRange(domResponse.Diffs);
+ }
+ if (domResponse.DetailedDiff != null)
+ {
+ foreach (var item in domResponse.DetailedDiff)
+ {
+ var domDiff = item.Value;
+ var grpcDiff = new Pulumirpc.PropertyDiff();
+ grpcDiff.InputDiff = domDiff.InputDiff;
+ grpcDiff.Kind = (Pulumirpc.PropertyDiff.Types.Kind)domDiff.Kind;
+ grpcResponse.DetailedDiff.Add(item.Key, grpcDiff);
+ }
+ }
+ return grpcResponse;
+ }
+ catch (NotImplementedException ex)
+ {
+ throw new RpcException(new Status(StatusCode.Unimplemented, ex.Message));
+ }
+ catch (System.Threading.Tasks.TaskCanceledException ex)
+ {
+ throw new RpcException(new Status(StatusCode.Cancelled, ex.Message));
+ }
+ catch (Exception ex)
+ {
+ throw new RpcException(new Status(StatusCode.Internal, ex.Message));
+ }
+ }
+
+ public override async Task Invoke(Pulumirpc.InvokeRequest request, ServerCallContext context)
+ {
+ try
+ {
+ var domRequest = new InvokeRequest(request.Tok, PropertyValue.Marshal(request.Args));
+ var domResponse = await this.implementation.Invoke(domRequest, context.CancellationToken);
+ var grpcResponse = new Pulumirpc.InvokeResponse();
+ grpcResponse.Return = domResponse.Return == null ? null : PropertyValue.Unmarshal(domResponse.Return);
+ if (domResponse.Failures != null)
+ {
+ foreach (var domFailure in domResponse.Failures)
+ {
+ var grpcFailure = new Pulumirpc.CheckFailure();
+ grpcFailure.Property = domFailure.Property;
+ grpcFailure.Reason = domFailure.Reason;
+ grpcResponse.Failures.Add(grpcFailure);
+ }
+ }
+ return grpcResponse;
+ }
+ catch (NotImplementedException ex)
+ {
+ throw new RpcException(new Status(StatusCode.Unimplemented, ex.Message));
+ }
+ catch (System.Threading.Tasks.TaskCanceledException ex)
+ {
+ throw new RpcException(new Status(StatusCode.Cancelled, ex.Message));
+ }
+ catch (Exception ex)
+ {
+ throw new RpcException(new Status(StatusCode.Internal, ex.Message));
+ }
+ }
+
+ public override async Task GetSchema(Pulumirpc.GetSchemaRequest request, ServerCallContext context)
+ {
+ try
+ {
+ var domRequest = new GetSchemaRequest(request.Version);
+ var domResponse = await this.implementation.GetSchema(domRequest, context.CancellationToken);
+ var grpcResponse = new Pulumirpc.GetSchemaResponse();
+ grpcResponse.Schema = domResponse.Schema ?? "";
+ return grpcResponse;
+ }
+ catch (NotImplementedException ex)
+ {
+ throw new RpcException(new Status(StatusCode.Unimplemented, ex.Message));
+ }
+ catch (System.Threading.Tasks.TaskCanceledException ex)
+ {
+ throw new RpcException(new Status(StatusCode.Cancelled, ex.Message));
+ }
+ catch (Exception ex)
+ {
+ throw new RpcException(new Status(StatusCode.Internal, ex.Message));
+ }
+ }
+
+ public override async Task Configure(Pulumirpc.ConfigureRequest request, ServerCallContext context)
+ {
+ try
+ {
+ var domRequest = new ConfigureRequest(request.Variables.ToImmutableDictionary(), PropertyValue.Marshal(request.Args), request.AcceptSecrets, request.AcceptResources);
+ var domResponse = await this.implementation.Configure(domRequest, context.CancellationToken);
+ var grpcResponse = new Pulumirpc.ConfigureResponse();
+ grpcResponse.AcceptSecrets = domResponse.AcceptSecrets;
+ grpcResponse.SupportsPreview = domResponse.SupportsPreview;
+ grpcResponse.AcceptResources = domResponse.AcceptResources;
+ grpcResponse.AcceptOutputs = domResponse.AcceptOutputs;
+ return grpcResponse;
+ }
+ catch (NotImplementedException ex)
+ {
+ throw new RpcException(new Status(StatusCode.Unimplemented, ex.Message));
+ }
+ catch (System.Threading.Tasks.TaskCanceledException ex)
+ {
+ throw new RpcException(new Status(StatusCode.Cancelled, ex.Message));
+ }
+ catch (Exception ex)
+ {
+ throw new RpcException(new Status(StatusCode.Internal, ex.Message));
+ }
+ }
+
+ public override async Task GetPluginInfo(Empty request, ServerCallContext context)
+ {
+ try
+ {
+ var domResponse = await this.implementation.GetPluginInfo(context.CancellationToken);
+ var grpcResponse = new Pulumirpc.PluginInfo();
+ grpcResponse.Version = domResponse.Version ?? "";
+ return grpcResponse;
+ }
+ catch (NotImplementedException ex)
+ {
+ throw new RpcException(new Status(StatusCode.Unimplemented, ex.Message));
+ }
+ catch (System.Threading.Tasks.TaskCanceledException ex)
+ {
+ throw new RpcException(new Status(StatusCode.Cancelled, ex.Message));
+ }
+ catch (Exception ex)
+ {
+ throw new RpcException(new Status(StatusCode.Internal, ex.Message));
+ }
+ }
+
+ public override async Task Cancel(Empty request, ServerCallContext context)
+ {
+ try
+ {
+ await this.implementation.Cancel(context.CancellationToken);
+ return new Empty();
+ }
+ catch (NotImplementedException ex)
+ {
+ throw new RpcException(new Status(StatusCode.Unimplemented, ex.Message));
+ }
+ catch (System.Threading.Tasks.TaskCanceledException ex)
+ {
+ throw new RpcException(new Status(StatusCode.Cancelled, ex.Message));
+ }
+ catch (Exception ex)
+ {
+ throw new RpcException(new Status(StatusCode.Internal, ex.Message));
+ }
+ }
+
+ public override async Task Create(Pulumirpc.CreateRequest request, ServerCallContext context)
+ {
+ try
+ {
+ var domRequest = new CreateRequest(request.Urn, PropertyValue.Marshal(request.Properties), TimeSpan.FromSeconds(request.Timeout), request.Preview);
+ var domResponse = await this.implementation.Create(domRequest, context.CancellationToken);
+ var grpcResponse = new Pulumirpc.CreateResponse();
+ grpcResponse.Id = domResponse.ID ?? "";
+ grpcResponse.Properties = domResponse.Properties == null ? null : PropertyValue.Unmarshal(domResponse.Properties);
+ return grpcResponse;
+ }
+ catch (NotImplementedException ex)
+ {
+ throw new RpcException(new Status(StatusCode.Unimplemented, ex.Message));
+ }
+ catch (System.Threading.Tasks.TaskCanceledException ex)
+ {
+ throw new RpcException(new Status(StatusCode.Cancelled, ex.Message));
+ }
+ catch (Exception ex)
+ {
+ throw new RpcException(new Status(StatusCode.Internal, ex.Message));
+ }
+ }
+
+ public override async Task Read(Pulumirpc.ReadRequest request, ServerCallContext context)
+ {
+ try
+ {
+ var domRequest = new ReadRequest(request.Id, request.Urn, PropertyValue.Marshal(request.Properties), PropertyValue.Marshal(request.Inputs));
+ var domResponse = await this.implementation.Read(domRequest, context.CancellationToken);
+ var grpcResponse = new Pulumirpc.ReadResponse();
+ grpcResponse.Id = domResponse.ID ?? "";
+ grpcResponse.Properties = domResponse.Properties == null ? null : PropertyValue.Unmarshal(domResponse.Properties);
+ grpcResponse.Inputs = domResponse.Inputs == null ? null : PropertyValue.Unmarshal(domResponse.Inputs);
+ return grpcResponse;
+ }
+ catch (NotImplementedException ex)
+ {
+ throw new RpcException(new Status(StatusCode.Unimplemented, ex.Message));
+ }
+ catch (System.Threading.Tasks.TaskCanceledException ex)
+ {
+ throw new RpcException(new Status(StatusCode.Cancelled, ex.Message));
+ }
+ catch (Exception ex)
+ {
+ throw new RpcException(new Status(StatusCode.Internal, ex.Message));
+ }
+ }
+
+ public override async Task Check(Pulumirpc.CheckRequest request, ServerCallContext context)
+ {
+ try
+ {
+ var domRequest = new CheckRequest(request.Urn, PropertyValue.Marshal(request.Olds), PropertyValue.Marshal(request.News), ImmutableArray.ToImmutableArray(request.RandomSeed));
+ var domResponse = await this.implementation.Check(domRequest, context.CancellationToken);
+ var grpcResponse = new Pulumirpc.CheckResponse();
+ grpcResponse.Inputs = domResponse.Inputs == null ? null : PropertyValue.Unmarshal(domResponse.Inputs);
+ if (domResponse.Failures != null)
+ {
+ foreach (var domFailure in domResponse.Failures)
+ {
+ var grpcFailure = new Pulumirpc.CheckFailure();
+ grpcFailure.Property = domFailure.Property;
+ grpcFailure.Reason = domFailure.Reason;
+ grpcResponse.Failures.Add(grpcFailure);
+ }
+ }
+ return grpcResponse;
+ }
+ catch (NotImplementedException ex)
+ {
+ throw new RpcException(new Status(StatusCode.Unimplemented, ex.Message));
+ }
+ catch (System.Threading.Tasks.TaskCanceledException ex)
+ {
+ throw new RpcException(new Status(StatusCode.Cancelled, ex.Message));
+ }
+ catch (Exception ex)
+ {
+ throw new RpcException(new Status(StatusCode.Internal, ex.Message));
+ }
+ }
+
+ public override async Task Diff(Pulumirpc.DiffRequest request, ServerCallContext context)
+ {
+ try
+ {
+ var domRequest = new DiffRequest(request.Urn, request.Id, PropertyValue.Marshal(request.Olds), PropertyValue.Marshal(request.News), request.IgnoreChanges.ToImmutableArray());
+ var domResponse = await this.implementation.Diff(domRequest, context.CancellationToken);
+ var grpcResponse = new Pulumirpc.DiffResponse();
+ if (domResponse.Changes.HasValue)
+ {
+ grpcResponse.Changes = domResponse.Changes.Value ? Pulumirpc.DiffResponse.Types.DiffChanges.DiffSome : Pulumirpc.DiffResponse.Types.DiffChanges.DiffNone;
+ }
+ if (domResponse.Stables != null)
+ {
+ grpcResponse.Stables.AddRange(domResponse.Stables);
+ }
+ if (domResponse.Replaces != null)
+ {
+ grpcResponse.Replaces.AddRange(domResponse.Replaces);
+ }
+ grpcResponse.DeleteBeforeReplace = domResponse.DeleteBeforeReplace;
+ if (domResponse.Diffs != null)
+ {
+ grpcResponse.Diffs.AddRange(domResponse.Diffs);
+ }
+ if (domResponse.DetailedDiff != null)
+ {
+ foreach (var item in domResponse.DetailedDiff)
+ {
+ var domDiff = item.Value;
+ var grpcDiff = new Pulumirpc.PropertyDiff();
+ grpcDiff.InputDiff = domDiff.InputDiff;
+ grpcDiff.Kind = (Pulumirpc.PropertyDiff.Types.Kind)domDiff.Kind;
+ grpcResponse.DetailedDiff.Add(item.Key, grpcDiff);
+ }
+ }
+ return grpcResponse;
+ }
+ catch (NotImplementedException ex)
+ {
+ throw new RpcException(new Status(StatusCode.Unimplemented, ex.Message));
+ }
+ catch (System.Threading.Tasks.TaskCanceledException ex)
+ {
+ throw new RpcException(new Status(StatusCode.Cancelled, ex.Message));
+ }
+ catch (Exception ex)
+ {
+ throw new RpcException(new Status(StatusCode.Internal, ex.Message));
+ }
+ }
+
+ public override async Task Update(Pulumirpc.UpdateRequest request, ServerCallContext context)
+ {
+ try
+ {
+ var domRequest = new UpdateRequest(request.Urn, request.Id, PropertyValue.Marshal(request.Olds), PropertyValue.Marshal(request.News), TimeSpan.FromSeconds(request.Timeout), request.IgnoreChanges.ToImmutableArray(), request.Preview);
+ var domResponse = await this.implementation.Update(domRequest, context.CancellationToken);
+ var grpcResponse = new Pulumirpc.UpdateResponse();
+ grpcResponse.Properties = domResponse.Properties == null ? null : PropertyValue.Unmarshal(domResponse.Properties);
+ return grpcResponse;
+ }
+ catch (NotImplementedException ex)
+ {
+ throw new RpcException(new Status(StatusCode.Unimplemented, ex.Message));
+ }
+ catch (System.Threading.Tasks.TaskCanceledException ex)
+ {
+ throw new RpcException(new Status(StatusCode.Cancelled, ex.Message));
+ }
+ catch (Exception ex)
+ {
+ throw new RpcException(new Status(StatusCode.Internal, ex.Message));
+ }
+ }
+
+ public override async Task Delete(Pulumirpc.DeleteRequest request, ServerCallContext context)
+ {
+ try
+ {
+ var domRequest = new DeleteRequest(request.Urn, request.Id, PropertyValue.Marshal(request.Properties), TimeSpan.FromSeconds(request.Timeout));
+ await this.implementation.Delete(domRequest, context.CancellationToken);
+ return new Empty();
+ }
+ catch (NotImplementedException ex)
+ {
+ throw new RpcException(new Status(StatusCode.Unimplemented, ex.Message));
+ }
+ catch (System.Threading.Tasks.TaskCanceledException ex)
+ {
+ throw new RpcException(new Status(StatusCode.Cancelled, ex.Message));
+ }
+ catch (Exception ex)
+ {
+ throw new RpcException(new Status(StatusCode.Internal, ex.Message));
+ }
+ }
+
+ //function configureRuntime(req: any, engineAddr: string | undefined) {
+ // // NOTE: these are globals! We should ensure that all settings are identical between calls, and eventually
+ // // refactor so we can avoid the global state.
+ // if (engineAddr === undefined) {
+ // throw new Error("fatal: Missing address");
+ // }
+
+ // settings.resetOptions(req.getProject(), req.getStack(), req.getParallel(), engineAddr,
+ // req.getMonitorendpoint(), req.getDryrun(), req.getOrganization());
+
+ // const pulumiConfig: {[key: string]: string} = {};
+ // const rpcConfig = req.getConfigMap();
+ // if (rpcConfig) {
+ // for (const [k, v] of rpcConfig.entries()) {
+ // pulumiConfig[k] = v;
+ // }
+ // }
+ // config.setAllConfig(pulumiConfig, req.getConfigsecretkeysList());
+ //}
+
+ public override async Task Construct(Pulumirpc.ConstructRequest request, ServerCallContext context)
+ {
+ try
+ {
+ // ConfigureRuntime
+ var deployment = new Deployment(new Deployment.RunnerOptions(){
+
+ });
+
+
+
+ // Rebuild the resource options.
+ // const dependsOn: resource.Resource[] = [];
+ // for (const urn of req.getDependenciesList()) {
+ // dependsOn.push(new resource.DependencyResource(urn));
+ // }
+ // const providers: Record = {};
+ // const rpcProviders = req.getProvidersMap();
+ // if (rpcProviders) {
+ // for (const [pkg, ref] of rpcProviders.entries()) {
+ // providers[pkg] = createProviderResource(ref);
+ // }
+ // }
+ // const opts: resource.ComponentResourceOptions = {
+ // aliases: req.getAliasesList(),
+ // dependsOn: dependsOn,
+ // protect: req.getProtect(),
+ // providers: providers,
+ // parent: req.getParent() ? new resource.DependencyResource(req.getParent()) : undefined,
+ // };
+
+ var domRequest = new ConstructRequest(request.Name, request.Type, PropertyValue.Marshal(request.Inputs), opts)
+ var domResponse = await this.implementation.Construct(domRequest, context.CancellationToken);
+ var grpcResponse = new Pulumirpc.ConstructResponse();
+ grpcResponse.Properties = domResponse.Properties == null ? null : PropertyValue.Unmarshal(domResponse.Properties);
+ return grpcResponse;
+ // // given that construct calls are serialized, we can attach an uncaught handler to pick up exceptions
+ // // in underlying user code. When we catch the error, we need to respond to the gRPC request with the error
+ // // to avoid a hang.
+ // const uncaughtHandler = (err: Error) => {
+ // if (!this.uncaughtErrors.has(err)) {
+ // this.uncaughtErrors.add(err);
+ // }
+ // // bubble the uncaught error in the user code back and terminate the outstanding gRPC request.
+ // callback(err, undefined);
+ // };
+ // process.on("uncaughtException", uncaughtHandler);
+ // // @ts-ignore 'unhandledRejection' will almost always invoke uncaughtHandler with an Error. so
+ // // just suppress the TS strictness here.
+ // process.on("unhandledRejection", uncaughtHandler);
+ // try {
+ // const req: any = call.request;
+ // const type = req.getType();
+ // const name = req.getName();
+
+ // if (!this.provider.construct) {
+ // callback(new Error(`unknown resource type ${type}`), undefined);
+ // return;
+ // }
+
+ // configureRuntime(req, this.engineAddr);
+
+ // const inputs = await deserializeInputs(req.getInputs(), req.getInputdependenciesMap());
+
+ // // Rebuild the resource options.
+ // const dependsOn: resource.Resource[] = [];
+ // for (const urn of req.getDependenciesList()) {
+ // dependsOn.push(new resource.DependencyResource(urn));
+ // }
+ // const providers: Record = {};
+ // const rpcProviders = req.getProvidersMap();
+ // if (rpcProviders) {
+ // for (const [pkg, ref] of rpcProviders.entries()) {
+ // providers[pkg] = createProviderResource(ref);
+ // }
+ // }
+ // const opts: resource.ComponentResourceOptions = {
+ // aliases: req.getAliasesList(),
+ // dependsOn: dependsOn,
+ // protect: req.getProtect(),
+ // providers: providers,
+ // parent: req.getParent() ? new resource.DependencyResource(req.getParent()) : undefined,
+ // };
+
+ // const result = await this.provider.construct(name, type, inputs, opts);
+
+ // const resp = new provproto.ConstructResponse();
+
+ // resp.setUrn(await output(result.urn).promise());
+
+ // const [state, stateDependencies] = await rpc.serializeResourceProperties(`construct(${type}, ${name})`, result.state);
+ // const stateDependenciesMap = resp.getStatedependenciesMap();
+ // for (const [key, resources] of stateDependencies) {
+ // const deps = new provproto.ConstructResponse.PropertyDependencies();
+ // deps.setUrnsList(await Promise.all(Array.from(resources).map(r => r.urn.promise())));
+ // stateDependenciesMap.set(key, deps);
+ // }
+ // resp.setState(structproto.Struct.fromJavaScript(state));
+
+ // // Wait for RPC operations to complete.
+ // await settings.waitForRPCs();
+
+ // callback(undefined, resp);
+ // } catch (e) {
+ // console.error(`${e}: ${e.stack}`);
+ // callback(e, undefined);
+ // } finally {
+ // // remove these uncaught handlers that are specific to this gRPC callback context
+ // process.off("uncaughtException", uncaughtHandler);
+ // process.off("unhandledRejection", uncaughtHandler);
+ // }
+ }
+ catch (NotImplementedException ex)
+ {
+ throw new RpcException(new Status(StatusCode.Unimplemented, ex.Message));
+ }
+ catch (System.Threading.Tasks.TaskCanceledException ex)
+ {
+ throw new RpcException(new Status(StatusCode.Cancelled, ex.Message));
+ }
+ catch (Exception ex)
+ {
+ throw new RpcException(new Status(StatusCode.Internal, ex.Message));
+ }
+ }
+
+ public override Task Call(Pulumirpc.CallRequest request, ServerCallContext context)
+ {
+ try
+ {
+ var domRequest = new CallRequest(request.Urn, request.Id, PropertyValue.Marshal(request.Properties), TimeSpan.FromSeconds(request.Timeout));
+ var domResponse = await this.implementation.Call(domRequest, context.CancellationToken);
+ var grpcResponse = new Pulumirpc.CallResponse();
+ grpcResponse.Properties = domResponse.Properties == null ? null : PropertyValue.Unmarshal(domResponse.Properties);
+ return grpcResponse;
+ }
+ catch (NotImplementedException ex)
+ {
+ throw new RpcException(new Status(StatusCode.Unimplemented, ex.Message));
+ }
+ catch (System.Threading.Tasks.TaskCanceledException ex)
+ {
+ throw new RpcException(new Status(StatusCode.Cancelled, ex.Message));
+ }
+ catch (Exception ex)
+ {
+ throw new RpcException(new Status(StatusCode.Internal, ex.Message));
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/sdk/dotnet/Pulumi/Pulumi.csproj b/sdk/dotnet/Pulumi/Pulumi.csproj
index 7c4733e5a6aa..605404949cf8 100644
--- a/sdk/dotnet/Pulumi/Pulumi.csproj
+++ b/sdk/dotnet/Pulumi/Pulumi.csproj
@@ -32,6 +32,7 @@
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive