From c5402939737e196a9ea6a82a11a77ae7deeb196b Mon Sep 17 00:00:00 2001 From: Koen Ekelschot Date: Wed, 15 Apr 2020 19:04:21 +0200 Subject: [PATCH] Add Access Token support to SqlServerDatabase (#395) --- product/roundhouse.console/Program.cs | 4 ++++ .../consoles/DefaultConfiguration.cs | 2 ++ .../ConfigurationPropertyHolder.cs | 1 + .../ReliableSqlConnection.cs | 16 +++++++++++++++- .../SqlServerDatabase.cs | 7 +++++++ product/roundhouse.tasks/Roundhouse.cs | 3 +++ 6 files changed, 32 insertions(+), 1 deletion(-) diff --git a/product/roundhouse.console/Program.cs b/product/roundhouse.console/Program.cs index 5d160822..cb075a54 100644 --- a/product/roundhouse.console/Program.cs +++ b/product/roundhouse.console/Program.cs @@ -133,6 +133,9 @@ private static void parse_arguments_and_set_up_configuration(ConfigurationProper string.Format( "ConnectionStringAdministration - This is used for connecting to master when you may have a different uid and password than normal."), option => configuration.ConnectionStringAdmin = option) + .Add("accesstoken=", + "AccessToken - This connection property is used to connect to a SQL Database using an access token (for example Azure AD token).", + option => configuration.AccessToken = option) .Add("ct=|commandtimeout=", string.Format( "CommandTimeout - This is the timeout when commands are run. This is not for admin commands or restore. Defaults to \"{0}\".", @@ -398,6 +401,7 @@ private static void parse_arguments_and_set_up_configuration(ConfigurationProper "/[sql]f[ilesdirectory] VALUE " + "/s[ervername] VALUE " + "/c[onnection]s[tring]a[dministration] VALUE " + + "/accesstoken VALUE " + "/c[ommand]t[imeout] VALUE /c[ommand]t[imeout]a[dmin] VALUE " + "/r[epositorypath] VALUE /v[ersion] VALUE /v[ersion]f[ile] VALUE /v[ersion]x[path] VALUE " + "/a[lter]d[atabasefoldername] /r[un]a[fter]c[reate]d[atabasefoldername] VALUE VALUE " + diff --git a/product/roundhouse.core/consoles/DefaultConfiguration.cs b/product/roundhouse.core/consoles/DefaultConfiguration.cs index 2aa4dbd9..dff16597 100644 --- a/product/roundhouse.core/consoles/DefaultConfiguration.cs +++ b/product/roundhouse.core/consoles/DefaultConfiguration.cs @@ -20,6 +20,7 @@ public DefaultConfiguration() public string DatabaseName { get; set; } public string ConnectionString { get; set; } public string ConnectionStringAdmin { get; set; } + public string AccessToken { get; set; } public int CommandTimeout { get; set; } public int CommandTimeoutAdmin { get; set; } public string SqlFilesDirectory { get; set; } @@ -89,6 +90,7 @@ public string EnvironmentName { public IDictionary to_token_dictionary() { var tokens = new Dictionary(StringComparer.OrdinalIgnoreCase); + tokens["AccessToken"] = AccessToken.to_string(); tokens["AfterMigrationFolderName"] = AfterMigrationFolderName.to_string(); tokens["AlterDatabaseFolderName"] = AlterDatabaseFolderName.to_string(); tokens["Baseline"] = Baseline.to_string(); diff --git a/product/roundhouse.core/infrastructure.app/ConfigurationPropertyHolder.cs b/product/roundhouse.core/infrastructure.app/ConfigurationPropertyHolder.cs index f343583c..c0205a24 100644 --- a/product/roundhouse.core/infrastructure.app/ConfigurationPropertyHolder.cs +++ b/product/roundhouse.core/infrastructure.app/ConfigurationPropertyHolder.cs @@ -14,6 +14,7 @@ public interface ConfigurationPropertyHolder string DatabaseName { get; set; } string ConnectionString { get; set; } string ConnectionStringAdmin { get; set; } + string AccessToken { get; set; } int CommandTimeout { get; set; } int CommandTimeoutAdmin { get; set; } string SqlFilesDirectory { get; set; } diff --git a/product/roundhouse.databases.sqlserver/ReliableSqlConnection.cs b/product/roundhouse.databases.sqlserver/ReliableSqlConnection.cs index 3a9ecddf..59bcee5d 100644 --- a/product/roundhouse.databases.sqlserver/ReliableSqlConnection.cs +++ b/product/roundhouse.databases.sqlserver/ReliableSqlConnection.cs @@ -28,7 +28,8 @@ internal sealed class ReliableSqlConnection : IDbConnection, ICloneable private readonly RetryPolicy connection_string_failover_policy = get_default_retry_policy(); private string connection_string; - + private string access_token; + private static RetryPolicy get_default_retry_policy() { @@ -99,6 +100,19 @@ public string ConnectionString } } + /// + /// Gets or sets the access token for a connection + /// + public string AccessToken + { + get => access_token; + set + { + access_token = value; + underlying_connection.AccessToken = value; + } + } + /// /// Gets the policy that determines whether to retry a connection request, based on how many /// times the request has been made and the reason for the last failure. diff --git a/product/roundhouse.databases.sqlserver/SqlServerDatabase.cs b/product/roundhouse.databases.sqlserver/SqlServerDatabase.cs index a2f4508e..ab4592a1 100644 --- a/product/roundhouse.databases.sqlserver/SqlServerDatabase.cs +++ b/product/roundhouse.databases.sqlserver/SqlServerDatabase.cs @@ -35,6 +35,7 @@ public SqlServerDatabase() private string connect_options = "Integrated Security=SSPI;"; private readonly TransientErrorDetectionStrategy error_detection_strategy = new TransientErrorDetectionStrategy(); + private string access_token; public override string sql_statement_separator_regex_pattern { @@ -50,6 +51,8 @@ public override string sql_statement_separator_regex_pattern public override void initialize_connections(ConfigurationPropertyHolder configuration_property_holder) { + access_token = configuration_property_holder.AccessToken; + if (!string.IsNullOrEmpty(connection_string)) { var connection_string_builder = new SqlConnectionStringBuilder(connection_string); @@ -102,6 +105,10 @@ protected override AdoNetConnection GetAdoNetConnection(string conn_string) var command_retry_policy = Policy.Handle().Retry(0); var connection = new ReliableSqlConnection(conn_string, connection_retry_policy, command_retry_policy); + if (!string.IsNullOrEmpty(access_token)) + { + connection.AccessToken = access_token; + } connection_specific_setup(connection); return new AdoNetConnection(connection); diff --git a/product/roundhouse.tasks/Roundhouse.cs b/product/roundhouse.tasks/Roundhouse.cs index 9732cb90..97304e89 100644 --- a/product/roundhouse.tasks/Roundhouse.cs +++ b/product/roundhouse.tasks/Roundhouse.cs @@ -60,6 +60,8 @@ bool ITask.Execute() public string ConnectionStringAdmin { get; set; } + public string AccessToken { get; set; } + public int CommandTimeout { get; set; } public int CommandTimeoutAdmin { get; set; } @@ -214,6 +216,7 @@ public IDictionary to_token_dictionary() { var tokens = new Dictionary(StringComparer.OrdinalIgnoreCase) { + { nameof(AccessToken), AccessToken.to_string() }, { nameof(AfterMigrationFolderName), AfterMigrationFolderName.to_string() }, { nameof(AlterDatabaseFolderName), AlterDatabaseFolderName.to_string() }, { nameof(Baseline), Baseline.to_string() },