Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add option to generate docker compose file with enviroment variables instead of secrets #254

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 36 additions & 28 deletions docs/Writerside/topics/Generate-Command.md

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
namespace Aspirate.Commands.Actions.Secrets;

public sealed class PopulateInputsAction(
IPasswordGenerator passwordGenerator,
IServiceProvider serviceProvider,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
namespace Aspirate.Commands.Actions.Secrets;

public sealed class PopulateInputsWithEnvVariablesAction(IServiceProvider serviceProvider) : BaseAction(serviceProvider)
{
public override Task<bool> ExecuteAsync()
{
Logger.WriteRuler("[purple]Generating enviroment variable placeholders for inputs[/]");

var parameterResources = CurrentState.LoadedAspireManifestResources.Where(x => x.Value is ParameterResource).ToArray();

if (parameterResources.Length == 0)
{
return Task.FromResult(true);
}

foreach (var parameter in parameterResources)
{
if (parameter.Value is ParameterResource resource)
{
resource.Value = $"${{{resource.Name.Replace('-', '_').ToUpperInvariant()}}}";
}
}

Logger.MarkupLine($"[green]({EmojiLiterals.CheckMark}) Done: [/] Input values have all been assigned enviroment variables.");

return Task.FromResult(true);
}
}
7 changes: 4 additions & 3 deletions src/Aspirate.Commands/Commands/BaseCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,10 @@ private async Task<int> ConstructCommand(TOptions options, IServiceCollection se
await stateService.RestoreState(stateOptions);

handler.CurrentState.PopulateStateFromOptions(options);

LoadSecrets(options, secretService, handler);

if (options.RequiresSecrets)
{
LoadSecrets(options, secretService, handler);
}
var exitCode = await handler.HandleAsync(options);

await stateService.SaveState(stateOptions);
Expand Down
1 change: 1 addition & 0 deletions src/Aspirate.Commands/Commands/BaseCommandOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ public abstract class BaseCommandOptions : ICommandOptions
public bool? DisableState { get; set; }
public string? SecretPassword { get; set; }
public string? LaunchProfile { get; set; }
public virtual bool RequiresSecrets => true;
}
45 changes: 23 additions & 22 deletions src/Aspirate.Commands/Commands/Generate/GenerateCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,27 +6,28 @@ public sealed class GenerateCommand : BaseCommand<GenerateOptions, GenerateComma

public GenerateCommand() : base("generate", "Builds, pushes containers, generates aspire manifest, helm chart and kustomize manifests.")
{
AddOption(ProjectPathOption.Instance);
AddOption(AspireManifestOption.Instance);
AddOption(OutputPathOption.Instance);
AddOption(SkipBuildOption.Instance);
AddOption(SkipFinalKustomizeGenerationOption.Instance);
AddOption(ContainerBuilderOption.Instance);
AddOption(ContainerImageTagOption.Instance);
AddOption(ContainerRegistryOption.Instance);
AddOption(ContainerRepositoryPrefixOption.Instance);
AddOption(ImagePullPolicyOption.Instance);
AddOption(NamespaceOption.Instance);
AddOption(OutputFormatOption.Instance);
AddOption(RuntimeIdentifierOption.Instance);
AddOption(SecretPasswordOption.Instance);
AddOption(PrivateRegistryOption.Instance);
AddOption(PrivateRegistryUrlOption.Instance);
AddOption(PrivateRegistryUsernameOption.Instance);
AddOption(PrivateRegistryPasswordOption.Instance);
AddOption(PrivateRegistryEmailOption.Instance);
AddOption(IncludeDashboardOption.Instance);
AddOption(ComposeBuildsOption.Instance);
AddOption(ReplaceSecretsOption.Instance);
AddOption(ProjectPathOption.Instance);
AddOption(AspireManifestOption.Instance);
AddOption(OutputPathOption.Instance);
AddOption(SkipBuildOption.Instance);
AddOption(SkipFinalKustomizeGenerationOption.Instance);
AddOption(ContainerBuilderOption.Instance);
AddOption(ContainerImageTagOption.Instance);
AddOption(ContainerRegistryOption.Instance);
AddOption(ContainerRepositoryPrefixOption.Instance);
AddOption(ImagePullPolicyOption.Instance);
AddOption(NamespaceOption.Instance);
AddOption(OutputFormatOption.Instance);
AddOption(RuntimeIdentifierOption.Instance);
AddOption(SecretPasswordOption.Instance);
AddOption(PrivateRegistryOption.Instance);
AddOption(PrivateRegistryUrlOption.Instance);
AddOption(PrivateRegistryUsernameOption.Instance);
AddOption(PrivateRegistryPasswordOption.Instance);
AddOption(PrivateRegistryEmailOption.Instance);
AddOption(IncludeDashboardOption.Instance);
AddOption(ComposeBuildsOption.Instance);
AddOption(ReplaceSecretsOption.Instance);
AddOption(UseEnvVariablesAsParameterValuesOption.Instance);
}
}
33 changes: 24 additions & 9 deletions src/Aspirate.Commands/Commands/Generate/GenerateCommandHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,32 +12,47 @@ public override Task<int> HandleAsync(GenerateOptions options)
return outputFormat.Name switch
{
nameof(OutputFormat.Kustomize) => GenerateKustomizeManifests(),
nameof(OutputFormat.DockerCompose) => GenerateDockerComposeManifests(),
nameof(OutputFormat.DockerCompose) => GenerateDockerComposeManifests(options.UseEnvVariablesAsParameterValues ?? false),
nameof(OutputFormat.Helm) => GenerateHelmManifests(),
_ => throw new ArgumentOutOfRangeException(nameof(options.OutputFormat), $"The output format '{options.OutputFormat}' is not supported."),
};
}

private ActionExecutor BaseGenerateActionSequence() =>
ActionExecutor
private ActionExecutor BaseGenerateActionSequence(bool useEnvVariablesAsParameterValues = false)
{
var result = ActionExecutor
.QueueAction(nameof(LoadConfigurationAction))
.QueueAction(nameof(GenerateAspireManifestAction))
.QueueAction(nameof(LoadAspireManifestAction))
.QueueAction(nameof(IncludeAspireDashboardAction))
.QueueAction(nameof(PopulateInputsAction))
.QueueAction(nameof(IncludeAspireDashboardAction));
if (!useEnvVariablesAsParameterValues)
{
result.QueueAction(nameof(PopulateInputsAction));
}
else
{
result.QueueAction(nameof(PopulateInputsWithEnvVariablesAction));
}
result
.QueueAction(nameof(SubstituteValuesAspireManifestAction))
.QueueAction(nameof(ApplyDaprAnnotationsAction))
.QueueAction(nameof(PopulateContainerDetailsForProjectsAction))
.QueueAction(nameof(BuildAndPushContainersFromProjectsAction))
.QueueAction(nameof(BuildAndPushContainersFromDockerfilesAction))
.QueueAction(nameof(SaveSecretsAction));
.QueueAction(nameof(BuildAndPushContainersFromDockerfilesAction));
if (!useEnvVariablesAsParameterValues)
{
result.QueueAction(nameof(SaveSecretsAction));
}

return result;
}

private ActionExecutor BaseKubernetesActionSequence() =>
BaseGenerateActionSequence()
.QueueAction(nameof(AskImagePullPolicyAction));

private Task<int> GenerateDockerComposeManifests() =>
BaseGenerateActionSequence()
private Task<int> GenerateDockerComposeManifests(bool useEnvVariablesAsParameterValues) =>
BaseGenerateActionSequence(useEnvVariablesAsParameterValues)
.QueueAction(nameof(GenerateDockerComposeManifestAction))
.ExecuteCommandsAsync();

Expand Down
3 changes: 3 additions & 0 deletions src/Aspirate.Commands/Commands/Generate/GenerateOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,7 @@ public sealed class GenerateOptions : BaseCommandOptions,
public bool? WithPrivateRegistry { get; set; }
public bool? IncludeDashboard { get; set; }
public bool? ReplaceSecrets { get; set; }
public bool? UseEnvVariablesAsParameterValues { get; set; }

public override bool RequiresSecrets => (!UseEnvVariablesAsParameterValues) ?? true;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
namespace Aspirate.Commands.Options;

public sealed class UseEnvVariablesAsParameterValuesOption : BaseOption<bool>
{
private static readonly string[] _aliases = ["--use-env-variables-as-parameter-values"];

private UseEnvVariablesAsParameterValuesOption() : base(_aliases, "ASPIRATE_USE_ENV_VARIABLES", false)
{
Name = nameof(IGenerateOptions.UseEnvVariablesAsParameterValues);
Description = "Replace parameter references with enviroment variable names";
Arity = ArgumentArity.ZeroOrOne;
IsRequired = false;
}

public static UseEnvVariablesAsParameterValuesOption Instance { get; } = new();
}
3 changes: 2 additions & 1 deletion src/Aspirate.Commands/ServiceCollectionExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace Aspirate.Commands;
namespace Aspirate.Commands;

/// <summary>
/// Extension methods for IServiceCollection to register services for AspirateState and AspirateActions.
Expand Down Expand Up @@ -39,6 +39,7 @@ public static IServiceCollection AddAspirateActions(this IServiceCollection serv
.RegisterAction<SubstituteValuesAspireManifestAction>()
.RegisterAction<ApplyDaprAnnotationsAction>()
.RegisterAction<PopulateInputsAction>()
.RegisterAction<PopulateInputsWithEnvVariablesAction>()
.RegisterAction<SaveSecretsAction>()
.RegisterAction<AskPrivateRegistryCredentialsAction>()
.RegisterAction<IncludeAspireDashboardAction>()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public void ResolveJsonExpressions(JsonNode? jsonNode, JsonNode rootNode)
} while (_unresolvedExpressionPointers.Count > 0);
}

[GeneratedRegex(@"\{([\w\.-]+)\}")]
[GeneratedRegex(@"(\$|)\{([\w\.-]+)\}")]
private static partial Regex PlaceholderPatternRegex();

public static IJsonExpressionProcessor CreateDefaultExpressionProcessor() =>
Expand Down Expand Up @@ -103,7 +103,12 @@ private void ReplaceWithResolvedExpression(JsonNode rootNode, JsonNode jsonValue
for (var i = 0; i < matches.Count; i++)
{
var match = matches[i];
var jsonPath = match.Groups[1].Value;
if (!string.IsNullOrEmpty(match.Groups[1].Value))
{
continue;
}

var jsonPath = match.Groups[2].Value;
var pathParts = jsonPath.Split('.');
if (pathParts.Length == 1)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ public interface IGenerateOptions
bool? SkipFinalKustomizeGeneration { get; set; }
string? ImagePullPolicy { get; set; }
string? OutputFormat { get; set; }
bool? UseEnvVariablesAsParameterValues { get; set; }
}
11 changes: 7 additions & 4 deletions src/Aspirate.Shared/Models/Aspirate/AspirateState.cs
Original file line number Diff line number Diff line change
Expand Up @@ -135,13 +135,13 @@ public class AspirateState :
public List<string> AspireComponentsToProcess { get; set; } = [];

[JsonIgnore]
public Dictionary<string, Resource> LoadedAspireManifestResources { get; set; } = new();
public Dictionary<string, Resource> LoadedAspireManifestResources { get; set; } = [];

[JsonIgnore]
public string? PrivateRegistryPassword { get; set; }

[JsonIgnore]
public Dictionary<string, Resource> FinalResources { get; } = new();
public Dictionary<string, Resource> FinalResources { get; } = [];

[JsonIgnore]
public bool StateWasLoadedFromPrevious { get; set; }
Expand Down Expand Up @@ -179,17 +179,20 @@ public class AspirateState :
[JsonIgnore]
public string? SecretPassword { get; set; }

[JsonIgnore]
public bool? UseEnvVariablesAsParameterValues { get; set; }

public void AppendToFinalResources(string key, Resource resource) =>
FinalResources.Add(key, resource);

public bool IsNotDeployable(Resource resource)
{
if (OutputFormat.Equals("compose", StringComparison.OrdinalIgnoreCase))
{
return (resource is ParameterResource or ValueResource);
return resource is ParameterResource or ValueResource;
}

return (resource is DaprResource or ParameterResource or ValueResource);
return resource is DaprResource or ParameterResource or ValueResource;
}

[JsonIgnore]
Expand Down