/// <summary> /// Determine the connection string for the specified <see cref="SqlRequest"/>. /// </summary> /// <param name="request"> /// The <see cref="SqlRequest"/> being executed. /// </param> /// <returns> /// The connection string. /// </returns> async Task <string> GetConnectionString(SqlRequest request) { if (request == null) { throw new ArgumentNullException(nameof(request)); } Log.LogInformation("Determining connection string for database {DatabaseId} in server {ServerId}...", request.DatabaseId, request.ServerId ); DatabaseServer targetServer = await DocumentSession.LoadAsync <DatabaseServer>(request.ServerId); if (targetServer == null) { Log.LogWarning("Cannot determine connection string for database {DatabaseId} in server {ServerId} (server not found).", request.DatabaseId, request.ServerId ); throw RespondWith(Ok(new SqlResult { ResultCode = -1, Errors = { new SqlError { Kind = SqlErrorKind.Infrastructure, Message = $"Unable to determine connection settings for database {request.DatabaseId} in server {request.ServerId} (server not found)." } } })); } List <ServiceV1> matchingServices = await KubeClient.ServicesV1().List( labelSelector: $"cloud.dimensiondata.daas.server-id = {targetServer.Id},cloud.dimensiondata.daas.service-type = internal", kubeNamespace: KubeOptions.KubeNamespace ); if (matchingServices.Count == 0) { Log.LogWarning("Cannot determine connection string for database {DatabaseId} in server {ServerId} (server's associated Kubernetes Service not found).", request.DatabaseId, request.ServerId ); throw RespondWith(Ok(new SqlResult { ResultCode = -1, Errors = { new SqlError { Kind = SqlErrorKind.Infrastructure, Message = $"Unable to determine connection settings for database {request.DatabaseId} in server {request.ServerId} (server's associated Kubernetes Service not found)." } } })); } ServiceV1 serverService = matchingServices[matchingServices.Count - 1]; (string serverFQDN, int?serverPort) = serverService.GetHostAndPort(portName: "sql-server"); if (serverPort == null) { Log.LogWarning("Cannot determine connection string for database {DatabaseId} in server {ServerId} (cannot find the port named 'sql-server' on server's associated Kubernetes Service).", request.DatabaseId, request.ServerId ); throw RespondWith(Ok(new SqlResult { ResultCode = -1, Errors = { new SqlError { Kind = SqlErrorKind.Infrastructure, Message = $"Unable to determine connection settings for database {request.DatabaseId} in server {request.ServerId} (cannot find the port named 'sql-server' on server's associated Kubernetes Service)." } } })); } Log.LogInformation("Database proxy will connect to SQL Server '{ServerFQDN}' on {ServerPort}.", serverFQDN, serverPort); var connectionStringBuilder = new SqlClient.SqlConnectionStringBuilder { DataSource = $"tcp:{serverFQDN},{serverPort}", }; var serverSettings = targetServer.GetSettings <SqlServerSettings>(); if (request.DatabaseId != MasterDatabaseId) { DatabaseInstance targetDatabase = await DocumentSession.LoadAsync <DatabaseInstance>(request.DatabaseId); if (targetDatabase == null) { Log.LogWarning("Cannot determine connection string for database {DatabaseId} in server {ServerId} (database not found).", request.DatabaseId, request.ServerId ); throw RespondWith(Ok(new SqlResult { ResultCode = -1, Errors = { new SqlError { Kind = SqlErrorKind.Infrastructure, Message = $"Unable to determine connection settings for database {request.DatabaseId} in server {request.ServerId} (database not found)." } } })); } connectionStringBuilder.InitialCatalog = targetDatabase.Name; if (request.ExecuteAsAdminUser) { connectionStringBuilder.UserID = "sa"; connectionStringBuilder.Password = serverSettings.AdminPassword; } else { connectionStringBuilder.UserID = targetDatabase.DatabaseUser; connectionStringBuilder.Password = targetDatabase.DatabasePassword; } } else { connectionStringBuilder.InitialCatalog = "master"; connectionStringBuilder.UserID = "sa"; connectionStringBuilder.Password = serverSettings.AdminPassword; } Log.LogInformation("Successfully determined connection string for database {DatabaseId} ({DatabaseName}) in server {ServerId} ({ServerSqlName}).", request.DatabaseId, connectionStringBuilder.InitialCatalog, request.ServerId, connectionStringBuilder.DataSource ); return(connectionStringBuilder.ConnectionString); }