-
Notifications
You must be signed in to change notification settings - Fork 161
Expand file tree
/
Copy pathPostgresBuilderExtensions.cs
More file actions
98 lines (83 loc) · 4.26 KB
/
PostgresBuilderExtensions.cs
File metadata and controls
98 lines (83 loc) · 4.26 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
using Aspire.Hosting.ApplicationModel;
using System.Text;
namespace Aspire.Hosting;
/// <summary>
/// Provides extension methods for adding PostgreSQL resources to an <see cref="IDistributedApplicationBuilder"/>.
/// </summary>
public static class PostgresBuilderExtensions
{
/// <summary>
/// Adds an administration and development platform for PostgreSQL to the application model using DbGate.
/// </summary>
/// <remarks>
/// This version of the package defaults to the <inheritdoc cref="DbGateContainerImageTags.Tag"/> tag of the <inheritdoc cref="DbGateContainerImageTags.Image"/> container image.
/// </remarks>
/// <param name="builder">The Postgres server resource builder.</param>
/// <param name="configureContainer">Configuration callback for DbGate container resource.</param>
/// <param name="containerName">The name of the container (Optional).</param>
/// <example>
/// Use in application host with a Postgres resource
/// <code lang="csharp">
/// var builder = DistributedApplication.CreateBuilder(args);
///
/// var postgres = builder.AddPostgres("postgres")
/// .WithDbGate();
/// var db = postgres.AddDatabase("db");
///
/// var api = builder.AddProject<Projects.Api>("api")
/// .WithReference(db);
///
/// builder.Build().Run();
/// </code>
/// </example>
/// <returns>A reference to the <see cref="IResourceBuilder{T}"/>.</returns>
public static IResourceBuilder<PostgresServerResource> WithDbGate(this IResourceBuilder<PostgresServerResource> builder, Action<IResourceBuilder<DbGateContainerResource>>? configureContainer = null, string? containerName = null)
{
ArgumentNullException.ThrowIfNull(builder);
containerName ??= $"{builder.Resource.Name}-dbgate";
var dbGateBuilder = DbGateBuilderExtensions.AddDbGate(builder.ApplicationBuilder, containerName);
dbGateBuilder
.WithEnvironment(context => ConfigureDbGateContainer(context, builder.ApplicationBuilder));
configureContainer?.Invoke(dbGateBuilder);
return builder;
}
private static void ConfigureDbGateContainer(EnvironmentCallbackContext context, IDistributedApplicationBuilder applicationBuilder)
{
var postgresInstances = applicationBuilder.Resources.OfType<PostgresServerResource>();
var counter = 1;
// Multiple WithDbGate calls will be ignored
if (context.EnvironmentVariables.ContainsKey($"LABEL_postgres{counter}"))
{
return;
}
foreach (var postgresServer in postgresInstances)
{
var user = postgresServer.UserNameParameter?.Value ?? "postgres";
// DbGate assumes Postgres is being accessed over a default Aspire container network and hardcodes the resource address
// This will need to be refactored once updated service discovery APIs are available
context.EnvironmentVariables.Add($"LABEL_postgres{counter}", postgresServer.Name);
context.EnvironmentVariables.Add($"SERVER_postgres{counter}", postgresServer.Name);
context.EnvironmentVariables.Add($"USER_postgres{counter}", user);
context.EnvironmentVariables.Add($"PASSWORD_postgres{counter}", postgresServer.PasswordParameter.Value);
context.EnvironmentVariables.Add($"PORT_postgres{counter}", postgresServer.PrimaryEndpoint.TargetPort!.ToString()!);
context.EnvironmentVariables.Add($"ENGINE_postgres{counter}", "postgres@dbgate-plugin-postgres");
counter++;
}
var instancesCount = postgresInstances.Count();
if (instancesCount > 0)
{
var strBuilder = new StringBuilder();
strBuilder.AppendJoin(',', Enumerable.Range(1, instancesCount).Select(i => $"postgres{i}"));
var connections = strBuilder.ToString();
string CONNECTIONS = context.EnvironmentVariables.GetValueOrDefault("CONNECTIONS")?.ToString() ?? string.Empty;
if (string.IsNullOrEmpty(CONNECTIONS))
{
context.EnvironmentVariables["CONNECTIONS"] = connections;
}
else
{
context.EnvironmentVariables["CONNECTIONS"] += $",{connections}";
}
}
}
}