diff --git a/.changes/unreleased/Improvements-225.yaml b/.changes/unreleased/Improvements-225.yaml new file mode 100644 index 00000000..7bdfbbf9 --- /dev/null +++ b/.changes/unreleased/Improvements-225.yaml @@ -0,0 +1,6 @@ +component: sdk +kind: Improvements +body: Add support for pulumi config env ls +time: 2024-01-23T15:08:21.991404636-08:00 +custom: + PR: "225" diff --git a/sdk/Pulumi.Automation.Tests/LocalWorkspaceTests.cs b/sdk/Pulumi.Automation.Tests/LocalWorkspaceTests.cs index bb38589e..5c160bcb 100644 --- a/sdk/Pulumi.Automation.Tests/LocalWorkspaceTests.cs +++ b/sdk/Pulumi.Automation.Tests/LocalWorkspaceTests.cs @@ -22,7 +22,6 @@ using ILogger = Microsoft.Extensions.Logging.ILogger; using static Pulumi.Automation.Tests.Utility; -using Xunit.Sdk; namespace Pulumi.Automation.Tests { @@ -159,16 +158,23 @@ public async Task AddAndRemoveEnvironment() var program = PulumiFn.Create(); var stackName = FullyQualifiedStackName(_pulumiOrg, projectName, $"int_test{GetTestSuffix()}"); await workspace.CreateStackAsync(stackName); + var stack = await WorkspaceStack.SelectAsync(stackName, workspace); - await Assert.ThrowsAsync(() => workspace.AddEnvironmentsAsync(stackName, new[] { "non-existent-env" })); + await Assert.ThrowsAsync(() => stack.AddEnvironmentsAsync(new[] { "non-existent-env" })); - await workspace.AddEnvironmentsAsync(stackName, new[] { "automation-api-test-env", "automation-api-test-env-2" }); + await stack.AddEnvironmentsAsync(new[] { "automation-api-test-env", "automation-api-test-env-2" }); + + var environments = await stack.ListEnvironmentsAsync(); + Assert.Equal(new string[] { "automation-api-test-env", "automation-api-test-env-2" }, environments); var config = await workspace.GetAllConfigAsync(stackName); Assert.Equal("test_value", config["node_env_test:new_key"].Value); Assert.Equal("business", config["node_env_test:also"].Value); - await workspace.RemoveEnvironmentAsync(stackName, "automation-api-test-env"); + await stack.RemoveEnvironmentAsync("automation-api-test-env"); + environments = await stack.ListEnvironmentsAsync(); + Assert.Equal(new string[] { "automation-api-test-env-2" }, environments); + config = await workspace.GetAllConfigAsync(stackName); Assert.Equal("business", config["node_env_test:also"].Value); Assert.False(config.ContainsKey("node_env_test:new_key")); diff --git a/sdk/Pulumi.Automation/LocalWorkspace.cs b/sdk/Pulumi.Automation/LocalWorkspace.cs index c5204217..fcbfc004 100644 --- a/sdk/Pulumi.Automation/LocalWorkspace.cs +++ b/sdk/Pulumi.Automation/LocalWorkspace.cs @@ -550,6 +550,14 @@ public override async Task AddEnvironmentsAsync(string stackName, IEnumerable + public override async Task> ListEnvironmentsAsync(string stackName, CancellationToken cancellationToken = default) + { + CheckSupportsEnvironmentsListCommand(); + var result = await this.RunCommandAsync(new[] { "config", "env", "ls", "--stack", stackName, "--json" }, cancellationToken).ConfigureAwait(false); + return this._serializer.DeserializeJson(result.StandardOutput).ToImmutableList(); + } + /// public override async Task RemoveEnvironmentAsync(string stackName, string environment, CancellationToken cancellationToken = default) { @@ -991,5 +999,16 @@ private void CheckSupportsEnvironmentsCommands() throw new InvalidOperationException("The Pulumi CLI version does not support env operations on a stack. Please update the Pulumi CLI."); } } + + private void CheckSupportsEnvironmentsListCommand() + { + var version = this._pulumiVersion ?? new SemVersion(3, 0); + + // 3.99 added this command (https://github.com/pulumi/pulumi/releases/tag/v3.99.0) + if (version < new SemVersion(3, 99)) + { + throw new InvalidOperationException("The Pulumi CLI version does not support env ls operations on a stack. Please update the Pulumi CLI."); + } + } } } diff --git a/sdk/Pulumi.Automation/Pulumi.Automation.xml b/sdk/Pulumi.Automation/Pulumi.Automation.xml index 9bdee7c5..261c2655 100644 --- a/sdk/Pulumi.Automation/Pulumi.Automation.xml +++ b/sdk/Pulumi.Automation/Pulumi.Automation.xml @@ -569,6 +569,9 @@ + + + @@ -1458,6 +1461,13 @@ List of environments to add to the end of the stack's import list. A cancellation token. + + + Returns the list of environments associated with the specified stack name + + The name of the stack. + A cancellation token. + Removes environments from a stack's import list. diff --git a/sdk/Pulumi.Automation/Workspace.cs b/sdk/Pulumi.Automation/Workspace.cs index 561a17a1..f8308050 100644 --- a/sdk/Pulumi.Automation/Workspace.cs +++ b/sdk/Pulumi.Automation/Workspace.cs @@ -133,6 +133,12 @@ internal Workspace(IPulumiCmd cmd) /// A cancellation token. public abstract Task AddEnvironmentsAsync(string stackName, IEnumerable environments, CancellationToken cancellationToken = default); + /// + /// Returns the list of environments associated with the specified stack name + /// + /// The name of the stack. + /// A cancellation token. + public abstract Task> ListEnvironmentsAsync(string stackName, CancellationToken cancellationToken = default); /// /// Removes environments from a stack's import list. diff --git a/sdk/Pulumi.Automation/WorkspaceStack.cs b/sdk/Pulumi.Automation/WorkspaceStack.cs index 764d37e5..cb8f32ec 100644 --- a/sdk/Pulumi.Automation/WorkspaceStack.cs +++ b/sdk/Pulumi.Automation/WorkspaceStack.cs @@ -285,6 +285,9 @@ public Task> RefreshConfigAsync(Cancell public Task AddEnvironmentsAsync(IEnumerable environments, CancellationToken cancellationToken = default) => this.Workspace.AddEnvironmentsAsync(this.Name, environments, cancellationToken); + public Task> ListEnvironmentsAsync(CancellationToken cancellationToken = default) + => this.Workspace.ListEnvironmentsAsync(this.Name, cancellationToken); + /// /// Removes environments from a stack's import list. /// diff --git a/sdk/Pulumi/Pulumi.xml b/sdk/Pulumi/Pulumi.xml index 657e9bde..955f1ba7 100644 --- a/sdk/Pulumi/Pulumi.xml +++ b/sdk/Pulumi/Pulumi.xml @@ -3650,7 +3650,7 @@ An object implementing the server-side handling logic. - Register service method with a service binder with or without implementation. Useful when customizing the service binding logic. + Register service method with a service binder with or without implementation. Useful when customizing the service binding logic. Note: this method is part of an experimental API that can change or be removed without any prior notice. Service methods will be bound by calling AddMethod on this object. An object implementing the server-side handling logic. @@ -4039,7 +4039,7 @@ An object implementing the server-side handling logic. - Register service method with a service binder with or without implementation. Useful when customizing the service binding logic. + Register service method with a service binder with or without implementation. Useful when customizing the service binding logic. Note: this method is part of an experimental API that can change or be removed without any prior notice. Service methods will be bound by calling AddMethod on this object. An object implementing the server-side handling logic. @@ -4323,7 +4323,7 @@ An object implementing the server-side handling logic. - Register service method with a service binder with or without implementation. Useful when customizing the service binding logic. + Register service method with a service binder with or without implementation. Useful when customizing the service binding logic. Note: this method is part of an experimental API that can change or be removed without any prior notice. Service methods will be bound by calling AddMethod on this object. An object implementing the server-side handling logic. @@ -5319,7 +5319,7 @@ An object implementing the server-side handling logic. - Register service method with a service binder with or without implementation. Useful when customizing the service binding logic. + Register service method with a service binder with or without implementation. Useful when customizing the service binding logic. Note: this method is part of an experimental API that can change or be removed without any prior notice. Service methods will be bound by calling AddMethod on this object. An object implementing the server-side handling logic. @@ -7548,7 +7548,7 @@ An object implementing the server-side handling logic. - Register service method with a service binder with or without implementation. Useful when customizing the service binding logic. + Register service method with a service binder with or without implementation. Useful when customizing the service binding logic. Note: this method is part of an experimental API that can change or be removed without any prior notice. Service methods will be bound by calling AddMethod on this object. An object implementing the server-side handling logic. @@ -8207,7 +8207,7 @@ An object implementing the server-side handling logic. - Register service method with a service binder with or without implementation. Useful when customizing the service binding logic. + Register service method with a service binder with or without implementation. Useful when customizing the service binding logic. Note: this method is part of an experimental API that can change or be removed without any prior notice. Service methods will be bound by calling AddMethod on this object. An object implementing the server-side handling logic. @@ -8467,7 +8467,7 @@ An object implementing the server-side handling logic. - Register service method with a service binder with or without implementation. Useful when customizing the service binding logic. + Register service method with a service binder with or without implementation. Useful when customizing the service binding logic. Note: this method is part of an experimental API that can change or be removed without any prior notice. Service methods will be bound by calling AddMethod on this object. An object implementing the server-side handling logic. @@ -8594,7 +8594,7 @@ An object implementing the server-side handling logic. - Register service method with a service binder with or without implementation. Useful when customizing the service binding logic. + Register service method with a service binder with or without implementation. Useful when customizing the service binding logic. Note: this method is part of an experimental API that can change or be removed without any prior notice. Service methods will be bound by calling AddMethod on this object. An object implementing the server-side handling logic. @@ -8723,7 +8723,7 @@ An object implementing the server-side handling logic. - Register service method with a service binder with or without implementation. Useful when customizing the service binding logic. + Register service method with a service binder with or without implementation. Useful when customizing the service binding logic. Note: this method is part of an experimental API that can change or be removed without any prior notice. Service methods will be bound by calling AddMethod on this object. An object implementing the server-side handling logic.