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:
Kevin Cunnane
2017-10-09 15:45:33 -07:00
committed by GitHub
parent fecf56bce2
commit 7acc668c04
49 changed files with 1844 additions and 556 deletions

View File

@@ -1,104 +1,120 @@
// WARNING:
// This file was generated by the Microsoft DataWarehouse String Resource Tool 1.37.0.0
// from information in sr.strings
// DO NOT MODIFY THIS FILE'S CONTENTS, THEY WILL BE OVERWRITTEN
//
namespace Microsoft.SqlTools.ResourceProvider.Core
{
using System;
using System.Reflection;
using System.Resources;
using System.Globalization;
// WARNING:
// This file was generated by the Microsoft DataWarehouse String Resource Tool 1.37.0.0
// from information in sr.strings
// DO NOT MODIFY THIS FILE'S CONTENTS, THEY WILL BE OVERWRITTEN
//
namespace Microsoft.SqlTools.ResourceProvider.Core
{
using System;
using System.Reflection;
using System.Resources;
using System.Globalization;
[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class SR
{
protected SR()
{ }
public static CultureInfo Culture
{
get
{
return Keys.Culture;
}
set
{
Keys.Culture = value;
}
}
[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class SR
{
protected SR()
{ }
public static CultureInfo Culture
{
get
{
return Keys.Culture;
}
set
{
Keys.Culture = value;
}
public static string AzureServerNotFound
{
get
{
return Keys.GetString(Keys.AzureServerNotFound);
}
}
public static string AzureServerNotFound
{
get
{
return Keys.GetString(Keys.AzureServerNotFound);
}
public static string AzureSubscriptionFailedErrorMessage
{
get
{
return Keys.GetString(Keys.AzureSubscriptionFailedErrorMessage);
}
}
public static string AzureSubscriptionFailedErrorMessage
{
get
{
return Keys.GetString(Keys.AzureSubscriptionFailedErrorMessage);
}
public static string DatabaseDiscoveryFailedErrorMessage
{
get
{
return Keys.GetString(Keys.DatabaseDiscoveryFailedErrorMessage);
}
}
public static string DatabaseDiscoveryFailedErrorMessage
{
get
{
return Keys.GetString(Keys.DatabaseDiscoveryFailedErrorMessage);
}
public static string FirewallRuleAccessForbidden
{
get
{
return Keys.GetString(Keys.FirewallRuleAccessForbidden);
}
}
public static string FirewallRuleAccessForbidden
{
get
{
return Keys.GetString(Keys.FirewallRuleAccessForbidden);
}
public static string FirewallRuleCreationFailed
{
get
{
return Keys.GetString(Keys.FirewallRuleCreationFailed);
}
}
public static string FirewallRuleCreationFailed
{
get
{
return Keys.GetString(Keys.FirewallRuleCreationFailed);
}
public static string FirewallRuleCreationFailedWithError
{
get
{
return Keys.GetString(Keys.FirewallRuleCreationFailedWithError);
}
}
public static string InvalidIpAddress
{
get
{
return Keys.GetString(Keys.InvalidIpAddress);
}
public static string InvalidIpAddress
{
get
{
return Keys.GetString(Keys.InvalidIpAddress);
}
}
public static string InvalidServerTypeErrorMessage
{
get
{
return Keys.GetString(Keys.InvalidServerTypeErrorMessage);
}
public static string InvalidServerTypeErrorMessage
{
get
{
return Keys.GetString(Keys.InvalidServerTypeErrorMessage);
}
}
public static string LoadingExportableFailedGeneralErrorMessage
{
get
{
return Keys.GetString(Keys.LoadingExportableFailedGeneralErrorMessage);
}
public static string LoadingExportableFailedGeneralErrorMessage
{
get
{
return Keys.GetString(Keys.LoadingExportableFailedGeneralErrorMessage);
}
}
[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
public class Keys
{
static ResourceManager resourceManager = new ResourceManager("Microsoft.SqlTools.ResourceProvider.Core.Localization.SR", typeof(SR).GetTypeInfo().Assembly);
static CultureInfo _culture = null;
public static string FirewallRuleUnsupportedConnectionType
{
get
{
return Keys.GetString(Keys.FirewallRuleUnsupportedConnectionType);
}
}
[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
public class Keys
{
static ResourceManager resourceManager = new ResourceManager("Microsoft.SqlTools.ResourceProvider.Core.Localization.SR", typeof(SR).GetTypeInfo().Assembly);
static CultureInfo _culture = null;
public const string AzureServerNotFound = "AzureServerNotFound";
@@ -116,6 +132,9 @@ namespace Microsoft.SqlTools.ResourceProvider.Core
public const string FirewallRuleCreationFailed = "FirewallRuleCreationFailed";
public const string FirewallRuleCreationFailedWithError = "FirewallRuleCreationFailedWithError";
public const string InvalidIpAddress = "InvalidIpAddress";
@@ -125,25 +144,28 @@ namespace Microsoft.SqlTools.ResourceProvider.Core
public const string LoadingExportableFailedGeneralErrorMessage = "LoadingExportableFailedGeneralErrorMessage";
private Keys()
{ }
public const string FirewallRuleUnsupportedConnectionType = "FirewallRuleUnsupportedConnectionType";
public static CultureInfo Culture
{
get
{
return _culture;
}
set
{
_culture = value;
}
}
public static string GetString(string key)
{
return resourceManager.GetString(key, _culture);
}
private Keys()
{ }
public static CultureInfo Culture
{
get
{
return _culture;
}
set
{
_culture = value;
}
}
public static string GetString(string key)
{
return resourceManager.GetString(key, _culture);
}
}
}

View File

@@ -1,152 +1,160 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype=">text/microsoft-resx</resheader>
<resheader name="version=">2.0</resheader>
<resheader name="reader=">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer=">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1="><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing=">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64=">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64=">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata=">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true=">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded=">
<xsd:element name="metadata=">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly=">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data=">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader=">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="AzureServerNotFound" xml:space="preserve">
<value>The server you specified {0} does not exist in any subscription in {1}. Either you have signed in with an incorrect account or your server was removed from subscription(s) in this account. Please check your account and try again.</value>
<comment></comment>
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype=">text/microsoft-resx</resheader>
<resheader name="version=">2.0</resheader>
<resheader name="reader=">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer=">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1="><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing=">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64=">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64=">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata=">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true=">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded=">
<xsd:element name="metadata=">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly=">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data=">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader=">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="AzureServerNotFound" xml:space="preserve">
<value>The server you specified {0} does not exist in any subscription in {1}. Either you have signed in with an incorrect account or your server was removed from subscription(s) in this account. Please check your account and try again.</value>
<comment></comment>
</data>
<data name="AzureSubscriptionFailedErrorMessage" xml:space="preserve">
<value>An error occurred while getting Azure subscriptions</value>
<comment></comment>
<data name="AzureSubscriptionFailedErrorMessage" xml:space="preserve">
<value>An error occurred while getting Azure subscriptions</value>
<comment></comment>
</data>
<data name="DatabaseDiscoveryFailedErrorMessage" xml:space="preserve">
<value>An error occurred while getting databases from servers of type {0} from {1}</value>
<comment></comment>
<data name="DatabaseDiscoveryFailedErrorMessage" xml:space="preserve">
<value>An error occurred while getting databases from servers of type {0} from {1}</value>
<comment></comment>
</data>
<data name="FirewallRuleAccessForbidden" xml:space="preserve">
<value>{0} does not have permission to change the server firewall rule. Try again with a different account that is an Owner or Contributor of the Azure subscription or the server.</value>
<comment></comment>
<data name="FirewallRuleAccessForbidden" xml:space="preserve">
<value>{0} does not have permission to change the server firewall rule. Try again with a different account that is an Owner or Contributor of the Azure subscription or the server.</value>
<comment></comment>
</data>
<data name="FirewallRuleCreationFailed" xml:space="preserve">
<value>An error occurred while creating a new firewall rule.</value>
<comment></comment>
<data name="FirewallRuleCreationFailed" xml:space="preserve">
<value>An error occurred while creating a new firewall rule.</value>
<comment></comment>
</data>
<data name="InvalidIpAddress" xml:space="preserve">
<value>Invalid IP address</value>
<comment></comment>
<data name="FirewallRuleCreationFailedWithError" xml:space="preserve">
<value>An error occurred while creating a new firewall rule: '{0}'</value>
<comment></comment>
</data>
<data name="InvalidServerTypeErrorMessage" xml:space="preserve">
<value>Server Type is invalid.</value>
<comment></comment>
<data name="InvalidIpAddress" xml:space="preserve">
<value>Invalid IP address</value>
<comment></comment>
</data>
<data name="LoadingExportableFailedGeneralErrorMessage" xml:space="preserve">
<value>A required dll cannot be loaded. Please repair your application.</value>
<comment></comment>
<data name="InvalidServerTypeErrorMessage" xml:space="preserve">
<value>Server Type is invalid.</value>
<comment></comment>
</data>
<data name="LoadingExportableFailedGeneralErrorMessage" xml:space="preserve">
<value>A required dll cannot be loaded. Please repair your application.</value>
<comment></comment>
</data>
<data name="FirewallRuleUnsupportedConnectionType" xml:space="preserve">
<value>Cannot open a firewall rule for the specified connection type</value>
<comment></comment>
</data>
</root>

View File

@@ -27,6 +27,8 @@ AzureSubscriptionFailedErrorMessage = An error occurred while getting Azure subs
DatabaseDiscoveryFailedErrorMessage = An error occurred while getting databases from servers of type {0} from {1}
FirewallRuleAccessForbidden = {0} does not have permission to change the server firewall rule. Try again with a different account that is an Owner or Contributor of the Azure subscription or the server.
FirewallRuleCreationFailed = An error occurred while creating a new firewall rule.
FirewallRuleCreationFailedWithError = An error occurred while creating a new firewall rule: '{0}'
InvalidIpAddress = Invalid IP address
InvalidServerTypeErrorMessage = Server Type is invalid.
LoadingExportableFailedGeneralErrorMessage = A required dll cannot be loaded. Please repair your application.
FirewallRuleUnsupportedConnectionType = Cannot open a firewall rule for the specified connection type

View File

@@ -42,6 +42,16 @@
<target state="new">An error occurred while creating a new firewall rule.</target>
<note></note>
</trans-unit>
<trans-unit id="FirewallRuleUnsupportedConnectionType">
<source>Cannot open a firewall rule for the specified connection type</source>
<target state="new">Cannot open a firewall rule for the specified connection type</target>
<note></note>
</trans-unit>
<trans-unit id="FirewallRuleCreationFailedWithError">
<source>An error occurred while creating a new firewall rule: '{0}'</source>
<target state="new">An error occurred while creating a new firewall rule: '{0}'</target>
<note></note>
</trans-unit>
</body>
</file>
</xliff>