Skip to content

Commit

Permalink
Add environment add and remove commands to automation api (#210)
Browse files Browse the repository at this point in the history
* Add environment add and remove commands to automation api

* Add changelog

* fix lint errors

* Update sdk/Pulumi.Automation.Tests/MoolumiFactAttribute.cs

Co-authored-by: Justin Van Patten <[email protected]>

---------

Co-authored-by: Justin Van Patten <[email protected]>
  • Loading branch information
cleverguy25 and justinvp authored Dec 15, 2023
1 parent e2b02a3 commit f1feb51
Show file tree
Hide file tree
Showing 8 changed files with 659 additions and 0 deletions.
6 changes: 6 additions & 0 deletions .changes/unreleased/Improvements-210.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
component: sdk
kind: Improvements
body: Add environment add and remove commands to automation api
time: 2023-12-13T17:49:09.172346903-08:00
custom:
PR: "210"
30 changes: 30 additions & 0 deletions sdk/Pulumi.Automation.Tests/LocalWorkspaceTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
using ILogger = Microsoft.Extensions.Logging.ILogger;

using static Pulumi.Automation.Tests.Utility;
using Xunit.Sdk;

namespace Pulumi.Automation.Tests
{
Expand Down Expand Up @@ -145,6 +146,35 @@ public async Task AddRemoveListPlugins()
Assert.DoesNotContain(plugins, p => p.Name == plugin && p.Version == version);
}

[MoolumiFact]
public async Task AddAndRemoveEnvironment()
{
var projectName = "node_env_test";
var projectSettings = new ProjectSettings(projectName, ProjectRuntimeName.NodeJS);
using var workspace = await LocalWorkspace.CreateAsync(new LocalWorkspaceOptions
{
ProjectSettings = projectSettings,
});

var program = PulumiFn.Create<ValidStack>();
var stackName = FullyQualifiedStackName(_pulumiOrg, projectName, $"int_test{GetTestSuffix()}");
await workspace.CreateStackAsync(stackName);

await Assert.ThrowsAsync<CommandException>(() => workspace.AddEnvironmentsAsync(stackName, new[] { "non-existent-env" }));

await workspace.AddEnvironmentsAsync(stackName, new[] { "automation-api-test-env", "automation-api-test-env-2" });
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");
config = await workspace.GetAllConfigAsync(stackName);
Assert.Equal("business", config["node_env_test:also"].Value);
Assert.False(config.ContainsKey("node_env_test:new_key"));
await workspace.RemoveStackAsync(stackName);
}

[Fact]
public async Task CreateSelectRemoveStack()
{
Expand Down
23 changes: 23 additions & 0 deletions sdk/Pulumi.Automation.Tests/MoolumiFactAttribute.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright 2016-2023, Pulumi Corporation

using System;
using Xunit;
using static Pulumi.Automation.Tests.Utility;

namespace Pulumi.Automation.Tests
{
/// <summary>
/// Skip a test if test org is not moolumi.
/// </summary>
public sealed class MoolumiFactAttribute : FactAttribute
{
public MoolumiFactAttribute()
{
var testOrg = GetTestOrg();
if (testOrg != "moolumi")
{
Skip = "Test org is not moolumi";
}
}
}
}
28 changes: 28 additions & 0 deletions sdk/Pulumi.Automation/LocalWorkspace.cs
Original file line number Diff line number Diff line change
Expand Up @@ -540,6 +540,23 @@ public override Task<ImmutableList<string>> SerializeArgsForOpAsync(string stack
public override Task PostCommandCallbackAsync(string stackName, CancellationToken cancellationToken = default)
=> Task.CompletedTask;


/// <inheritdoc/>
public override async Task AddEnvironmentsAsync(string stackName, IEnumerable<string> environments, CancellationToken cancellationToken = default)
{
CheckSupportsEnvironmentsCommands();
var args = new List<string> { "config", "env", "add", "--stack", stackName, "--yes" };
args.AddRange(environments);
await this.RunCommandAsync(args, cancellationToken).ConfigureAwait(false);
}

/// <inheritdoc/>
public override async Task RemoveEnvironmentAsync(string stackName, string environment, CancellationToken cancellationToken = default)
{
CheckSupportsEnvironmentsCommands();
await this.RunCommandAsync(new[] { "config", "env", "rm", environment, "--stack", stackName, "--yes" }, cancellationToken).ConfigureAwait(false);
}

/// <inheritdoc/>
public override async Task<string> GetTagAsync(string stackName, string key, CancellationToken cancellationToken = default)
{
Expand Down Expand Up @@ -963,5 +980,16 @@ internal IReadOnlyList<string> GetRemoteArgs()

return args;
}

private void CheckSupportsEnvironmentsCommands()
{
var version = this._pulumiVersion ?? new SemVersion(3, 0);

// 3.95 added this command (https://github.com/pulumi/pulumi/releases/tag/v3.95.0)
if (version < new SemVersion(3, 95))
{
throw new InvalidOperationException("The Pulumi CLI version does not support env operations on a stack. Please update the Pulumi CLI.");
}
}
}
}
40 changes: 40 additions & 0 deletions sdk/Pulumi.Automation/Pulumi.Automation.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 19 additions & 0 deletions sdk/Pulumi.Automation/Workspace.cs
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,25 @@ internal Workspace(IPulumiCmd cmd)
/// <param name="cancellationToken">A cancellation token.</param>
public abstract Task PostCommandCallbackAsync(string stackName, CancellationToken cancellationToken = default);

/// <summary>
/// Adds environments to the end of a stack's import list. Imported environments are merged in order
/// per the ESC merge rules. The list of environments behaves as if it were the import list in an anonymous
/// environment.
/// </summary>
/// <param name="stackName">The name of the stack.</param>
/// <param name="environments">List of environments to add to the end of the stack's import list.</param>
/// <param name="cancellationToken">A cancellation token.</param>
public abstract Task AddEnvironmentsAsync(string stackName, IEnumerable<string> environments, CancellationToken cancellationToken = default);


/// <summary>
/// Removes environments from a stack's import list.
/// </summary>
/// <param name="stackName">The name of the stack.</param>
/// <param name="environment">The name of the environment to remove from the stack's configuration.</param>
/// <param name="cancellationToken">A cancellation token.</param>
public abstract Task RemoveEnvironmentAsync(string stackName, string environment, CancellationToken cancellationToken = default);

/// <summary>
/// Returns the value associated with the specified stack name and key,
/// scoped to the Workspace.
Expand Down
19 changes: 19 additions & 0 deletions sdk/Pulumi.Automation/WorkspaceStack.cs
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,25 @@ public Task RemoveAllConfigAsync(IEnumerable<string> keys, bool path, Cancellati
public Task<ImmutableDictionary<string, ConfigValue>> RefreshConfigAsync(CancellationToken cancellationToken = default)
=> this.Workspace.RefreshConfigAsync(this.Name, cancellationToken);


/// <summary>
/// Adds environments to the end of a stack's import list. Imported environments are merged in order
/// per the ESC merge rules. The list of environments behaves as if it were the import list in an anonymous
/// environment.
/// </summary>
/// <param name="environments">List of environments to add to the end of the stack's import list.</param>
/// <param name="cancellationToken">A cancellation token.</param>
public Task AddEnvironmentsAsync(IEnumerable<string> environments, CancellationToken cancellationToken = default)
=> this.Workspace.AddEnvironmentsAsync(this.Name, environments, cancellationToken);

/// <summary>
/// Removes environments from a stack's import list.
/// </summary>
/// <param name="environment">The name of the environment to remove from the stack's configuration.</param>
/// <param name="cancellationToken">A cancellation token.</param>
public Task RemoveEnvironmentAsync(string environment, CancellationToken cancellationToken = default)
=> this.Workspace.RemoveEnvironmentAsync(this.Name, environment, cancellationToken);

/// <summary>
/// Creates or updates the resources in a stack by executing the program in the Workspace.
/// <para/>
Expand Down
Loading

0 comments on commit f1feb51

Please sign in to comment.