private static Section CreateAppendixServiceParityResultSection( ref DocumentInfo documentInfo, ServiceParityResult serviceParityResult, CostEstimationResult costEstimationResult) { // TODO: extract to extension method // TODO: move hard code string to resource file var appendixServiceParityResultSection = documentInfo.CreateSection(); var appendixServiceParityResultTitle = appendixServiceParityResultSection.AddParagraph("Service Parity", DocumentInfo.TitleStyleName); appendixServiceParityResultTitle.AddBookmark("ServiceParity"); // All parities if (serviceParityResult.Pass) { appendixServiceParityResultSection.AddParagraph( "There is no service failed in the parity rule check regarding this migration & expansion", DocumentInfo.TableDesStyleName); } else { appendixServiceParityResultSection.AddParagraph( "Below are the summary of all services failed in the parity rule check regarding this migration & expansion: ", DocumentInfo.TableDesStyleName); var detailsAll = serviceParityResult.Details.Where(d => d.Value.Pass == false).ToDictionary(i => i.Key, i => i.Value); // Group up parities by resource group foreach (var resourceGroup in costEstimationResult.DetailsByResourceGroup) { // ResourceGroup.Key is the name of the group if (resourceGroup.Value.Where(r => detailsAll.Keys.Contains(r.ResourceId)).Count() != 0) { var resourceGroupName = resourceGroup.Key; var groupNameTxt = appendixServiceParityResultSection.AddParagraph( "Resource Group: " + resourceGroupName, DocumentInfo.TableDesStyleName); } var parityTable = DocumentInfo.CreateTable(ref appendixServiceParityResultSection); parityTable.AddColumn("4cm"); // Rule name parityTable.AddColumn("2cm"); // Pass parityTable.AddColumn("12cm"); // Message // Check each resource in the group foreach (var resource in resourceGroup.Value) { if (detailsAll.Keys.Contains(resource.ResourceId) && detailsAll[resource.ResourceId].Pass == false) { // Resource name var parityResourceName = parityTable.AddRow(); parityResourceName.Cells[0].AddParagraph("Resource Name"); parityResourceName.Cells[0].Format.Font.Bold = true; parityResourceName.Cells[1].MergeRight = 1; parityResourceName.Cells[1].Column.Width = "14.5cm"; documentInfo.AddParagraphWordWrap(parityResourceName.Cells[1], resource.ResourceName); // Resource Id var parityResourceID = parityTable.AddRow(); parityResourceID.Cells[0].AddParagraph("Resource ID"); parityResourceID.Cells[0].Format.Font.Bold = true; parityResourceID.Cells[1].MergeRight = 1; parityResourceID.Cells[1].Column.Width = "14.5cm"; var cutMark = "providers"; var cut = resource.ResourceId.IndexOf(cutMark, StringComparison.OrdinalIgnoreCase) + cutMark.Length; var resourceID = cut == -1 ? resource.ResourceId : resource.ResourceId.Substring(cut, resource.ResourceId.Length - cut); documentInfo.AddParagraphWordWrap(parityResourceID.Cells[1], resourceID); var parityProperties = parityTable.AddRow(); parityResourceID.Cells[1].Column.Width = "2cm"; parityProperties.Format.Font.Bold = true; parityProperties.Cells[0].AddParagraph("RuleName"); parityProperties.Cells[1].AddParagraph("Pass"); parityProperties.Cells[2].AddParagraph("Message"); // Check each parity result for the resource foreach (var ruleCheck in detailsAll[resource.ResourceId].Details.Where(d => d.Pass == false)) { var ruleCheckRow = parityTable.AddRow(); documentInfo.AddParagraphWordWrap(ruleCheckRow.Cells[0], ruleCheck.Brief); documentInfo.AddParagraphWordWrap(ruleCheckRow.Cells[1], "N"); documentInfo.AddParagraphWordWrap(ruleCheckRow.Cells[2], ruleCheck.Message); } } } } } return(appendixServiceParityResultSection); }
private static Section CreateCostEstimationSection( ref DocumentInfo documentInfo, RegionInfo regionInfo, CostEstimationResult costEstimationResult) { // TODO: extract to extension method // TODO: move hard code string to resource file. var subscriptionName = costEstimationResult.SubscriptionName; var costEstimationSection = documentInfo.CreateSection(); var costTitle = costEstimationSection.AddParagraph("Cost Estimation", DocumentInfo.TitleStyleName); costTitle.AddBookmark("CostEstimation" + subscriptionName); if (costEstimationResult.HasError) { costEstimationSection.AddParagraph( "Failed to retrieve Azure resource usage to build the cost estimation due to insufficient permission. Please check your Azure RBAC role and ensure you have any of the role below for the whole subscription: Reader, Contributor and Owner.", DocumentInfo.TableDesStyleName); return(costEstimationSection); } costEstimationSection.AddParagraph( "To best help customer plan and estimate the cost in destination environment, China Cloud Migration & Expansion tool set takes customer’s source service usage of one billing cycle as a reference to perform a cost estimation for the same service usage in the destination. Below is the cost estimation summary report. Please note that the cost only reflects the services that is available in destination environment. For services that is not available in destination, N/A are marked.", DocumentInfo.TableDesStyleName); // Make Cost Summary Table var costSummaryTalbe = DocumentInfo.CreateTable(ref costEstimationSection); var headCostSummaryColumn = costSummaryTalbe.AddColumn("8cm"); headCostSummaryColumn.Format.Font.Bold = true; costSummaryTalbe.AddColumn("8cm"); var costSummaryRow = costSummaryTalbe.AddRow(); costSummaryRow.Cells[0].AddParagraph("Reference Environment"); costSummaryRow.Cells[1].AddParagraph("Microsoft Azure"); costSummaryRow = costSummaryTalbe.AddRow(); costSummaryRow.Cells[0].AddParagraph("Reference Subscription"); costSummaryRow.Cells[1].AddParagraph(subscriptionName); costSummaryRow = costSummaryTalbe.AddRow(); costSummaryRow.Cells[0].AddParagraph("Target Environment"); costSummaryRow.Cells[1].AddParagraph(regionInfo.TargetRegionName); costSummaryRow = costSummaryTalbe.AddRow(); costSummaryRow.Cells[0].AddParagraph("Usage Collection Period"); costSummaryRow.Cells[1].AddParagraph(FormattableString.Invariant($"{costEstimationResult.StartTime:r} - {costEstimationResult.EndTime:r}")); costSummaryRow = costSummaryTalbe.AddRow(); costSummaryRow.Cells[0].AddParagraph("Target Price Base"); costSummaryRow.Cells[1].AddParagraph("List Price"); costSummaryRow = costSummaryTalbe.AddRow(); costSummaryRow.Cells[0].AddParagraph("Currency"); costSummaryRow.Cells[1].AddParagraph(regionInfo.CurrencyUnit); costSummaryRow = costSummaryTalbe.AddRow(); costSummaryRow.Cells[0].AddParagraph("Currency Format"); costSummaryRow.Cells[1].AddParagraph(regionInfo.CurrencyCulture.EnglishName); costSummaryRow = costSummaryTalbe.AddRow(); costSummaryRow.Cells[0].AddParagraph("Total Cost in Period for Available Resources"); if (!costEstimationResult.Details.Any()) { costSummaryRow.Cells[1].AddParagraph("N/A"); } else { costEstimationSection.AddParagraph( "Please check the below cost list with price by Resource Group:", DocumentInfo.TableDesStyleName); // Resource Details decimal totalCost = 0; decimal totalOriginalCost = 0; foreach (var kvp in costEstimationResult.DetailsByResourceGroup) { if (!kvp.Value.Any(d => d.EstimatedCost.HasValue)) { continue; } var resourceGroup = kvp.Key; var costTable = DocumentInfo.CreateTable(ref costEstimationSection); costEstimationSection.AddParagraph(string.Empty); AddCostTableHeaders(ref costTable, documentInfo, resourceGroup); foreach (var detail in kvp.Value.Where(d => d.EstimatedCost.HasValue)) { AddCostTableRow(ref costTable, documentInfo, regionInfo, detail); totalCost += detail.EstimatedCost.Value; } foreach (var detail in kvp.Value.Where(d => !d.EstimatedCost.HasValue)) { AddCostTableRow(ref costTable, documentInfo, regionInfo, detail).Cells[0].Format.Font.Color = Colors.Red; // ToDo: Is it necessary to put on total original costs? if (!string.IsNullOrWhiteSpace(detail.SourceMeterId) && string.IsNullOrWhiteSpace(detail.TargetMeterId)) { totalOriginalCost += detail.OriginalCost.Value; } } } // Add total cost to summary table costSummaryRow.Cells[1].AddParagraph(ToCurrencyString(totalCost, regionInfo.CurrencySymbol)); } return(costEstimationSection); }
private static Section CreateMigrationSummarySection( ref DocumentInfo documentInfo, RegionInfo regionInfo, CostEstimationResult costEstimationResult, ServiceParityResult serviceParityResult) { // TODO: extract to extension method // TODO: move hard code string to resource file var subscriptionName = costEstimationResult.SubscriptionName; var resourceGroupsCount = costEstimationResult.ResourceGroupsCount; var resourcesCount = costEstimationResult.ResourcesCount; var migrationSummarySection = documentInfo.CreateSection(); var summaryTitle = migrationSummarySection.AddParagraph( "Assessment Summary for " + subscriptionName, DocumentInfo.TitleStyleName); summaryTitle.AddBookmark("MigrationSummary" + subscriptionName); migrationSummarySection.AddParagraph( "Based on user selection and configuration, here is summary about subscription " + subscriptionName + ":", DocumentInfo.TableDesStyleName); var shortSummary = DocumentInfo.CreateTable(ref migrationSummarySection); var summaryTitleColumn = shortSummary.AddColumn("8cm"); summaryTitleColumn.Format.Font = DocumentInfo.ContentFontBold.Clone(); shortSummary.AddColumn("8cm"); var shortSummaryRow = shortSummary.AddRow(); shortSummaryRow.Cells[0].AddParagraph("Reference Environment"); shortSummaryRow.Cells[1].AddParagraph("Microsoft Azure"); shortSummaryRow = shortSummary.AddRow(); shortSummaryRow.Cells[0].AddParagraph("Reference Subscription"); documentInfo.AddParagraphWordWrap(shortSummaryRow.Cells[1], subscriptionName); shortSummaryRow = shortSummary.AddRow(); shortSummaryRow.Cells[0].AddParagraph("Target Environment"); shortSummaryRow.Cells[1].AddParagraph(regionInfo.TargetRegionName); shortSummaryRow = shortSummary.AddRow(); shortSummaryRow.Cells[0].AddParagraph("Number of Resource Group"); shortSummaryRow.Cells[1].AddParagraph(resourceGroupsCount.ToString(CultureInfo.InvariantCulture)); shortSummaryRow = shortSummary.AddRow(); shortSummaryRow.Cells[0].AddParagraph("Number of Resources"); shortSummaryRow.Cells[1].AddParagraph(resourcesCount.ToString(CultureInfo.InvariantCulture)); shortSummaryRow = shortSummary.AddRow(); shortSummaryRow.Cells[0].AddParagraph("Number of Resources Failed in Parity Rule Check/Number of All Resources"); var detailPassFailed = serviceParityResult.Details.Where(d => !d.Value.Pass); var resourceNotPassedCount = costEstimationResult.Details.Where(c => detailPassFailed.Any(d => d.Key == c.ResourceId)).GroupBy(g => g.ResourceId).Count(); shortSummaryRow.Cells[1].AddParagraph(FormattableString.Invariant($"{resourceNotPassedCount}/{resourcesCount}")); shortSummaryRow = shortSummary.AddRow(); shortSummaryRow.Cells[0].AddParagraph("Target Region"); shortSummaryRow.Cells[1].AddParagraph(costEstimationResult.TargetRegion); return(migrationSummarySection); }
private static Section CreateAppendixResouceListSection( ref DocumentInfo documentInfo, RegionInfo regionInfo, CostEstimationResult costEstimationResult) { // TODO: extract to extension method // TODO: move hard code string to resource file. var subscriptionName = costEstimationResult.SubscriptionName; var appendixResouceListSection = documentInfo.CreateSection(); var appendixResourceListTitle = appendixResouceListSection.AddParagraph( "Full Resource List For " + subscriptionName, DocumentInfo.TitleStyleName); appendixResourceListTitle.AddBookmark("AppendixResourceList" + subscriptionName); // Resource List by Resource Group appendixResouceListSection.AddParagraph( "Here is the full resource list in reference subscription related to this migration: ", DocumentInfo.TableDesStyleName); var locationMap = costEstimationResult.LocationMap[costEstimationResult.SubscriptionId]; foreach (var kvp in costEstimationResult.DetailsByResourceGroup) { var resourceTable = DocumentInfo.CreateTable(ref appendixResouceListSection); resourceTable.AddColumn("5cm"); resourceTable.AddColumn("7cm"); resourceTable.AddColumn("4.5cm"); var resourceGroupName = resourceTable.AddRow(); resourceGroupName.Cells[0].AddParagraph("Resource Group Name"); resourceGroupName.Cells[0].Format.Font.Bold = true; resourceGroupName.Cells[1].MergeRight = 1; documentInfo.AddParagraphWordWrap(resourceGroupName.Cells[1], kvp.Key); var resourceProperties = resourceTable.AddRow(); resourceProperties.Format.Font.Bold = true; resourceProperties.Cells[0].AddParagraph("Name"); resourceProperties.Cells[1].AddParagraph("Type"); resourceProperties.Cells[2].AddParagraph("Location"); foreach (var detail in kvp.Value) { var resourceRow = resourceTable.AddRow(); documentInfo.AddParagraphWordWrap(resourceRow.Cells[0], detail.ResourceName); documentInfo.AddParagraphWordWrap(resourceRow.Cells[1], detail.ResourceType); if (locationMap.TryGetValue(detail.Location, out var locationDisplayName)) { documentInfo.AddParagraphWordWrap(resourceRow.Cells[2], locationDisplayName); } else { documentInfo.AddParagraphWordWrap(resourceRow.Cells[2], detail.Location); } } appendixResouceListSection.AddParagraph(string.Empty); } return(appendixResouceListSection); }