diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3c5bede06..b2fafefb0 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,7 @@
### Added
+- 370 Add protected Docker daemon socket support (@vlaskal)
- 421 Add Azurite module (@vlaskal)
- 421 Add Cosmos DB Linux Emulator (@Yeseh, @ktjn)
- 504 Add Elasticsearch module (@chertby)
diff --git a/Packages.props b/Packages.props
index 9c9761afb..72027045e 100644
--- a/Packages.props
+++ b/Packages.props
@@ -6,8 +6,10 @@
+
+
diff --git a/src/Testcontainers/Builders/MTlsEndpointAuthenticationProvider.cs b/src/Testcontainers/Builders/MTlsEndpointAuthenticationProvider.cs
new file mode 100644
index 000000000..1da666f3b
--- /dev/null
+++ b/src/Testcontainers/Builders/MTlsEndpointAuthenticationProvider.cs
@@ -0,0 +1,95 @@
+namespace DotNet.Testcontainers.Builders
+{
+ using System;
+ using System.IO;
+ using System.Linq;
+ using System.Security.Cryptography.X509Certificates;
+ using Docker.DotNet.X509;
+ using DotNet.Testcontainers.Configurations;
+ using Org.BouncyCastle.Crypto;
+ using Org.BouncyCastle.OpenSsl;
+ using Org.BouncyCastle.Pkcs;
+ using Org.BouncyCastle.Security;
+ using Org.BouncyCastle.X509;
+
+ ///
+ internal sealed class MTlsEndpointAuthenticationProvider : TlsEndpointAuthenticationProvider
+ {
+ private static readonly X509CertificateParser CertificateParser = new X509CertificateParser();
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public MTlsEndpointAuthenticationProvider()
+ : this(PropertiesFileConfiguration.Instance, EnvironmentConfiguration.Instance)
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// A list of custom configurations.
+ public MTlsEndpointAuthenticationProvider(params ICustomConfiguration[] customConfigurations)
+ : base(customConfigurations)
+ {
+ }
+
+ ///
+ public override bool IsApplicable()
+ {
+ var certificatesFiles = new[] { ClientCertificateFileName, ClientCertificateKeyFileName };
+ return this.TlsEnabled && this.TlsVerifyEnabled && certificatesFiles.Select(fileName => Path.Combine(this.CertificatesDirectoryPath, fileName)).All(File.Exists);
+ }
+
+ ///
+ public override IDockerEndpointAuthenticationConfiguration GetAuthConfig()
+ {
+ var credentials = new CertificateCredentials(this.GetClientCertificate());
+ credentials.ServerCertificateValidationCallback = this.ServerCertificateValidationCallback;
+ return new DockerEndpointAuthenticationConfiguration(this.DockerEngine, credentials);
+ }
+
+ ///
+ protected override X509Certificate2 GetClientCertificate()
+ {
+ var clientCertificateFilePath = Path.Combine(this.CertificatesDirectoryPath, ClientCertificateFileName);
+ var clientCertificateKeyFilePath = Path.Combine(this.CertificatesDirectoryPath, ClientCertificateKeyFileName);
+ return CreateFromPemFile(clientCertificateFilePath, clientCertificateKeyFilePath);
+ }
+
+ private static X509Certificate2 CreateFromPemFile(string certPemFilePath, string keyPemFilePath)
+ {
+ if (!File.Exists(certPemFilePath))
+ {
+ throw new FileNotFoundException(certPemFilePath);
+ }
+
+ if (!File.Exists(keyPemFilePath))
+ {
+ throw new FileNotFoundException(keyPemFilePath);
+ }
+
+ using (var keyPairStream = new StreamReader(keyPemFilePath))
+ {
+ var store = new Pkcs12StoreBuilder().Build();
+
+ var certificate = CertificateParser.ReadCertificate(File.ReadAllBytes(certPemFilePath));
+
+ var password = Guid.NewGuid().ToString("D");
+
+ var keyPair = (AsymmetricCipherKeyPair)new PemReader(keyPairStream).ReadObject();
+
+ var certificateEntry = new X509CertificateEntry(certificate);
+
+ var keyEntry = new AsymmetricKeyEntry(keyPair.Private);
+ store.SetKeyEntry(certificate.SubjectDN + "_key", keyEntry, new[] { certificateEntry });
+
+ using (var certificateStream = new MemoryStream())
+ {
+ store.Save(certificateStream, password.ToCharArray(), new SecureRandom());
+ return new X509Certificate2(Pkcs12Utilities.ConvertToDefiniteLength(certificateStream.ToArray()), password);
+ }
+ }
+ }
+ }
+}
diff --git a/src/Testcontainers/Builders/TlsEndpointAuthenticationProvider.cs b/src/Testcontainers/Builders/TlsEndpointAuthenticationProvider.cs
new file mode 100644
index 000000000..e9740b007
--- /dev/null
+++ b/src/Testcontainers/Builders/TlsEndpointAuthenticationProvider.cs
@@ -0,0 +1,115 @@
+namespace DotNet.Testcontainers.Builders
+{
+ using System;
+ using System.IO;
+ using System.Linq;
+ using System.Net;
+ using System.Net.Security;
+ using System.Security.Cryptography.X509Certificates;
+ using DotNet.Testcontainers.Configurations;
+
+ ///
+ internal class TlsEndpointAuthenticationProvider : DockerEndpointAuthenticationProvider
+ {
+ protected const string CaCertificateFileName = "ca.pem";
+
+ protected const string ClientCertificateFileName = "cert.pem";
+
+ protected const string ClientCertificateKeyFileName = "key.pem";
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public TlsEndpointAuthenticationProvider()
+ : this(PropertiesFileConfiguration.Instance, EnvironmentConfiguration.Instance)
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// A list of custom configurations.
+ public TlsEndpointAuthenticationProvider(params ICustomConfiguration[] customConfigurations)
+ : this(customConfigurations
+ .OrderByDescending(item => item.GetDockerTlsVerify())
+ .ThenByDescending(item => item.GetDockerTls())
+ .DefaultIfEmpty(new PropertiesFileConfiguration(Array.Empty()))
+ .First())
+ {
+ }
+
+ private TlsEndpointAuthenticationProvider(ICustomConfiguration customConfiguration)
+ {
+ this.TlsEnabled = customConfiguration.GetDockerTls() || customConfiguration.GetDockerTlsVerify();
+ this.TlsVerifyEnabled = customConfiguration.GetDockerTlsVerify();
+ this.CertificatesDirectoryPath = customConfiguration.GetDockerCertPath() ?? Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".docker");
+ this.DockerEngine = customConfiguration.GetDockerHost() ?? new Uri("tcp://localhost:2376");
+ }
+
+ protected bool TlsEnabled { get; }
+
+ protected bool TlsVerifyEnabled { get; }
+
+ protected string CertificatesDirectoryPath { get; }
+
+ protected Uri DockerEngine { get; }
+
+ ///
+ public override bool IsApplicable()
+ {
+ return this.TlsEnabled;
+ }
+
+ ///
+ public override IDockerEndpointAuthenticationConfiguration GetAuthConfig()
+ {
+ var credentials = new TlsCredentials();
+ credentials.ServerCertificateValidationCallback = this.ServerCertificateValidationCallback;
+ return new DockerEndpointAuthenticationConfiguration(this.DockerEngine, credentials);
+ }
+
+ ///
+ /// Gets the root certificate authority (CA).
+ ///
+ /// The root certificate authority (CA).
+ protected virtual X509Certificate2 GetCaCertificate()
+ {
+ return new X509Certificate2(Path.Combine(this.CertificatesDirectoryPath, CaCertificateFileName));
+ }
+
+ ///
+ /// Gets the client certificate.
+ ///
+ /// The client certificate.
+ protected virtual X509Certificate2 GetClientCertificate()
+ {
+ return null;
+ }
+
+ ///
+ protected virtual bool ServerCertificateValidationCallback(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
+ {
+ switch (sslPolicyErrors)
+ {
+ case SslPolicyErrors.None:
+ return true;
+ case SslPolicyErrors.RemoteCertificateNameMismatch:
+ case SslPolicyErrors.RemoteCertificateNotAvailable:
+ return false;
+ case SslPolicyErrors.RemoteCertificateChainErrors:
+ default:
+ using (var caCertificate = this.GetCaCertificate())
+ {
+ var validationChain = new X509Chain();
+ validationChain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
+ validationChain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority;
+ validationChain.ChainPolicy.ExtraStore.Add(caCertificate);
+ validationChain.ChainPolicy.ExtraStore.AddRange(chain.ChainElements.OfType().Select(element => element.Certificate).ToArray());
+ var isVerified = validationChain.Build(new X509Certificate2(certificate));
+ var isSignedByExpectedRoot = validationChain.ChainElements[validationChain.ChainElements.Count - 1].Certificate.RawData.SequenceEqual(caCertificate.RawData);
+ return isVerified && isSignedByExpectedRoot;
+ }
+ }
+ }
+ }
+}
diff --git a/src/Testcontainers/Clients/DockerSystemOperations.cs b/src/Testcontainers/Clients/DockerSystemOperations.cs
index 77fabcfaa..70362df7b 100644
--- a/src/Testcontainers/Clients/DockerSystemOperations.cs
+++ b/src/Testcontainers/Clients/DockerSystemOperations.cs
@@ -3,6 +3,7 @@ namespace DotNet.Testcontainers.Clients
using System;
using System.Threading;
using System.Threading.Tasks;
+ using Docker.DotNet.Models;
using DotNet.Testcontainers.Configurations;
using Microsoft.Extensions.Logging;
@@ -19,5 +20,10 @@ public async Task GetIsWindowsEngineEnabled(CancellationToken ct = default
return (await this.Docker.System.GetSystemInfoAsync(ct)
.ConfigureAwait(false)).OperatingSystem.Contains("Windows");
}
+
+ public Task GetVersion(CancellationToken ct = default)
+ {
+ return this.Docker.System.GetVersionAsync(ct);
+ }
}
}
diff --git a/src/Testcontainers/Clients/IDockerSystemOperations.cs b/src/Testcontainers/Clients/IDockerSystemOperations.cs
index 39ad21a74..6f11ec298 100644
--- a/src/Testcontainers/Clients/IDockerSystemOperations.cs
+++ b/src/Testcontainers/Clients/IDockerSystemOperations.cs
@@ -2,9 +2,12 @@ namespace DotNet.Testcontainers.Clients
{
using System.Threading;
using System.Threading.Tasks;
+ using Docker.DotNet.Models;
internal interface IDockerSystemOperations
{
Task GetIsWindowsEngineEnabled(CancellationToken ct = default);
+
+ Task GetVersion(CancellationToken ct = default);
}
}
diff --git a/src/Testcontainers/Configurations/DockerEndpointAuthenticationConfiguration.cs b/src/Testcontainers/Configurations/DockerEndpointAuthenticationConfiguration.cs
index 10c63b35b..cb81865ea 100644
--- a/src/Testcontainers/Configurations/DockerEndpointAuthenticationConfiguration.cs
+++ b/src/Testcontainers/Configurations/DockerEndpointAuthenticationConfiguration.cs
@@ -12,11 +12,16 @@
/// Initializes a new instance of the struct.
///
/// The Docker API endpoint.
- public DockerEndpointAuthenticationConfiguration(Uri endpoint)
+ /// The Docker API authentication credentials.
+ public DockerEndpointAuthenticationConfiguration(Uri endpoint, Credentials credentials = null)
{
+ this.Credentials = credentials;
this.Endpoint = endpoint;
}
+ ///
+ public Credentials Credentials { get; }
+
///
public Uri Endpoint { get; }
@@ -24,7 +29,7 @@ public DockerEndpointAuthenticationConfiguration(Uri endpoint)
public DockerClientConfiguration GetDockerClientConfiguration(Guid sessionId = default)
{
var defaultHttpRequestHeaders = new ReadOnlyDictionary(new Dictionary { { "x-tc-sid", sessionId.ToString("D") } });
- return new DockerClientConfiguration(this.Endpoint, defaultHttpRequestHeaders: defaultHttpRequestHeaders);
+ return new DockerClientConfiguration(this.Endpoint, this.Credentials, defaultHttpRequestHeaders: defaultHttpRequestHeaders);
}
}
}
diff --git a/src/Testcontainers/Configurations/IDockerEndpointAuthenticationConfiguration.cs b/src/Testcontainers/Configurations/IDockerEndpointAuthenticationConfiguration.cs
index 3a8a48508..ab1851c3e 100644
--- a/src/Testcontainers/Configurations/IDockerEndpointAuthenticationConfiguration.cs
+++ b/src/Testcontainers/Configurations/IDockerEndpointAuthenticationConfiguration.cs
@@ -15,6 +15,12 @@ public interface IDockerEndpointAuthenticationConfiguration
[NotNull]
Uri Endpoint { get; }
+ ///
+ /// Gets the Docker API credentials.
+ ///
+ [CanBeNull]
+ Credentials Credentials { get; }
+
///
/// Gets the Docker client configuration.
///
diff --git a/src/Testcontainers/Configurations/TestcontainersSettings.cs b/src/Testcontainers/Configurations/TestcontainersSettings.cs
index 2a959bd7f..3533ab78b 100644
--- a/src/Testcontainers/Configurations/TestcontainersSettings.cs
+++ b/src/Testcontainers/Configurations/TestcontainersSettings.cs
@@ -21,7 +21,14 @@ public static class TestcontainersSettings
private static readonly IDockerImage RyukContainerImage = new DockerImage("testcontainers/ryuk:0.3.4");
private static readonly IDockerEndpointAuthenticationConfiguration DockerEndpointAuthConfig =
- new IDockerEndpointAuthenticationProvider[] { new EnvironmentEndpointAuthenticationProvider(), new NpipeEndpointAuthenticationProvider(), new UnixEndpointAuthenticationProvider() }
+ new IDockerEndpointAuthenticationProvider[]
+ {
+ new MTlsEndpointAuthenticationProvider(),
+ new TlsEndpointAuthenticationProvider(),
+ new EnvironmentEndpointAuthenticationProvider(),
+ new NpipeEndpointAuthenticationProvider(),
+ new UnixEndpointAuthenticationProvider(),
+ }
.AsParallel()
.Where(authProvider => authProvider.IsApplicable())
.Where(authProvider => authProvider.IsAvailable())
diff --git a/src/Testcontainers/Configurations/TlsCredentials.cs b/src/Testcontainers/Configurations/TlsCredentials.cs
new file mode 100644
index 000000000..3a30e6efa
--- /dev/null
+++ b/src/Testcontainers/Configurations/TlsCredentials.cs
@@ -0,0 +1,27 @@
+namespace DotNet.Testcontainers.Configurations
+{
+ using System.Net;
+ using System.Net.Http;
+ using Docker.DotNet.X509;
+ using Microsoft.Net.Http.Client;
+
+ internal sealed class TlsCredentials : CertificateCredentials
+ {
+ public TlsCredentials()
+ : base(null)
+ {
+ }
+
+ public override bool IsTlsCredentials()
+ {
+ return true;
+ }
+
+ public override HttpMessageHandler GetHandler(HttpMessageHandler innerHandler)
+ {
+ var handler = (ManagedHandler)innerHandler;
+ handler.ServerCertificateValidationCallback = this.ServerCertificateValidationCallback ?? ServicePointManager.ServerCertificateValidationCallback;
+ return handler;
+ }
+ }
+}
diff --git a/src/Testcontainers/Testcontainers.csproj b/src/Testcontainers/Testcontainers.csproj
index 1c67783b2..ad657e5bb 100644
--- a/src/Testcontainers/Testcontainers.csproj
+++ b/src/Testcontainers/Testcontainers.csproj
@@ -1,4 +1,4 @@
-
+
netstandard2.0;netstandard2.1
@@ -9,8 +9,10 @@
+
+
diff --git a/tests/Testcontainers.Tests/Fixtures/Containers/Unix/DockerMTlsFixture.cs b/tests/Testcontainers.Tests/Fixtures/Containers/Unix/DockerMTlsFixture.cs
new file mode 100644
index 000000000..6dbba714c
--- /dev/null
+++ b/tests/Testcontainers.Tests/Fixtures/Containers/Unix/DockerMTlsFixture.cs
@@ -0,0 +1,27 @@
+namespace DotNet.Testcontainers.Tests.Fixtures
+{
+ using System.Collections.Generic;
+ using DotNet.Testcontainers.Builders;
+ using DotNet.Testcontainers.Containers;
+ using JetBrains.Annotations;
+
+ [UsedImplicitly]
+ public sealed class DockerMTlsFixture : ProtectDockerDaemonSocket
+ {
+ public DockerMTlsFixture()
+ : base(new TestcontainersBuilder())
+ {
+ }
+
+ public override IList CustomProperties
+ {
+ get
+ {
+ var customProperties = base.CustomProperties;
+ customProperties.Add("docker.tls=false");
+ customProperties.Add("docker.tls.verify=true");
+ return customProperties;
+ }
+ }
+ }
+}
diff --git a/tests/Testcontainers.Tests/Fixtures/Containers/Unix/DockerTlsFixture.cs b/tests/Testcontainers.Tests/Fixtures/Containers/Unix/DockerTlsFixture.cs
new file mode 100644
index 000000000..1dc8d3f4a
--- /dev/null
+++ b/tests/Testcontainers.Tests/Fixtures/Containers/Unix/DockerTlsFixture.cs
@@ -0,0 +1,28 @@
+namespace DotNet.Testcontainers.Tests.Fixtures
+{
+ using System.Collections.Generic;
+ using DotNet.Testcontainers.Builders;
+ using DotNet.Testcontainers.Containers;
+ using JetBrains.Annotations;
+
+ [UsedImplicitly]
+ public sealed class DockerTlsFixture : ProtectDockerDaemonSocket
+ {
+ public DockerTlsFixture()
+ : base(new TestcontainersBuilder()
+ .WithCommand("--tlsverify=false"))
+ {
+ }
+
+ public override IList CustomProperties
+ {
+ get
+ {
+ var customProperties = base.CustomProperties;
+ customProperties.Add("docker.tls=true");
+ customProperties.Add("docker.tls.verify=false");
+ return customProperties;
+ }
+ }
+ }
+}
diff --git a/tests/Testcontainers.Tests/Fixtures/Containers/Unix/Modules/Databases/AzuriteFixture.cs b/tests/Testcontainers.Tests/Fixtures/Containers/Unix/Modules/Databases/AzuriteFixture.cs
index 69a752589..84cbab413 100644
--- a/tests/Testcontainers.Tests/Fixtures/Containers/Unix/Modules/Databases/AzuriteFixture.cs
+++ b/tests/Testcontainers.Tests/Fixtures/Containers/Unix/Modules/Databases/AzuriteFixture.cs
@@ -11,9 +11,6 @@ namespace DotNet.Testcontainers.Tests.Fixtures
public static class AzuriteFixture
{
- // We cannot use `Path.GetTempPath()` on macOS, see: https://github.com/common-workflow-language/cwltool/issues/328.
- private static readonly string TempDir = Environment.GetEnvironmentVariable("AGENT_TEMPDIRECTORY") ?? Directory.GetCurrentDirectory();
-
[UsedImplicitly]
public class AzuriteDefaultFixture : IAsyncLifetime
{
@@ -92,7 +89,7 @@ public sealed class AzuriteWithCustomWorkspaceFixture : AzuriteDefaultFixture, I
public AzuriteWithCustomWorkspaceFixture()
: base(new AzuriteTestcontainerConfiguration
{
- Location = Path.Combine(TempDir, Guid.NewGuid().ToString("N")),
+ Location = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString("D")),
})
{
if (this.Configuration.Location != null)
diff --git a/tests/Testcontainers.Tests/Fixtures/Containers/Unix/ProtectDockerDaemonSocket.cs b/tests/Testcontainers.Tests/Fixtures/Containers/Unix/ProtectDockerDaemonSocket.cs
new file mode 100644
index 000000000..2a14bf080
--- /dev/null
+++ b/tests/Testcontainers.Tests/Fixtures/Containers/Unix/ProtectDockerDaemonSocket.cs
@@ -0,0 +1,71 @@
+namespace DotNet.Testcontainers.Tests.Fixtures
+{
+ using System;
+ using System.Collections.Generic;
+ using System.IO;
+ using System.Threading.Tasks;
+ using DotNet.Testcontainers.Builders;
+ using DotNet.Testcontainers.Configurations;
+ using DotNet.Testcontainers.Containers;
+ using DotNet.Testcontainers.Images;
+ using Xunit;
+
+ public abstract class ProtectDockerDaemonSocket : IAsyncLifetime
+ {
+ public const string DockerVersion = "20.10.18";
+
+ private const string CertsDirectoryName = "certs";
+
+ private const ushort TlsPort = 2376;
+
+ private readonly string hostCertsDirectoryPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString("D"), CertsDirectoryName);
+
+ private readonly string containerCertsDirectoryPath = Path.Combine("/", CertsDirectoryName);
+
+ private readonly IDockerImage image = new DockerImage(string.Empty, "docker", DockerVersion + "-dind");
+
+ private readonly ITestcontainersContainer container;
+
+ protected ProtectDockerDaemonSocket(ITestcontainersBuilder containerConfiguration)
+ {
+ this.container = containerConfiguration
+ .WithImage(this.image)
+ .WithPrivileged(true)
+ .WithExposedPort(TlsPort)
+ .WithPortBinding(TlsPort, true)
+ .WithBindMount(this.hostCertsDirectoryPath, this.containerCertsDirectoryPath, AccessMode.ReadWrite)
+ .WithWaitStrategy(Wait.ForUnixContainer().UntilPortIsAvailable(TlsPort))
+ .Build();
+ }
+
+ public virtual IList CustomProperties
+ {
+ get
+ {
+ var customProperties = new List();
+ customProperties.Add($"docker.host={this.TcpEndpoint}");
+ customProperties.Add($"docker.cert.path={Path.Combine(this.hostCertsDirectoryPath, "client")}");
+ return customProperties;
+ }
+ }
+
+ private Uri TcpEndpoint
+ {
+ get
+ {
+ return new UriBuilder("tcp", this.container.Hostname, this.container.GetMappedPublicPort(TlsPort)).Uri;
+ }
+ }
+
+ public Task InitializeAsync()
+ {
+ _ = Directory.CreateDirectory(this.hostCertsDirectoryPath);
+ return this.container.StartAsync();
+ }
+
+ public Task DisposeAsync()
+ {
+ return this.container.DisposeAsync().AsTask();
+ }
+ }
+}
diff --git a/tests/Testcontainers.Tests/Unit/Configurations/DockerEndpointAuthenticationProviderTest.cs b/tests/Testcontainers.Tests/Unit/Configurations/DockerEndpointAuthenticationProviderTest.cs
index eeec3102d..ba9d9ad36 100644
--- a/tests/Testcontainers.Tests/Unit/Configurations/DockerEndpointAuthenticationProviderTest.cs
+++ b/tests/Testcontainers.Tests/Unit/Configurations/DockerEndpointAuthenticationProviderTest.cs
@@ -2,6 +2,7 @@ namespace DotNet.Testcontainers.Tests.Unit
{
using System;
using System.Collections.Generic;
+ using System.IO;
using System.Runtime.InteropServices;
using DotNet.Testcontainers.Builders;
using DotNet.Testcontainers.Configurations;
@@ -11,6 +12,22 @@ public sealed class DockerEndpointAuthenticationProviderTest
{
private const string DockerHost = "tcp://127.0.0.1:2375";
+ private const string DockerTlsHost = "tcp://127.0.0.1:2376";
+
+ private static readonly string CertificatesDirectoryPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString("D"));
+
+ private static readonly ICustomConfiguration DockerHostConfiguration = new PropertiesFileConfiguration(new[] { "docker.host=" + DockerHost });
+
+ private static readonly ICustomConfiguration DockerTlsHostConfiguration = new PropertiesFileConfiguration(new[] { "docker.host=" + DockerTlsHost });
+
+ static DockerEndpointAuthenticationProviderTest()
+ {
+ _ = Directory.CreateDirectory(CertificatesDirectoryPath);
+ _ = File.Create(Path.Combine(CertificatesDirectoryPath, "ca.pem"));
+ _ = File.Create(Path.Combine(CertificatesDirectoryPath, "cert.pem"));
+ _ = File.Create(Path.Combine(CertificatesDirectoryPath, "key.pem"));
+ }
+
[Theory]
[ClassData(typeof(AuthProviderTestData))]
internal void AuthProviderShouldBeApplicable(IDockerEndpointAuthenticationProvider authProvider, bool isApplicable)
@@ -35,11 +52,20 @@ public AuthProviderTestData()
{
var isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
var defaultConfiguration = new PropertiesFileConfiguration(Array.Empty());
- var dockerHostConfiguration = new PropertiesFileConfiguration(new[] { "docker.host=" + DockerHost });
+ var dockerTlsConfiguration = new PropertiesFileConfiguration("docker.tls=true", $"docker.cert.path={CertificatesDirectoryPath}");
+ var dockerMTlsConfiguration = new PropertiesFileConfiguration("docker.tls.verify=true", $"docker.cert.path={CertificatesDirectoryPath}");
+ this.Add(new object[] { new MTlsEndpointAuthenticationProvider(defaultConfiguration), false });
+ this.Add(new object[] { new MTlsEndpointAuthenticationProvider(dockerMTlsConfiguration), true });
+ this.Add(new object[] { new MTlsEndpointAuthenticationProvider(Array.Empty()), false });
+ this.Add(new object[] { new MTlsEndpointAuthenticationProvider(defaultConfiguration, dockerMTlsConfiguration), true });
+ this.Add(new object[] { new TlsEndpointAuthenticationProvider(defaultConfiguration), false });
+ this.Add(new object[] { new TlsEndpointAuthenticationProvider(dockerTlsConfiguration), true });
+ this.Add(new object[] { new TlsEndpointAuthenticationProvider(Array.Empty()), false });
+ this.Add(new object[] { new TlsEndpointAuthenticationProvider(defaultConfiguration, dockerTlsConfiguration), true });
this.Add(new object[] { new EnvironmentEndpointAuthenticationProvider(defaultConfiguration), false });
- this.Add(new object[] { new EnvironmentEndpointAuthenticationProvider(dockerHostConfiguration), true });
+ this.Add(new object[] { new EnvironmentEndpointAuthenticationProvider(DockerHostConfiguration), true });
this.Add(new object[] { new EnvironmentEndpointAuthenticationProvider(Array.Empty()), false });
- this.Add(new object[] { new EnvironmentEndpointAuthenticationProvider(defaultConfiguration, dockerHostConfiguration), true });
+ this.Add(new object[] { new EnvironmentEndpointAuthenticationProvider(defaultConfiguration, DockerHostConfiguration), true });
this.Add(new object[] { new NpipeEndpointAuthenticationProvider(), isWindows });
this.Add(new object[] { new UnixEndpointAuthenticationProvider(), !isWindows });
}
@@ -49,8 +75,8 @@ private sealed class AuthConfigTestData : List