From 384ef8966066b6c2ee973b906ff78418f533f174 Mon Sep 17 00:00:00 2001 From: Roy Ben-Shabat Date: Mon, 3 Feb 2020 19:57:18 +0200 Subject: Working on Azure Utils. --- .../Azure/Tango.AzureUtils.UI/App.config | 4 + .../Azure/Tango.AzureUtils.UI/MainWindow.xaml.cs | 29 ++ .../Tango.AzureUtils.UI/Tango.AzureUtils.UI.csproj | 4 + .../Deployment/DeploymentManager.cs | 484 +++++++++++++++++++-- .../Deployment/DeploymentProgressEventArgs.cs | 17 + .../Tango.AzureUtils/Deployment/DeploymentStage.cs | 16 + .../Deployment/ExtensionMethods.cs | 18 +- .../Deployment/UpgradeConfiguration.cs | 15 + .../Azure/Tango.AzureUtils/Tango.AzureUtils.csproj | 32 ++ .../Azure/Tango.AzureUtils/app.config | 14 + .../Azure/Tango.AzureUtils/packages.config | 2 + 11 files changed, 600 insertions(+), 35 deletions(-) create mode 100644 Software/Visual_Studio/Azure/Tango.AzureUtils/Deployment/DeploymentProgressEventArgs.cs create mode 100644 Software/Visual_Studio/Azure/Tango.AzureUtils/Deployment/DeploymentStage.cs create mode 100644 Software/Visual_Studio/Azure/Tango.AzureUtils/Deployment/UpgradeConfiguration.cs (limited to 'Software/Visual_Studio/Azure') diff --git a/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/App.config b/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/App.config index eb51eb63b..2b12e43f8 100644 --- a/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/App.config +++ b/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/App.config @@ -9,6 +9,10 @@ + + + + \ No newline at end of file diff --git a/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/MainWindow.xaml.cs b/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/MainWindow.xaml.cs index c7d1728bd..2ba632f76 100644 --- a/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/MainWindow.xaml.cs +++ b/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/MainWindow.xaml.cs @@ -20,9 +20,38 @@ namespace Tango.AzureUtils.UI /// public partial class MainWindow : Window { + private static string app_id = "be33437c-5052-449f-ab9d-a88d008eae24"; + private static string client_secret = "bf67fb6f-4d06-4893-988c-6b347aff23d6"; + private static string tenant_id = "2ebd63a5-bc2f-41dc-9066-4409ed5e5dd4"; + private static string subscription_id = "10c8aa60-3b15-4e0d-b412-6aeef90e5e91"; + + Tango.AzureUtils.Deployment.DeploymentManager manager = new Deployment.DeploymentManager(new AzureUtilsCredentials() + { + ClientID = app_id, + ClientSecret = client_secret, + TenantID = tenant_id, + SubscriptionID = subscription_id + }); + public MainWindow() { InitializeComponent(); + + Test(); + } + + private async void Test() + { + var apps = await manager.GetAllWebAppsAsync(); + + var machineService = apps.SingleOrDefault(x => x.Name == "MachineService"); + + var devSlot = await machineService.DeploymentSlots.GetByNameAsync("MachineService-DEV"); + var testSlot = await machineService.DeploymentSlots.GetByNameAsync("MachineService-TEST"); + + await manager.OpenSQLExaminerData(devSlot, testSlot); + + var a = 5; } } } diff --git a/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/Tango.AzureUtils.UI.csproj b/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/Tango.AzureUtils.UI.csproj index 08d69d41d..c2b723760 100644 --- a/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/Tango.AzureUtils.UI.csproj +++ b/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/Tango.AzureUtils.UI.csproj @@ -227,6 +227,10 @@ + + {a34ee0f0-649d-41c8-8489-b6f1cc6924ee} + Tango.Core + {4a6b97e5-5eba-4702-a016-6f4004f14b08} Tango.AzureUtils diff --git a/Software/Visual_Studio/Azure/Tango.AzureUtils/Deployment/DeploymentManager.cs b/Software/Visual_Studio/Azure/Tango.AzureUtils/Deployment/DeploymentManager.cs index e9ae6e97b..8a3b6ad7b 100644 --- a/Software/Visual_Studio/Azure/Tango.AzureUtils/Deployment/DeploymentManager.cs +++ b/Software/Visual_Studio/Azure/Tango.AzureUtils/Deployment/DeploymentManager.cs @@ -1,4 +1,5 @@ -using Microsoft.Azure.Management.AppService.Fluent; +using FluentFTP; +using Microsoft.Azure.Management.AppService.Fluent; using Microsoft.Azure.Management.Fluent; using Microsoft.Azure.Management.ResourceManager.Fluent; using Microsoft.Azure.Management.ResourceManager.Fluent.Authentication; @@ -6,27 +7,70 @@ using Microsoft.Azure.Storage; using Microsoft.Azure.Storage.Blob; using System; using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Data.Entity; +using System.Diagnostics; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; +using System.Xml; +using System.Xml.Linq; +using Tango.BL; +using Tango.BL.Entities; +using Tango.Core; +using Tango.Core.Helpers; namespace Tango.AzureUtils.Deployment { - public class DeploymentManager + public class DeploymentManager : ExtendedObject { private AzureUtilsCredentials _credentials; private IAzure _azure; + private IProgress _ftpDownloadProgress; + private IProgress _ftpUploadProgress; + + //TODO: Embedded TFP injection to current package! + + #region Events + + public event EventHandler DeploymentProgress; + + #endregion + + #region Properties + + private UpgradeConfiguration _upgradeConfiguration; + public UpgradeConfiguration UpgradeConfiguration + { + get { return _upgradeConfiguration; } + set { _upgradeConfiguration = value; RaisePropertyChangedAuto(); } + } + + #endregion + + #region Constructors public DeploymentManager(AzureUtilsCredentials credentials) { + UpgradeConfiguration = new UpgradeConfiguration(); + _credentials = credentials; + + _ftpDownloadProgress = new Progress((p) => + { + OnProgress(DeploymentStage.DownloadingFTP, $"Downloading {p.RemotePath}...", p.Progress, 100, false); + }); + + _ftpUploadProgress = new Progress((p) => + { + OnProgress(DeploymentStage.UploadingFTP, $"Uploading {p.LocalPath}...", p.Progress, 100, false); + }); } - private static string app_id = "be33437c-5052-449f-ab9d-a88d008eae24"; - private static string client_secret = "bf67fb6f-4d06-4893-988c-6b347aff23d6"; - private static string tenant_id = "2ebd63a5-bc2f-41dc-9066-4409ed5e5dd4"; - private static string subscription_id = "10c8aa60-3b15-4e0d-b412-6aeef90e5e91"; + #endregion + + #region Authenticate private IAzure GetOrCreateAzure() { @@ -44,56 +88,430 @@ namespace Tango.AzureUtils.Deployment return _azure; } - public List GetAllWebApps() + #endregion + + #region Helpers + + public async Task> GetAllWebAppsAsync() + { + return (await GetOrCreateAzure().WebApps.ListAsync()).ToList(); + } + + #endregion + + #region Init + + public void Init() + { + GetOrCreateAzure(); + } + + #endregion + + #region Full Upgrade + + public async Task PerformFullUpgrade(IWebAppBase sourceApp, IWebAppBase targetApp) + { + await ValidateUpgrade(sourceApp, targetApp); + + await UpgradeStorage(sourceApp, targetApp); + await UpgradeVersions(sourceApp, targetApp); + + if (UpgradeConfiguration.UpgradeMachineService) + { + await UpgradeMachineService(sourceApp, targetApp); + } + } + + #endregion + + #region SQLExaminer + + public async Task OpenSQLExaminerSchema(IWebAppBase sourceApp, IWebAppBase targetApp) + { + String projectFile = Path.Combine(AssemblyHelper.GetCurrentAssemblyFolder(), "Deployment", "GENERAL_ENV_UPGRADE.seproj"); + + using (Stream stream = GetFileStream(projectFile)) + { + XElement projectXml = XElement.Load(stream); + var sourceSettings = await sourceApp.GetMachineServiceSettingsAsync(); + var targetSettings = await targetApp.GetMachineServiceSettingsAsync(); + ApplyDatabaseSettingsToProjectXml(projectXml, sourceSettings, targetSettings); + + var tempFile = TemporaryManager.CreateImaginaryFile(".seproj"); + tempFile.Persist = true; + + File.WriteAllText(tempFile, projectXml.ToString()); + + Process.Start(tempFile); + } + } + + public async Task OpenSQLExaminerData(IWebAppBase sourceApp, IWebAppBase targetApp) + { + String projectFile = Path.Combine(AssemblyHelper.GetCurrentAssemblyFolder(), "Deployment", "GENERAL_ENV_UPGRADE.sdeproj"); + + using (Stream stream = GetFileStream(projectFile)) + { + XElement projectXml = XElement.Load(stream); + var sourceSettings = await sourceApp.GetMachineServiceSettingsAsync(); + var targetSettings = await targetApp.GetMachineServiceSettingsAsync(); + ApplyDatabaseSettingsToProjectXml(projectXml, sourceSettings, targetSettings); + + var tempFile = TemporaryManager.CreateImaginaryFile(".sdeproj"); + tempFile.Persist = true; + + File.WriteAllText(tempFile, projectXml.ToString()); + + Process.Start(tempFile); + } + } + + private Stream GetFileStream(String projectFile) + { + byte[] projectBytes = File.ReadAllBytes(projectFile); + MemoryStream stream = new MemoryStream(projectBytes); + return stream; + } + + private void ApplyDatabaseSettingsToProjectXml(XElement projectXml, MachineServiceSettings sourceSettings, MachineServiceSettings targetSettings) + { + var sourceElement = projectXml.Elements().SelectMany(x => x.Descendants()).SingleOrDefault(x => x.Name == "Source" && x.Attributes().SingleOrDefault(y => y.Name == "id").Value == "1"); + var targetElement = projectXml.Elements().SelectMany(x => x.Descendants()).SingleOrDefault(x => x.Name == "Source" && x.Attributes().SingleOrDefault(y => y.Name == "id").Value == "2"); + + ApplyDatabaseSettingsToSourceElement(sourceElement, sourceSettings); + ApplyDatabaseSettingsToSourceElement(targetElement, targetSettings); + } + + private void ApplyDatabaseSettingsToSourceElement(XElement sourceElement, MachineServiceSettings settings) + { + sourceElement.Element("ServerName").SetValue(settings.DB_ADDRESS); + sourceElement.Element("Database").SetValue(settings.DB_CATALOG); + sourceElement.Element("Login").SetValue(settings.DB_USER_NAME); + sourceElement.Element("Password").SetValue(settings.DB_PASSWORD); + } + + #endregion + + #region FTP + + private async Task> DownloadWebAppFiles(IWebAppBase app, String targetFolder) + { + var profile = await app.GetPublishingProfileAsync(); + + using (var ftp = new FtpClient(profile.FtpUrl, profile.FtpUsername, profile.FtpPassword)) + { + var downloadResults = await ftp.DownloadDirectoryAsync(targetFolder, "/site/wwwroot", progress: _ftpDownloadProgress); + + foreach (var downloadResult in downloadResults) + { + if (downloadResult.IsFailed) + { + throw downloadResult.Exception; + } + } + + return downloadResults; + } + } + + private async Task> UploadWebAppFiles(IWebAppBase app, String sourceFolder) + { + var profile = await app.GetPublishingProfileAsync(); + + using (var ftp = new FtpClient(profile.FtpUrl, profile.FtpUsername, profile.FtpPassword)) + { + var uploadResults = await ftp.UploadDirectoryAsync(sourceFolder, "/site/wwwroot", existsMode: FtpRemoteExists.Overwrite, progress: _ftpUploadProgress); + + foreach (var uploadResult in uploadResults) + { + if (uploadResult.IsFailed) + { + throw uploadResult.Exception; + } + } + + return uploadResults; + } + } + + #endregion + + #region Machine Service + + public async Task UpgradeMachineService(IWebAppBase sourceApp, IWebAppBase targetApp) + { + var webAppFilesTempFolder = TemporaryManager.CreateFolder(); + var downloadResults = await DownloadWebAppFiles(sourceApp, webAppFilesTempFolder); + var uploadResults = await UploadWebAppFiles(targetApp, webAppFilesTempFolder + "\\wwwroot"); + } + + #endregion + + #region Applications Versions & Storage Blobs + + public async Task GetLatestMachineStudioVersion(IWebAppBase app) + { + MachineServiceSettings settings = null; + + try + { + settings = await app.GetMachineServiceSettingsAsync(); + } + catch (Exception ex) + { + throw new ArgumentException("Could not fetch machine service settings. Please check that all settings are available."); + } + + try + { + DataSource dataSource = settings.ToDataSource(); + + using (var db = ObservablesContext.CreateDefault(dataSource)) + { + var versions = await db.MachineStudioVersions.ToListAsync(); + var latest_machine_version = versions.OrderByDescending(x => Version.Parse(x.Version)).FirstOrDefault(); + return latest_machine_version; + } + } + catch (Exception ex) + { + throw new InvalidDataException("Could not retrieve latest Machine Studio version from database.", ex); + } + } + + public async Task GetLatestPPCVersion(IWebAppBase app) { - return GetOrCreateAzure().WebApps.List().ToList(); + MachineServiceSettings settings = null; + + try + { + settings = await app.GetMachineServiceSettingsAsync(); + } + catch (Exception ex) + { + throw new ArgumentException("Could not fetch machine service settings. Please check that all settings are available.", ex); + } + + try + { + DataSource dataSource = settings.ToDataSource(); + + using (var db = ObservablesContext.CreateDefault(dataSource)) + { + var versions = await db.TangoVersions.ToListAsync(); + var latest_machine_version = versions.OrderByDescending(x => Version.Parse(x.Version)).FirstOrDefault(); + return latest_machine_version; + } + } + catch (Exception ex) + { + throw new InvalidDataException("Could not retrieve latest PPC version from database.", ex); + } } - public void UpdateSlot(IDeploymentSlot slot) + public async Task UpgradeStorage(IWebAppBase sourceApp, IWebAppBase targetApp) { - + await ValidateUpgrade(sourceApp, targetApp); + + var latestMachineStudioVersion = await GetLatestMachineStudioVersion(sourceApp); + var latestPPCVersion = await GetLatestPPCVersion(sourceApp); + + var sourceSettings = await sourceApp.GetMachineServiceSettingsAsync(); + var targetSettings = await targetApp.GetMachineServiceSettingsAsync(); + + var sourceAccount = CloudStorageAccount.Parse(sourceSettings.STORAGE_ACCOUNT); + var sourceClient = sourceAccount.CreateCloudBlobClient(); + + var targetAccount = CloudStorageAccount.Parse(targetSettings.STORAGE_ACCOUNT); + var targetClient = targetAccount.CreateCloudBlobClient(); + + var sourceMachineStudioContainer = sourceClient.GetContainerReference(sourceSettings.MACHINE_STUDIO_VERSIONS_CONTAINER); + var targetMachineStudioContainer = targetClient.GetContainerReference(targetSettings.MACHINE_STUDIO_VERSIONS_CONTAINER); + + var sourcePPCContainer = sourceClient.GetContainerReference(sourceSettings.TANGO_VERSIONS_CONTAINER); + var targetPPCContainer = targetClient.GetContainerReference(targetSettings.TANGO_VERSIONS_CONTAINER); + + var sourceMachineStudioBlob = sourceMachineStudioContainer.GetBlockBlobReference(latestMachineStudioVersion.BlobName); + var sourceMachineStudioInstallerBlob = sourceMachineStudioContainer.GetBlockBlobReference(latestMachineStudioVersion.InstallerBlobName); + + var targetMachineStudioBlob = CreateEmptyBlob(targetMachineStudioContainer, sourceMachineStudioBlob.Name); + var targetMachineStudioInstallerBlob = CreateEmptyBlob(targetMachineStudioContainer, sourceMachineStudioInstallerBlob.Name); + + await Task.Factory.StartNew(() => + { + targetMachineStudioBlob.StartCopy(sourceMachineStudioBlob); + targetMachineStudioInstallerBlob.StartCopy(sourceMachineStudioInstallerBlob); + }); } - public void Deploy() + public async Task UpgradeVersions(IWebAppBase sourceApp, IWebAppBase targetApp) { - var credentials = SdkContext.AzureCredentialsFactory.FromServicePrincipal( - app_id, - client_secret, - tenant_id, - AzureEnvironment.AzureGlobalCloud); + await ValidateUpgrade(sourceApp, targetApp); + + if (UpgradeConfiguration.UpgradeMachineStudio) + { + await UpgradeMachineStudioVersion(sourceApp, targetApp); + } - var azure = Azure.Authenticate(credentials).WithSubscription(subscription_id); - var webApps = azure.WebApps.List(); + if (UpgradeConfiguration.UpgradePPC) + { + await UpgradePPCVersion(sourceApp, targetApp); + } + } - var machineService = webApps.SingleOrDefault(x => x.Name == "MachineService"); - var devSlot = machineService.DeploymentSlots.GetByName("MachineService-DEV"); - var devProfile = devSlot.GetPublishingProfile(); + private async Task UpgradeMachineStudioVersion(IWebAppBase sourceApp, IWebAppBase targetApp) + { + var latestMachineStudioVersion = await GetLatestMachineStudioVersion(sourceApp); - String ftpAddress = devProfile.FtpUrl; - String ftpUser = devProfile.FtpUsername; - String ftpPassword = devProfile.FtpPassword; + var targetDataSource = (await targetApp.GetMachineServiceSettingsAsync()).ToDataSource(); - foreach (var ds in machineService.DeploymentSlots.List()) + using (var db = ObservablesContext.CreateDefault(targetDataSource)) { - Console.WriteLine(ds.Name); + db.MachineStudioVersions.Add(latestMachineStudioVersion); + await db.SaveChangesAsync(); } + } - CloudStorageAccount sourceAccount = CloudStorageAccount.Parse("DefaultEndpointsProtocol=https;AccountName=tangostorage;AccountKey=S4z/D+Yg6mwMis+bs/VpcDLA9yE1iZaYq23shQlRIi2KmM9E7JY8zdZjeAPOPdG3gONHoNDEpsgH6D4cqQ/bsA==;EndpointSuffix=core.windows.net"); - CloudBlobClient sourceClient = sourceAccount.CreateCloudBlobClient(); + private async Task UpgradePPCVersion(IWebAppBase sourceApp, IWebAppBase targetApp) + { + var latestPPCVersion = await GetLatestPPCVersion(sourceApp); - var sourceContainer = sourceClient.GetContainerReference("machine-studio-versions-test"); - var sourceBlob = sourceContainer.GetBlockBlobReference("Machine Studio v4.0.34.0.zip"); + var targetDataSource = (await targetApp.GetMachineServiceSettingsAsync()).ToDataSource(); - var targetContainer = sourceClient.GetContainerReference("machine-studio-versions-dev"); + using (var db = ObservablesContext.CreateDefault(targetDataSource)) + { + db.TangoVersions.Add(latestPPCVersion); + await db.SaveChangesAsync(); + } + } - CloudBlockBlob targetBlob = targetContainer.GetBlockBlobReference(sourceBlob.Name); + private CloudBlockBlob CreateEmptyBlob(CloudBlobContainer container, String name) + { + CloudBlockBlob targetBlob = container.GetBlockBlobReference(name); using (MemoryStream ms = new MemoryStream()) { targetBlob.UploadFromStream(ms);//Empty memory stream. Will create an empty blob. } - targetBlob.StartCopy(sourceBlob); + return targetBlob; + } + + #endregion + + #region Validation + + public async Task ValidateUpgrade(IWebAppBase sourceApp, IWebAppBase targetApp) + { + if (UpgradeConfiguration.UpgradeMachineStudio) + { + await ValidateMachineStudioUpgrade(sourceApp, targetApp); + } + + if (UpgradeConfiguration.UpgradePPC) + { + await ValidatePPCUpgrade(sourceApp, targetApp); + } + } + + private async Task ValidateMachineStudioUpgrade(IWebAppBase sourceApp, IWebAppBase targetApp) + { + var sourceSettings = await sourceApp.GetMachineServiceSettingsAsync(); + var targetSettings = await targetApp.GetMachineServiceSettingsAsync(); + + var latestSourceMachineStudioVersion = await GetLatestMachineStudioVersion(sourceApp); + + //Check if there is any source machine studio version. + if (latestSourceMachineStudioVersion == null) + { + throw new ValidationException("Could not locate a Machine Studio version entry on the source database."); + } + + var latestTargetMachineStudioVersion = await GetLatestMachineStudioVersion(targetApp); + + //Check target latest machine studio version is older if there is any. + if (latestTargetMachineStudioVersion != null && Version.Parse(latestSourceMachineStudioVersion.Version) <= Version.Parse(latestTargetMachineStudioVersion.Version)) + { + throw new ValidationException($"Machine Studio source version is '{latestSourceMachineStudioVersion.Version}' while target version is '{latestTargetMachineStudioVersion.Version}'."); + } + + var targetAccount = CloudStorageAccount.Parse(targetSettings.STORAGE_ACCOUNT); + var targetClient = targetAccount.CreateCloudBlobClient(); + + var targetMachineStudioContainer = targetClient.GetContainerReference(targetSettings.MACHINE_STUDIO_VERSIONS_CONTAINER); + + //Check machine studio binaries blob not exists on the target. + var targetMachineStudioBlob = targetMachineStudioContainer.GetBlockBlobReference(latestSourceMachineStudioVersion.BlobName); + if (await targetMachineStudioBlob.ExistsAsync()) + { + throw new ValidationException($"Machine Studio Block blob '{latestSourceMachineStudioVersion.BlobName}' already exists on the target storage."); + } + + //Check machine studio installer blob not exists on the target. + var targetMachineStudioInstallerBlob = targetMachineStudioContainer.GetBlockBlobReference(latestSourceMachineStudioVersion.InstallerBlobName); + if (await targetMachineStudioInstallerBlob.ExistsAsync()) + { + throw new ValidationException($"Machine Studio Block blob '{latestSourceMachineStudioVersion.InstallerBlobName}' already exists on the target storage."); + } + } + + private async Task ValidatePPCUpgrade(IWebAppBase sourceApp, IWebAppBase targetApp) + { + var sourceSettings = await sourceApp.GetMachineServiceSettingsAsync(); + var targetSettings = await targetApp.GetMachineServiceSettingsAsync(); + + var latestSourcePPCVersion = await GetLatestPPCVersion(sourceApp); + + //Check if there is any source PPC version. + if (latestSourcePPCVersion == null) + { + throw new ValidationException("Could not locate a PPC version entry on the source database."); + } + + var latestTargetPPCVersion = await GetLatestPPCVersion(targetApp); + + //Check target latest PPC version is older if there is any. + if (latestTargetPPCVersion != null && Version.Parse(latestSourcePPCVersion.Version) <= Version.Parse(latestTargetPPCVersion.Version)) + { + throw new ValidationException($"PPC source version is '{latestSourcePPCVersion.Version}' while target version is '{latestTargetPPCVersion.Version}'."); + } + + var targetAccount = CloudStorageAccount.Parse(targetSettings.STORAGE_ACCOUNT); + var targetClient = targetAccount.CreateCloudBlobClient(); + + var targetPPCContainer = targetClient.GetContainerReference(targetSettings.TANGO_VERSIONS_CONTAINER); + + //Check PPC binaries blob not exists on the target. + var targetPPCBlob = targetPPCContainer.GetBlockBlobReference(latestSourcePPCVersion.BlobName); + if (await targetPPCBlob.ExistsAsync()) + { + throw new ValidationException($"PPC Block blob '{latestSourcePPCVersion.BlobName}' already exists on the target storage."); + } + + //Check PPC installer blob not exists on the target. + var targetPPCInstallerBlob = targetPPCContainer.GetBlockBlobReference(latestSourcePPCVersion.InstallerBlobName); + if (await targetPPCInstallerBlob.ExistsAsync()) + { + throw new ValidationException($"PPC Block blob '{latestSourcePPCVersion.InstallerBlobName}' already exists on the target storage."); + } + } + + #endregion + + #region Virtual Methods + + protected virtual void OnProgress(DeploymentStage stage, String message = null, double progress = 0, double maximum = 100, bool indeterminate = true) + { + DeploymentProgress?.Invoke(this, new DeploymentProgressEventArgs() + { + Stage = stage, + Message = message, + Progress = progress, + Maximum = maximum, + IsIndeterminate = indeterminate, + }); } + #endregion } } diff --git a/Software/Visual_Studio/Azure/Tango.AzureUtils/Deployment/DeploymentProgressEventArgs.cs b/Software/Visual_Studio/Azure/Tango.AzureUtils/Deployment/DeploymentProgressEventArgs.cs new file mode 100644 index 000000000..5fe166464 --- /dev/null +++ b/Software/Visual_Studio/Azure/Tango.AzureUtils/Deployment/DeploymentProgressEventArgs.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.AzureUtils.Deployment +{ + public class DeploymentProgressEventArgs : EventArgs + { + public DeploymentStage Stage { get; set; } + public double Progress { get; set; } + public double Maximum { get; set; } + public bool IsIndeterminate { get; set; } + public String Message { get; set; } + } +} diff --git a/Software/Visual_Studio/Azure/Tango.AzureUtils/Deployment/DeploymentStage.cs b/Software/Visual_Studio/Azure/Tango.AzureUtils/Deployment/DeploymentStage.cs new file mode 100644 index 000000000..531a1ed8c --- /dev/null +++ b/Software/Visual_Studio/Azure/Tango.AzureUtils/Deployment/DeploymentStage.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.AzureUtils.Deployment +{ + public enum DeploymentStage + { + Ready, + Initializing, + DownloadingFTP, + UploadingFTP, + } +} diff --git a/Software/Visual_Studio/Azure/Tango.AzureUtils/Deployment/ExtensionMethods.cs b/Software/Visual_Studio/Azure/Tango.AzureUtils/Deployment/ExtensionMethods.cs index 6b57ce53a..b9437e49e 100644 --- a/Software/Visual_Studio/Azure/Tango.AzureUtils/Deployment/ExtensionMethods.cs +++ b/Software/Visual_Studio/Azure/Tango.AzureUtils/Deployment/ExtensionMethods.cs @@ -5,14 +5,15 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using Tango.AzureUtils.Deployment; +using Tango.Core; public static class ExtensionMethods { - public static MachineServiceSettings GetMachineServiceSettings(this IWebAppBase app) + public static async Task GetMachineServiceSettingsAsync(this IWebAppBase app) { MachineServiceSettings settings = new MachineServiceSettings(); - var s = app.GetAppSettings(); + var s = await app.GetAppSettingsAsync(); settings.DB_ADDRESS = s[nameof(MachineServiceSettings.DB_ADDRESS)].Value; settings.DB_CATALOG = s[nameof(MachineServiceSettings.DB_CATALOG)].Value; @@ -24,4 +25,17 @@ public static class ExtensionMethods return settings; } + + public static DataSource ToDataSource(this MachineServiceSettings settings) + { + DataSource dataSource = new DataSource(); + dataSource.Type = DataSourceType.SQLServer; + dataSource.Address = settings.DB_ADDRESS; + dataSource.Catalog = settings.DB_CATALOG; + dataSource.UserName = settings.DB_USER_NAME; + dataSource.Password = settings.DB_PASSWORD; + dataSource.IntegratedSecurity = false; + + return dataSource; + } } diff --git a/Software/Visual_Studio/Azure/Tango.AzureUtils/Deployment/UpgradeConfiguration.cs b/Software/Visual_Studio/Azure/Tango.AzureUtils/Deployment/UpgradeConfiguration.cs new file mode 100644 index 000000000..233034d0d --- /dev/null +++ b/Software/Visual_Studio/Azure/Tango.AzureUtils/Deployment/UpgradeConfiguration.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.AzureUtils.Deployment +{ + public class UpgradeConfiguration + { + public bool UpgradeMachineService { get; set; } + public bool UpgradeMachineStudio { get; set; } + public bool UpgradePPC { get; set; } + } +} diff --git a/Software/Visual_Studio/Azure/Tango.AzureUtils/Tango.AzureUtils.csproj b/Software/Visual_Studio/Azure/Tango.AzureUtils/Tango.AzureUtils.csproj index 7643f389c..d3dc6a69f 100644 --- a/Software/Visual_Studio/Azure/Tango.AzureUtils/Tango.AzureUtils.csproj +++ b/Software/Visual_Studio/Azure/Tango.AzureUtils/Tango.AzureUtils.csproj @@ -31,6 +31,15 @@ 4 + + ..\..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.dll + + + ..\..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.SqlServer.dll + + + ..\..\packages\FluentFTP.30.0.0\lib\net45\FluentFTP.dll + ..\..\packages\Hyak.Common.1.2.2\lib\net452\Hyak.Common.dll @@ -155,6 +164,7 @@ ..\..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll + @@ -163,6 +173,7 @@ + @@ -174,13 +185,34 @@ + + + + + Deployment\GENERAL_ENV_UPGRADE.sdeproj + PreserveNewest + + + Deployment\GENERAL_ENV_UPGRADE.seproj + PreserveNewest + + + + {f441feee-322a-4943-b566-110e12fd3b72} + Tango.BL + + + {a34ee0f0-649d-41c8-8489-b6f1cc6924ee} + Tango.Core + + \ No newline at end of file diff --git a/Software/Visual_Studio/Azure/Tango.AzureUtils/app.config b/Software/Visual_Studio/Azure/Tango.AzureUtils/app.config index dde2c3cc6..0c152335c 100644 --- a/Software/Visual_Studio/Azure/Tango.AzureUtils/app.config +++ b/Software/Visual_Studio/Azure/Tango.AzureUtils/app.config @@ -1,11 +1,25 @@  + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/Software/Visual_Studio/Azure/Tango.AzureUtils/packages.config b/Software/Visual_Studio/Azure/Tango.AzureUtils/packages.config index 9f49cc92c..9d0723d02 100644 --- a/Software/Visual_Studio/Azure/Tango.AzureUtils/packages.config +++ b/Software/Visual_Studio/Azure/Tango.AzureUtils/packages.config @@ -1,5 +1,7 @@  + + -- cgit v1.3.1