Skip to content

Commit 9019377

Browse files
github-actions[bot]Alirexaadavidfowleerhardt
authored
[release/9.3] Accept null value in Redis WithPassword to ensure password dosen't set in redis-server (#9283)
* Accept null value in Redis WithPassword to ensure password dosen't in redis-server * Update tests/Aspire.Hosting.Redis.Tests/AddRedisTests.cs * Apply suggestions from code review * Fix manifest * fix redis-insight test * Update playground app manifest * Update playground/Redis/Redis.AppHost/Program.cs Co-authored-by: Eric Erhardt <[email protected]> * Update src/Aspire.Hosting.Redis/RedisBuilderExtensions.cs Co-authored-by: Eric Erhardt <[email protected]> * Revert manifest changes --------- Co-authored-by: Alireza Baloochi <[email protected]> Co-authored-by: David Fowler <[email protected]> Co-authored-by: Eric Erhardt <[email protected]>
1 parent 4a4188d commit 9019377

File tree

4 files changed

+86
-17
lines changed

4 files changed

+86
-17
lines changed

src/Aspire.Hosting.Redis/RedisBuilderExtensions.cs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -417,14 +417,13 @@ public static IResourceBuilder<RedisInsightResource> WithDataBindMount(this IRes
417417
/// Configures the password that the Redis resource is used.
418418
/// </summary>
419419
/// <param name="builder">The resource builder.</param>
420-
/// <param name="password">The parameter used to provide the password for the Redis resource.</param>
420+
/// <param name="password">The parameter used to provide the password for the Redis resource. If <see langword="null"/>, no password will be configured.</param>
421421
/// <returns>The <see cref="IResourceBuilder{T}"/>.</returns>
422-
public static IResourceBuilder<RedisResource> WithPassword(this IResourceBuilder<RedisResource> builder, IResourceBuilder<ParameterResource> password)
422+
public static IResourceBuilder<RedisResource> WithPassword(this IResourceBuilder<RedisResource> builder, IResourceBuilder<ParameterResource>? password)
423423
{
424424
ArgumentNullException.ThrowIfNull(builder);
425-
ArgumentNullException.ThrowIfNull(password);
426425

427-
builder.Resource.SetPassword(password.Resource);
426+
builder.Resource.SetPassword(password?.Resource);
428427
return builder;
429428
}
430429

src/Aspire.Hosting.Redis/RedisResource.cs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,10 +77,8 @@ public ReferenceExpression ConnectionStringExpression
7777
return BuildConnectionString().GetValueAsync(cancellationToken);
7878
}
7979

80-
internal void SetPassword(ParameterResource password)
80+
internal void SetPassword(ParameterResource? password)
8181
{
82-
ArgumentNullException.ThrowIfNull(password);
83-
8482
PasswordParameter = password;
8583
}
8684
}

tests/Aspire.Hosting.Redis.Tests/AddRedisTests.cs

Lines changed: 73 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ public async Task RedisCreatesConnectionStringWithDefaultPassword()
128128
}
129129

130130
[Fact]
131-
public async Task VerifyWithoutPasswordManifest()
131+
public async Task VerifyDefaultManifest()
132132
{
133133
using var builder = TestDistributedApplicationBuilder.Create();
134134
var redis = builder.AddRedis("redis");
@@ -161,6 +161,37 @@ public async Task VerifyWithoutPasswordManifest()
161161
Assert.Equal(expectedManifest, manifest.ToString());
162162
}
163163

164+
[Fact]
165+
public async Task VerifyWithoutPasswordManifest()
166+
{
167+
using var builder = TestDistributedApplicationBuilder.Create();
168+
var redis = builder.AddRedis("redis").WithPassword(null);
169+
170+
var manifest = await ManifestUtils.GetManifest(redis.Resource);
171+
172+
var expectedManifest = $$"""
173+
{
174+
"type": "container.v0",
175+
"connectionString": "{redis.bindings.tcp.host}:{redis.bindings.tcp.port}",
176+
"image": "{{RedisContainerImageTags.Registry}}/{{RedisContainerImageTags.Image}}:{{RedisContainerImageTags.Tag}}",
177+
"entrypoint": "/bin/sh",
178+
"args": [
179+
"-c",
180+
"redis-server"
181+
],
182+
"bindings": {
183+
"tcp": {
184+
"scheme": "tcp",
185+
"protocol": "tcp",
186+
"transport": "tcp",
187+
"targetPort": 6379
188+
}
189+
}
190+
}
191+
""";
192+
Assert.Equal(expectedManifest, manifest.ToString());
193+
}
194+
164195
[Fact]
165196
public async Task VerifyWithPasswordManifest()
166197
{
@@ -260,6 +291,7 @@ public async Task WithRedisInsightProducesCorrectEnvironmentVariables()
260291
var builder = DistributedApplication.CreateBuilder();
261292
var redis1 = builder.AddRedis("myredis1").WithRedisInsight();
262293
var redis2 = builder.AddRedis("myredis2").WithRedisInsight();
294+
var redis3 = builder.AddRedis("myredis3").WithRedisInsight().WithPassword(null);
263295
using var app = builder.Build();
264296

265297
// Add fake allocated endpoints.
@@ -311,6 +343,21 @@ public async Task WithRedisInsightProducesCorrectEnvironmentVariables()
311343
{
312344
Assert.Equal("RI_REDIS_PASSWORD2", item.Key);
313345
Assert.Equal(redis2.Resource.PasswordParameter!.Value, item.Value);
346+
},
347+
(item) =>
348+
{
349+
Assert.Equal("RI_REDIS_HOST3", item.Key);
350+
Assert.Equal(redis3.Resource.Name, item.Value);
351+
},
352+
(item) =>
353+
{
354+
Assert.Equal("RI_REDIS_PORT3", item.Key);
355+
Assert.Equal($"{redis3.Resource.PrimaryEndpoint.TargetPort!.Value}", item.Value);
356+
},
357+
(item) =>
358+
{
359+
Assert.Equal("RI_REDIS_ALIAS3", item.Key);
360+
Assert.Equal(redis3.Resource.Name, item.Value);
314361
});
315362

316363
}
@@ -391,26 +438,44 @@ public void VerifyRedisResourceWithHostPort()
391438
Assert.Equal(1000, endpoint.Port);
392439
}
393440

394-
[Fact]
395-
public async Task VerifyRedisResourceWithPassword()
441+
[Theory]
442+
[InlineData(false)]
443+
[InlineData(true)]
444+
public async Task VerifyRedisResourceWithPassword(bool withPassword)
396445
{
397446
using var builder = TestDistributedApplicationBuilder.Create();
398447

399-
var password = "p@ssw0rd1";
400-
var pass = builder.AddParameter("pass", password);
401448
var redis = builder
402449
.AddRedis("myRedis")
403-
.WithPassword(pass)
404450
.WithEndpoint("tcp", e => e.AllocatedEndpoint = new AllocatedEndpoint(e, "localhost", 5001));
405451

452+
var password = "p@ssw0rd1";
453+
if (withPassword)
454+
{
455+
var pass = builder.AddParameter("pass", password);
456+
redis.WithPassword(pass);
457+
}
458+
else
459+
{
460+
redis.WithPassword(null);
461+
}
462+
406463
using var app = builder.Build();
407464
var appModel = app.Services.GetRequiredService<DistributedApplicationModel>();
408465
var containerResource = Assert.Single(appModel.Resources.OfType<RedisResource>());
409466

410467
var connectionStringResource = Assert.Single(appModel.Resources.OfType<IResourceWithConnectionString>());
411468
var connectionString = await connectionStringResource.GetConnectionStringAsync(default);
412-
Assert.Equal("{myRedis.bindings.tcp.host}:{myRedis.bindings.tcp.port},password={pass.value}", connectionStringResource.ConnectionStringExpression.ValueExpression);
413-
Assert.StartsWith($"localhost:5001,password={password}", connectionString);
469+
if (withPassword)
470+
{
471+
Assert.Equal("{myRedis.bindings.tcp.host}:{myRedis.bindings.tcp.port},password={pass.value}", connectionStringResource.ConnectionStringExpression.ValueExpression);
472+
Assert.Equal($"localhost:5001,password={password}", connectionString);
473+
}
474+
else
475+
{
476+
Assert.Equal("{myRedis.bindings.tcp.host}:{myRedis.bindings.tcp.port}", connectionStringResource.ConnectionStringExpression.ValueExpression);
477+
Assert.Equal($"localhost:5001", connectionString);
478+
}
414479
}
415480

416481
[Fact]

tests/Aspire.Hosting.Redis.Tests/RedisFunctionalTests.cs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ public async Task VerifyWithRedisInsightImportDatabases()
136136
IResourceBuilder<RedisInsightResource>? redisInsightBuilder = null;
137137
var redis2 = builder.AddRedis("redis-2").WithRedisInsight(c => redisInsightBuilder = c);
138138
Assert.NotNull(redisInsightBuilder);
139+
var redis3 = builder.AddRedis("redis-3").WithPassword(null);
139140

140141
using var app = builder.Build();
141142

@@ -169,13 +170,19 @@ public async Task VerifyWithRedisInsightImportDatabases()
169170
Assert.Equal(redis2.Resource.Name, db.Name);
170171
Assert.Equal(redis2.Resource.Name, db.Host);
171172
Assert.Equal(redis2.Resource.PrimaryEndpoint.TargetPort, db.Port);
173+
},
174+
db =>
175+
{
176+
Assert.Equal(redis3.Resource.Name, db.Name);
177+
Assert.Equal(redis3.Resource.Name, db.Host);
178+
Assert.Equal(redis3.Resource.PrimaryEndpoint.TargetPort, db.Port);
172179
});
173180

174181
foreach (var db in databases)
175182
{
176183
var cts2 = new CancellationTokenSource(TimeSpan.FromSeconds(2));
177-
var testConnectionResponse = await client.GetAsync($"/api/databases/test/{db.Id}", cts2.Token);
178-
response.EnsureSuccessStatusCode();
184+
var testConnectionResponse = await client.GetAsync($"/api/databases/{db.Id}/connect", cts2.Token);
185+
testConnectionResponse.EnsureSuccessStatusCode();
179186
}
180187
}
181188

0 commit comments

Comments
 (0)