From 710f385447d62a8029b908fc10e9583822426f5b Mon Sep 17 00:00:00 2001 From: Mikhail Shilkov Date: Tue, 12 Jan 2021 15:54:08 +0100 Subject: [PATCH] [dotnet] Unsecret and IsSecret implementation for .NET (#6092) --- CHANGELOG.md | 8 +++ sdk/dotnet/Pulumi.Tests/Core/OutputTests.cs | 57 +++++++++++++++++++++ sdk/dotnet/Pulumi/Core/Output.cs | 16 ++++++ sdk/dotnet/Pulumi/PublicAPI.Shipped.txt | 2 + 4 files changed, 83 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c9013fc9b..8554071eb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,14 @@ CHANGELOG - [sdk/dotnet] Moved urn value retrieval into if statement for MockMonitor [#6081](https://github.com/pulumi/pulumi/pull/6081) +- [sdk/dotnet] Added `Pulumi.Output.Unsecret` which will take an existing secret output and + create a non-secret variant with an unwrapped secret value. + [#6092](https://github.com/pulumi/pulumi/pull/6092) + +- [sdk/dotnet] Added `Pulumi.Output.IsSecretAsync` which will take an existing output and + determine if an output has a secret within the output. + [#6092](https://github.com/pulumi/pulumi/pull/6092) + ## 2.17.0 (2021-01-06) - Respect the `version` resource option for provider resources. diff --git a/sdk/dotnet/Pulumi.Tests/Core/OutputTests.cs b/sdk/dotnet/Pulumi.Tests/Core/OutputTests.cs index 082a50f3e..5e913b926 100644 --- a/sdk/dotnet/Pulumi.Tests/Core/OutputTests.cs +++ b/sdk/dotnet/Pulumi.Tests/Core/OutputTests.cs @@ -293,6 +293,63 @@ namespace Pulumi.Tests.Core var data = await o.DataTask.ConfigureAwait(false); Assert.Equal(new[] { 1, 2 }, data.Value); }); + + [Fact] + public Task IsSecretAsyncOnKnownOutput() + => RunInPreview(async () => + { + var o1 = CreateOutput(0, isKnown: true, isSecret: true); + var o2 = CreateOutput(1, isKnown: true, isSecret: false); + var isSecret1 = await Output.IsSecretAsync(o1).ConfigureAwait(false); + var isSecret2 = await Output.IsSecretAsync(o2).ConfigureAwait(false); + Assert.True(isSecret1); + Assert.False(isSecret2); + }); + + [Fact] + public Task IsSecretAsyncOnAwaitableOutput() + => RunInPreview(async () => + { + var o1 = CreateOutput(0, isKnown: true, isSecret: true).Apply(a => Task.FromResult("inner1")); + var o2 = CreateOutput(1, isKnown: true, isSecret: false).Apply(a => Task.FromResult("inner2")); + var isSecret1 = await Output.IsSecretAsync(o1).ConfigureAwait(false); + var isSecret2 = await Output.IsSecretAsync(o2).ConfigureAwait(false); + Assert.True(isSecret1); + Assert.False(isSecret2); + }); + + [Fact] + public Task UnsecretOnKnownSecretValue() + => RunInPreview(async () => + { + var secret = CreateOutput(1, isKnown: true, isSecret: true); + var notSecret = Output.Unsecret(secret); + var notSecretData = await notSecret.DataTask.ConfigureAwait(false); + Assert.False(notSecretData.IsSecret); + Assert.Equal(1, notSecretData.Value); + }); + + [Fact] + public Task UnsecretOnAwaitableSecretValue() + => RunInPreview(async () => + { + var secret = CreateOutput(0, isKnown: true, isSecret: true).Apply(a => Task.FromResult("inner")); + var notSecret = Output.Unsecret(secret); + var notSecretData = await notSecret.DataTask.ConfigureAwait(false); + Assert.False(notSecretData.IsSecret); + Assert.Equal("inner", notSecretData.Value); + }); + + [Fact] + public Task UnsecretOnNonSecretValue() + => RunInPreview(async () => + { + var secret = CreateOutput(2, isKnown: true, isSecret: false); + var notSecret = Output.Unsecret(secret); + var notSecretData = await notSecret.DataTask.ConfigureAwait(false); + Assert.False(notSecretData.IsSecret); + Assert.Equal(2, notSecretData.Value); + }); } public class NormalTests diff --git a/sdk/dotnet/Pulumi/Core/Output.cs b/sdk/dotnet/Pulumi/Core/Output.cs index 261043a64..448842237 100644 --- a/sdk/dotnet/Pulumi/Core/Output.cs +++ b/sdk/dotnet/Pulumi/Core/Output.cs @@ -27,6 +27,22 @@ namespace Pulumi public static Output CreateSecret(Task value) => Output.CreateSecret(value); + /// + /// Returns a new which is a copy of the existing output but marked as + /// a non-secret. The original output is not modified in any way. + /// + public static Output Unsecret(Output output) + => output.WithIsSecret(Task.FromResult(false)); + + /// + /// Retrieves the secretness status of the given output. + /// + public static async Task IsSecretAsync(Output output) + { + var dataTask = await output.DataTask.ConfigureAwait(false); + return dataTask.IsSecret; + } + /// /// Combines all the values in /// into a single with an diff --git a/sdk/dotnet/Pulumi/PublicAPI.Shipped.txt b/sdk/dotnet/Pulumi/PublicAPI.Shipped.txt index 0386c35e0..0e3d72872 100644 --- a/sdk/dotnet/Pulumi/PublicAPI.Shipped.txt +++ b/sdk/dotnet/Pulumi/PublicAPI.Shipped.txt @@ -302,6 +302,7 @@ static Pulumi.Output.Create(T value) -> Pulumi.Output static Pulumi.Output.CreateSecret(System.Threading.Tasks.Task value) -> Pulumi.Output static Pulumi.Output.CreateSecret(T value) -> Pulumi.Output static Pulumi.Output.Format(System.FormattableString formattableString) -> Pulumi.Output +static Pulumi.Output.IsSecretAsync(Pulumi.Output output) -> System.Threading.Tasks.Task static Pulumi.Output.Tuple(Pulumi.Input item1, Pulumi.Input item2, Pulumi.Input item3, Pulumi.Input item4, Pulumi.Input item5, Pulumi.Input item6, Pulumi.Input item7, Pulumi.Input item8) -> Pulumi.Output<(T1, T2, T3, T4, T5, T6, T7, T8)> static Pulumi.Output.Tuple(Pulumi.Output item1, Pulumi.Output item2, Pulumi.Output item3, Pulumi.Output item4, Pulumi.Output item5, Pulumi.Output item6, Pulumi.Output item7, Pulumi.Output item8) -> Pulumi.Output<(T1, T2, T3, T4, T5, T6, T7, T8)> static Pulumi.Output.Tuple(Pulumi.Input item1, Pulumi.Input item2, Pulumi.Input item3, Pulumi.Input item4, Pulumi.Input item5, Pulumi.Input item6, Pulumi.Input item7) -> Pulumi.Output<(T1, T2, T3, T4, T5, T6, T7)> @@ -316,6 +317,7 @@ static Pulumi.Output.Tuple(Pulumi.Input item1, Pulumi.Input static Pulumi.Output.Tuple(Pulumi.Output item1, Pulumi.Output item2, Pulumi.Output item3) -> Pulumi.Output<(T1, T2, T3)> static Pulumi.Output.Tuple(Pulumi.Input item1, Pulumi.Input item2) -> Pulumi.Output<(T1, T2)> static Pulumi.Output.Tuple(Pulumi.Output item1, Pulumi.Output item2) -> Pulumi.Output<(T1, T2)> +static Pulumi.Output.Unsecret(Pulumi.Output output) -> Pulumi.Output static Pulumi.Output.Create(System.Threading.Tasks.Task value) -> Pulumi.Output static Pulumi.OutputExtensions.AsT0(this Pulumi.Output> output) -> Pulumi.Output static Pulumi.OutputExtensions.AsT1(this Pulumi.Output> output) -> Pulumi.Output