Skip to content

Commit

Permalink
Introduce type for URN values (#293)
Browse files Browse the repository at this point in the history
  • Loading branch information
algompluecker authored Jul 8, 2024
1 parent 9828223 commit 86acdc0
Show file tree
Hide file tree
Showing 7 changed files with 69 additions and 34 deletions.
6 changes: 6 additions & 0 deletions .changes/unreleased/Improvements-293.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
component: sdk
kind: Improvements
body: Strongly type URN values in Provider
time: 2024-07-07T12:42:32.5457649+02:00
custom:
PR: "293"
6 changes: 3 additions & 3 deletions sdk/Pulumi.Tests/Provider/PropertyValueTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ public async Task DeserializingSecretInputsWorks()
public async Task DeserializingBasicInputsWorks()
{
var serializer = CreateSerializer();
var resources = ImmutableArray.Create("pulumi:pulumi:Stack");
var resources = ImmutableArray.Create(new Urn("pulumi:pulumi:Stack"));
var output = new PropertyValue(new OutputReference(
value: new PropertyValue("Hello"),
dependencies: resources));
Expand Down Expand Up @@ -289,7 +289,7 @@ public async Task DeserializingWrappedOutputSecretWorks()
var secretOutput = new PropertyValue(
new PropertyValue(new OutputReference(
value: new PropertyValue("Hello"),
dependencies: ImmutableArray<string>.Empty)));
dependencies: ImmutableArray<Urn>.Empty)));

var deserialized = await serializer.Deserialize<Input<string>>(secretOutput);
var deserializedOutput = deserialized.ToOutput();
Expand All @@ -307,7 +307,7 @@ public async Task DeserializingWrappedSecretInOutputWorks()
var secretOutput = new PropertyValue(
new OutputReference(
value: new PropertyValue(new PropertyValue("Hello")),
dependencies: ImmutableArray<string>.Empty));
dependencies: ImmutableArray<Urn>.Empty));

var deserialized = await serializer.Deserialize<Input<string>>(secretOutput);
var deserializedOutput = deserialized.ToOutput();
Expand Down
4 changes: 2 additions & 2 deletions sdk/Pulumi/Provider/Host.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public sealed class LogMessage
/// <summary>
/// The (optional) resource urn this log is associated with.
/// </summary>
public readonly string? Urn;
public readonly Urn? Urn;

/// <summary>
/// The (optional) stream id that a stream of log messages can be associated with. This allows
Expand All @@ -67,7 +67,7 @@ public sealed class LogMessage
/// </summary>
public readonly bool Ephemeral;

public LogMessage(LogSeverity severity, string message, string? urn = null, int streamId = 0, bool ephemeral = false)
public LogMessage(LogSeverity severity, string message, Urn? urn = null, int streamId = 0, bool ephemeral = false)
{
Severity = severity;
Message = message;
Expand Down
14 changes: 7 additions & 7 deletions sdk/Pulumi/Provider/PropertyValue.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@ public enum PropertyValueType

public readonly struct ResourceReference : IEquatable<ResourceReference>
{
public readonly string URN;
public readonly Urn URN;
public readonly PropertyValue Id;
public readonly string PackageVersion;

public ResourceReference(string urn, PropertyValue id, string version)
public ResourceReference(Urn urn, PropertyValue id, string version)
{
URN = urn;
Id = id;
Expand Down Expand Up @@ -72,9 +72,9 @@ public bool Equals(ResourceReference other)
public readonly struct OutputReference : IEquatable<OutputReference>
{
public readonly PropertyValue? Value;
public readonly ImmutableArray<string> Dependencies;
public readonly ImmutableArray<Urn> Dependencies;

public OutputReference(PropertyValue? value, ImmutableArray<string> dependencies)
public OutputReference(PropertyValue? value, ImmutableArray<Urn> dependencies)
{
Value = value;
Dependencies = dependencies;
Expand Down Expand Up @@ -697,7 +697,7 @@ internal static PropertyValue Unmarshal(Value value)
throw new InvalidOperationException("Value was marked as a Resource, but did not conform to required shape.");
}

return new PropertyValue(new ResourceReference(urn, Unmarshal(id), version));
return new PropertyValue(new ResourceReference(new Urn(urn), Unmarshal(id), version));
}
case Constants.SpecialOutputValueSig:
{
Expand All @@ -719,7 +719,7 @@ internal static PropertyValue Unmarshal(Value value)
}
}

var dependenciesBuilder = ImmutableArray.CreateBuilder<string>();
var dependenciesBuilder = ImmutableArray.CreateBuilder<Urn>();
if (structValue.Fields.TryGetValue(Constants.DependenciesName, out var dependencies))
{
if (dependencies.KindCase == Value.KindOneofCase.ListValue)
Expand All @@ -728,7 +728,7 @@ internal static PropertyValue Unmarshal(Value value)
{
if (dependency.KindCase == Value.KindOneofCase.StringValue)
{
dependenciesBuilder.Add(dependency.StringValue);
dependenciesBuilder.Add(new Urn(dependency.StringValue));
}
else
{
Expand Down
4 changes: 2 additions & 2 deletions sdk/Pulumi/Provider/PropertyValueSerializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -269,11 +269,11 @@ public async Task<PropertyValue> Serialize<T>(T value)
}

var outputValue = await Serialize(data.Value);
var dependantResources = ImmutableArray.CreateBuilder<string>();
var dependantResources = ImmutableArray.CreateBuilder<Urn>();
foreach (var resource in data.Resources)
{
var urn = await resource.Urn.GetValueAsync("").ConfigureAwait(false);
dependantResources.Add(urn);
dependantResources.Add(new Urn(urn));
}

var outputProperty = new PropertyValue(new OutputReference(
Expand Down
58 changes: 38 additions & 20 deletions sdk/Pulumi/Provider/Provider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ namespace Pulumi.Experimental.Provider
{
public sealed class CheckRequest
{
public readonly string Urn;
public readonly Urn Urn;

// Note the Go SDK directly exposes resource.URN and so providers can work with it directly. I've
// decided _not_ to copy that to the dotnet SDK on the basis that long term I'd like URNs to be opaque
// tokens to everything but the engine. If CheckRequests need the resource type and name they should
Expand All @@ -36,7 +37,10 @@ public sealed class CheckRequest
public readonly ImmutableDictionary<string, PropertyValue> NewInputs;
public readonly ImmutableArray<byte> RandomSeed;

public CheckRequest(string urn, ImmutableDictionary<string, PropertyValue> oldInputs, ImmutableDictionary<string, PropertyValue> newInputs, ImmutableArray<byte> randomSeed)
public CheckRequest(Urn urn,
ImmutableDictionary<string, PropertyValue> oldInputs,
ImmutableDictionary<string, PropertyValue> newInputs,
ImmutableArray<byte> randomSeed)
{
Urn = urn;
OldInputs = oldInputs;
Expand Down Expand Up @@ -66,15 +70,19 @@ public sealed class CheckResponse

public sealed class DiffRequest
{
public readonly string Urn;
public readonly Urn Urn;
public string Type => Pulumi.Urn.Type(Urn);
public string Name => Pulumi.Urn.Name(Urn);
public readonly string Id;
public readonly ImmutableDictionary<string, PropertyValue> OldState;
public readonly ImmutableDictionary<string, PropertyValue> NewInputs;
public readonly ImmutableArray<string> IgnoreChanges;

public DiffRequest(string urn, string id, ImmutableDictionary<string, PropertyValue> oldState, ImmutableDictionary<string, PropertyValue> newInputs, ImmutableArray<string> ignoreChanges)
public DiffRequest(Urn urn,
string id,
ImmutableDictionary<string, PropertyValue> oldState,
ImmutableDictionary<string, PropertyValue> newInputs,
ImmutableArray<string> ignoreChanges)
{
Urn = urn;
Id = id;
Expand Down Expand Up @@ -174,14 +182,14 @@ public sealed class ConfigureResponse

public sealed class CreateRequest
{
public readonly string Urn;
public readonly Urn Urn;
public string Type => Pulumi.Urn.Type(Urn);
public string Name => Pulumi.Urn.Name(Urn);
public readonly ImmutableDictionary<string, PropertyValue> Properties;
public readonly TimeSpan Timeout;
public readonly bool Preview;

public CreateRequest(string urn, ImmutableDictionary<string, PropertyValue> properties, TimeSpan timeout, bool preview)
public CreateRequest(Urn urn, ImmutableDictionary<string, PropertyValue> properties, TimeSpan timeout, bool preview)
{
Urn = urn;
Properties = properties;
Expand All @@ -198,14 +206,14 @@ public sealed class CreateResponse

public sealed class ReadRequest
{
public readonly string Urn;
public readonly Urn Urn;
public readonly string Id;
public string Type => Pulumi.Urn.Type(Urn);
public string Name => Pulumi.Urn.Name(Urn);
public readonly ImmutableDictionary<string, PropertyValue> Properties;
public readonly ImmutableDictionary<string, PropertyValue> Inputs;

public ReadRequest(string urn, string id, ImmutableDictionary<string, PropertyValue> properties, ImmutableDictionary<string, PropertyValue> inputs)
public ReadRequest(Urn urn, string id, ImmutableDictionary<string, PropertyValue> properties, ImmutableDictionary<string, PropertyValue> inputs)
{
Urn = urn;
Id = id;
Expand All @@ -223,7 +231,7 @@ public sealed class ReadResponse

public sealed class UpdateRequest
{
public readonly string Urn;
public readonly Urn Urn;
public readonly string Id;
public string Type => Pulumi.Urn.Type(Urn);
public string Name => Pulumi.Urn.Name(Urn);
Expand All @@ -233,7 +241,13 @@ public sealed class UpdateRequest
public readonly ImmutableArray<string> IgnoreChanges;
public readonly bool Preview;

public UpdateRequest(string urn, string id, ImmutableDictionary<string, PropertyValue> olds, ImmutableDictionary<string, PropertyValue> news, TimeSpan timeout, ImmutableArray<string> ignoreChanges, bool preview)
public UpdateRequest(Urn urn,
string id,
ImmutableDictionary<string, PropertyValue> olds,
ImmutableDictionary<string, PropertyValue> news,
TimeSpan timeout,
ImmutableArray<string> ignoreChanges,
bool preview)
{
Urn = urn;
Id = id;
Expand All @@ -252,14 +266,14 @@ public sealed class UpdateResponse

public sealed class DeleteRequest
{
public readonly string Urn;
public readonly Urn Urn;
public readonly string Id;
public string Type => Pulumi.Urn.Type(Urn);
public string Name => Pulumi.Urn.Name(Urn);
public readonly ImmutableDictionary<string, PropertyValue> Properties;
public readonly TimeSpan Timeout;

public DeleteRequest(string urn, string id, ImmutableDictionary<string, PropertyValue> properties, TimeSpan timeout)
public DeleteRequest(Urn urn, string id, ImmutableDictionary<string, PropertyValue> properties, TimeSpan timeout)
{
Urn = urn;
Id = id;
Expand Down Expand Up @@ -530,7 +544,7 @@ private ImmutableDictionary<string, PropertyValue> Marshal(Struct? properties)
{
try
{
var domRequest = new CheckRequest(request.Urn, Marshal(request.Olds), Marshal(request.News), ImmutableArray.ToImmutableArray(request.RandomSeed));
var domRequest = new CheckRequest(new Urn(request.Urn), Marshal(request.Olds), Marshal(request.News), ImmutableArray.ToImmutableArray(request.RandomSeed));
using var cts = GetToken(context);
var domResponse = await Implementation.CheckConfig(domRequest, cts.Token);
var grpcResponse = new Pulumirpc.CheckResponse();
Expand Down Expand Up @@ -565,7 +579,7 @@ private ImmutableDictionary<string, PropertyValue> Marshal(Struct? properties)
{
try
{
var domRequest = new DiffRequest(request.Urn, request.Id, Marshal(request.Olds), Marshal(request.News), request.IgnoreChanges.ToImmutableArray());
var domRequest = new DiffRequest(new Urn(request.Urn), request.Id, Marshal(request.Olds), Marshal(request.News), request.IgnoreChanges.ToImmutableArray());
using var cts = GetToken(context);
var domResponse = await Implementation.DiffConfig(domRequest, cts.Token);
var grpcResponse = new Pulumirpc.DiffResponse();
Expand Down Expand Up @@ -728,7 +742,7 @@ private ImmutableDictionary<string, PropertyValue> Marshal(Struct? properties)
{
try
{
var domRequest = new CreateRequest(request.Urn, Marshal(request.Properties), TimeSpan.FromSeconds(request.Timeout), request.Preview);
var domRequest = new CreateRequest(new Urn(request.Urn), Marshal(request.Properties), TimeSpan.FromSeconds(request.Timeout), request.Preview);
using var cts = GetToken(context);
var domResponse = await Implementation.Create(domRequest, cts.Token);
var grpcResponse = new Pulumirpc.CreateResponse();
Expand All @@ -754,7 +768,7 @@ private ImmutableDictionary<string, PropertyValue> Marshal(Struct? properties)
{
try
{
var domRequest = new ReadRequest(request.Urn, request.Id, Marshal(request.Properties), Marshal(request.Inputs));
var domRequest = new ReadRequest(new Urn(request.Urn), request.Id, Marshal(request.Properties), Marshal(request.Inputs));
using var cts = GetToken(context);
var domResponse = await Implementation.Read(domRequest, cts.Token);
var grpcResponse = new Pulumirpc.ReadResponse();
Expand All @@ -781,7 +795,8 @@ private ImmutableDictionary<string, PropertyValue> Marshal(Struct? properties)
{
try
{
var domRequest = new CheckRequest(request.Urn, Marshal(request.Olds), Marshal(request.News), ImmutableArray.ToImmutableArray(request.RandomSeed));
var domRequest = new CheckRequest(new Urn(request.Urn), Marshal(request.Olds), Marshal(request.News),
request.RandomSeed.ToImmutableArray());
using var cts = GetToken(context);
var domResponse = await Implementation.Check(domRequest, cts.Token);
var grpcResponse = new Pulumirpc.CheckResponse();
Expand Down Expand Up @@ -816,7 +831,8 @@ private ImmutableDictionary<string, PropertyValue> Marshal(Struct? properties)
{
try
{
var domRequest = new DiffRequest(request.Urn, request.Id, Marshal(request.Olds), Marshal(request.News), request.IgnoreChanges.ToImmutableArray());
var domRequest = new DiffRequest(new Urn(request.Urn), request.Id, Marshal(request.Olds), Marshal(request.News),
request.IgnoreChanges.ToImmutableArray());
using var cts = GetToken(context);
var domResponse = await Implementation.Diff(domRequest, cts.Token);
var grpcResponse = new Pulumirpc.DiffResponse();
Expand Down Expand Up @@ -868,7 +884,9 @@ private ImmutableDictionary<string, PropertyValue> Marshal(Struct? properties)
{
try
{
var domRequest = new UpdateRequest(request.Urn, request.Id, Marshal(request.Olds), Marshal(request.News), TimeSpan.FromSeconds(request.Timeout), request.IgnoreChanges.ToImmutableArray(), request.Preview);
var domRequest = new UpdateRequest(new Urn(request.Urn), request.Id, Marshal(request.Olds), Marshal(request.News),
TimeSpan.FromSeconds(request.Timeout),
request.IgnoreChanges.ToImmutableArray(), request.Preview);
using var cts = GetToken(context);
var domResponse = await Implementation.Update(domRequest, cts.Token);
var grpcResponse = new Pulumirpc.UpdateResponse();
Expand All @@ -893,7 +911,7 @@ public override async Task<Empty> Delete(Pulumirpc.DeleteRequest request, Server
{
try
{
var domRequest = new DeleteRequest(request.Urn, request.Id, Marshal(request.Properties), TimeSpan.FromSeconds(request.Timeout));
var domRequest = new DeleteRequest(new Urn(request.Urn), request.Id, Marshal(request.Properties), TimeSpan.FromSeconds(request.Timeout));
using var cts = GetToken(context);
await Implementation.Delete(domRequest, cts.Token);
return new Empty();
Expand Down
11 changes: 11 additions & 0 deletions sdk/Pulumi/Provider/Urn.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using System;

namespace Pulumi.Experimental.Provider;

public record struct Urn(string Value)
{
public static implicit operator string(Urn value)
{
return value.Value;
}
}

0 comments on commit 86acdc0

Please sign in to comment.