aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/Azure
diff options
context:
space:
mode:
authorRoy Ben Shabat <Roy.mail.net@gmail.com>2020-02-06 01:19:06 +0200
committerRoy Ben Shabat <Roy.mail.net@gmail.com>2020-02-06 01:19:06 +0200
commitc210f8d477af51fd70af0901315a48e193568059 (patch)
tree2ceda8036375cedf39bed1ccd652a9d89d2997f0 /Software/Visual_Studio/Azure
parent42f6e5e39ba83531adf8712155ca0015346bd662 (diff)
downloadTango-c210f8d477af51fd70af0901315a48e193568059.tar.gz
Tango-c210f8d477af51fd70af0901315a48e193568059.zip
Working on azure utils...
Diffstat (limited to 'Software/Visual_Studio/Azure')
-rw-r--r--Software/Visual_Studio/Azure/Tango.AzureUtils.UI/ViewModels/EnvironmentCreationViewVM.cs29
-rw-r--r--Software/Visual_Studio/Azure/Tango.AzureUtils.UI/Views/EnvironmentCreationView.xaml5
-rw-r--r--Software/Visual_Studio/Azure/Tango.AzureUtils/AzureUtilsComponentBase.cs39
-rw-r--r--Software/Visual_Studio/Azure/Tango.AzureUtils/AzureUtilsConfirmationEventArgs.cs36
-rw-r--r--Software/Visual_Studio/Azure/Tango.AzureUtils/AzureUtilsStage.cs14
-rw-r--r--Software/Visual_Studio/Azure/Tango.AzureUtils/Deployment/DeploymentManager.cs19
-rw-r--r--Software/Visual_Studio/Azure/Tango.AzureUtils/Environment/EnvironmentManager.cs166
-rw-r--r--Software/Visual_Studio/Azure/Tango.AzureUtils/Tango.AzureUtils.csproj9
8 files changed, 273 insertions, 44 deletions
diff --git a/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/ViewModels/EnvironmentCreationViewVM.cs b/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/ViewModels/EnvironmentCreationViewVM.cs
index 5a1fa8cca..74995c16d 100644
--- a/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/ViewModels/EnvironmentCreationViewVM.cs
+++ b/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/ViewModels/EnvironmentCreationViewVM.cs
@@ -4,6 +4,7 @@ using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
+using System.Windows;
using Microsoft.Azure.Management.AppService.Fluent;
using Microsoft.Azure.Management.Fluent;
using Tango.AzureUtils.ActiveDirectory;
@@ -33,7 +34,7 @@ namespace Tango.AzureUtils.UI.ViewModels
}
private String _slotName;
- [Required]
+ [Required(ErrorMessage = "Deployment slot name is required.")]
public String SlotName
{
get { return _slotName; }
@@ -41,8 +42,8 @@ namespace Tango.AzureUtils.UI.ViewModels
}
private String _email;
- [Required]
- [EmailAddress]
+ [Required(ErrorMessage = "Active directory email is required.")]
+ [EmailAddress(ErrorMessage = "Please enter a valid email.")]
public String Email
{
get { return _email; }
@@ -50,7 +51,7 @@ namespace Tango.AzureUtils.UI.ViewModels
}
private String _password;
- [Required]
+ [Required(ErrorMessage = "Password is required.")]
public String Password
{
get { return _password; }
@@ -67,8 +68,6 @@ namespace Tango.AzureUtils.UI.ViewModels
public override void OnApplicationReady()
{
Email = "roy@twine-s.com";
- Password = "1Creativity";
- SlotName = "ROY";
}
public override void OnAuthenticated(IAzure azure, List<IWebAppBase> apps)
@@ -77,7 +76,21 @@ namespace Tango.AzureUtils.UI.ViewModels
DeploymentSlots = apps.OfType<IDeploymentSlot>().Where(x => x.Parent == _machineServiceApp).ToList();
SelectedDeploymentSlot = DeploymentSlots.FirstOrDefault();
- _environmentManager = new EnvironmentManager(azure, new ActiveDirectoryManager(azure, AzureUtilsAuthenticationFactory.GetCredentials()));
+ _environmentManager = new EnvironmentManager(azure);
+ _environmentManager.ConfirmationRequired += _environmentManager_ConfirmationRequired;
+ _environmentManager.Progress += (x, e) => StatusManager.UpdateStatus(e);
+ }
+
+ private void _environmentManager_ConfirmationRequired(object sender, AzureUtilsConfirmationEventArgs e)
+ {
+ if (MessageBox.Show(e.Message, "Confirmation Required", MessageBoxButton.OKCancel, MessageBoxImage.Question) == MessageBoxResult.OK)
+ {
+ e.Confirm();
+ }
+ else
+ {
+ e.Cancel();
+ }
}
private async void CreateDeploymentSlot()
@@ -87,9 +100,7 @@ namespace Tango.AzureUtils.UI.ViewModels
if (!Validate()) return;
IsFree = false;
- StatusManager.UpdateStatus(AzureUtilsStage.Creating, "Creating new deployment slot...", true);
await _environmentManager.CreateDeploymentSlot(_machineServiceApp as IWebApp, SelectedDeploymentSlot, SlotName, Email, Password);
- StatusManager.UpdateStatus(AzureUtilsStage.Ready, "Deployment slot created successfully.");
}
catch (Exception ex)
{
diff --git a/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/Views/EnvironmentCreationView.xaml b/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/Views/EnvironmentCreationView.xaml
index 4c899bf2d..c7278e2da 100644
--- a/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/Views/EnvironmentCreationView.xaml
+++ b/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/Views/EnvironmentCreationView.xaml
@@ -4,6 +4,7 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:vm="clr-namespace:Tango.AzureUtils.UI.ViewModels"
+ xmlns:helpers="clr-namespace:Tango.SharedUI.Helpers;assembly=Tango.SharedUI"
xmlns:global="clr-namespace:Tango.AzureUtils.UI"
xmlns:local="clr-namespace:Tango.AzureUtils.UI.Views"
mc:Ignorable="d"
@@ -34,9 +35,9 @@
<TextBox Margin="0 2 0 0" FontSize="20" Text="{Binding Email}"></TextBox>
<TextBlock Margin="0 10 0 0">Password</TextBlock>
- <TextBox Margin="0 2 0 0" FontSize="20" Text="{Binding Password}"></TextBox>
+ <PasswordBox Margin="0 2 0 0" FontSize="20" helpers:PasswordHelper.Attach="True" helpers:PasswordHelper.Password="{Binding Password,Mode=TwoWay}"></PasswordBox>
- <Button Margin="0 40 0 0" Padding="20" Command="{Binding CreateDeploymentSlotCommand}">CREATE DEPLOYMENT SLOT</Button>
+ <Button Margin="0 40 0 0" Padding="20" Command="{Binding CreateDeploymentSlotCommand}">CREATE ENVIRONMENT</Button>
</StackPanel>
</Grid>
</Grid>
diff --git a/Software/Visual_Studio/Azure/Tango.AzureUtils/AzureUtilsComponentBase.cs b/Software/Visual_Studio/Azure/Tango.AzureUtils/AzureUtilsComponentBase.cs
index 507c9adbc..5ad584cd7 100644
--- a/Software/Visual_Studio/Azure/Tango.AzureUtils/AzureUtilsComponentBase.cs
+++ b/Software/Visual_Studio/Azure/Tango.AzureUtils/AzureUtilsComponentBase.cs
@@ -5,6 +5,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Tango.Core;
+using Tango.Logging;
namespace Tango.AzureUtils
{
@@ -13,6 +14,7 @@ namespace Tango.AzureUtils
protected IAzure Azure { get; private set; }
public event EventHandler<AzureUtilsProgressEventArgs> Progress;
+ public event EventHandler<AzureUtilsConfirmationEventArgs> ConfirmationRequired;
public AzureUtilsComponentBase(IAzure azure)
{
@@ -21,6 +23,8 @@ namespace Tango.AzureUtils
protected virtual void OnProgress(AzureUtilsStage stage, String message = null, double progress = 0, double maximum = 100, bool indeterminate = true)
{
+ LogManager.Log($"{stage}: {message}");
+
Progress?.Invoke(this, new AzureUtilsProgressEventArgs()
{
Stage = stage,
@@ -30,5 +34,40 @@ namespace Tango.AzureUtils
IsIndeterminate = indeterminate,
});
}
+
+ protected virtual void OnProgress(AzureUtilsProgressEventArgs e)
+ {
+ Progress?.Invoke(this, e);
+ }
+
+ protected async Task<bool> RequestConfirmation(String message, bool throwIfCancel = true)
+ {
+ LogManager.Log($"Confirmation Required: {message}");
+
+ AzureUtilsConfirmationEventArgs e = new AzureUtilsConfirmationEventArgs(message);
+ if (ConfirmationRequired != null)
+ {
+ OnProgress(AzureUtilsStage.ConfirmationRequired, "Waiting for user confirmation...");
+
+ OnRequestConfirmation(e);
+ var result = await e.GetAwaiter();
+
+ if (!result)
+ {
+ throw new OperationCanceledException("Operation canceled.");
+ }
+
+ return result;
+ }
+ else
+ {
+ return true;
+ }
+ }
+
+ protected void OnRequestConfirmation(AzureUtilsConfirmationEventArgs e)
+ {
+ ConfirmationRequired?.Invoke(this, e);
+ }
}
}
diff --git a/Software/Visual_Studio/Azure/Tango.AzureUtils/AzureUtilsConfirmationEventArgs.cs b/Software/Visual_Studio/Azure/Tango.AzureUtils/AzureUtilsConfirmationEventArgs.cs
new file mode 100644
index 000000000..9a27e06de
--- /dev/null
+++ b/Software/Visual_Studio/Azure/Tango.AzureUtils/AzureUtilsConfirmationEventArgs.cs
@@ -0,0 +1,36 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.AzureUtils
+{
+ public class AzureUtilsConfirmationEventArgs : EventArgs
+ {
+ private TaskCompletionSource<bool> _completionSource;
+
+ public String Message { get; set; }
+
+ public AzureUtilsConfirmationEventArgs(String message)
+ {
+ Message = message;
+ _completionSource = new TaskCompletionSource<bool>();
+ }
+
+ internal Task<bool> GetAwaiter()
+ {
+ return _completionSource.Task;
+ }
+
+ public void Confirm()
+ {
+ _completionSource.SetResult(true);
+ }
+
+ public void Cancel()
+ {
+ _completionSource.SetResult(false);
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Azure/Tango.AzureUtils/AzureUtilsStage.cs b/Software/Visual_Studio/Azure/Tango.AzureUtils/AzureUtilsStage.cs
index 3364dc8c7..994ada3aa 100644
--- a/Software/Visual_Studio/Azure/Tango.AzureUtils/AzureUtilsStage.cs
+++ b/Software/Visual_Studio/Azure/Tango.AzureUtils/AzureUtilsStage.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
@@ -12,12 +13,21 @@ namespace Tango.AzureUtils
Initializing,
Error,
Validating,
+ [Description("Confirmation Required")]
+ ConfirmationRequired,
//Deployment
- DownloadingFTP,
- UploadingFTP,
+ Downloading,
+ Uploading,
//Environment
Creating,
+
+ [Description("Environment Group")]
+ EnvironmentGroup,
+ [Description("Deployment Slot")]
+ DeploymentSlot,
+ Database,
+ Storage,
}
}
diff --git a/Software/Visual_Studio/Azure/Tango.AzureUtils/Deployment/DeploymentManager.cs b/Software/Visual_Studio/Azure/Tango.AzureUtils/Deployment/DeploymentManager.cs
index 3c27d8e01..2500b293c 100644
--- a/Software/Visual_Studio/Azure/Tango.AzureUtils/Deployment/DeploymentManager.cs
+++ b/Software/Visual_Studio/Azure/Tango.AzureUtils/Deployment/DeploymentManager.cs
@@ -51,12 +51,12 @@ namespace Tango.AzureUtils.Deployment
_ftpDownloadProgress = new Progress<FtpProgress>((p) =>
{
- OnProgress(AzureUtilsStage.DownloadingFTP, $"Downloading {p.RemotePath}...", p.Progress, 100, false);
+ OnProgress(AzureUtilsStage.Downloading, $"Downloading {p.RemotePath}...", p.Progress, 100, false);
});
_ftpUploadProgress = new Progress<FtpProgress>((p) =>
{
- OnProgress(AzureUtilsStage.UploadingFTP, $"Uploading {p.LocalPath}...", p.Progress, 100, false);
+ OnProgress(AzureUtilsStage.Uploading, $"Uploading {p.LocalPath}...", p.Progress, 100, false);
});
}
@@ -77,6 +77,8 @@ namespace Tango.AzureUtils.Deployment
{
await ValidateUpgrade(sourceApp, targetApp);
+ await OpenSQLExaminerSchema(sourceApp, targetApp);
+ await OpenSQLExaminerData(sourceApp, targetApp);
await UpgradeStorage(sourceApp, targetApp);
await UpgradeVersions(sourceApp, targetApp);
@@ -107,13 +109,21 @@ namespace Tango.AzureUtils.Deployment
File.WriteAllText(tempFile, projectXml.ToString());
Process.Start(tempFile);
+
+ await RequestConfirmation($"Please synchronize the database schema between '{sourceSettings.DB_CATALOG}' and '{targetSettings.DB_CATALOG}'.\nPlease confirm in order to continue.");
+ OnProgress(AzureUtilsStage.Database, $"Waiting for database schema synchronization...");
}
}
- public async Task OpenSQLExaminerData(IWebAppBase sourceApp, IWebAppBase targetApp)
+ public async Task OpenSQLExaminerData(IWebAppBase sourceApp, IWebAppBase targetApp, bool forCreation = false)
{
String projectFile = Path.Combine(AssemblyHelper.GetCurrentAssemblyFolder(), "Deployment", "GENERAL_ENV_UPGRADE.sdeproj");
+ if (forCreation)
+ {
+ projectFile = Path.Combine(AssemblyHelper.GetCurrentAssemblyFolder(), "Deployment", "GENERAL_ENV_CREATE.sdeproj");
+ }
+
using (Stream stream = GetFileStream(projectFile))
{
XElement projectXml = XElement.Load(stream);
@@ -127,6 +137,9 @@ namespace Tango.AzureUtils.Deployment
File.WriteAllText(tempFile, projectXml.ToString());
Process.Start(tempFile);
+
+ await RequestConfirmation($"Please synchronize the database static collections between '{sourceSettings.DB_CATALOG}' and '{targetSettings.DB_CATALOG}'.\nPlease confirm in order to continue.");
+ OnProgress(AzureUtilsStage.Database, $"Waiting for database static collections synchronization...");
}
}
diff --git a/Software/Visual_Studio/Azure/Tango.AzureUtils/Environment/EnvironmentManager.cs b/Software/Visual_Studio/Azure/Tango.AzureUtils/Environment/EnvironmentManager.cs
index c7e48fab1..822813742 100644
--- a/Software/Visual_Studio/Azure/Tango.AzureUtils/Environment/EnvironmentManager.cs
+++ b/Software/Visual_Studio/Azure/Tango.AzureUtils/Environment/EnvironmentManager.cs
@@ -11,6 +11,8 @@ using Microsoft.Azure.Management.Sql.Fluent.Models;
using Microsoft.WindowsAzure.Storage;
using Tango.AzureUtils.ActiveDirectory;
using Tango.AzureUtils.Deployment;
+using Tango.BL;
+using Tango.Core;
using Tango.Core.DB;
namespace Tango.AzureUtils.Environment
@@ -18,88 +20,196 @@ namespace Tango.AzureUtils.Environment
public class EnvironmentManager : AzureUtilsComponentBase
{
private ActiveDirectoryManager _adManager;
+ private DeploymentManager _deploymentManager;
- public EnvironmentManager(IAzure azure, ActiveDirectoryManager activeDirectoryManager) : base(azure)
+ public EnvironmentManager(IAzure azure) : base(azure)
{
- _adManager = activeDirectoryManager;
+ _adManager = new ActiveDirectoryManager(azure, AzureUtilsAuthenticationFactory.GetCredentials());
+ _adManager.ConfirmationRequired += (x, e) => OnRequestConfirmation(e);
+ _adManager.Progress += (x, e) => OnProgress(e);
+
+ _deploymentManager = new DeploymentManager(azure);
+ _deploymentManager.ConfirmationRequired += (x, e) => OnRequestConfirmation(e);
+ _deploymentManager.Progress += (x, e) => OnProgress(e);
}
#region Deployment Slots
- public async Task<IDeploymentSlot> CreateDeploymentSlot(IWebApp app, IDeploymentSlot existingSlot, String name, String adEmail, String adPassword)
+ public async Task<IDeploymentSlot> CreateDeploymentSlot(IWebApp app, IDeploymentSlot sourceSlot, String name, String adEmail, String adPassword)
{
- var settings = await existingSlot.GetMachineServiceSettingsAsync();
-
String dbCatalog = $"Tango_{name}";
String machineStudioContainerName = $"machine-studio-versions-{name.ToLower()}";
String ppcContainerName = $"tango-versions-{name.ToLower()}";
String machineServiceBackupsContainerName = $"machine-service-backups-{name.ToLower()}";
String machineServiceLogsContainerName = $"machine-service-logs-{name.ToLower()}";
String environmentGroupName = $"Tango {name}";
+ String slotName = app.Name + "-" + name;
+ OnProgress(AzureUtilsStage.Initializing, $"Retrieving '{sourceSlot.Name}' settings...");
+ var settings = await sourceSlot.GetMachineServiceSettingsAsync();
+
+ OnProgress(AzureUtilsStage.EnvironmentGroup, $"Authenticating with active directory graph...");
await _adManager.Authenticate(adEmail, adPassword);
if (!await _adManager.IsGroupExists(environmentGroupName))
{
+ OnProgress(AzureUtilsStage.EnvironmentGroup, $"Creating environment group '{environmentGroupName}'...");
await _adManager.AddGroup(environmentGroupName);
+
+ OnProgress(AzureUtilsStage.EnvironmentGroup, $"Adding environment group user '{adEmail}'...");
await _adManager.AddUserToGroup(environmentGroupName, adEmail);
}
+ else
+ {
+ await RequestConfirmation($"Environment group '{environmentGroupName}' already exists. Do you wish to continue?");
+ }
- return new object() as IDeploymentSlot;
+ OnProgress(AzureUtilsStage.DeploymentSlot, $"Checking '{app.Name}' deployment slots...");
+ IDeploymentSlot slot = (await app.DeploymentSlots.ListAsync()).ToList().SingleOrDefault(x => x.Name == slotName);
+
+ if (slot == null)
+ {
+ //Add Slot
+ OnProgress(AzureUtilsStage.DeploymentSlot, $"Creating new deployment slot '{slotName}'...");
- var dictionary = new Dictionary<string, string>();
- dictionary.Add(nameof(MachineServiceSettings.DB_ADDRESS), settings.DB_ADDRESS);
- dictionary.Add(nameof(MachineServiceSettings.DB_CATALOG), dbCatalog);
- dictionary.Add(nameof(MachineServiceSettings.DB_PASSWORD), settings.DB_PASSWORD);
- dictionary.Add(nameof(MachineServiceSettings.DB_USER_NAME), settings.DB_USER_NAME);
- dictionary.Add(nameof(MachineServiceSettings.DEPLOYMENT_SLOT), name);
- dictionary.Add(nameof(MachineServiceSettings.ENFORCE_MACHINE_STUDIO_VERSION), settings.ENFORCE_MACHINE_STUDIO_VERSION);
- dictionary.Add(nameof(MachineServiceSettings.ENVIRONMENT_GROUP), environmentGroupName);
- dictionary.Add(nameof(MachineServiceSettings.STORAGE_ACCOUNT), settings.STORAGE_ACCOUNT);
- dictionary.Add(nameof(MachineServiceSettings.MACHINE_STUDIO_VERSIONS_CONTAINER), machineStudioContainerName);
- dictionary.Add(nameof(MachineServiceSettings.TANGO_VERSIONS_CONTAINER), ppcContainerName);
+ var dictionary = new Dictionary<string, string>();
+ dictionary.Add(nameof(MachineServiceSettings.DB_ADDRESS), settings.DB_ADDRESS);
+ dictionary.Add(nameof(MachineServiceSettings.DB_CATALOG), dbCatalog);
+ dictionary.Add(nameof(MachineServiceSettings.DB_PASSWORD), settings.DB_PASSWORD);
+ dictionary.Add(nameof(MachineServiceSettings.DB_USER_NAME), settings.DB_USER_NAME);
+ dictionary.Add(nameof(MachineServiceSettings.DEPLOYMENT_SLOT), name);
+ dictionary.Add(nameof(MachineServiceSettings.ENFORCE_MACHINE_STUDIO_VERSION), settings.ENFORCE_MACHINE_STUDIO_VERSION);
+ dictionary.Add(nameof(MachineServiceSettings.ENVIRONMENT_GROUP), environmentGroupName);
+ dictionary.Add(nameof(MachineServiceSettings.STORAGE_ACCOUNT), settings.STORAGE_ACCOUNT);
+ dictionary.Add(nameof(MachineServiceSettings.MACHINE_STUDIO_VERSIONS_CONTAINER), machineStudioContainerName);
+ dictionary.Add(nameof(MachineServiceSettings.TANGO_VERSIONS_CONTAINER), ppcContainerName);
- //Add Slot
- var slot = await app.DeploymentSlots
- .Define(app.Name + "-" + name)
+ slot = await app.DeploymentSlots
+ .Define(slotName)
.WithBrandNewConfiguration()
.WithWebAppAlwaysOn(true)
.WithWebSocketsEnabled(true)
.WithStickyAppSettings(dictionary)
.WithStickyConnectionString(dbCatalog, $"Server=tcp:twine.database.windows.net,1433;Initial Catalog={dbCatalog};Persist Security Info=False;User ID=BackupUser;Password=Aa123456;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;", Microsoft.Azure.Management.AppService.Fluent.Models.ConnectionStringType.SQLAzure)
.CreateAsync();
+ }
+ else
+ {
+ await RequestConfirmation($"Deployment slot '{slotName}' already exists. Do you wish to continue.");
+ }
//Add Database
+ OnProgress(AzureUtilsStage.Database, $"Checking twine database server...");
var sqlServer = (await Azure.SqlServers.ListAsync()).SingleOrDefault(x => x.Name == "twine");
- var database = await sqlServer.Databases.Define(dbCatalog).WithEdition(DatabaseEdition.Standard).CreateAsync();
+ var existingDatabase = (await sqlServer.Databases.ListAsync()).SingleOrDefault(x => x.Name == dbCatalog);
+
+ if (existingDatabase == null)
+ {
+ OnProgress(AzureUtilsStage.Database, $"Creating new database '{dbCatalog}'...");
+ var database = await sqlServer.Databases.Define(dbCatalog).WithEdition(DatabaseEdition.Standard).CreateAsync();
+ }
+ else
+ {
+ await RequestConfirmation($"Database '{dbCatalog}' already exists. Do you wish to continue?");
+ }
+
+ //Add permissions for environment group on database
+ OnProgress(AzureUtilsStage.Database, $"Adding environment group permissions on '{dbCatalog}'...");
+ using (DbManager db = DbManager.FromDataSource(new DataSource()
+ {
+ Type = DataSourceType.Azure,
+ Address = settings.DB_ADDRESS,
+ Catalog = dbCatalog,
+ UserName = adEmail,
+ Password = adPassword,
+ IntegratedSecurity = false
+ }))
+ {
+ try
+ {
+ await db.ExecuteCommandAsync($"CREATE USER [{environmentGroupName}] FROM EXTERNAL PROVIDER");
+ await db.ExecuteCommandAsync($"ALTER ROLE db_datareader ADD MEMBER [{environmentGroupName}];");
+ await db.ExecuteCommandAsync($"ALTER ROLE db_datawriter ADD MEMBER [{environmentGroupName}];");
+ }
+ catch (Exception ex)
+ {
+ await RequestConfirmation($"Error creating/adding permissions for environment group '{environmentGroupName}' on database.\n{ex.FlattenMessage()}\n\nDo you wish to continue?");
+ }
+ }
+
+ OnProgress(AzureUtilsStage.Database, $"Adding BackupUser permissions on '{dbCatalog}'...");
+ //Create backup user
using (DbManager db = DbManager.FromCredentials(settings.DB_ADDRESS, dbCatalog, settings.DB_USER_NAME, settings.DB_PASSWORD))
{
- await db.ExecuteCommandAsync("CREATE USER [BackupUser] FOR LOGIN [BackupUser] WITH DEFAULT_SCHEMA=[dbo]");
- await db.ExecuteCommandAsync("EXEC sp_addrolemember N'db_owner', N'BackupUser'");
- await db.ExecuteCommandAsync("EXEC sp_addrolemember N'db_accessadmin', N'BackupUser'");
- await db.ExecuteCommandAsync("EXEC sp_addrolemember N'db_securityadmin', N'BackupUser'");
- await db.ExecuteCommandAsync("EXEC sp_addrolemember N'db_backupoperator', N'BackupUser'");
- await db.ExecuteCommandAsync("EXEC sp_addrolemember N'db_datareader', N'BackupUser'");
- await db.ExecuteCommandAsync("EXEC sp_addrolemember N'db_datawriter', N'BackupUser'");
+ try
+ {
+ await db.ExecuteCommandAsync("CREATE USER [BackupUser] FOR LOGIN [BackupUser] WITH DEFAULT_SCHEMA=[dbo]");
+ await db.ExecuteCommandAsync("EXEC sp_addrolemember N'db_owner', N'BackupUser'");
+ await db.ExecuteCommandAsync("EXEC sp_addrolemember N'db_accessadmin', N'BackupUser'");
+ await db.ExecuteCommandAsync("EXEC sp_addrolemember N'db_securityadmin', N'BackupUser'");
+ await db.ExecuteCommandAsync("EXEC sp_addrolemember N'db_backupoperator', N'BackupUser'");
+ await db.ExecuteCommandAsync("EXEC sp_addrolemember N'db_datareader', N'BackupUser'");
+ await db.ExecuteCommandAsync("EXEC sp_addrolemember N'db_datawriter', N'BackupUser'");
+ }
+ catch (Exception ex)
+ {
+ await RequestConfirmation($"Error creating/adding permissions for BackupUser on database.\n{ex.FlattenMessage()}\n\nDo you wish to continue?");
+ }
}
+ //Synchronize Schema
+ //await _deploymentManager.OpenSQLExaminerSchema(sourceSlot, slot);
+ //await RequestConfirmation($"Please synchronize the database schema between '{settings.DB_CATALOG}' and '{dbCatalog}'.\nPlease confirm in order to continue.");
+ //OnProgress(AzureUtilsStage.Database, $"Waiting for database schema synchronization...");
+
+ //await _deploymentManager.OpenSQLExaminerData(sourceSlot, slot, true);
+ //await RequestConfirmation($"Please synchronize the database static collections between '{settings.DB_CATALOG}' and '{dbCatalog}'.\nPlease confirm in order to continue.");
+ //OnProgress(AzureUtilsStage.Database, $"Waiting for database static collections synchronization...");
+
+ //OnProgress(AzureUtilsStage.Database, $"Retrieving latest Machine Studio version...");
+ //var latestMsVersion = await _deploymentManager.GetLatestMachineStudioVersion(sourceSlot);
+
+ //OnProgress(AzureUtilsStage.Database, $"Retrieving latest PPC version...");
+ //var latestPPCVersion = await _deploymentManager.GetLatestPPCVersion(sourceSlot);
+
+ //var targetSettings = await slot.GetMachineServiceSettingsAsync();
+
+ //using (ObservablesContext db = ObservablesContext.CreateDefault(targetSettings.ToDataSource()))
+ //{
+ // db.MachineStudioVersions.Add(latestMsVersion);
+ // db.TangoVersions.Add(latestPPCVersion);
+ //}
+
//Add Storage Containers
+ OnProgress(AzureUtilsStage.Storage, $"Connecting to storage account...");
var targetAccount = CloudStorageAccount.Parse(settings.STORAGE_ACCOUNT);
var targetClient = targetAccount.CreateCloudBlobClient();
+ OnProgress(AzureUtilsStage.Storage, $"Creating storage container '{machineStudioContainerName}'...");
var machineStudioContainer = targetClient.GetContainerReference(machineStudioContainerName);
await machineStudioContainer.CreateIfNotExistsAsync();
+ OnProgress(AzureUtilsStage.Storage, $"Creating storage container '{ppcContainerName}'...");
var ppcContainer = targetClient.GetContainerReference(ppcContainerName);
await ppcContainer.CreateIfNotExistsAsync();
+ OnProgress(AzureUtilsStage.Storage, $"Creating storage container '{machineServiceBackupsContainerName}'...");
var machineServiceBackupsContainer = targetClient.GetContainerReference(machineServiceBackupsContainerName);
await machineServiceBackupsContainer.CreateIfNotExistsAsync();
+ OnProgress(AzureUtilsStage.Storage, $"Creating storage container '{machineServiceLogsContainerName}'...");
var machineServiceLogsContainer = targetClient.GetContainerReference(machineServiceLogsContainerName);
await machineServiceLogsContainer.CreateIfNotExistsAsync();
+ _deploymentManager.UpgradeConfiguration.UpgradeMachineService = true;
+ _deploymentManager.UpgradeConfiguration.UpgradeMachineStudio = true;
+ _deploymentManager.UpgradeConfiguration.UpgradePPC = true;
+
+ await _deploymentManager.PerformFullUpgrade(sourceSlot, slot);
+
+ OnProgress(AzureUtilsStage.Ready, "Deployment slot created successfully.", 0, 100, false);
+
return slot;
}
diff --git a/Software/Visual_Studio/Azure/Tango.AzureUtils/Tango.AzureUtils.csproj b/Software/Visual_Studio/Azure/Tango.AzureUtils/Tango.AzureUtils.csproj
index 77547a85c..f7a0e2436 100644
--- a/Software/Visual_Studio/Azure/Tango.AzureUtils/Tango.AzureUtils.csproj
+++ b/Software/Visual_Studio/Azure/Tango.AzureUtils/Tango.AzureUtils.csproj
@@ -226,6 +226,7 @@
<Compile Include="AzureUtilsAuthenticationFactory.cs" />
<Compile Include="AzureUtilsComponentBase.cs" />
<Compile Include="AzureUtilsCredentials.cs" />
+ <Compile Include="AzureUtilsConfirmationEventArgs.cs" />
<Compile Include="Deployment\DeploymentManager.cs" />
<Compile Include="AzureUtilsProgressEventArgs.cs" />
<Compile Include="AzureUtilsStage.cs" />
@@ -244,6 +245,10 @@
<Link>Deployment\GENERAL_ENV_UPGRADE.seproj</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
+ <Content Include="..\..\..\DB\SQLExaminer Projects\GENERAL_ENV_CREATE.sdeproj">
+ <Link>Deployment\GENERAL_ENV_CREATE.sdeproj</Link>
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
<None Include="app.config" />
<None Include="packages.config" />
</ItemGroup>
@@ -256,6 +261,10 @@
<Project>{a34ee0f0-649d-41c8-8489-b6f1cc6924ee}</Project>
<Name>Tango.Core</Name>
</ProjectReference>
+ <ProjectReference Include="..\..\Tango.Logging\Tango.Logging.csproj">
+ <Project>{BC932DBD-7CDB-488C-99E4-F02CF441F55E}</Project>
+ <Name>Tango.Logging</Name>
+ </ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project> \ No newline at end of file