mirror of
https://github.com/ckaczor/sqltoolsservice.git
synced 2026-01-14 01:25:40 -05:00
Create Firewall Rule support with a simple Resource Provider implementation
Implementation of the resource provider APIs in order to support Create Firewall Rule. Provides definition for a ResourceProvider and Authentication service. The ResourceProvider supports firewall rules for now, and since authentication is routed through that method it will call into the auth service to set up the current account to be used. Additional notes: - Fixed deserialization by adding an Accept header. This shouldn't be necessary, but for some reason the firewall rule defaults to XML without this - Use generic server list and parse the ID to get the resource group, avoiding a large number of extra calls for each RG - Errors now include error message from the API
This commit is contained in:
@@ -0,0 +1,102 @@
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
using System;
|
||||
using System.Data.SqlClient;
|
||||
using System.Net;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Microsoft.SqlTools.ResourceProvider.Core.Firewall
|
||||
{
|
||||
internal interface IFirewallErrorParser
|
||||
{
|
||||
/// <summary>
|
||||
/// Parses given error message and error code to see if it's firewall rule error
|
||||
/// and finds the blocked ip address
|
||||
/// </summary>
|
||||
FirewallParserResponse ParseErrorMessage(string errorMessage, int errorCode);
|
||||
|
||||
/// <summary>
|
||||
/// Parses given error message and error code to see if it's firewall rule error
|
||||
/// and finds the blocked ip address
|
||||
/// </summary>
|
||||
FirewallParserResponse ParseException(SqlException sqlException);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parses an error to check for firewall rule error. Will include the blocked ip address if firewall rule error is detected
|
||||
/// </summary>
|
||||
public class FirewallErrorParser : IFirewallErrorParser
|
||||
{
|
||||
/// <summary>
|
||||
/// Parses given error message and error code to see if it's firewall rule error
|
||||
/// and finds the blocked ip address
|
||||
/// </summary>
|
||||
public FirewallParserResponse ParseException(SqlException sqlException)
|
||||
{
|
||||
CommonUtil.CheckForNull(sqlException, "sqlException");
|
||||
return ParseErrorMessage(sqlException.Message, sqlException.Number);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parses given error message and error code to see if it's firewall rule error
|
||||
/// and finds the blocked ip address
|
||||
/// </summary>
|
||||
public FirewallParserResponse ParseErrorMessage(string errorMessage, int errorCode)
|
||||
{
|
||||
CommonUtil.CheckForNull(errorMessage, "errorMessage");
|
||||
|
||||
FirewallParserResponse response = new FirewallParserResponse();
|
||||
if (IsSqlAzureFirewallBlocked(errorCode))
|
||||
{
|
||||
// Connection failed due to blocked client IP
|
||||
IPAddress clientIp;
|
||||
if (TryParseClientIp(errorMessage, out clientIp))
|
||||
{
|
||||
response = new FirewallParserResponse(true, clientIp);
|
||||
}
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parses the given message to find the blocked ip address
|
||||
/// </summary>
|
||||
private static bool TryParseClientIp(string message, out IPAddress clientIp)
|
||||
{
|
||||
clientIp = null;
|
||||
try
|
||||
{
|
||||
Regex regex =
|
||||
new Regex(
|
||||
@"\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b",
|
||||
RegexOptions.IgnoreCase);
|
||||
Match match = regex.Match(message);
|
||||
|
||||
if (match.Success)
|
||||
{
|
||||
string clientIpValue = match.Value;
|
||||
return IPAddress.TryParse(clientIpValue, out clientIp);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
//TODO: trace?
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if given error code is firewall rule blocked error code
|
||||
/// </summary>
|
||||
private bool IsSqlAzureFirewallBlocked(int errorCode)
|
||||
{
|
||||
return errorCode == SqlAzureFirewallBlockedErrorNumber;
|
||||
}
|
||||
|
||||
private const int SqlAzureFirewallBlockedErrorNumber = 40615; // http://msdn.microsoft.com/en-us/library/windowsazure/ff394106.aspx
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user