示例#1
0
        public static string MakePage(string targetRegion,
                                      RegionInfo regionInfo,
                                      ServiceParityResult parityResult,
                                      CostEstimationResult costEstimationResult)
        {
            StringBuilder sb = new StringBuilder();

            using (HtmlTextWriter w = new HtmlTextWriter(new StringWriter(sb, CultureInfo.CurrentCulture)))
            {
                #region Html
                w.AddAttribute("lang", "en");
                w.RenderBeginTag(HtmlTextWriterTag.Html);
                MakeHead(w);
                MakeBody(w,
                         targetRegion,
                         regionInfo,
                         parityResult,
                         costEstimationResult);
                w.RenderEndTag();
                #endregion Html
            }

            string html = sb.ToString();
            return(html);
        }
示例#2
0
        public async Task <string> CreateReportAsync(
            ServiceParityResult parityResult,
            CostEstimationResult costEstimationResult)
        {
            var targetRegion = costEstimationResult.TargetRegion;

            var regionInfo = await GetRegionInfoAsync(targetRegion);

            // Create a MigraDoc document and initialize the page setting
            var documentInfo = new DocumentInfo();

            // Introduction Section
            var introSection = documentInfo.CreateIntroSection();

            // Migration Summary Section
            CreateMigrationSummarySection(
                ref documentInfo,
                regionInfo,
                costEstimationResult,
                parityResult);

            // Service Parity Result
            CreateAppendixServiceParityResultSection(
                ref documentInfo,
                parityResult,
                costEstimationResult);

            // TODO: extract common parameters for creating section
            var needCostEstimation = !costEstimationResult.Details.All(d => d.EstimatedCost == null) || costEstimationResult.HasError;

            if (needCostEstimation)
            {
                // Cost Estimation Section
                CreateCostEstimationSection(
                    ref documentInfo,
                    regionInfo,
                    costEstimationResult);
            }

            // Appendix Full Resource List
            CreateAppendixResouceListSection(
                ref documentInfo,
                regionInfo,
                costEstimationResult);

            // Conclusion Section
            documentInfo.CreateConclusionSection();

            // Making TOC
            AppendTOCToIntroductionSection(
                ref introSection,
                costEstimationResult.SubscriptionName,
                needCostEstimation);

            return(documentInfo.MakePDF());
        }
示例#3
0
 private static void MakeAssessmentSummary(HtmlTextWriter w,
                                           RegionInfo regionInfo,
                                           CostEstimationResult costEstimationResult,
                                           ServiceParityResult serviceParityResult)
 {
     MakeHeader(w, "AssessmentSummary for " + costEstimationResult.SubscriptionName, "AssessmentSummary");
     MakeParagraph(w, "Based on user selection and configuration, here is summary about subscription CHN;TST;SHARED;0002:");
     MakeAssessmentSummaryTable(w,
                                regionInfo,
                                costEstimationResult,
                                serviceParityResult);
 }
示例#4
0
        private static void MakeAssessmentSummaryTable(HtmlTextWriter w,
                                                       RegionInfo regionInfo,
                                                       CostEstimationResult costEstimationResult,
                                                       ServiceParityResult serviceParityResult)
        {
            var subscriptionName    = costEstimationResult.SubscriptionName;
            var resourceGroupsCount = costEstimationResult.ResourceGroupsCount;
            var resourcesCount      = costEstimationResult.ResourcesCount;

            #region Table
            w.AddAttribute(HtmlTextWriterAttribute.Class, "table table-bordered");
            w.RenderBeginTag(HtmlTextWriterTag.Table);

            #region Tbody
            w.RenderBeginTag(HtmlTextWriterTag.Tbody);

            #region Reference Environment
            MakeKeyValueRow(w, "Reference Environment", "Microsoft Azure");
            #endregion Reference Environment

            #region Reference Subscription
            MakeKeyValueRow(w, "Reference Subscription", subscriptionName);
            #endregion Reference Subscription

            #region Target Environment
            MakeKeyValueRow(w, "Target Environment", regionInfo.TargetRegionName);
            #endregion Target Environment

            #region Number of Resource Group
            MakeKeyValueRow(w, "Number of Resource Group", resourceGroupsCount.ToString(CultureInfo.InvariantCulture));
            #endregion Number of Resource Group

            #region Number of Resources
            MakeKeyValueRow(w, "Number of Resources", resourcesCount.ToString(CultureInfo.InvariantCulture));
            #endregion Number of Resources

            #region 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();
            MakeKeyValueRow(w, "Number of Resources Failed in Parity Rule Check/Number of All Resources", FormattableString.Invariant($"{resourceNotPassedCount}/{resourcesCount}"));
            #endregion Number of Resources Failed in Parity Rule Check/Number of All Resources

            #region Target Region
            MakeKeyValueRow(w, "Target Region", costEstimationResult.TargetRegion);
            #endregion Target Region

            w.RenderEndTag();
            #endregion Tbody

            w.RenderEndTag();
            #endregion Table
        }
示例#5
0
        public async Task <AssessmentReport> ProcessAsync(
            ServiceParityResult serviceParityResult,
            CostEstimationResult costEstimationResult)
        {
            //IReportGenerator reportGenerator = new PdfReportGenerator();

            IReportGenerator reportGenerator = new HtmlReportGenerator();
            AssessmentReport report          = await reportGenerator.ProcessAsync(
                this.context,
                serviceParityResult,
                costEstimationResult);

            return(report);
        }
示例#6
0
        // TODO: split code file
        public async Task <AssessmentReport> ProcessAsync(
            IAssessmentContext context,
            ServiceParityResult serviceParityResult,
            CostEstimationResult costEstimationResult)
        {
            var reportFilePath =
                await this.CreateReportAsync(
                    serviceParityResult,
                    costEstimationResult);

            return(new AssessmentReport
            {
                ReportFilePath = reportFilePath
            });
        }
示例#7
0
 private static void MakeServiceParity(HtmlTextWriter w,
                                       ServiceParityResult serviceParityResult,
                                       CostEstimationResult costEstimationResult)
 {
     MakeHeader(w, "Service Parity", "ServiceParity");
     if (serviceParityResult.Pass)
     {
         MakeParagraph(w, "There is no service failed in the parity rule check regarding this migration & expansion");
     }
     else
     {
         MakeParagraph(w, "Below are the summary of all services failed in the parity rule check regarding this migration & expansion:");
     }
     MakeSeviceParityTable(w,
                           serviceParityResult,
                           costEstimationResult);
 }
示例#8
0
        private static void MakeCostEstimation(HtmlTextWriter w,
                                               RegionInfo regionInfo,
                                               CostEstimationResult costEstimationResult)
        {
            MakeHeader(w, "Cost Estimation", "CostEstimation");
            if (costEstimationResult.HasError)
            {
                MakeParagraph(w,
                              "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.");
                return;
            }
            MakeParagraph(w, @"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.");

            MakeCostEstimationSummaryTable(w,
                                           regionInfo,
                                           costEstimationResult);

            MakeCostEstimationResourceGroupTable(w,
                                                 regionInfo,
                                                 costEstimationResult);
        }
示例#9
0
        public async Task <string> CreateReportAsync(
            ServiceParityResult parityResult,
            CostEstimationResult costEstimationResult)
        {
            var targetRegion = costEstimationResult.TargetRegion;

            var regionInfo = await GetRegionInfoAsync(targetRegion);

            var htmlReport = MakePage(targetRegion,
                                      regionInfo,
                                      parityResult,
                                      costEstimationResult);

            var filename = "CCMEAssessmentReport" + DateTime.Now.ToString("yyyyMMddHHmmss", CultureInfo.InvariantCulture) + ".html";
            var path     = Path.Combine(Path.GetTempPath(), filename);

            Debug.WriteLine(FormattableString.Invariant($"Save PDF document to: {path}"));

            File.WriteAllText(path, htmlReport);
            return(path);
        }
示例#10
0
        private static void MakeBody(HtmlTextWriter w,
                                     string targetRegion,
                                     RegionInfo regionInfo,
                                     ServiceParityResult parityResult,
                                     CostEstimationResult costEstimationResult)
        {
            var needCostEstimation = !costEstimationResult.Details.All(d => d.EstimatedCost == null) || costEstimationResult.HasError;

            #region Body
            w.AddStyleAttribute(HtmlTextWriterStyle.FontSize, "medium");
            w.RenderBeginTag(HtmlTextWriterTag.Body);
            w.AddAttribute(HtmlTextWriterAttribute.Class, "container");
            w.RenderBeginTag(HtmlTextWriterTag.Div);
            MakeIntroduction(w);
            MakeTableOfContent(w,
                               costEstimationResult.SubscriptionName,
                               needCostEstimation);
            MakeAssessmentSummary(w,
                                  regionInfo,
                                  costEstimationResult,
                                  parityResult);
            MakeServiceParity(w,
                              parityResult,
                              costEstimationResult);
            if (needCostEstimation)
            {
                MakeCostEstimation(w,
                                   regionInfo,
                                   costEstimationResult);
            }

            MakeFullResourceList(w,
                                 regionInfo,
                                 costEstimationResult);

            MakeConclusion(w);
            w.RenderEndTag();
            w.RenderEndTag();
            #endregion Body
        }
示例#11
0
        private static void MakeFullResourceList(HtmlTextWriter w,
                                                 RegionInfo regionInfo,
                                                 CostEstimationResult costEstimationResult)
        {
            MakeHeader(w, "Full Resource List for " + costEstimationResult.SubscriptionName, "FullResourceList");
            MakeParagraph(w, @"Here is the full resource list in reference subscription related to this migration:");

            var locationMap = costEstimationResult.LocationMap[costEstimationResult.SubscriptionId];

            foreach (var kvp in costEstimationResult.DetailsByResourceGroup)
            {
                #region Table
                w.AddAttribute(HtmlTextWriterAttribute.Class, "table table-bordered");
                w.RenderBeginTag(HtmlTextWriterTag.Table);

                #region Tbody
                w.RenderBeginTag(HtmlTextWriterTag.Tbody);

                #region Resource Group Name
                w.RenderBeginTag(HtmlTextWriterTag.Tr);
                w.AddAttribute(HtmlTextWriterAttribute.Scope, "row");
                w.RenderBeginTag(HtmlTextWriterTag.Th);
                w.Write("Resource Group Name");
                w.RenderEndTag();
                w.AddAttribute(HtmlTextWriterAttribute.Colspan, "2");
                w.RenderBeginTag(HtmlTextWriterTag.Td);
                w.Write(kvp.Key);
                w.RenderEndTag();
                w.RenderEndTag();
                #endregion Resource Group Name

                #region Head for Name Type Location
                w.RenderBeginTag(HtmlTextWriterTag.Tr);
                w.AddAttribute(HtmlTextWriterAttribute.Scope, "col");
                w.AddAttribute(HtmlTextWriterAttribute.Style, "width:30%");
                w.RenderBeginTag(HtmlTextWriterTag.Th);
                w.Write("Name");
                w.RenderEndTag();

                w.AddAttribute(HtmlTextWriterAttribute.Scope, "col");
                w.AddAttribute(HtmlTextWriterAttribute.Style, "width:55%");
                w.RenderBeginTag(HtmlTextWriterTag.Th);
                w.Write("Type");
                w.RenderEndTag();

                w.AddAttribute(HtmlTextWriterAttribute.Scope, "col");
                w.AddAttribute(HtmlTextWriterAttribute.Style, "width:15%");
                w.RenderBeginTag(HtmlTextWriterTag.Th);
                w.Write("Location");
                w.RenderEndTag();

                w.RenderEndTag();
                #endregion Head for Name Type Location

                #region Data for Name Type Location
                foreach (var detail in kvp.Value)
                {
                    #region Row
                    w.RenderBeginTag(HtmlTextWriterTag.Tr);

                    #region Name
                    w.RenderBeginTag(HtmlTextWriterTag.Td);
                    w.Write(detail.ResourceName);
                    w.RenderEndTag();
                    #endregion Name

                    #region Type
                    w.RenderBeginTag(HtmlTextWriterTag.Td);
                    w.Write(detail.ResourceType);
                    w.RenderEndTag();
                    #endregion Type

                    #region Location
                    w.RenderBeginTag(HtmlTextWriterTag.Td);
                    if (locationMap.TryGetValue(detail.Location, out var locationDisplayName))
                    {
                        w.Write(locationDisplayName);
                    }
                    else
                    {
                        w.Write(detail.Location);
                    }
                    w.RenderEndTag();
                    #endregion Location

                    w.RenderEndTag();
                    #endregion Row
                }
                #endregion Data for Name Type Location

                w.RenderEndTag();
                #endregion Tbody

                w.RenderEndTag();
                #endregion Table
            }
        }
示例#12
0
        private static void MakeSeviceParityTable(HtmlTextWriter w,
                                                  ServiceParityResult serviceParityResult,
                                                  CostEstimationResult costEstimationResult)
        {
            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;
                    MakeParagraph(w, "Resource Group: " + resourceGroupName);
                }
                // Check each resource in the group
                foreach (var resource in resourceGroup.Value)
                {
                    if (detailsAll.Keys.Contains(resource.ResourceId) && detailsAll[resource.ResourceId].Pass == false)
                    {
                        #region Table
                        w.AddAttribute(HtmlTextWriterAttribute.Class, "table table-bordered");
                        w.RenderBeginTag(HtmlTextWriterTag.Table);

                        #region Tbody
                        w.RenderBeginTag(HtmlTextWriterTag.Tbody);

                        #region Resource Name
                        w.RenderBeginTag(HtmlTextWriterTag.Tr);
                        w.AddAttribute(HtmlTextWriterAttribute.Scope, "row");
                        w.RenderBeginTag(HtmlTextWriterTag.Th);
                        w.Write("Resource Name");
                        w.RenderEndTag();
                        w.AddAttribute(HtmlTextWriterAttribute.Colspan, "2");
                        w.RenderBeginTag(HtmlTextWriterTag.Td);
                        w.Write(resource.ResourceName);
                        w.RenderEndTag();
                        w.RenderEndTag();
                        #endregion Resource Name

                        #region Resource Id
                        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);

                        w.RenderBeginTag(HtmlTextWriterTag.Tr);
                        w.AddAttribute(HtmlTextWriterAttribute.Scope, "row");
                        w.RenderBeginTag(HtmlTextWriterTag.Th);
                        w.Write("Resource Id");
                        w.RenderEndTag();
                        w.AddAttribute(HtmlTextWriterAttribute.Colspan, "2");
                        w.RenderBeginTag(HtmlTextWriterTag.Td);
                        w.Write(resourceID);
                        w.RenderEndTag();
                        w.RenderEndTag();
                        #endregion Resource Id

                        #region Head for RuleName Pass Message
                        w.RenderBeginTag(HtmlTextWriterTag.Tr);

                        w.AddAttribute(HtmlTextWriterAttribute.Style, "width:30%");
                        w.AddAttribute(HtmlTextWriterAttribute.Scope, "col");
                        w.RenderBeginTag(HtmlTextWriterTag.Th);
                        w.Write("RuleName");
                        w.RenderEndTag();

                        w.AddAttribute(HtmlTextWriterAttribute.Style, "width:15%");
                        w.AddAttribute(HtmlTextWriterAttribute.Scope, "col");
                        w.RenderBeginTag(HtmlTextWriterTag.Th);
                        w.Write("Pass");
                        w.RenderEndTag();

                        w.AddAttribute(HtmlTextWriterAttribute.Style, "width:55%");
                        w.AddAttribute(HtmlTextWriterAttribute.Scope, "col");
                        w.RenderBeginTag(HtmlTextWriterTag.Th);
                        w.Write("Message");
                        w.RenderEndTag();

                        w.RenderEndTag();
                        #endregion Head for RuleName Pass Message

                        #region Data for RuleName Pass Message
                        foreach (var ruleCheck in detailsAll[resource.ResourceId].Details.Where(d => d.Pass == false))
                        {
                            w.RenderBeginTag(HtmlTextWriterTag.Tr);
                            w.RenderBeginTag(HtmlTextWriterTag.Td);
                            w.Write(ruleCheck.Brief);
                            w.RenderEndTag();

                            w.RenderBeginTag(HtmlTextWriterTag.Td);
                            w.Write("N");
                            w.RenderEndTag();

                            w.RenderBeginTag(HtmlTextWriterTag.Td);
                            w.Write(ruleCheck.Message);
                            w.RenderEndTag();

                            w.RenderEndTag();
                        }
                        #endregion Data for RuleName Pass Message

                        w.RenderEndTag();
                        #endregion Tbody

                        w.RenderEndTag();
                        #endregion Table
                    }
                }
            }
        }
示例#13
0
        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);
        }
示例#14
0
        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);
        }
示例#15
0
        private static void MakeCostEstimationSummaryTable(HtmlTextWriter w,
                                                           RegionInfo regionInfo,
                                                           CostEstimationResult costEstimationResult)
        {
            #region Table
            w.AddAttribute(HtmlTextWriterAttribute.Class, "table table-bordered");
            w.RenderBeginTag(HtmlTextWriterTag.Table);

            #region Tbody
            w.RenderBeginTag(HtmlTextWriterTag.Tbody);

            #region Reference Environment
            MakeKeyValueRow(w, "Reference Environment", "Microsoft Azure");
            #endregion Reference Environment

            #region Reference Subscription
            MakeKeyValueRow(w, "Reference Subscription", costEstimationResult.SubscriptionName);
            #endregion Reference Subscription

            #region Target Environment
            MakeKeyValueRow(w, "Target Environment", regionInfo.TargetRegionName);
            #endregion Target Environment

            #region Usage Collection Period
            MakeKeyValueRow(w, "Usage Collection Period", FormattableString.Invariant($"{costEstimationResult.StartTime:r} - {costEstimationResult.EndTime:r}"));
            #endregion Usage Collection Period

            #region Target Price Base
            MakeKeyValueRow(w, "Target Price Base", "List Price");
            #endregion Target Price Base

            #region Currency
            MakeKeyValueRow(w, "Currency", regionInfo.CurrencyUnit);
            #endregion Currency

            #region Currency Format
            MakeKeyValueRow(w, "Currency Format", regionInfo.CurrencyCulture.EnglishName);
            #endregion Currency Format

            #region Total Cost in Period for Available Resources
            if (!costEstimationResult.Details.Any())
            {
                MakeKeyValueRow(w, "Total Cost in Period for Available Resources", "N/A");
            }
            else
            {
                decimal totalCost = 0;
                foreach (var kvp in costEstimationResult.DetailsByResourceGroup)
                {
                    if (!kvp.Value.Any(d => d.EstimatedCost.HasValue))
                    {
                        continue;
                    }
                    foreach (var detail in kvp.Value.Where(d => d.EstimatedCost.HasValue))
                    {
                        totalCost += detail.EstimatedCost.Value;
                    }
                }
                MakeKeyValueRow(w, "Total Cost in Period for Available Resources", ToCurrencyString(totalCost, regionInfo.CurrencySymbol));
            }
            #endregion Total Cost in Period for Available Resources

            w.RenderEndTag();
            #endregion Tbody

            w.RenderEndTag();
            #endregion Table
        }
示例#16
0
        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);
        }
示例#17
0
        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);
        }
示例#18
0
        private static void MakeCostEstimationResourceGroupTable(HtmlTextWriter w,
                                                                 RegionInfo regionInfo,
                                                                 CostEstimationResult costEstimationResult)
        {
            foreach (var kvp in costEstimationResult.DetailsByResourceGroup)
            {
                if (!kvp.Value.Any(d => d.EstimatedCost.HasValue))
                {
                    continue;
                }

                #region Table
                w.AddAttribute(HtmlTextWriterAttribute.Class, "table table-bordered");
                w.RenderBeginTag(HtmlTextWriterTag.Table);

                #region Tbody
                w.RenderBeginTag(HtmlTextWriterTag.Tbody);

                #region Resource Group Name
                w.RenderBeginTag(HtmlTextWriterTag.Tr);
                w.AddAttribute(HtmlTextWriterAttribute.Scope, "row");
                w.RenderBeginTag(HtmlTextWriterTag.Th);
                w.Write("Resource Group Name");
                w.RenderEndTag();
                w.AddAttribute(HtmlTextWriterAttribute.Colspan, "4");
                w.RenderBeginTag(HtmlTextWriterTag.Td);
                w.Write(kvp.Key);
                w.RenderEndTag();
                w.RenderEndTag();
                #endregion Resource Group Name

                #region Head for Name Category MeterName Quantity DailyCost
                w.RenderBeginTag(HtmlTextWriterTag.Tr);
                w.AddAttribute(HtmlTextWriterAttribute.Scope, "col");
                w.AddAttribute(HtmlTextWriterAttribute.Style, "width:20%");
                w.RenderBeginTag(HtmlTextWriterTag.Th);
                w.Write("Name");
                w.RenderEndTag();

                w.AddAttribute(HtmlTextWriterAttribute.Scope, "col");
                w.AddAttribute(HtmlTextWriterAttribute.Style, "width:20%");
                w.RenderBeginTag(HtmlTextWriterTag.Th);
                w.Write("Category");
                w.RenderEndTag();

                w.AddAttribute(HtmlTextWriterAttribute.Scope, "col");
                w.AddAttribute(HtmlTextWriterAttribute.Style, "width:20%");
                w.RenderBeginTag(HtmlTextWriterTag.Th);
                w.Write("Meter Name");
                w.RenderEndTag();

                w.AddAttribute(HtmlTextWriterAttribute.Scope, "col");
                w.AddAttribute(HtmlTextWriterAttribute.Style, "width:20%");
                w.RenderBeginTag(HtmlTextWriterTag.Th);
                w.Write("Quantity");
                w.RenderEndTag();

                w.AddAttribute(HtmlTextWriterAttribute.Scope, "col");
                w.AddAttribute(HtmlTextWriterAttribute.Style, "width:20%");
                w.RenderBeginTag(HtmlTextWriterTag.Th);
                w.Write("Daily Cost");
                w.RenderEndTag();

                w.RenderEndTag();
                #endregion Head for Name Category MeterName Quantity DailyCost

                #region Data for Name Category MeterName Quantity DailyCost
                foreach (var detail in kvp.Value.Where(d => d.EstimatedCost.HasValue))
                {
                    w.RenderBeginTag(HtmlTextWriterTag.Tr);

                    MakeCostEstimationResouceGroupTableRow(w, detail, regionInfo);

                    w.RenderEndTag();
                }

                foreach (var detail in kvp.Value.Where(d => !d.EstimatedCost.HasValue))
                {
                    w.RenderBeginTag(HtmlTextWriterTag.Tr);

                    MakeCostEstimationResouceGroupTableRow(w, detail, regionInfo, true);

                    w.RenderEndTag();
                }

                #endregion Data for Name Category MeterName Quantity DailyCost

                w.RenderEndTag();
                #endregion Tbody

                w.RenderEndTag();
                #endregion Table
            }
        }