Skip to content

Commit b7c4dad

Browse files
authored
AutoWire detected proxies during setup (#59)
1 parent 90fa59a commit b7c4dad

File tree

11 files changed

+102
-37
lines changed

11 files changed

+102
-37
lines changed

examples/Elastic.Ephemeral.Example/Elastic.Ephemeral.Example.csproj

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,11 @@
99
</PropertyGroup>
1010

1111
<ItemGroup>
12-
<ProjectReference Include="..\..\src\Elastic.Elasticsearch.Ephemeral\Elastic.Elasticsearch.Ephemeral.csproj"/>
12+
<ProjectReference Include="..\..\src\Elastic.Elasticsearch.Ephemeral\Elastic.Elasticsearch.Ephemeral.csproj" />
13+
</ItemGroup>
14+
15+
<ItemGroup>
16+
<PackageReference Include="Elastic.Transport" Version="0.4.12" />
1317
</ItemGroup>
1418

1519
</Project>

examples/Elastic.Ephemeral.Example/Program.cs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,12 @@
33
// See the LICENSE file in the project root for more information
44

55
using Elastic.Elasticsearch.Ephemeral;
6+
using Elastic.Elasticsearch.Managed;
7+
using Elastic.Transport;
8+
using Elastic.Transport.Products.Elasticsearch;
9+
using static Elastic.Elasticsearch.Ephemeral.ClusterAuthentication;
610
using static Elastic.Elasticsearch.Ephemeral.ClusterFeatures;
11+
using HttpMethod = Elastic.Transport.HttpMethod;
712

813

914
var config = new EphemeralClusterConfiguration("8.7.0", XPack | Security | SSL);
@@ -16,4 +21,18 @@
1621
exitEvent.Set();
1722
};
1823
using var started = cluster.Start();
24+
25+
var pool = new StaticNodePool(cluster.NodesUris());
26+
var transportConfig = new TransportConfiguration(pool, productRegistration: ElasticsearchProductRegistration.Default)
27+
.Authentication(new BasicAuthentication(Admin.Username, Admin.Password))
28+
.ServerCertificateValidationCallback(CertificateValidations.AllowAll);
29+
if (cluster.DetectedProxy != DetectedProxySoftware.None)
30+
transportConfig = transportConfig.Proxy(new Uri("http://localhost:8080"), null!, null!);
31+
32+
var transport = new DefaultHttpTransport(transportConfig);
33+
34+
var response = await transport.RequestAsync<StringResponse>(HttpMethod.GET, "/");
35+
Console.WriteLine(response);
36+
37+
1938
exitEvent.WaitOne();

examples/ScratchPad/Program.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ private static void ManualConfigRun()
3939
var features = Security | XPack | SSL;
4040
var config = new EphemeralClusterConfiguration(version, features, plugins, 1)
4141
{
42-
HttpFiddlerAware = true,
42+
AutoWireKnownProxies = true,
4343
ShowElasticsearchOutputAfterStarted = true,
4444
CacheEsHomeInstallation = false,
4545
TrialMode = XPackTrialMode.Trial,

examples/ScratchPad/ValidateCombinations.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public static void Run()
3838
Console.WriteLine($"{v} {f}");
3939

4040
Console.ForegroundColor = reset;
41-
var config = new EphemeralClusterConfiguration(v, f, plugins, 1) {HttpFiddlerAware = true,};
41+
var config = new EphemeralClusterConfiguration(v, f, plugins, 1) {AutoWireKnownProxies = true,};
4242

4343
using (var cluster = new EphemeralCluster(config))
4444
try

src/Elastic.Elasticsearch.Ephemeral/EphemeralCluster.cs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,13 @@ protected EphemeralCluster(TConfiguration clusterConfiguration) : base(clusterCo
3737

3838
public virtual ICollection<Uri> NodesUris(string hostName = null)
3939
{
40-
hostName = hostName ?? (ClusterConfiguration.HttpFiddlerAware && Process.GetProcessesByName("fiddler").Any()
41-
? "ipv4.fiddler"
42-
: "localhost");
40+
hostName ??= "localhost";
41+
if (hostName == "localhost" && ClusterConfiguration.AutoWireKnownProxies)
42+
{
43+
if (DetectedProxy == DetectedProxySoftware.Fiddler)
44+
hostName = "ipv4.fiddler"; //magic reverse proxy address for fiddler
45+
}
46+
4347
var ssl = ClusterConfiguration.EnableSsl ? "s" : "";
4448
return Nodes
4549
.Select(n => $"http{ssl}://{hostName}:{n.Port ?? 9200}")

src/Elastic.Elasticsearch.Ephemeral/EphemeralClusterConfiguration.cs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,14 @@ public EphemeralClusterConfiguration(ElasticVersion version, ClusterFeatures fea
8989
/// </summary>
9090
public XPackTrialMode TrialMode { get; set; }
9191

92-
/// <summary> Bootstrapping HTTP calls should attempt to auto route traffic through fiddler if its running </summary>
93-
public bool HttpFiddlerAware { get; set; }
92+
/// <summary>
93+
/// Bootstrapping HTTP calls should attempt to auto route traffic through known proxy software if they are running
94+
/// <list type="buller">
95+
/// <item> <description>Fiddler, typically on Windows</description></item>
96+
/// <item> <description>mitmproxy, typically on non Windows OS's</description></item>
97+
/// </list>
98+
/// </summary>
99+
public bool AutoWireKnownProxies { get; set; }
94100

95101
protected virtual string NodePrefix => "ephemeral";
96102

src/Elastic.Elasticsearch.Ephemeral/Tasks/IClusterComposeTask.cs

Lines changed: 30 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
using System.Text;
1717
using System.Threading;
1818
using System.Threading.Tasks;
19+
using Elastic.Elasticsearch.Managed;
1920
using Elastic.Elasticsearch.Managed.ConsoleWriters;
2021
using ICSharpCode.SharpZipLib.GZip;
2122
using ICSharpCode.SharpZipLib.Tar;
@@ -87,6 +88,9 @@ private HttpResponseMessage Call(
8788
AutomaticDecompression =
8889
DecompressionMethods.Deflate | DecompressionMethods.GZip | DecompressionMethods.None,
8990
};
91+
if (cluster.DetectedProxy != DetectedProxySoftware.None)
92+
handler.Proxy = new WebProxy { Address = new Uri("http://localhost:8080") };
93+
9094
cluster.Writer.WriteDiagnostic(
9195
$"{{{nameof(Call)}}} [{statusUrl}] SSL: {cluster.ClusterConfiguration.EnableSsl} Security: {cluster.ClusterConfiguration.EnableSecurity}");
9296
if (cluster.ClusterConfiguration.EnableSsl)
@@ -98,39 +102,37 @@ private HttpResponseMessage Call(
98102
#endif
99103
}
100104

101-
using (var client = new HttpClient(handler) {Timeout = TimeSpan.FromSeconds(20)})
105+
using var client = new HttpClient(handler) {Timeout = TimeSpan.FromSeconds(20)};
106+
if (cluster.ClusterConfiguration.EnableSecurity)
102107
{
103-
if (cluster.ClusterConfiguration.EnableSecurity)
104-
{
105-
var byteArray =
106-
Encoding.ASCII.GetBytes(
107-
$"{ClusterAuthentication.Admin.Username}:{ClusterAuthentication.Admin.Password}");
108-
client.DefaultRequestHeaders.Authorization =
109-
new AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray));
110-
}
108+
var byteArray =
109+
Encoding.ASCII.GetBytes(
110+
$"{ClusterAuthentication.Admin.Username}:{ClusterAuthentication.Admin.Password}");
111+
client.DefaultRequestHeaders.Authorization =
112+
new AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray));
113+
}
111114

112-
try
113-
{
114-
var response = verb(client, statusUrl, tokenSource.Token).ConfigureAwait(false).GetAwaiter()
115-
.GetResult();
116-
if (response.StatusCode == HttpStatusCode.OK) return response;
117-
cluster.Writer.WriteDiagnostic(
118-
$"{{{nameof(Call)}}} [{statusUrl}] Bad status code: [{(int) response.StatusCode}]");
119-
var body = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();
120-
foreach (var l in (body ?? string.Empty).Split('\n', '\r'))
121-
cluster.Writer.WriteDiagnostic($"{{{nameof(Call)}}} [{statusUrl}] returned [{l}]");
122-
}
123-
catch (Exception e)
124-
{
125-
cluster.Writer.WriteError($"{{{nameof(Call)}}} [{statusUrl}] exception: {e}");
126-
// ignored
127-
}
128-
finally
129-
{
115+
try
116+
{
117+
var response = verb(client, statusUrl, tokenSource.Token).ConfigureAwait(false).GetAwaiter()
118+
.GetResult();
119+
if (response.StatusCode == HttpStatusCode.OK) return response;
120+
cluster.Writer.WriteDiagnostic(
121+
$"{{{nameof(Call)}}} [{statusUrl}] Bad status code: [{(int) response.StatusCode}]");
122+
var body = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();
123+
foreach (var l in (body ?? string.Empty).Split('\n', '\r'))
124+
cluster.Writer.WriteDiagnostic($"{{{nameof(Call)}}} [{statusUrl}] returned [{l}]");
125+
}
126+
catch (Exception e)
127+
{
128+
cluster.Writer.WriteError($"{{{nameof(Call)}}} [{statusUrl}] exception: {e}");
129+
// ignored
130+
}
131+
finally
132+
{
130133
#if !NETSTANDARD
131134
ServicePointManager.ServerCertificateValidationCallback -= ServerCertificateValidationCallback;
132135
#endif
133-
}
134136
}
135137

136138
return null;

src/Elastic.Elasticsearch.Ephemeral/Tasks/InstallationTasks/PrintConfiguration.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ string F(ClusterFeatures feature)
5050
cluster.Writer?.WriteDiagnostic(
5151
$"{{{nameof(PrintConfiguration)}}} {{{nameof(c.SkipBuiltInAfterStartTasks)}}} [{c.SkipBuiltInAfterStartTasks}]");
5252
cluster.Writer?.WriteDiagnostic(
53-
$"{{{nameof(PrintConfiguration)}}} {{{nameof(c.HttpFiddlerAware)}}} [{c.HttpFiddlerAware}]");
53+
$"{{{nameof(PrintConfiguration)}}} {{{nameof(c.AutoWireKnownProxies)}}} [{c.AutoWireKnownProxies}]");
5454
cluster.Writer?.WriteDiagnostic(
5555
$"{{{nameof(PrintConfiguration)}}} {{{nameof(c.NoCleanupAfterNodeStopped)}}} [{c.NoCleanupAfterNodeStopped}]");
5656
}

src/Elastic.Elasticsearch.Managed/ClusterBase.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,15 @@
55
using System;
66
using System.Collections.Generic;
77
using System.Collections.ObjectModel;
8+
using System.Diagnostics;
89
using System.IO;
910
using System.Linq;
1011
using System.Threading;
1112
using Elastic.Elasticsearch.Managed.Configuration;
1213
using Elastic.Elasticsearch.Managed.ConsoleWriters;
1314
using Elastic.Elasticsearch.Managed.FileSystem;
1415
using ProcNet.Std;
16+
using static Elastic.Elasticsearch.Managed.DetectedProxySoftware;
1517

1618
namespace Elastic.Elasticsearch.Managed
1719
{
@@ -30,6 +32,11 @@ public interface ICluster<out TConfiguration> : IDisposable
3032
IDisposable Start(TimeSpan waitForStarted);
3133

3234
IDisposable Start(IConsoleLineHandler writer, TimeSpan waitForStarted);
35+
36+
/// <summary>
37+
/// Whether known proxies were detected as running during startup
38+
/// </summary>
39+
DetectedProxySoftware DetectedProxy { get; }
3340
}
3441

3542

@@ -75,8 +82,18 @@ NodeConfiguration Modify(NodeConfiguration n, int p)
7582
node.NodeConfiguration.InitialMasterNodes(initialMasterNodes);
7683

7784
Nodes = new ReadOnlyCollection<ElasticsearchNode>(nodes);
85+
86+
if (Process.GetProcessesByName("fiddler").Any()) DetectedProxy = Fiddler;
87+
else if (Process.GetProcessesByName("mitmproxy").Any()) DetectedProxy = MitmProxy;
88+
else DetectedProxy = None;
7889
}
7990

91+
/// <summary>
92+
/// Whether known proxies were detected as running during startup
93+
/// </summary>
94+
public DetectedProxySoftware DetectedProxy { get; }
95+
96+
8097
/// <summary>
8198
/// A short name to identify the cluster defaults to the <see cref="ClusterBase" /> subclass name with Cluster
8299
/// removed

src/Elastic.Elasticsearch.Managed/Configuration/ClusterConfiguration.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ public ClusterConfiguration(ElasticVersion version, Func<ElasticVersion, string,
8080
if (logsPathDefault != fs.LogsPath) Add("path.logs", fs.LogsPath);
8181

8282
if (version.Major < 6) Add("path.conf", fs.ConfigPath);
83+
8384
}
8485

8586
public Artifact Artifact { get; }
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// Licensed to Elasticsearch B.V under one or more agreements.
2+
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
3+
// See the LICENSE file in the project root for more information
4+
5+
namespace Elastic.Elasticsearch.Managed;
6+
7+
public enum DetectedProxySoftware
8+
{
9+
None,
10+
Fiddler,
11+
MitmProxy
12+
}

0 commit comments

Comments
 (0)