Skip to content
This repository has been archived by the owner on Apr 23, 2020. It is now read-only.

Commit

Permalink
Trying a different approach for proxy support using WebProxy.DefaultP…
Browse files Browse the repository at this point in the history
…roxy. Pulled proxy handling in New Relic SDK. Added proxy config section similar to the .NET Agent.
  • Loading branch information
edchapel committed Sep 15, 2013
1 parent 42b72cd commit 372ad47
Show file tree
Hide file tree
Showing 8 changed files with 178 additions and 136 deletions.
Binary file modified lib/NewRelic.Platform.Binding.DotNET.dll
Binary file not shown.
Binary file removed lib/NewRelic.Platform.Binding.DotNET.pdb
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,18 @@ namespace NewRelic.Microsoft.SqlServer.Plugin.Configuration
{
internal class NewRelicConfigurationSection : ConfigurationSection
{
[ConfigurationProperty("service")]
[ConfigurationProperty("service", IsRequired = true)]
public ServiceElement Service
{
get { return ((ServiceElement) (base["service"])); }
}

[ConfigurationProperty("proxy")]
public ProxyElement Proxy
{
get { return ((ProxyElement)(base["proxy"])); }
}

[ConfigurationProperty("sqlServers")]
public SqlServerCollection SqlServers
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
using System.Configuration;

namespace NewRelic.Microsoft.SqlServer.Plugin.Configuration
{
internal class ProxyElement : ConfigurationElement
{
/// <summary>
/// The proxy server host name. Required.
/// </summary>
[ConfigurationProperty("host", DefaultValue = "", IsKey = false, IsRequired = true)]
public string Host
{
get { return ((string)(base["host"])); }
set { base["host"] = value; }
}
/// <summary>
/// The proxy server port (optional - defaults to 8080).
/// </summary>
[ConfigurationProperty("port", DefaultValue = "8080", IsKey = false, IsRequired = false)]
public string Port
{
get { return ((string)(base["port"])); }
set { base["port"] = value; }
}
/// <summary>
/// The username used to authenticate with the proxy server (optional).
/// </summary>
[ConfigurationProperty("user", DefaultValue = "", IsKey = false, IsRequired = false)]
public string User
{
get { return ((string)(base["user"])); }
set { base["user"] = value; }
}
/// <summary>
/// The password used to authenticate with the proxy server (optional).
/// </summary>
[ConfigurationProperty("password", DefaultValue = "", IsKey = false, IsRequired = false)]
public string Password
{
get { return ((string)(base["password"])); }
set { base["password"] = value; }
}
/// <summary>
/// The domain used to authenticate with the proxy server (optional).
/// </summary>
[ConfigurationProperty("domain", DefaultValue = "", IsKey = false, IsRequired = false)]
public string Domain
{
get { return ((string)(base["domain"])); }
set { base["domain"] = value; }
}
/// <summary>
/// 'true' or 'false. Uses the credentials of the account running the plugin (optional - defaults to false).
/// </summary>
[ConfigurationProperty("useDefaultCredentials", DefaultValue = "false", IsKey = false, IsRequired = false)]
public string UseDefaultCredentials
{
get { return ((string)(base["useDefaultCredentials"])); }
set { base["useDefaultCredentials"] = value; }
}
}
}
71 changes: 71 additions & 0 deletions src/NewRelic.Microsoft.SqlServer.Plugin/Configuration/Settings.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Security.Principal;
using System.Text.RegularExpressions;
Expand All @@ -13,6 +14,7 @@ namespace NewRelic.Microsoft.SqlServer.Plugin.Configuration
public class Settings
{
private string _version;
private static string _ProxyDetails;

public Settings(ISqlEndpoint[] endpoints)
{
Expand Down Expand Up @@ -74,9 +76,72 @@ internal static Settings FromConfigurationSection(NewRelicConfigurationSection s
settings.ServiceName = service.ServiceName;
}

var webProxy = GetWebProxy(section, log);
if (webProxy != null)
{
WebRequest.DefaultWebProxy = webProxy;
}

return settings;
}

private static IWebProxy GetWebProxy(NewRelicConfigurationSection section, ILog log)
{
var proxyElement = section.Proxy;
if (proxyElement == null || !proxyElement.ElementInformation.IsPresent) return null;

Uri uri;
if (!Uri.TryCreate(proxyElement.Host, UriKind.RelativeOrAbsolute, out uri))
{
log.ErrorFormat("Proxy host '{0}' is not a valid URI, skipping proxy.", proxyElement.Host);
return null;
}

int port;
if (!int.TryParse(proxyElement.Port, out port))
{
log.ErrorFormat("Unable to parse proxy port from '{0}', skipping proxy. Expecting a number from 1-65535.", proxyElement.Port);
return null;
}

WebProxy webProxy;
try
{
webProxy = new WebProxy(proxyElement.Host, port);
}
catch (Exception e)
{
log.ErrorFormat("Proxy settings are invalid. {0}", e.Message);
return null;
}

if ("true".Equals(proxyElement.UseDefaultCredentials, StringComparison.InvariantCultureIgnoreCase))
{
webProxy.UseDefaultCredentials = true;
webProxy.Credentials = CredentialCache.DefaultCredentials;
_ProxyDetails = string.Format("Proxy Server: {0}:{1} with default credentials", proxyElement.Host, port);
}
else if (!string.IsNullOrEmpty(proxyElement.User))
{
if (string.IsNullOrEmpty(proxyElement.Domain))
{
webProxy.Credentials = new NetworkCredential(proxyElement.User, proxyElement.Password);
_ProxyDetails = string.Format("Proxy Server: {0}@{1}:{2}", proxyElement.User, proxyElement.Host, port);
}
else
{
webProxy.Credentials = new NetworkCredential(proxyElement.User, proxyElement.Password, proxyElement.Domain);
_ProxyDetails = string.Format("Proxy Server: {0}\\{1}@{2}:{3}", proxyElement.Domain, proxyElement.User, proxyElement.Host, port);
}
}
else
{
_ProxyDetails = string.Format("Proxy Server: {0}:{1}", proxyElement.Host, port);
}

return webProxy;
}

public void ToLog(ILog log)
{
// Pending review by New Relic before adding this information
Expand All @@ -87,6 +152,12 @@ public void ToLog(ILog log)
log.Info(" Windows Service: " + (Environment.UserInteractive ? "No" : "Yes"));
log.InfoFormat(@" User: {0}\{1}", Environment.UserDomainName, Environment.UserName);
log.Info(" Run as Administrator: " + (IsProcessElevated ? "Yes" : "No"));

if (_ProxyDetails != null)
{
log.Info(" " + _ProxyDetails);
}

log.Info(" Total Endpoints: " + Endpoints.Length);
log.Info(" Poll Interval Seconds: " + PollIntervalSeconds);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@
<Compile Include="Configuration\Database.cs" />
<Compile Include="Configuration\DatabaseCollection.cs" />
<Compile Include="Configuration\DatabaseElement.cs" />
<Compile Include="Configuration\ProxyElement.cs" />
<Compile Include="IMetricQuery.cs" />
<Compile Include="IQueryContext.cs" />
<Compile Include="ISqlEndpoint.cs" />
Expand Down
87 changes: 19 additions & 68 deletions src/NewRelic.Microsoft.SqlServer.Plugin/app.config
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,6 @@
<section name="newRelic" type="NewRelic.Microsoft.SqlServer.Plugin.Configuration.NewRelicConfigurationSection, NewRelic.Microsoft.SqlServer.Plugin" />
</configSections>

<appSettings>
<!--
Proxy Settings [Optional] - See Network Settings below for further explaination
proxyAddress [Optional when using proxy with default credentials off]
Defines the address of the target proxy
proxyUsername [Required when using proxy with default credentials off]
Defines the username to log onto the proxy. This name can be prefixed with the
appropriate domain for example "OFFICE\jsmith"
proxyPassword [Required when using proxy with default credentials off]
Defines the password for the above account, used when initiating a request through the proxy
-->
<!--
<add key="proxyAddress" value="http://www.proxyaddress:5503"/>
<add key="proxyUsername" value="OFFICE\jdoe"/>
<add key="proxyPassword" value="p@ssw0rd"/>
-->
</appSettings>
<newRelic>
<!--
licenseKey [Required]
Expand All @@ -38,6 +18,24 @@
######
-->
<service licenseKey="YOUR_KEY_HERE" pollIntervalSeconds="60" />

<!-- Proxy settings for connecting to the New Relic service. -->
<!-- If a proxy is used, the host attribute is required.
Attributes:
host - The proxy server host name.
port - The proxy server port (optional - defaults to 8080).
user - The username used to authenticate with the proxy server (optional).
password - The password used to authenticate with the proxy server (optional).
domain - The domain used to authenticate with the proxy server (optional).
useDefaultCredentials - 'true' or 'false. Uses the credentials of the account running the plugin (optional - defaults to false).
If specified, 'user' and 'password' are ignored.
-->

<!--
<proxy host="hostname" />
-->

<!-- List of SQL Server instances. Server 2008, 2008 R2, and 2012 supported. -->
<sqlServers>
<!--
Expand Down Expand Up @@ -105,51 +103,4 @@
connectionString="Server=tcp:{Azure SQL Server Name}.database.windows.net,1433;Database={Azure SQL Database Name};User ID={Azure SQL User Name}@{Azure SQL Server Name};Password={Password for User Name};Trusted_Connection=False;Encrypt=True;Connection Timeout=30;" />
</azure>
</newRelic>

<!--
Network Settings
================
These settings are optional, but necessary to make the plugin work in environments that use a proxy server to communicate with the outside world.
Example 1 - default credentials
If the host machine is already configured to use the proxy and the credentials under which the plugin Windows Service is running can access the proxy,
Then all you have to do is tell the app to use the default proxy settings like so:
-->
<!--
<system.net>
<defaultProxy enabled="true" useDefaultCredentials="true">
<proxy usesystemdefault="True" bypassonlocal="True" />
</defaultProxy>
</system.net>
-->
<!--
Example 2 - alternate credentials
If the proxy requires login credentials different from those under which the plugin Windows Service is running, you will need to the following configuration.
The configuration below, tells the app to use our custom Proxy provider that will get its credential information from the "proxyUsername" and "proxyPassword" appSettings
-->
<!--
<system.net>
<defaultProxy enabled="true" useDefaultCredentials="false">
<module type="NewRelic.Platform.Binding.DotNET.Proxy, NewRelic.Platform.Binding.DotNET"/>
</defaultProxy>
</system.net>
-->
<!--
Which will also require that you add proxyUsername and proxyPassword to <appSettings> at the top of the file.
In addition you can optionally specify to use any proxy address by setting proxyAddress (leaving this off, the plugin will use the proxy address used configured in Windows internet options)
For example these values could be:
<add key="proxyUsername" value="OFFICE\jdoe"/>
<add key="proxyPassword" value="p@ssw0rd"/>
And if you so desire:
<add key="proxyAddress" value="http://www.proxyaddress:5503"/>
-->

</configuration>
</configuration>
Loading

0 comments on commit 372ad47

Please sign in to comment.