private void FixCrossReferencesWithLegacyApplianceConfig(LegacyApplianceConfig config) { List <BandwidthSetting> bandwidthSettingList = (List <BandwidthSetting>)config.BandwidthSettings; List <StorageAccountCredential> sacList = (List <StorageAccountCredential>)config.StorageAccountCredentials; foreach (MigrationDataContainer dataContainer in config.CloudConfigurations) { dataContainer.BandwidthSetting = bandwidthSettingList.Find(bwSetting => bwSetting.InstanceId == dataContainer.BandwidthSetting.InstanceId); dataContainer.PrimaryStorageAccountCredential = sacList.Find(sac => sac.InstanceId == dataContainer.PrimaryStorageAccountCredential.InstanceId); dataContainer.BackupStorageAccountCredential = sacList.Find(sac => sac.InstanceId == dataContainer.BackupStorageAccountCredential.InstanceId); } List <AccessControlRecord> acrList = (List <AccessControlRecord>)config.AccessControlRecords; foreach (VirtualDisk virtualDisk in config.Volumes) { MigrationDataContainer dataContainer = ((List <MigrationDataContainer>)config.CloudConfigurations).Find(dc => dc.InstanceId == virtualDisk.DataContainerId); virtualDisk.DataContainer = this.ConvertToDataContainer(dataContainer); virtualDisk.DataContainer.VolumeCount++; virtualDisk.AcrList = acrList.FindAll(acr => virtualDisk.AcrIdList.Contains(acr.InstanceId)); foreach (AccessControlRecord acr in virtualDisk.AcrList) { acr.VolumeCount++; } } }
private LegacyApplianceConfig CreateConfig() { LegacyApplianceConfigTestParser parser = new LegacyApplianceConfigTestParser(); string configpath = Path.Combine(System.Environment.CurrentDirectory, "Data"); configpath = Path.Combine(configpath, ConfigurationManager.AppSettings["MigrationUnitTestConfig"]); LegacyApplianceConfig config = parser.ParseLegacyApplianceTestConfig(configpath); config.DeviceId = ConfigurationManager.AppSettings["MigrationTargetDeviceID"]; return(config); }
private LegacyApplianceConfig CreateLegacyApplianceConfig(XmlDocument document) { LegacyApplianceConfig config = new LegacyApplianceConfig(); XmlNode node = document.SelectSingleNode(@"//LegacyApplianceConfig"); config.InstanceId = node.Attributes["Id"].Value; config.Name = node.Attributes["Name"].Value; config.SerialNumber = int.Parse(node.Attributes["SerialNo"].Value); config.TotalCount = int.Parse(node.Attributes["TotalCount"].Value); return(config); }
/// <summary> /// Checks if the provided config is empty or not /// </summary> /// <param name='config'> /// Required. A LegacyApplianceConfig /// </param> /// <returns> /// The boolean specifying whether the config is empty or not /// </returns> private static bool IsConfigEmpty(LegacyApplianceConfig config) { return(config.AccessControlRecords.Count == 0 && config.BackupPolicies.Count == 0 && config.BandwidthSettings.Count == 0 && (config.InboundChapSettings == null || config.InboundChapSettings.Count == 0) && config.StorageAccountCredentials.Count == 0 && (config.TargetChapSettings == null || config.TargetChapSettings.Count == 0) && config.CloudConfigurations.Count == 0 && config.VolumeGroups.Count == 0 && config.Volumes.Count == 0); }
public override void ExecuteCmdlet() { try { WriteVerbose(string.Format(Resources.MigrationMsgQueringDeviceId, TargetDeviceName)); string deviceid = StorSimpleClient.GetDeviceId(TargetDeviceName); if (!File.Exists(ConfigFilePath)) { throw new FileNotFoundException(String.Format(Resources.MigrationConfigFileNotFound, StorSimpleContext.ResourceName, ConfigFilePath)); } else if (string.IsNullOrEmpty(deviceid)) { throw new ArgumentException(String.Format(Resources.NoDeviceFoundWithGivenNameInResourceMessage, StorSimpleContext.ResourceName, TargetDeviceName)); } else { // creating the config file parser instance - parser decrypt the xml and parses the config xml WriteVerbose(string.Format(Resources.MigrationMsgDeviceFound, deviceid)); var secretsEncryptor = new ServiceSecretEncryptor(this.StorSimpleClient); var parser = new LegacyApplianceConfigParser(secretsEncryptor); var legacyApplianceMetaData = new LegacyApplianceConfiguration(); legacyApplianceMetaData.Details = parser.ParseLegacyApplianceConfig(ConfigFilePath, ConfigDecryptionKey); LegacyApplianceConfig config = legacyApplianceMetaData.Details; legacyApplianceMetaData.LegacyConfigId = Guid.NewGuid().ToString(); config.InstanceId = config.Name = legacyApplianceMetaData.LegacyConfigId; legacyApplianceMetaData.ConfigFile = ConfigFilePath; legacyApplianceMetaData.ImportedOn = DateTime.Now; legacyApplianceMetaData.TargetApplianceName = TargetDeviceName; config.DeviceId = deviceid; legacyApplianceMetaData.Result = Resources.ImportLegacyApplianceConfigSuccessMessage; WriteVerbose(Resources.MigrationMsgUploadingConfig); var configList = ConfigSplitHelper.Split(legacyApplianceMetaData.Details); foreach (var singleConfig in configList) { StorSimpleClient.ImportLegacyApplianceConfig(legacyApplianceMetaData.LegacyConfigId, singleConfig); } WriteObject(legacyApplianceMetaData); } } catch (Exception exception) { this.HandleException(exception); } }
public LegacyApplianceConfig ParseLegacyApplianceTestConfig(string configXml) { XmlDocument document = new XmlDocument(); document.Load(configXml); LegacyApplianceConfig config = CreateLegacyApplianceConfig(document); config.AccessControlRecords = ParseACRs(document); config.BackupPolicies = ParseBackupPolicy(document); config.BandwidthSettings = ParseBandwidthSetting(document); config.CloudConfigurations = ParseVolumeContainer(document); config.Volumes = ParseVolume(document); config.VolumeGroups = ParseVolumeGroup(document); config.TargetChapSettings = ParseTargetChap(document); config.InboundChapSettings = ParseInboundChap(document); config.StorageAccountCredentials = ParseSACs(document); this.FixCrossReferencesWithLegacyApplianceConfig(config); return(config); }
public void VerifyMigration() { using (var context = UndoContext.Current) { context.Start(); var client = GetServiceClient <StorSimpleManagementClient>(); LegacyApplianceConfig config = CreateConfig(); List <MigrationDataContainer> dcList = new List <MigrationDataContainer>(config.CloudConfigurations); List <string> dcNameList = dcList.Select(migrationDC => migrationDC.Name).ToList(); // Import legacy appliance config returns void, other than http status code. An exception from hydra spec if the http response code is not expected client.MigrateLegacyAppliance.ImportLegacyApplianceConfig(config.InstanceId, config, GetCustomRequestHeaders()); MigrationPlanStartRequest startMigrationPlanRequest = new MigrationPlanStartRequest() { ConfigId = config.InstanceId, DataContainerNameList = dcNameList }; client.MigrateLegacyAppliance.StartMigrationPlan(startMigrationPlanRequest, GetCustomRequestHeaders()); client.MigrateLegacyAppliance.UpdateMigrationPlan(config.InstanceId, GetCustomRequestHeaders()); var getmigrationPlanResponse = client.MigrateLegacyAppliance.GetMigrationPlan(config.InstanceId, GetCustomRequestHeaders()); Assert.NotNull(getmigrationPlanResponse); Assert.NotNull(getmigrationPlanResponse.MigrationPlans); Assert.True(1 == getmigrationPlanResponse.MigrationPlans.Count); Assert.NotNull(getmigrationPlanResponse.MigrationPlans[0].MigrationPlanInfo); Assert.True(dcList.Count == getmigrationPlanResponse.MigrationPlans[0].MigrationPlanInfo.Count); List <MigrationPlanInfo> migrationPlanInfoList = new List <MigrationPlanInfo>(getmigrationPlanResponse.MigrationPlans[0].MigrationPlanInfo); Assert.True(0 == migrationPlanInfoList.FindAll(plan => !dcNameList.Contains(plan.DataContainerName)).Count); var getmigrationAllPlanResponse = client.MigrateLegacyAppliance.GetAllMigrationPlan(GetCustomRequestHeaders()); Assert.NotNull(getmigrationAllPlanResponse); Assert.NotNull(getmigrationAllPlanResponse.MigrationPlans); Assert.True(0 < getmigrationAllPlanResponse.MigrationPlans.Count); List <MigrationPlan> allPlans = new List <MigrationPlan>(getmigrationAllPlanResponse.MigrationPlans); Assert.True(null != allPlans.Find(plan => plan.ConfigId == config.InstanceId)); MigrationImportDataContainerRequest importDCRequest = new MigrationImportDataContainerRequest() { DataContainerNames = new List <string>() }; client.MigrateLegacyAppliance.MigrationImportDataContainer(config.InstanceId, importDCRequest, GetCustomRequestHeaders()); client.MigrateLegacyAppliance.UpdateDataContainerMigrationStatus(config.InstanceId, GetCustomRequestHeaders()); var getMigrationStatus = client.MigrateLegacyAppliance.GetDataContainerMigrationStatus(config.InstanceId, GetCustomRequestHeaders()); Assert.NotNull(getMigrationStatus); Assert.NotNull(getMigrationStatus.MigrationDataContainerStatuses); List <MigrationDataContainerStatus> migrationStatusList = new List <MigrationDataContainerStatus>(getMigrationStatus.MigrationDataContainerStatuses); Assert.True(dcList.Count == migrationStatusList.Count); Assert.True(0 == migrationStatusList.FindAll(status => !dcNameList.Contains(status.CloudConfigurationName)).Count); // Migration will start only after 12mins and will take roughly around 14mins to complete for single dc. TestUtilities.Wait(14 * 60 * 1000); DateTime timeOutTime = DateTime.UtcNow.AddMinutes(6); while (true) { if (0 <= DateTime.UtcNow.CompareTo(timeOutTime)) { throw new System.TimeoutException("Import DC did not completed in expected time"); } client.MigrateLegacyAppliance.UpdateDataContainerMigrationStatus(config.InstanceId, GetCustomRequestHeaders()); var migrationStatus = client.MigrateLegacyAppliance.GetDataContainerMigrationStatus(config.InstanceId, GetCustomRequestHeaders()); List <MigrationDataContainerStatus> statusList = new List <MigrationDataContainerStatus>(migrationStatus.MigrationDataContainerStatuses); if (dcList.Count != statusList.FindAll(status => MigrationStatus.Completed == status.Status || MigrationStatus.Failed == status.Status).Count) { TestUtilities.Wait(30 * 1000); } else { break; } } MigrationConfirmStatusRequest confirmRequest = new MigrationConfirmStatusRequest() { DataContainerNameList = new List <string>(), Operation = MigrationOperation.Commit }; client.MigrateLegacyAppliance.ConfirmMigration(config.InstanceId, confirmRequest, GetCustomRequestHeaders()); client.MigrateLegacyAppliance.UpdateMigrationConfirmStatus(config.InstanceId, GetCustomRequestHeaders()); var getConfirmStatus = client.MigrateLegacyAppliance.GetMigrationConfirmStatus(config.InstanceId, GetCustomRequestHeaders()); Assert.NotNull(getConfirmStatus); Assert.NotNull(getConfirmStatus.ContainerConfirmStatus); List <MigrationContainerConfirmStatus> confirmStatusList = new List <MigrationContainerConfirmStatus>(getConfirmStatus.ContainerConfirmStatus); Assert.True(dcList.Count == confirmStatusList.Count); Assert.True(0 == confirmStatusList.FindAll(status => !dcNameList.Contains(status.CloudConfigurationName)).Count); } }
/// <summary> /// Hydra spec for import legacy appliance config rest api.The rest api /// imports the legacy config to the service /// </summary> /// <param name='operations'> /// Reference to the /// Microsoft.WindowsAzure.Management.StorSimple.IMigrationOperations. /// </param> /// <param name='configId'> /// Required. Unique id for config being imported /// </param> /// <param name='request'> /// Required. Legacy appliance config to be imported /// </param> /// <param name='customRequestHeaders'> /// Required. The Custom Request Headers which client must use. /// </param> /// <returns> /// A standard service response including an HTTP status code and /// request ID. /// </returns> public static Task <AzureOperationResponse> ImportLegacyApplianceConfigAsync(this IMigrationOperations operations, string configId, LegacyApplianceConfig request, CustomRequestHeaders customRequestHeaders) { return(operations.ImportLegacyApplianceConfigAsync(configId, request, customRequestHeaders, CancellationToken.None)); }
/// <summary> /// Hydra spec for import legacy appliance config rest api.The rest api /// imports the legacy config to the service /// </summary> /// <param name='operations'> /// Reference to the /// Microsoft.WindowsAzure.Management.StorSimple.IMigrationOperations. /// </param> /// <param name='configId'> /// Required. Unique id for config being imported /// </param> /// <param name='request'> /// Required. Legacy appliance config to be imported /// </param> /// <param name='customRequestHeaders'> /// Required. The Custom Request Headers which client must use. /// </param> /// <returns> /// A standard service response including an HTTP status code and /// request ID. /// </returns> public static AzureOperationResponse ImportLegacyApplianceConfig(this IMigrationOperations operations, string configId, LegacyApplianceConfig request, CustomRequestHeaders customRequestHeaders) { return(Task.Factory.StartNew((object s) => { return ((IMigrationOperations)s).ImportLegacyApplianceConfigAsync(configId, request, customRequestHeaders); } , operations, CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Default).Unwrap().GetAwaiter().GetResult()); }
/// <summary> /// Splits the inputConfig in smaller chunks of a size which the service can accept /// </summary> /// <param name='inputConfig'> /// Required. The complete list of LegacyApplianceConfig parsed /// </param> /// <returns> /// The smaller chunks of LegacyApplianceConfig which the service can process /// </returns> public static List <LegacyApplianceConfig> Split(LegacyApplianceConfig inputConfig) { var splitConfig = new List <LegacyApplianceConfig>(); var serialNumber = 1; var parentConfig = new LegacyApplianceConfig(); parentConfig.AccessControlRecords = new List <AccessControlRecord>(inputConfig.AccessControlRecords); parentConfig.BackupPolicies = new List <MigrationBackupPolicy>(inputConfig.BackupPolicies); parentConfig.BandwidthSettings = new List <BandwidthSetting>(inputConfig.BandwidthSettings); parentConfig.DeviceId = inputConfig.DeviceId; if (inputConfig.InboundChapSettings != null) { parentConfig.InboundChapSettings = new List <MigrationChapSetting>(inputConfig.InboundChapSettings); } parentConfig.InstanceId = inputConfig.InstanceId; parentConfig.Name = inputConfig.Name; parentConfig.OperationInProgress = inputConfig.OperationInProgress; parentConfig.SerialNumber = inputConfig.SerialNumber; parentConfig.StorageAccountCredentials = new List <StorageAccountCredential>(inputConfig.StorageAccountCredentials); if (inputConfig.TargetChapSettings != null) { parentConfig.TargetChapSettings = new List <MigrationChapSetting>(inputConfig.TargetChapSettings); } parentConfig.TotalCount = inputConfig.TotalCount; parentConfig.CloudConfigurations = new List <MigrationDataContainer>(inputConfig.CloudConfigurations); parentConfig.VolumeGroups = new List <VirtualDiskGroup>(inputConfig.VolumeGroups); parentConfig.Volumes = new List <VirtualDisk>(inputConfig.Volumes); while (!IsConfigEmpty(parentConfig)) { var config = new LegacyApplianceConfig(); var currRank = 0; var rank = 0; var objectCountCanBeAccomodated = 0; var objectsAccomodated = 0; config.SerialNumber = serialNumber++; config.DeviceId = parentConfig.DeviceId; config.InstanceId = parentConfig.InstanceId; config.Name = parentConfig.Name; config.OperationInProgress = parentConfig.OperationInProgress; rank = FindRank(typeof(VirtualDisk)); objectCountCanBeAccomodated = (maxRank - currRank) / rank; if (objectCountCanBeAccomodated > 0) { objectsAccomodated = Math.Min(objectCountCanBeAccomodated, parentConfig.Volumes.Count); config.Volumes = new List <VirtualDisk>( config.Volumes.Concat( parentConfig.Volumes.Take(objectsAccomodated))); parentConfig.Volumes = RemoveFirstNItems(new List <VirtualDisk>(parentConfig.Volumes), objectsAccomodated); } else { objectsAccomodated = 0; config.Volumes = new List <VirtualDisk>(); } currRank += rank * objectsAccomodated; rank = FindRank(typeof(MigrationDataContainer)); objectCountCanBeAccomodated = (maxRank - currRank) / rank; if (objectCountCanBeAccomodated > 0) { objectsAccomodated = Math.Min(objectCountCanBeAccomodated, parentConfig.CloudConfigurations.Count); config.CloudConfigurations = new List <MigrationDataContainer>( config.CloudConfigurations.Concat( parentConfig.CloudConfigurations.Take(objectsAccomodated))); parentConfig.CloudConfigurations = RemoveFirstNItems(new List <MigrationDataContainer>(parentConfig.CloudConfigurations), objectsAccomodated); } else { objectsAccomodated = 0; config.CloudConfigurations = new List <MigrationDataContainer>(); } currRank += rank * objectsAccomodated; rank = FindRank(typeof(MigrationBackupPolicy)); objectCountCanBeAccomodated = (maxRank - currRank) / rank; if (objectCountCanBeAccomodated > 0) { objectsAccomodated = Math.Min(objectCountCanBeAccomodated, parentConfig.BackupPolicies.Count); config.BackupPolicies = new List <MigrationBackupPolicy>( config.BackupPolicies.Concat( parentConfig.BackupPolicies.Take(objectsAccomodated))); parentConfig.BackupPolicies = RemoveFirstNItems(new List <MigrationBackupPolicy>(parentConfig.BackupPolicies), objectsAccomodated); } else { objectsAccomodated = 0; config.BackupPolicies = new List <MigrationBackupPolicy>(); } currRank += rank * objectsAccomodated; rank = FindRank(typeof(BandwidthSetting)); objectCountCanBeAccomodated = (maxRank - currRank) / rank; if (objectCountCanBeAccomodated > 0) { objectsAccomodated = Math.Min(objectCountCanBeAccomodated, parentConfig.BandwidthSettings.Count); config.BandwidthSettings = new List <BandwidthSetting>( config.BandwidthSettings.Concat( parentConfig.BandwidthSettings.Take(objectsAccomodated))); parentConfig.BandwidthSettings = RemoveFirstNItems(new List <BandwidthSetting>(parentConfig.BandwidthSettings), objectsAccomodated); } else { objectsAccomodated = 0; config.BandwidthSettings = new List <BandwidthSetting>(); } currRank += rank * objectsAccomodated; rank = FindRank(typeof(VirtualDiskGroup)); objectCountCanBeAccomodated = (maxRank - currRank) / rank; if (objectCountCanBeAccomodated > 0) { objectsAccomodated = Math.Min(objectCountCanBeAccomodated, parentConfig.VolumeGroups.Count); config.VolumeGroups = new List <VirtualDiskGroup>( config.VolumeGroups.Concat( parentConfig.VolumeGroups.Take(objectsAccomodated))); parentConfig.VolumeGroups = RemoveFirstNItems(new List <VirtualDiskGroup>(parentConfig.VolumeGroups), objectsAccomodated); } else { objectsAccomodated = 0; config.VolumeGroups = new List <VirtualDiskGroup>(); } currRank += rank * objectsAccomodated; if (parentConfig.InboundChapSettings != null) { rank = FindRank(typeof(MigrationChapSetting)); objectCountCanBeAccomodated = (maxRank - currRank) / rank; if (objectCountCanBeAccomodated > 0) { objectsAccomodated = Math.Min(objectCountCanBeAccomodated, parentConfig.InboundChapSettings.Count); config.InboundChapSettings = new List <MigrationChapSetting>( config.InboundChapSettings.Concat( parentConfig.InboundChapSettings.Take(objectsAccomodated))); parentConfig.InboundChapSettings = RemoveFirstNItems(new List <MigrationChapSetting>(parentConfig.InboundChapSettings), objectsAccomodated); } else { objectsAccomodated = 0; config.InboundChapSettings = new List <MigrationChapSetting>(); } currRank += rank * objectsAccomodated; } if (parentConfig.TargetChapSettings != null) { rank = FindRank(typeof(MigrationChapSetting)); objectCountCanBeAccomodated = (maxRank - currRank) / rank; if (objectCountCanBeAccomodated > 0) { objectsAccomodated = Math.Min(objectCountCanBeAccomodated, parentConfig.TargetChapSettings.Count); config.TargetChapSettings = new List <MigrationChapSetting>( config.TargetChapSettings.Concat( parentConfig.TargetChapSettings.Take(objectsAccomodated))); parentConfig.TargetChapSettings = RemoveFirstNItems(new List <MigrationChapSetting>(parentConfig.TargetChapSettings), objectsAccomodated); } else { objectsAccomodated = 0; config.TargetChapSettings = new List <MigrationChapSetting>(); } currRank += rank * objectsAccomodated; } rank = FindRank(typeof(StorageAccountCredential)); objectCountCanBeAccomodated = (maxRank - currRank) / rank; if (objectCountCanBeAccomodated > 0) { objectsAccomodated = Math.Min(objectCountCanBeAccomodated, parentConfig.StorageAccountCredentials.Count); config.StorageAccountCredentials = new List <StorageAccountCredential>( config.StorageAccountCredentials.Concat( parentConfig.StorageAccountCredentials.Take(objectsAccomodated))); parentConfig.StorageAccountCredentials = RemoveFirstNItems(new List <StorageAccountCredential>(parentConfig.StorageAccountCredentials), objectsAccomodated); } else { objectsAccomodated = 0; config.StorageAccountCredentials = new List <StorageAccountCredential>(); } currRank += rank * objectsAccomodated; rank = FindRank(typeof(AccessControlRecord)); objectCountCanBeAccomodated = (maxRank - currRank) / rank; if (objectCountCanBeAccomodated > 0) { objectsAccomodated = Math.Min(objectCountCanBeAccomodated, parentConfig.AccessControlRecords.Count); config.AccessControlRecords = new List <AccessControlRecord>( config.AccessControlRecords.Concat( parentConfig.AccessControlRecords.Take(objectsAccomodated))); parentConfig.AccessControlRecords = RemoveFirstNItems(new List <AccessControlRecord>(parentConfig.AccessControlRecords), objectsAccomodated); } else { objectsAccomodated = 0; config.AccessControlRecords = new List <AccessControlRecord>(); } splitConfig.Add(config); } foreach (var config in splitConfig) { config.TotalCount = splitConfig.Count; } return(splitConfig); }
public AzureOperationResponse ImportLegacyApplianceConfig(string configId, LegacyApplianceConfig legacyApplConfig) { return(this.GetStorSimpleClient().MigrateLegacyAppliance.ImportLegacyApplianceConfig(configId, legacyApplConfig, this.GetCustomRequestHeaders())); }