diff --git a/ChangeLog.md b/ChangeLog.md index 5ac9121..ab5eb31 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -5,6 +5,12 @@ All notable changes to AADConnectConfigDocumenter project will be documented in ### Version [Unreleased] * Support for adding report metadata to include section / concept contents. +------------ + +### Version 1.17.0802.0 + +#### Added +- Added check-box control to hide default synchronization rules. ------------ diff --git a/src/AzureADConnectSyncDocumenter.cmd b/src/AzureADConnectSyncDocumenter.cmd index 33ebbaf..7c60964 100644 --- a/src/AzureADConnectSyncDocumenter.cmd +++ b/src/AzureADConnectSyncDocumenter.cmd @@ -1,2 +1,5 @@ AzureADConnectSyncDocumenterCmd.exe "Contoso\Pilot" "Contoso\Production" +ECHO OFF +ECHO **************************************************************************************************** +ECHO Execution complete. Please check any errors or warnings in the AADConnectSyncDocumenter-Error.log... @pause \ No newline at end of file diff --git a/src/AzureADConnectSyncDocumenter/AzureADConnectSyncDocumenter.cs b/src/AzureADConnectSyncDocumenter/AzureADConnectSyncDocumenter.cs index 54d5c05..00dc8da 100644 --- a/src/AzureADConnectSyncDocumenter/AzureADConnectSyncDocumenter.cs +++ b/src/AzureADConnectSyncDocumenter/AzureADConnectSyncDocumenter.cs @@ -377,6 +377,11 @@ orderby name foreach (var connector in pilot) { var configEnvironment = production.Any(productionConnector => (string)productionConnector.Element("name") == (string)connector.Element("name")) ? ConfigEnvironment.PilotAndProduction : ConfigEnvironment.PilotOnly; + if (configEnvironment == ConfigEnvironment.PilotOnly) + { + Logger.Instance.WriteWarning("The connector '{0}' only exists in the first set of configuration files. If this is not expected, please edit the config files to match names of this connector in the two enviorments as instructed in the ReadMe wiki.", (string)connector.Element("name")); + } + this.ProcessConnectorConfiguration(connector, configEnvironment); } @@ -384,6 +389,8 @@ orderby name foreach (var connector in production) { + Logger.Instance.WriteWarning("The connector '{0}' only exists in the second set of configuration files and will be documented as a connector that is deleted from the configuration. If this is not intended, please edit the config files to match names of this connector in the two enviorments as instructed in the ReadMe wiki.", (string)connector.Element("name")); + this.ProcessConnectorConfiguration(connector, ConfigEnvironment.ProductionOnly); } } diff --git a/src/AzureADConnectSyncDocumenter/Documenter.cs b/src/AzureADConnectSyncDocumenter/Documenter.cs index b882f4b..1f3bc4b 100644 --- a/src/AzureADConnectSyncDocumenter/Documenter.cs +++ b/src/AzureADConnectSyncDocumenter/Documenter.cs @@ -1450,6 +1450,18 @@ protected void WriteDocumenterInfo() this.WriteBreakTag(); + this.ReportWriter.WriteFullBeginTag("strong"); + this.ReportWriter.Write("Hide Default Sync Rules:"); + this.ReportWriter.WriteEndTag("strong"); + + this.ReportWriter.WriteBeginTag("input"); + this.ReportWriter.WriteAttribute("type", "checkbox"); + this.ReportWriter.WriteAttribute("id", "HideDefaultSyncRules"); + this.ReportWriter.WriteAttribute("onclick", "ToggleDefaultRuleVisibility();"); + this.ReportWriter.WriteLine(HtmlTextWriter.SelfClosingTagEnd); + + this.WriteBreakTag(); + this.ReportWriter.WriteFullBeginTag("strong"); this.ReportWriter.Write("Legend:"); this.ReportWriter.WriteEndTag("strong"); @@ -2077,8 +2089,7 @@ protected void WriteTableHeader(DataTable headerTable) { this.ReportWriter.WriteBeginTag("col"); this.ReportWriter.WriteAttribute("style", "width:" + columnWidth + "%;"); - this.ReportWriter.Write(HtmlTextWriter.TagRightChar); - this.ReportWriter.WriteEndTag("col"); + this.ReportWriter.Write(HtmlTextWriter.SelfClosingTagEnd); } } diff --git a/src/AzureADConnectSyncDocumenter/Scripts/Documenter.js b/src/AzureADConnectSyncDocumenter/Scripts/Documenter.js index 18cdc73..c911b5a 100644 --- a/src/AzureADConnectSyncDocumenter/Scripts/Documenter.js +++ b/src/AzureADConnectSyncDocumenter/Scripts/Documenter.js @@ -20,6 +20,19 @@ } } +function ToggleDefaultRuleVisibility() { + var x = document.getElementById("HideDefaultSyncRules"); + var elements = document.getElementsByClassName("DefaultRuleCanHide"); + for (var i = 0; i < elements.length; ++i) { + if (x.checked == true) { + elements[i].style.display = "none"; + } + else { + elements[i].style.display = ""; + } + } +} + function DownloadScript(downloadLink) { var scripts = document.getElementsByClassName("PowerShellScript"); var data = ""; diff --git a/src/AzureADConnectSyncDocumenter/Scripts/PowerShellScriptHeader.ps1 b/src/AzureADConnectSyncDocumenter/Scripts/PowerShellScriptHeader.ps1 index e14f161..acab96d 100644 --- a/src/AzureADConnectSyncDocumenter/Scripts/PowerShellScriptHeader.ps1 +++ b/src/AzureADConnectSyncDocumenter/Scripts/PowerShellScriptHeader.ps1 @@ -1,13 +1,11 @@ -<# - This script is generated by the Azure AD Connect Configuration Documenter tool. - The latest version of the tool can be downloaded from https://aka.ms/AADConnectConfigDocumenter. - - NO WARRANTY OF ANY KIND IS PROVIDED. THE ENTIRE RISK OF THE USE OR THE RESULTS FROM THE USE OF THIS SCRIPT REMAINS WITH THE USER. - - When the script is executed, the sync rule configuration of the server is made same as what was provided as the "Pilot" configuration. - The "Pilot" configuration was the first argument passed when running the AAD Connect Config Documenter executable. -#> - +############################################################################################################################################# +# This script is generated by the Azure AD Connect Configuration Documenter tool. +# The latest version of the tool can be downloaded from https://aka.ms/AADConnectConfigDocumenter. +# +# NO WARRANTY OF ANY KIND IS PROVIDED. THE ENTIRE RISK OF THE USE OR THE RESULTS FROM THE USE OF THIS SCRIPT REMAINS WITH THE USER. +# +# When the script is executed, the sync rule configuration of the server is made same as what was provided as the "Pilot" configuration. +# The "Pilot" configuration was the first argument passed when running the AAD Connect Config Documenter executable. ############################################################################################################################################# function Get-CurrentLine { diff --git a/src/AzureADConnectSyncDocumenter/StyleCop.Cache b/src/AzureADConnectSyncDocumenter/StyleCop.Cache index 1963766..cf21849 100644 --- a/src/AzureADConnectSyncDocumenter/StyleCop.Cache +++ b/src/AzureADConnectSyncDocumenter/StyleCop.Cache @@ -177,7 +177,7 @@ 2016/11/09 21:13:02.000 2017/04/16 06:55:54.094 - 2017/06/17 07:02:06.124 + 2017/07/27 06:40:54.984 2016/11/09 21:13:02.000 2016/11/09 21:13:02.000 -277821146 @@ -223,7 +223,7 @@ 2016/11/09 21:13:02.000 2017/04/16 06:55:54.094 - 2017/07/03 23:05:46.690 + 2017/07/27 13:03:47.893 2016/11/09 21:13:02.000 2016/11/09 21:13:02.000 -277821146 @@ -269,7 +269,7 @@ 2016/11/09 21:13:02.000 2017/04/16 06:55:54.094 - 2017/07/03 23:09:48.706 + 2017/07/28 06:56:35.707 2016/11/09 21:13:02.000 2016/11/09 21:13:02.000 -277821146 @@ -499,7 +499,7 @@ 2016/11/09 21:13:02.000 2017/04/16 06:55:54.094 - 2017/06/18 06:02:37.186 + 2017/07/28 07:19:20.934 2016/11/09 21:13:02.000 2016/11/09 21:13:02.000 -277821146 @@ -522,7 +522,7 @@ 2016/11/09 21:13:02.000 2017/04/16 06:55:54.094 - 2017/07/03 21:30:13.063 + 2017/07/27 06:28:24.476 2016/11/09 21:13:02.000 2016/11/09 21:13:02.000 -277821146 diff --git a/src/AzureADConnectSyncDocumenter/SyncRuleDocumenter.cs b/src/AzureADConnectSyncDocumenter/SyncRuleDocumenter.cs index efed0eb..090408c 100644 --- a/src/AzureADConnectSyncDocumenter/SyncRuleDocumenter.cs +++ b/src/AzureADConnectSyncDocumenter/SyncRuleDocumenter.cs @@ -44,15 +44,20 @@ internal class SyncRuleDocumenter : ConnectorDocumenter private const string LoggerContextItemSyncRuleReportType = "Sync Rule Report Type"; /// - /// The synchronize rule direction + /// The synchronization rule direction /// private SyncRuleDirection syncRuleDirection; /// - /// The synchronize rule report type + /// The synchronization rule report type /// private SyncRuleReportType syncRuleReportType; + /// + /// Indicates if the the synchronization rule is inferred as a default sync rule can be made invisible + /// + private bool defaultSyncRuleVisibility; + /// /// Initializes a new instance of the class. /// @@ -71,8 +76,9 @@ public SyncRuleDocumenter(XElement pilotXml, XElement productionXml, string sync { this.SyncRuleName = syncRuleName; this.SyncRuleGuid = syncRuleGuid; - this.ReportFileName = Documenter.GetTempFilePath(this.ConnectorName + "_" + this.SyncRuleName + "_" + this.SyncRuleGuid + ".tmp.html"); - this.ReportToCFileName = Documenter.GetTempFilePath(this.ConnectorName + "_" + this.SyncRuleName + "_" + this.SyncRuleGuid + ".TOC.tmp.html"); + this.defaultSyncRuleVisibility = false; + this.ReportFileName = Documenter.GetTempFilePath(this.SyncRuleGuid + ".tmp.html"); + this.ReportToCFileName = Documenter.GetTempFilePath(this.SyncRuleGuid + ".TOC.tmp.html"); // Set Logger call context items Logger.SetContextItem(SyncRuleDocumenter.LoggerContextItemSyncRuleName, this.SyncRuleName); @@ -212,9 +218,10 @@ public Tuple GetReport(SyncRuleReportType reportType) } } + this.WriteSyncRuleReportHeader(); + try { - this.WriteSyncRuleReportHeader(); this.PrintConnectorSyncRuleDescription(); this.PrintConnectorSyncRuleScopingFilter(); this.PrintConnectorSyncRuleJoinRules(); @@ -229,6 +236,12 @@ public Tuple GetReport(SyncRuleReportType reportType) } finally { + if (!this.defaultSyncRuleVisibility) + { + this.ReportWriter.WriteEndTag("div"); + this.ReportToCWriter.WriteEndTag("div"); + } + this.ResetDiffgram(); // reset the diffgram variables } @@ -259,13 +272,23 @@ private void WriteSyncRuleReportHeader() if (this.syncRuleReportType != SyncRuleReportType.AllSections) { bookmark += this.syncRuleReportType.ToString(); - this.ReportFileName = Documenter.GetTempFilePath(this.syncRuleReportType + "." + this.ConnectorName + "_" + this.SyncRuleName + "_" + this.SyncRuleGuid + ".tmp.html"); - this.ReportToCFileName = Documenter.GetTempFilePath(this.syncRuleReportType + "." + this.ConnectorName + "_" + this.SyncRuleName + "_" + this.SyncRuleGuid + ".TOC.tmp.html"); + this.ReportFileName = Documenter.GetTempFilePath(this.SyncRuleGuid + ".tmp.html"); + this.ReportToCFileName = Documenter.GetTempFilePath(this.SyncRuleGuid + ".TOC.tmp.html"); } this.ReportWriter = new XhtmlTextWriter(new StreamWriter(this.ReportFileName)); this.ReportToCWriter = new XhtmlTextWriter(new StreamWriter(this.ReportToCFileName)); + if (!this.defaultSyncRuleVisibility) + { + this.ReportWriter.WriteBeginTag("div"); + this.ReportWriter.WriteAttribute("class", "DefaultRuleCanHide"); + this.ReportWriter.Write(HtmlTextWriter.TagRightChar); + this.ReportToCWriter.WriteBeginTag("div"); + this.ReportToCWriter.WriteAttribute("class", "DefaultRuleCanHide"); + this.ReportToCWriter.Write(HtmlTextWriter.TagRightChar); + } + this.WriteSectionHeader(this.SyncRuleName, 5, bookmark, this.SyncRuleGuid); } finally @@ -366,6 +389,21 @@ private void FillConnectorSyncRuleDescriptionDataSet(bool pilotConfig) var table = dataSet.Tables[0]; this.syncRuleDirection = (SyncRuleDirection)Enum.Parse(typeof(SyncRuleDirection), (string)syncRule.Element("direction"), true); + var defaultSyncRule = ((string)syncRule.Element("immutable-tag") ?? string.Empty).StartsWith("Microsoft.", StringComparison.OrdinalIgnoreCase); + + // Only turn the visibility on and never off. + if (this.defaultSyncRuleVisibility == false) + { + this.defaultSyncRuleVisibility = !defaultSyncRule; + } + + // Any disabled rule will also be always visible. + // Ideally we should have any unsupported customisation to default sync rule always visible + // as well but for now depend on the PowerShell script to flag that + if (((string)syncRule.Element("disabled") ?? string.Empty).Equals("true", StringComparison.OrdinalIgnoreCase)) + { + this.defaultSyncRuleVisibility = true; + } var setting = (string)syncRule.Element("name"); Documenter.AddRow(table, new object[] { 0, "Name", setting }); @@ -417,6 +455,11 @@ private void FillConnectorSyncRuleDescriptionDataSet(bool pilotConfig) table.AcceptChanges(); } + else + { + // The missing rule in either of the environments will make the rule always visible + this.defaultSyncRuleVisibility = true; + } } } finally diff --git a/src/AzureADConnectSyncDocumenterCmd/Program.cs b/src/AzureADConnectSyncDocumenterCmd/Program.cs index cd76fb2..0c0c583 100644 --- a/src/AzureADConnectSyncDocumenterCmd/Program.cs +++ b/src/AzureADConnectSyncDocumenterCmd/Program.cs @@ -25,14 +25,25 @@ public class Program /// The command-line arguments. public static void Main(string[] args) { - if (args == null || args.Length < 2) + try { - string errorMsg = string.Format(CultureInfo.CurrentUICulture, "Usage: {0} {1} {2}.", new object[] { Assembly.GetExecutingAssembly().GetName().Name, "{Pilot / Target Config Folder}", "{Production / Reference / Baseline Config Folder}" }); - throw new ArgumentException(errorMsg, "args"); - } + if (args == null || args.Length < 2) + { + string errorMsg = string.Format(CultureInfo.CurrentUICulture, "Missing commnad-line arguments. Usage: {0} {1} {2}.", new object[] { Assembly.GetExecutingAssembly().GetName().Name, "{Pilot / Target Config Folder}", "{Production / Reference / Baseline Config Folder}" }); + Console.Error.WriteLine(errorMsg); + Console.ReadKey(); + return; + } - var documenter = new AzureADConnectSyncDocumenter(args[0], args[1]); - documenter.GenerateReport(); + var documenter = new AzureADConnectSyncDocumenter(args[0], args[1]); + documenter.GenerateReport(); + } + catch (Exception e) + { + Console.Error.WriteLine(e.ToString()); + Console.WriteLine("Press any key to exit..."); + Console.ReadKey(); + } } } } diff --git a/src/VersionInfo.cs b/src/VersionInfo.cs index 36a1ff2..c5c02c4 100644 --- a/src/VersionInfo.cs +++ b/src/VersionInfo.cs @@ -22,7 +22,7 @@ internal static class VersionInfo /// Build Number (MMDD) /// Revision (if any on the same day) /// - internal const string Version = "1.17.0703.0"; + internal const string Version = "1.17.0802.0"; /// /// File Version information for the assembly consists of the following four values: @@ -31,6 +31,6 @@ internal static class VersionInfo /// Build Number (MMDD) /// Revision (if any on the same day) /// - internal const string FileVersion = "1.17.0703.0"; + internal const string FileVersion = "1.17.0802.0"; } } \ No newline at end of file