Skip to content

Commit

Permalink
[#370] #IMPLEMENT 'assemblyName: DotNet.Testcontainers; function: Doc…
Browse files Browse the repository at this point in the history
…kerEndpointAuthenticationProvider'

{Add Docker endpoint auth provider.}
  • Loading branch information
HofmeisterAn committed Jun 6, 2022
1 parent d535f16 commit 9ed452b
Show file tree
Hide file tree
Showing 12 changed files with 206 additions and 19 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
namespace DotNet.Testcontainers.Builders
{
using System.Linq;
using DotNet.Testcontainers.Configurations;

/// <inheritdoc cref="IAuthenticationProvider{TAuthenticationConfiguration}" />
internal sealed class DockerEndpointAuthenticationProvider : IAuthenticationProvider<IDockerEndpointAuthenticationConfiguration>
{
/// <inheritdoc />
public bool IsApplicable()
{
return true;
}

/// <inheritdoc />
public IDockerEndpointAuthenticationConfiguration GetAuthConfig(string hostname)
{
return new IAuthenticationProvider<IDockerEndpointAuthenticationConfiguration>[] { new EnvironmentEndpointAuthenticationProvider(), new NpipeEndpointAuthenticationProvider(), new UnixEndpointAuthenticationProvider() }
.First(authenticationProvider => authenticationProvider.IsApplicable())
.GetAuthConfig(hostname);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
namespace DotNet.Testcontainers.Builders
{
using System;
using DotNet.Testcontainers.Configurations;

/// <inheritdoc cref="IAuthenticationProvider{TAuthenticationConfiguration}" />
internal sealed class EnvironmentEndpointAuthenticationProvider : IAuthenticationProvider<IDockerEndpointAuthenticationConfiguration>
{
private readonly Uri dockerEngine;

public EnvironmentEndpointAuthenticationProvider()
{
this.dockerEngine = Uri.TryCreate(Environment.GetEnvironmentVariable("DOCKER_HOST"), UriKind.RelativeOrAbsolute, out var dockerHost) ? dockerHost : null;
}

/// <inheritdoc />
public bool IsApplicable()
{
return this.dockerEngine != null;
}

/// <inheritdoc />
public IDockerEndpointAuthenticationConfiguration GetAuthConfig(string hostname)
{
return new DockerEndpointAuthenticationConfiguration(this.dockerEngine);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
namespace DotNet.Testcontainers.Builders
{
using System;
using System.Runtime.InteropServices;
using DotNet.Testcontainers.Configurations;

/// <inheritdoc cref="IAuthenticationProvider{TAuthenticationConfiguration}" />
internal sealed class NpipeEndpointAuthenticationProvider : IAuthenticationProvider<IDockerEndpointAuthenticationConfiguration>
{
#pragma warning disable S1075

private static readonly Uri DockerEngine = new Uri("npipe://./pipe/docker_engine");

#pragma warning restore S1075

/// <inheritdoc />
public bool IsApplicable()
{
return RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
}

/// <inheritdoc />
public IDockerEndpointAuthenticationConfiguration GetAuthConfig(string hostname)
{
return new DockerEndpointAuthenticationConfiguration(DockerEngine);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
namespace DotNet.Testcontainers.Builders
{
using System;
using System.Runtime.InteropServices;
using DotNet.Testcontainers.Configurations;

/// <inheritdoc cref="IAuthenticationProvider{TAuthenticationConfiguration}" />
internal sealed class UnixEndpointAuthenticationProvider : IAuthenticationProvider<IDockerEndpointAuthenticationConfiguration>
{
private static readonly Uri DockerEngine = new Uri("unix:/var/run/docker.sock");

/// <inheritdoc />
public bool IsApplicable()
{
return !RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
}

/// <inheritdoc />
public IDockerEndpointAuthenticationConfiguration GetAuthConfig(string hostname)
{
return new DockerEndpointAuthenticationConfiguration(DockerEngine);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,24 @@
{
using System;
using Docker.DotNet;
using JetBrains.Annotations;

/// <summary>
/// A authentication configuration to authenticate against private Docker clients.
/// An authentication configuration to authenticate against private Docker clients.
/// </summary>
public interface IDockerEndpointAuthenticationConfiguration
{
/// <summary>
/// Gets the Docker API endpoint.
/// </summary>
[NotNull]
Uri Endpoint { get; }

/// <summary>
/// Gets the Docker client configuration.
/// </summary>
/// <returns>The Docker client configuration.</returns>
[NotNull]
DockerClientConfiguration GetDockerClientConfiguration();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ namespace DotNet.Testcontainers.Configurations
using JetBrains.Annotations;

/// <summary>
/// A authentication configuration to authenticate against private Docker registries.
/// An authentication configuration to authenticate against private Docker registries.
/// </summary>
public interface IDockerRegistryAuthenticationConfiguration
{
Expand Down
18 changes: 14 additions & 4 deletions src/DotNet.Testcontainers/Configurations/Unix.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
namespace DotNet.Testcontainers.Configurations
{
using System;
using DotNet.Testcontainers.Builders;
using JetBrains.Annotations;

/// <summary>
Expand All @@ -9,14 +10,13 @@ namespace DotNet.Testcontainers.Configurations
[PublicAPI]
public sealed class Unix : IOperatingSystem
{
private static readonly Uri DockerEngine = new Uri("unix:/var/run/docker.sock");

/// <summary>
/// Initializes a new instance of the <see cref="Unix" /> class.
/// </summary>
[PublicAPI]
public Unix()
: this(DockerEngine)
: this(new DockerEndpointAuthenticationProvider()
.GetAuthConfig(null))
{
}

Expand All @@ -36,8 +36,18 @@ public Unix(string endpoint)
/// <param name="endpoint">The Docker API endpoint.</param>
[PublicAPI]
public Unix(Uri endpoint)
: this(new DockerEndpointAuthenticationConfiguration(endpoint))
{
}

/// <summary>
/// Initializes a new instance of the <see cref="Unix" /> class.
/// </summary>
/// <param name="dockerEndpointAuthConfig">The Docker endpoint authentication configuration.</param>
[PublicAPI]
public Unix(IDockerEndpointAuthenticationConfiguration dockerEndpointAuthConfig)
{
this.DockerEndpointAuthConfig = new DockerEndpointAuthenticationConfiguration(endpoint);
this.DockerEndpointAuthConfig = dockerEndpointAuthConfig;
}

/// <inheritdoc />
Expand Down
22 changes: 14 additions & 8 deletions src/DotNet.Testcontainers/Configurations/Windows.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
namespace DotNet.Testcontainers.Configurations
{
using System;
using DotNet.Testcontainers.Builders;
using JetBrains.Annotations;

/// <summary>
Expand All @@ -9,18 +10,13 @@ namespace DotNet.Testcontainers.Configurations
[PublicAPI]
public sealed class Windows : IOperatingSystem
{
#pragma warning disable S1075

private static readonly Uri DockerEngine = new Uri("npipe://./pipe/docker_engine");

#pragma warning restore S1075

/// <summary>
/// Initializes a new instance of the <see cref="Windows" /> class.
/// </summary>
[PublicAPI]
public Windows()
: this(DockerEngine)
: this(new DockerEndpointAuthenticationProvider()
.GetAuthConfig(null))
{
}

Expand All @@ -40,8 +36,18 @@ public Windows(string endpoint)
/// <param name="endpoint">The Docker API endpoint.</param>
[PublicAPI]
public Windows(Uri endpoint)
: this(new DockerEndpointAuthenticationConfiguration(endpoint))
{
}

/// <summary>
/// Initializes a new instance of the <see cref="Windows" /> class.
/// </summary>
/// <param name="dockerEndpointAuthConfig">The Docker endpoint authentication configuration.</param>
[PublicAPI]
public Windows(IDockerEndpointAuthenticationConfiguration dockerEndpointAuthConfig)
{
this.DockerEndpointAuthConfig = new DockerEndpointAuthenticationConfiguration(endpoint);
this.DockerEndpointAuthConfig = dockerEndpointAuthConfig;
}

/// <inheritdoc />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
namespace DotNet.Testcontainers.Tests.Unit
{
using System;
using DotNet.Testcontainers.Builders;
using Xunit;

[CollectionDefinition(nameof(DockerEndpointAuthenticationProviderTest), DisableParallelization = true)]
public sealed class DockerEndpointAuthenticationProviderTest
{
[Collection(nameof(DockerEndpointAuthenticationProviderTest))]
public sealed class EnvironmentEndpointAuthenticationProviderTest : IDisposable
{
private const string DockerHost = "127.0.0.1:2375";

public EnvironmentEndpointAuthenticationProviderTest()
{
Environment.SetEnvironmentVariable("DOCKER_HOST", DockerHost);
}

[Fact]
public void GetAuthConfig()
{
using (var clientConfiguration = new DockerEndpointAuthenticationProvider().GetAuthConfig(null)!.GetDockerClientConfiguration())
{
Assert.Equal(DockerHost, clientConfiguration.EndpointBaseUri.ToString());
}
}

public void Dispose()
{
Environment.SetEnvironmentVariable("DOCKER_HOST", null);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public void GetHostnameFromDockerImage(string dockerImageName, string hostname)
[Fact]
public void ShouldGetDefaultDockerRegistryAuthenticationConfiguration()
{
IAuthenticationProvider authenticationProvider = new DockerRegistryAuthenticationProvider("/tmp/docker.config", TestcontainersSettings.Logger);
var authenticationProvider = new DockerRegistryAuthenticationProvider("/tmp/docker.config", TestcontainersSettings.Logger);
Assert.Equal(default(DockerRegistryAuthenticationConfiguration), authenticationProvider.GetAuthConfig(DockerRegistry));
}

Expand All @@ -60,7 +60,7 @@ public void ShouldGetNull(string jsonDocument, bool isApplicable)
var jsonElement = JsonDocument.Parse(jsonDocument).RootElement;

// When
IAuthenticationProvider authenticationProvider = new Base64Provider(jsonElement, TestcontainersSettings.Logger);
var authenticationProvider = new Base64Provider(jsonElement, TestcontainersSettings.Logger);
var authConfig = authenticationProvider.GetAuthConfig(DockerRegistry);

// Then
Expand All @@ -76,7 +76,7 @@ public void ShouldGetAuthConfig()
var jsonElement = JsonDocument.Parse(jsonDocument).RootElement;

// When
IAuthenticationProvider authenticationProvider = new Base64Provider(jsonElement, TestcontainersSettings.Logger);
var authenticationProvider = new Base64Provider(jsonElement, TestcontainersSettings.Logger);
var authConfig = authenticationProvider.GetAuthConfig(DockerRegistry);

// Then
Expand All @@ -100,7 +100,7 @@ public void ShouldGetNull(string jsonDocument, bool isApplicable)
var jsonElement = JsonDocument.Parse(jsonDocument).RootElement;

// When
IAuthenticationProvider authenticationProvider = new CredsStoreProvider(jsonElement, TestcontainersSettings.Logger);
var authenticationProvider = new CredsStoreProvider(jsonElement, TestcontainersSettings.Logger);
var authConfig = authenticationProvider.GetAuthConfig(DockerRegistry);

// Then
Expand All @@ -120,7 +120,7 @@ public void ShouldGetAuthConfig()
var jsonElement = JsonDocument.Parse(jsonDocument).RootElement;

// When
IAuthenticationProvider authenticationProvider = new CredsStoreProvider(jsonElement, TestcontainersSettings.Logger);
var authenticationProvider = new CredsStoreProvider(jsonElement, TestcontainersSettings.Logger);
var authConfig = authenticationProvider.GetAuthConfig(DockerRegistry);

// Then
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,21 @@ public static class TestcontainersContainerTest
[Collection(nameof(Testcontainers))]
public sealed class WithConfiguration
{
[Fact]
public void GetAuthConfig()
{
// Given
var expected = new UnixEndpointAuthenticationProvider().GetAuthConfig(null);

// When
var actual = new DockerEndpointAuthenticationProvider().GetAuthConfig(null);

// Then
Assert.NotNull(expected);
Assert.NotNull(actual);
Assert.Equal(expected.Endpoint, actual.Endpoint);
}

[Fact]
public async Task IsLinuxEngineEnabled()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,21 @@ public static class TestcontainersContainerTest
[Collection(nameof(Testcontainers))]
public sealed class WithConfiguration
{
[SkipOnLinuxEngine]
public void GetAuthConfig()
{
// Given
var expected = new NpipeEndpointAuthenticationProvider().GetAuthConfig(null);

// When
var actual = new DockerEndpointAuthenticationProvider().GetAuthConfig(null);

// Then
Assert.NotNull(expected);
Assert.NotNull(actual);
Assert.Equal(expected.Endpoint, actual.Endpoint);
}

[SkipOnLinuxEngine]
public async Task IsWindowsEngineEnabled()
{
Expand Down

0 comments on commit 9ed452b

Please sign in to comment.