From 4999d97ed7265b121e0a3cbc0518b92a0eceeb60 Mon Sep 17 00:00:00 2001 From: Ji Jiang Date: Thu, 1 Feb 2018 17:29:34 +0000 Subject: [PATCH 1/3] Revert "CP-21997: Delete unused CFUValidator code" This reverts commit 95c7e47bf7ea96b237a90cbba31fe4219582b91e. --- CFUValidator/CFUValidator.cs | 279 ++++++++++++++++++ CFUValidator/CFUValidator.csproj | 150 ++++++++++ .../CFUCommandLineOptionManager.cs | 131 ++++++++ .../CommandLineOptions/CommandLineArgument.cs | 63 ++++ .../CommandLineOptions/CommandLineParser.cs | 72 +++++ CFUValidator/ConsoleSpinner.cs | 85 ++++++ .../AlertFeatureValidatorDecorator.cs | 60 ++++ CFUValidator/OutputDecorators/Decorator.cs | 53 ++++ .../OutputDecorators/OuputComponent.cs | 66 +++++ .../OutputDecorators/PatchAlertDecorator.cs | 80 +++++ .../XenCenterUpdateDecorator.cs | 58 ++++ .../XenServerUpdateDecorator.cs | 60 ++++ CFUValidator/Program.cs | 88 ++++++ CFUValidator/Properties/AssemblyInfo.cs | 67 +++++ ...nativeUrlDownloadUpdatesXmlSourceAction.cs | 81 +++++ .../Updates/ICheckForUpdatesXMLSource.cs | 48 +++ .../Updates/ReadFromFileUpdatesXmlSource.cs | 77 +++++ CFUValidator/Updates/XmlRetrieverFactory.cs | 50 ++++ .../Validators/AlertFeatureValidator.cs | 74 +++++ .../Validators/CorePatchDetailsValidator.cs | 72 +++++ CFUValidator/Validators/PatchURLValidator.cs | 104 +++++++ .../Validators/ZipContentsValidator.cs | 98 ++++++ CFUValidator/app.config | 3 + XenAdmin.sln | 20 +- 24 files changed, 1934 insertions(+), 5 deletions(-) create mode 100644 CFUValidator/CFUValidator.cs create mode 100644 CFUValidator/CFUValidator.csproj create mode 100644 CFUValidator/CommandLineOptions/CFUCommandLineOptionManager.cs create mode 100644 CFUValidator/CommandLineOptions/CommandLineArgument.cs create mode 100644 CFUValidator/CommandLineOptions/CommandLineParser.cs create mode 100644 CFUValidator/ConsoleSpinner.cs create mode 100644 CFUValidator/OutputDecorators/AlertFeatureValidatorDecorator.cs create mode 100644 CFUValidator/OutputDecorators/Decorator.cs create mode 100644 CFUValidator/OutputDecorators/OuputComponent.cs create mode 100644 CFUValidator/OutputDecorators/PatchAlertDecorator.cs create mode 100644 CFUValidator/OutputDecorators/XenCenterUpdateDecorator.cs create mode 100644 CFUValidator/OutputDecorators/XenServerUpdateDecorator.cs create mode 100644 CFUValidator/Program.cs create mode 100644 CFUValidator/Properties/AssemblyInfo.cs create mode 100644 CFUValidator/Updates/AlternativeUrlDownloadUpdatesXmlSourceAction.cs create mode 100644 CFUValidator/Updates/ICheckForUpdatesXMLSource.cs create mode 100644 CFUValidator/Updates/ReadFromFileUpdatesXmlSource.cs create mode 100644 CFUValidator/Updates/XmlRetrieverFactory.cs create mode 100644 CFUValidator/Validators/AlertFeatureValidator.cs create mode 100644 CFUValidator/Validators/CorePatchDetailsValidator.cs create mode 100644 CFUValidator/Validators/PatchURLValidator.cs create mode 100644 CFUValidator/Validators/ZipContentsValidator.cs create mode 100644 CFUValidator/app.config diff --git a/CFUValidator/CFUValidator.cs b/CFUValidator/CFUValidator.cs new file mode 100644 index 000000000..6a4e06ed7 --- /dev/null +++ b/CFUValidator/CFUValidator.cs @@ -0,0 +1,279 @@ +/* Copyright (c) Citrix Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +using System; +using System.Linq; +using System.Collections.Generic; +using System.Text; +using CFUValidator.CommandLineOptions; +using CFUValidator.OutputDecorators; +using CFUValidator.Updates; +using CFUValidator.Validators; +using Moq; +using XenAdmin; +using XenAdmin.Alerts; +using XenAdmin.Core; +using XenAdminTests; +using XenAPI; + +namespace CFUValidator +{ + public class CFUValidationException : Exception + { + public CFUValidationException(string message) : base(message){} + } + + public class CFUValidator + { + private readonly MockObjectManager mom = new MockObjectManager(); + private readonly XmlRetrieverFactory xmlFactory = new XmlRetrieverFactory(); + private const string id = "id"; + private string XmlLocation { get; set; } + private string ServerVersion { get; set; } + private OptionUsage UrlOrFile { get; set; } + private List InstalledHotfixes { get; set; } + private bool CheckHotfixContents{ get; set; } + + public CFUValidator(OptionUsage urlOrFile, string xmlLocation, string serverVersion, + List installedHotfixes, bool checkHotfixContents) + { + if(urlOrFile != OptionUsage.File && urlOrFile != OptionUsage.Url) + throw new ArgumentException("urlOrFile option should be either File or Url"); + + mom.CreateNewConnection(id); + ConnectionsManager.XenConnections.AddRange(mom.AllConnections); + XmlLocation = xmlLocation; + ServerVersion = serverVersion; + InstalledHotfixes = installedHotfixes; + UrlOrFile = urlOrFile; + CheckHotfixContents = checkHotfixContents; + } + + public void Run() + { + List xenServerPatches; + List xenServerVersions; + List xenCenterVersions; + + Status = "Getting check for updates XML from " + XmlLocation + "..."; + ReadCheckForUpdatesXML(out xenServerPatches, out xenServerVersions, out xenCenterVersions); + + List versionToCheck = GetVersionToCheck(xenServerVersions); + + foreach (string ver in versionToCheck) + { + ServerVersion = ver; + RunTestsForGivenServerVersion(xenServerVersions, xenServerPatches, xenCenterVersions); + } + + } + + + private List GetVersionToCheck(List xenServerVersions) + { + if(ServerVersion == CFUCommandLineOptionManager.AllVersions) + return xenServerVersions.ConvertAll(i => i.Version.ToString()).Distinct().ToList(); + + return new List{ServerVersion}; + } + + private void RunTestsForGivenServerVersion(List xenServerVersions, + List xenServerPatches, + List xenCenterVersions) + { + CheckProvidedVersionNumber(xenServerVersions); + + Status = String.Format("Generating server {0} mock-ups...", ServerVersion); + SetupMocks(xenServerPatches, xenServerVersions); + + Status = "Determining XenCenter update required..."; + var xcupdateAlert = XenAdmin.Core.Updates.NewXenCenterUpdateAlert(xenCenterVersions, new Version(ServerVersion)); + + Status = "Determining XenServer update required..."; + var updateAlert = XenAdmin.Core.Updates.NewXenServerVersionAlert(xenServerVersions); + + Status = "Determining patches required..."; + var patchAlerts = XenAdmin.Core.Updates.NewXenServerPatchAlerts(xenServerVersions, xenServerPatches).Where(alert => !alert.CanIgnore).ToList(); + + //Build patch checks list + List validators = new List + { + new CorePatchDetailsValidator(patchAlerts), + new PatchURLValidator(patchAlerts), + new ZipContentsValidator(patchAlerts) + }; + + Status = "Running patch check(s), this may take some time..."; + RunValidators(validators); + + Status = "Generating summary..."; + GeneratePatchSummary(patchAlerts, validators, updateAlert, xcupdateAlert); + } + + private void CheckProvidedVersionNumber(List xenServerVersions) + { + if (!xenServerVersions.Any(v => v.Version.ToString() == ServerVersion)) + { + StringBuilder sb = new StringBuilder("\nAvailable versions are:\n"); + xenServerVersions.ConvertAll(i=>i.Version.ToString()).Distinct().ToList().ForEach(v=>sb.AppendLine(v)); + throw new CFUValidationException("Could not find the version in the check for updates file: " + ServerVersion + sb); + } + } + + public string Output { get; private set; } + + #region Status event code + public delegate void StatusChangedHandler(object sender, EventArgs e); + + public event StatusChangedHandler StatusChanged; + + protected virtual void OnStatusChanged() + { + if (StatusChanged != null) + StatusChanged(Status, EventArgs.Empty); + } + + private string status; + private string Status + { + get { return status; } + set + { + status = value; + OnStatusChanged(); + } + } + #endregion + + private void RunValidators(List validators) + { + int count = 1; + foreach (AlertFeatureValidator validator in validators) + { + if (validator is ZipContentsValidator && !CheckHotfixContents) + continue; + + Status = count++ + ". " + validator.Description + "..."; + + validator.StatusChanged += validator_StatusChanged; + validator.Validate(); + validator.StatusChanged -= validator_StatusChanged; + } + Status = "Validator checks complete"; + } + + private void validator_StatusChanged(object sender, EventArgs e) + { + Status = sender as string; + } + + private void GeneratePatchSummary(List alerts, List validators, + XenServerVersionAlert updateAlert, XenCenterUpdateAlert xcupdateAlert) + { + OuputComponent oc = new OutputTextOuputComponent(XmlLocation, ServerVersion); + XenCenterUpdateDecorator xcud = new XenCenterUpdateDecorator(oc, xcupdateAlert); + XenServerUpdateDecorator xsud = new XenServerUpdateDecorator(xcud, updateAlert); + PatchAlertDecorator pad = new PatchAlertDecorator(xsud, alerts); + AlertFeatureValidatorDecorator afdCoreFields = new AlertFeatureValidatorDecorator(pad, + validators.First(v => v is CorePatchDetailsValidator), + "Core fields in patch checks:"); + AlertFeatureValidatorDecorator afdPatchUrl = new AlertFeatureValidatorDecorator(afdCoreFields, + validators.First(v => v is PatchURLValidator), + "Required patch URL checks:"); + AlertFeatureValidatorDecorator afdZipContents = new AlertFeatureValidatorDecorator(afdPatchUrl, + validators.First(v => v is ZipContentsValidator), + "Required patch zip content checks:"); + + if(CheckHotfixContents) + Output = afdZipContents.Generate().Insert(0, Output).ToString(); + else + Output = afdPatchUrl.Generate().Insert(0, Output).ToString(); + + } + + private void ReadCheckForUpdatesXML(out List patches, out List versions, out List xcVersions) + { + ICheckForUpdatesXMLSource checkForUpdates = xmlFactory.GetAction(UrlOrFile, XmlLocation); + checkForUpdates.RunAsync(); + + ConsoleSpinner spinner = new ConsoleSpinner(); + while(!checkForUpdates.IsCompleted) + { + spinner.Turn(checkForUpdates.PercentComplete); + } + + if (checkForUpdates.ErrorRaised != null) + throw checkForUpdates.ErrorRaised; + + patches = checkForUpdates.XenServerPatches; + versions = checkForUpdates.XenServerVersions; + xcVersions = checkForUpdates.XenCenterVersions; + } + + private void SetupMocks(List xenServerPatches, List xenServerVersions) + { + Mock master = mom.NewXenObject(id); + Mock pool = mom.NewXenObject(id); + XenRef masterRef = new XenRef("ref"); + pool.Setup(p => p.master).Returns(masterRef); + mom.MockCacheFor(id).Setup(c => c.Resolve(It.IsAny>())).Returns(pool.Object); + mom.MockConnectionFor(id).Setup(c => c.Resolve(masterRef)).Returns(master.Object); + master.Setup(h => h.software_version).Returns(new Dictionary()); + master.Setup(h => h.ProductVersion).Returns(ServerVersion); + master.Setup(h => h.AppliedPatches()).Returns(GenerateMockPoolPatches(xenServerPatches)); + + //Currently build number will be referenced first so if it's present hook it up + string buildNumber = xenServerVersions.First(v => v.Version.ToString() == ServerVersion).BuildNumber; + master.Setup(h=>h.BuildNumberRaw).Returns(buildNumber); + } + + private List GenerateMockPoolPatches(List xenServerPatches) + { + List patches = new List(); + + foreach (string installedHotfix in InstalledHotfixes) + { + string hotfix = installedHotfix; + XenServerPatch match = xenServerPatches.Find(m => m.Name.Contains(hotfix)); + + if(match == null) + throw new CFUValidationException("No patch could be found in the XML matching " + hotfix); + + Mock pp = mom.NewXenObject(id); + pp.Setup(p => p.uuid).Returns(match.Uuid); + patches.Add(pp.Object); + } + + return patches; + } + + } +} diff --git a/CFUValidator/CFUValidator.csproj b/CFUValidator/CFUValidator.csproj new file mode 100644 index 000000000..2553f82f8 --- /dev/null +++ b/CFUValidator/CFUValidator.csproj @@ -0,0 +1,150 @@ + + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {39308480-78C3-40B4-924D-06914F343ACD} + Exe + Properties + CFUValidator + CFUValidator + v4.6 + 512 + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + 3.5 + + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + false + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + false + + + + False + ..\packages\Moq.dll + + + + 3.5 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + False + .NET Framework Client Profile + false + + + False + .NET Framework 2.0 %28x86%29 + false + + + False + .NET Framework 3.0 %28x86%29 + false + + + False + .NET Framework 3.5 + false + + + False + .NET Framework 3.5 SP1 + true + + + False + Windows Installer 3.1 + true + + + + + {21B9482C-D255-40D5-ABA7-C8F00F99547C} + XenAdminTests + + + {70BDA4BC-F062-4302-8ACD-A15D8BF31D65} + XenAdmin + + + {9861DFA1-B41F-432D-A43F-226257DEBBB9} + XenCenterLib + + + {B306FC59-4441-4A5F-9F54-D3F68D4EE38D} + XenModel + + + + + + + + \ No newline at end of file diff --git a/CFUValidator/CommandLineOptions/CFUCommandLineOptionManager.cs b/CFUValidator/CommandLineOptions/CFUCommandLineOptionManager.cs new file mode 100644 index 000000000..477e40283 --- /dev/null +++ b/CFUValidator/CommandLineOptions/CFUCommandLineOptionManager.cs @@ -0,0 +1,131 @@ +/* Copyright (c) Citrix Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace CFUValidator.CommandLineOptions +{ + internal class CFUCommandLineOptionManager + { + private readonly List clas; + public CFUCommandLineOptionManager(List clas) + { + this.clas = clas; + } + + //Not to be called from inside this class to keep IoC + public static List EmptyArguments + { + get + { + return new List + { + new CommandLineArgument( OptionUsage.Help, 'h', "Display this help" ), + new CommandLineArgument( OptionUsage.CheckZipContents, 'c', "Optionally check the zip contents of the hotfixes" ), + new CommandLineArgument( OptionUsage.Url, 'u', " Cannot be used with -f flag"), + new CommandLineArgument( OptionUsage.File, 'f', " Cannot be used with -u flag" ), + new CommandLineArgument( OptionUsage.ServerVersion, 's', " eg. 6.0.2" ), + new CommandLineArgument( OptionUsage.Hotfix, 'p', " eg. XS602E001 (space delimited)" ) + }; + } + } + + public static string AllVersions = "999.999.999"; + + public string XmlLocation { get { return GetFileUsageCLA().Options.First(); } } + + public bool CheckHotfixContents { get { return clas.First(c => c.Usage == OptionUsage.CheckZipContents).IsActiveOption; } } + + private CommandLineArgument GetFileUsageCLA() + { + CommandLineArgument claForUrl = clas.First(c => c.Usage == OptionUsage.Url); + CommandLineArgument claForFle = clas.First(c => c.Usage == OptionUsage.File); + if (claForUrl.IsActiveOption && claForFle.IsActiveOption) + throw new CFUValidationException(String.Format("Switches '-{0}' and '-{1}' cannot be used at the same time", claForFle.Switch, claForUrl.Switch)); + + if (!claForUrl.IsActiveOption && !claForFle.IsActiveOption) + throw new CFUValidationException(String.Format("You must provide either option '-{0}' or '-{1}'", claForFle.Switch, claForUrl.Switch)); + + if (claForFle.IsActiveOption) + return claForFle; + + return claForUrl; + } + + public OptionUsage FileSource { get {return GetFileUsageCLA().Usage; } } + + public string ServerVersion + { + get + { + CommandLineArgument cla = clas.First(c => c.Usage == OptionUsage.ServerVersion); + return !cla.IsActiveOption ? AllVersions : cla.Options.First(); + } + } + + public List InstalledHotfixes + { + get + { + CommandLineArgument cla = clas.First(c => c.Usage == OptionUsage.Hotfix); + if (!cla.IsActiveOption) + return new List(); + return cla.Options; + } + } + + + public bool IsHelpRequired + { + get + { + return clas.First(c => c.Usage == OptionUsage.Help).IsActiveOption; + } + } + + public string Help + { + get + { + StringBuilder sb = new StringBuilder("Execute the command with the following command line options\n\nOptions:\n"); + foreach (CommandLineArgument cla in clas.OrderBy(c => c.Switch)) + { + sb.AppendLine(String.Format("-{0} {1}", cla.Switch, cla.Description)); + } + return sb.ToString(); + } + } + + } +} diff --git a/CFUValidator/CommandLineOptions/CommandLineArgument.cs b/CFUValidator/CommandLineOptions/CommandLineArgument.cs new file mode 100644 index 000000000..c27e03cc3 --- /dev/null +++ b/CFUValidator/CommandLineOptions/CommandLineArgument.cs @@ -0,0 +1,63 @@ +/* Copyright (c) Citrix Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +using System.Collections.Generic; + +namespace CFUValidator.CommandLineOptions +{ + public enum OptionUsage + { + Help, + Url, + File, + Hotfix, + ServerVersion, + CheckZipContents + } + + public class CommandLineArgument + { + public CommandLineArgument(OptionUsage usage, char commandSwitch, string description) + { + Switch = commandSwitch; + Description = description; + Usage = usage; + Options = null; + IsActiveOption = false; + } + + public OptionUsage Usage { get; private set; } + public char Switch { get; private set; } + public List Options { get; set; } + public string Description { get; private set; } + public bool IsActiveOption { get; set; } + } +} diff --git a/CFUValidator/CommandLineOptions/CommandLineParser.cs b/CFUValidator/CommandLineOptions/CommandLineParser.cs new file mode 100644 index 000000000..a2a6e5b88 --- /dev/null +++ b/CFUValidator/CommandLineOptions/CommandLineParser.cs @@ -0,0 +1,72 @@ +/* Copyright (c) Citrix Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text.RegularExpressions; + +namespace CFUValidator.CommandLineOptions +{ + public class CommandLineParser + { + private readonly string[] args; + + public List ParsedArguments { get; private set; } + + public CommandLineParser(string[] args, List argsToParse) + { + this.args = args; + ParsedArguments = argsToParse; + } + + public void Parse() + { + string[] recastArgs = Regex.Split(string.Join(" ", args).Trim(), @"(?=[-])(?<=[ ])"); + foreach (string arg in recastArgs) + { + if(String.IsNullOrEmpty(arg)) + continue; + + string optionSwitch = Regex.Match(arg, "[-]{1}[a-z]{1}").Value.Trim(); + char switchChar = Convert.ToChar(optionSwitch.Substring(1, 1)); + string[] splitArgs = arg.Replace(optionSwitch, "").Trim().Split(' '); + + CommandLineArgument cla = ParsedArguments.FirstOrDefault(c => c.Switch == switchChar); + if (cla != null) + { + cla.Options = splitArgs.Where(s=>!String.IsNullOrEmpty(s)).ToList(); + cla.IsActiveOption = true; + } + } + } + } +} diff --git a/CFUValidator/ConsoleSpinner.cs b/CFUValidator/ConsoleSpinner.cs new file mode 100644 index 000000000..7bf79c927 --- /dev/null +++ b/CFUValidator/ConsoleSpinner.cs @@ -0,0 +1,85 @@ +/* Copyright (c) Citrix Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +using System; +using System.Threading; + +namespace CFUValidator +{ + public class ConsoleSpinner + { + int counter; + private const string working = "Working "; + + public ConsoleSpinner() + { + counter = 0; + } + + public void Turn() + { + counter++; + switch (counter % 4) + { + case 0: WriteAtOrigin(working + "/"); break; + case 1: WriteAtOrigin(working + "-"); break; + case 2: WriteAtOrigin(working + "\\"); break; + case 3: WriteAtOrigin(working + "|"); break; + } + Thread.Sleep(500); + } + + public void Turn(double percentageComplete) + { + counter++; + switch (counter % 4) + { + case 0: WriteAtOrigin(working + "/ (" + percentageComplete + "%)"); break; + case 1: WriteAtOrigin(working + "- (" + percentageComplete + "%)"); break; + case 2: WriteAtOrigin(working + "\\ (" + percentageComplete + "%)"); break; + case 3: WriteAtOrigin(working + "| (" + percentageComplete + "%)"); break; + } + Thread.Sleep(500); + } + + private void WriteAtOrigin(string toWrite) + { + try + { + Console.SetCursorPosition(0, Console.CursorTop); + Console.Write(toWrite); + Console.SetCursorPosition(0, Console.CursorTop); + } + catch (SystemException){} + } + } +} + diff --git a/CFUValidator/OutputDecorators/AlertFeatureValidatorDecorator.cs b/CFUValidator/OutputDecorators/AlertFeatureValidatorDecorator.cs new file mode 100644 index 000000000..e77dbd2c3 --- /dev/null +++ b/CFUValidator/OutputDecorators/AlertFeatureValidatorDecorator.cs @@ -0,0 +1,60 @@ +/* Copyright (c) Citrix Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +using System; +using System.Text; +using CFUValidator.Validators; + +namespace CFUValidator.OutputDecorators +{ + class AlertFeatureValidatorDecorator : Decorator + { + private readonly string header; + private readonly AlertFeatureValidator validator; + public AlertFeatureValidatorDecorator(OuputComponent ouputComponent, AlertFeatureValidator validator, string header) + { + SetComponent(ouputComponent); + this.validator = validator; + this.header = header; + } + + public override StringBuilder Generate() + { + StringBuilder sb = base.Generate(); + sb.AppendLine(header); + if (validator.ErrorsFound) + validator.Results.ForEach(v => sb.AppendLine(v)); + else + sb.AppendLine("all OK"); + return sb.AppendLine(String.Empty); + } + } +} diff --git a/CFUValidator/OutputDecorators/Decorator.cs b/CFUValidator/OutputDecorators/Decorator.cs new file mode 100644 index 000000000..1179f050d --- /dev/null +++ b/CFUValidator/OutputDecorators/Decorator.cs @@ -0,0 +1,53 @@ +/* Copyright (c) Citrix Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +using System; +using System.Text; + +namespace CFUValidator.OutputDecorators +{ + abstract class Decorator : OuputComponent + { + private OuputComponent ouputComponent; + public void SetComponent(OuputComponent ouputComponentToSet) + { + ouputComponent = ouputComponentToSet; + } + + public override StringBuilder Generate() + { + if(ouputComponent != null) + return ouputComponent.Generate(); + + throw new NullReferenceException(); + } + } +} diff --git a/CFUValidator/OutputDecorators/OuputComponent.cs b/CFUValidator/OutputDecorators/OuputComponent.cs new file mode 100644 index 000000000..2c56ab8f8 --- /dev/null +++ b/CFUValidator/OutputDecorators/OuputComponent.cs @@ -0,0 +1,66 @@ +/* Copyright (c) Citrix Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace CFUValidator.OutputDecorators +{ + public abstract class OuputComponent + { + public abstract StringBuilder Generate(); + } + + public class OutputTextOuputComponent : OuputComponent + { + private readonly string location; + private readonly string serverVersion; + public OutputTextOuputComponent(string location, string serverVersion) + { + this.location = location; + this.serverVersion = serverVersion; + } + + public override StringBuilder Generate() + { + string header = String.Format("\nSummary for server version {0}, XML from {1}, generated on {2}\n\n", serverVersion, + location, Date.ToLocalTime()); + return new StringBuilder(header); + } + + private DateTime Date + { + get { return DateTime.Now; } + } + } +} diff --git a/CFUValidator/OutputDecorators/PatchAlertDecorator.cs b/CFUValidator/OutputDecorators/PatchAlertDecorator.cs new file mode 100644 index 000000000..c17387978 --- /dev/null +++ b/CFUValidator/OutputDecorators/PatchAlertDecorator.cs @@ -0,0 +1,80 @@ +/* Copyright (c) Citrix Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; +using XenAdmin.Alerts; + +namespace CFUValidator.OutputDecorators +{ + + class PatchAlertDecorator : Decorator + { + private readonly List alerts; + private const string header = "Patches required ({0}):"; + private const string zeroResults = "No patches required"; + private const string hotfixRegex = "XS[0-9]+E[A-Z]*[0-9]+"; + private const string unknown = "Name unknown (uuid={0})"; + + public PatchAlertDecorator(OuputComponent ouputComponent, List alerts) + { + SetComponent(ouputComponent); + this.alerts = alerts; + } + + public override StringBuilder Generate() + { + StringBuilder sb = base.Generate(); + sb.AppendLine(String.Format(header, alerts.Count)); + AddAlertSummary(sb); + return sb.AppendLine(String.Empty); + } + + private void AddAlertSummary(StringBuilder sb) + { + if (alerts.Count == 0) + sb.AppendLine(zeroResults); + + foreach (XenServerPatchAlert alert in alerts.OrderBy(a => a.Patch.Name)) + { + string patchName = Regex.Match(alert.Patch.Name, hotfixRegex).Value; + string nameToReturn = String.IsNullOrEmpty(patchName) ? alert.Patch.Name.Trim() : patchName; + + sb.AppendLine(!String.IsNullOrEmpty(nameToReturn) + ? nameToReturn + : String.Format(unknown, alert.Patch.Uuid)); + } + } + } +} diff --git a/CFUValidator/OutputDecorators/XenCenterUpdateDecorator.cs b/CFUValidator/OutputDecorators/XenCenterUpdateDecorator.cs new file mode 100644 index 000000000..b7f26a56c --- /dev/null +++ b/CFUValidator/OutputDecorators/XenCenterUpdateDecorator.cs @@ -0,0 +1,58 @@ +/* Copyright (c) Citrix Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +using System; +using System.Text; +using XenAdmin.Alerts; + +namespace CFUValidator.OutputDecorators +{ + class XenCenterUpdateDecorator: Decorator + { + private readonly XenCenterUpdateAlert alert; + private const string header = "XenCenter updates required:"; + private const string updateNotFound = "XenCenter update could not be found"; + + public XenCenterUpdateDecorator(OuputComponent ouputComponent, XenCenterUpdateAlert alert) + { + SetComponent(ouputComponent); + this.alert = alert; + } + + public override StringBuilder Generate() + { + StringBuilder sb = base.Generate(); + sb.AppendLine(header); + sb.AppendLine(alert == null ? updateNotFound : alert.NewVersion.VersionAndLang); + return sb.AppendLine(String.Empty); + } + } +} diff --git a/CFUValidator/OutputDecorators/XenServerUpdateDecorator.cs b/CFUValidator/OutputDecorators/XenServerUpdateDecorator.cs new file mode 100644 index 000000000..2384d8929 --- /dev/null +++ b/CFUValidator/OutputDecorators/XenServerUpdateDecorator.cs @@ -0,0 +1,60 @@ +/* Copyright (c) Citrix Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using XenAdmin.Alerts; + +namespace CFUValidator.OutputDecorators +{ + class XenServerUpdateDecorator : Decorator + { + private readonly XenServerVersionAlert alert; + private const string header = "XenServer updates required:"; + private const string updateNotFound = "XenServer update could not be found"; + + public XenServerUpdateDecorator(OuputComponent ouputComponent, XenServerVersionAlert alert) + { + SetComponent(ouputComponent); + this.alert = alert; + } + + public override StringBuilder Generate() + { + StringBuilder sb = base.Generate(); + sb.AppendLine(header); + sb.AppendLine(alert == null ? updateNotFound : alert.Version.Name); + return sb.AppendLine(String.Empty); + } + } +} diff --git a/CFUValidator/Program.cs b/CFUValidator/Program.cs new file mode 100644 index 000000000..7d7f79713 --- /dev/null +++ b/CFUValidator/Program.cs @@ -0,0 +1,88 @@ +/* Copyright (c) Citrix Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +using System; +using CFUValidator.CommandLineOptions; + +namespace CFUValidator +{ + class Program + { + static void Main(string[] args) + { + CFUValidator cfuValidator = null; + try + { + CommandLineParser parser = new CommandLineParser(args, CFUCommandLineOptionManager.EmptyArguments); + parser.Parse(); + + CFUCommandLineOptionManager manager = new CFUCommandLineOptionManager(parser.ParsedArguments); + + if(manager.IsHelpRequired || args.Length == 0) + { + Console.WriteLine(manager.Help); + Environment.Exit(1); + } + + cfuValidator = new CFUValidator(manager.FileSource, manager.XmlLocation, + manager.ServerVersion, manager.InstalledHotfixes, + manager.CheckHotfixContents); + cfuValidator.StatusChanged += cfuValidator_StatusChanged; + cfuValidator.Run(); + Console.WriteLine(cfuValidator.Output); + + } + catch (CFUValidationException ex) + { + Console.WriteLine(ex.Message); + Environment.Exit(1); + } + catch(Exception ex) + { + Console.WriteLine("\n **** Unexpected exception occured ****: " + ex.Message); + Console.WriteLine(ex.StackTrace); + Environment.Exit(1); + } + finally + { + if (cfuValidator != null) + cfuValidator.StatusChanged -= cfuValidator_StatusChanged; + } + + Environment.Exit(0); + } + + static void cfuValidator_StatusChanged(object sender, EventArgs e) + { + Console.WriteLine(sender as string); + } + } +} diff --git a/CFUValidator/Properties/AssemblyInfo.cs b/CFUValidator/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..b320cc479 --- /dev/null +++ b/CFUValidator/Properties/AssemblyInfo.cs @@ -0,0 +1,67 @@ +/* Copyright (c) Citrix Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("CFUValidator")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("CFUValidator")] +[assembly: AssemblyCopyright("Copyright © 2013")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("1fc53fff-32d6-4775-a913-203c3410d388")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/CFUValidator/Updates/AlternativeUrlDownloadUpdatesXmlSourceAction.cs b/CFUValidator/Updates/AlternativeUrlDownloadUpdatesXmlSourceAction.cs new file mode 100644 index 000000000..f5dbdaff6 --- /dev/null +++ b/CFUValidator/Updates/AlternativeUrlDownloadUpdatesXmlSourceAction.cs @@ -0,0 +1,81 @@ +/* Copyright (c) Citrix Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +using System; +using System.IO; +using System.Net; +using System.Threading; +using System.Xml; +using XenAdmin.Actions; +using XenAdmin.Core; +using XenAPI; + +namespace CFUValidator.Updates +{ + class AlternativeUrlDownloadUpdatesXmlSourceAction : DownloadUpdatesXmlAction, ICheckForUpdatesXMLSource + { + private readonly string newLocation; + + public AlternativeUrlDownloadUpdatesXmlSourceAction(string url) + : base(true, true, true, string.Empty, string.Empty) + { + newLocation = url; + ErrorRaised = null; + } + + protected override XmlDocument FetchCheckForUpdatesXml(string location) + { + XmlDocument xdoc; + using (Stream xmlstream = GetXmlDoc()) + { + xdoc = Helpers.LoadXmlDocument(xmlstream); + } + return xdoc; + } + + private Stream GetXmlDoc() + { + try + { + WebRequest wr = WebRequest.Create(newLocation); + return wr.GetResponse().GetResponseStream(); + } + catch (Exception) + { + ErrorRaised = new CFUValidationException("Failed to wget the URL: " + newLocation); + throw ErrorRaised; + } + } + + public Exception ErrorRaised { get; private set; } + + } +} diff --git a/CFUValidator/Updates/ICheckForUpdatesXMLSource.cs b/CFUValidator/Updates/ICheckForUpdatesXMLSource.cs new file mode 100644 index 000000000..34355291c --- /dev/null +++ b/CFUValidator/Updates/ICheckForUpdatesXMLSource.cs @@ -0,0 +1,48 @@ +/* Copyright (c) Citrix Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using XenAdmin.Core; + +namespace CFUValidator.Updates +{ + interface ICheckForUpdatesXMLSource + { + List XenServerPatches { get; } + List XenServerVersions{ get; } + List XenCenterVersions { get; } + bool IsCompleted { get; } + void RunAsync(); + int PercentComplete { get; } + Exception ErrorRaised { get; } + } +} diff --git a/CFUValidator/Updates/ReadFromFileUpdatesXmlSource.cs b/CFUValidator/Updates/ReadFromFileUpdatesXmlSource.cs new file mode 100644 index 000000000..536399512 --- /dev/null +++ b/CFUValidator/Updates/ReadFromFileUpdatesXmlSource.cs @@ -0,0 +1,77 @@ +/* Copyright (c) Citrix Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +using System; +using System.IO; +using System.Xml; +using XenAdmin.Actions; + +namespace CFUValidator.Updates +{ + class ReadFromFileUpdatesXmlSource : DownloadUpdatesXmlAction, ICheckForUpdatesXMLSource + { + private readonly string newLocation; + public ReadFromFileUpdatesXmlSource(string location) + : base(true, true, true, string.Empty, string.Empty) + { + newLocation = location; + ErrorRaised = null; + } + + protected override XmlDocument FetchCheckForUpdatesXml(string location) + { + if (!File.Exists(newLocation)) + { + ErrorRaised = new CFUValidationException("File not found at: " + newLocation); + throw ErrorRaised; + } + + try + { + XmlDocument xdoc = new XmlDocument(); + using (StreamReader sr = new StreamReader(newLocation)) + { + xdoc.Load(sr); + } + return xdoc; + } + catch(Exception) + { + ErrorRaised = new CFUValidationException("Could not read/parse file: " + newLocation); + throw ErrorRaised; + } + + } + + public Exception ErrorRaised { get; private set; } + + } +} diff --git a/CFUValidator/Updates/XmlRetrieverFactory.cs b/CFUValidator/Updates/XmlRetrieverFactory.cs new file mode 100644 index 000000000..c37f0d338 --- /dev/null +++ b/CFUValidator/Updates/XmlRetrieverFactory.cs @@ -0,0 +1,50 @@ +/* Copyright (c) Citrix Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +using System; +using CFUValidator.CommandLineOptions; +using XenAdmin.Actions; + +namespace CFUValidator.Updates +{ + class XmlRetrieverFactory + { + public ICheckForUpdatesXMLSource GetAction(OptionUsage usage, string location) + { + if (usage == OptionUsage.Url) + return new AlternativeUrlDownloadUpdatesXmlSourceAction(location); + if (usage == OptionUsage.File) + return new ReadFromFileUpdatesXmlSource(location); + + throw new ArgumentException("No action was found for the provided usage"); + } + } +} diff --git a/CFUValidator/Validators/AlertFeatureValidator.cs b/CFUValidator/Validators/AlertFeatureValidator.cs new file mode 100644 index 000000000..e7faabe8e --- /dev/null +++ b/CFUValidator/Validators/AlertFeatureValidator.cs @@ -0,0 +1,74 @@ +/* Copyright (c) Citrix Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using XenAdmin.Alerts; + +namespace CFUValidator.Validators +{ + abstract class AlertFeatureValidator + { + protected List alerts; + + protected AlertFeatureValidator(List alerts) + { + this.alerts = alerts; + Results = new List(); + } + + public abstract void Validate(); + public abstract string Description { get; } + public List Results { get; protected set; } + public bool ErrorsFound { get { return Results.Count > 0; } } + + public delegate void StatusChangedHandler(object sender, EventArgs e); + + public event StatusChangedHandler StatusChanged; + + protected virtual void OnStatusChanged() + { + if (StatusChanged != null) + StatusChanged(Status, EventArgs.Empty); + } + + private string status; + protected string Status + { + get { return status; } + set + { + status = value; + OnStatusChanged(); + } + } + } +} diff --git a/CFUValidator/Validators/CorePatchDetailsValidator.cs b/CFUValidator/Validators/CorePatchDetailsValidator.cs new file mode 100644 index 000000000..e5411b549 --- /dev/null +++ b/CFUValidator/Validators/CorePatchDetailsValidator.cs @@ -0,0 +1,72 @@ +/* Copyright (c) Citrix Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +using System.Collections.Generic; +using XenAdmin.Alerts; + +namespace CFUValidator.Validators +{ + class CorePatchDetailsValidator : AlertFeatureValidator + { + public CorePatchDetailsValidator(List alerts) : base(alerts){} + + public override void Validate() + { + foreach (XenServerPatchAlert alert in alerts) + { + VerifyPatchDetailsMissing(alert); + } + } + + private void VerifyPatchDetailsMissing(XenServerPatchAlert alert) + { + if(string.IsNullOrEmpty(alert.Patch.Uuid)) + Results.Add("Missing patch uuid for patch: " + alert.Patch.Name); + if(string.IsNullOrEmpty(alert.Patch.Name)) + Results.Add("Missing patch name for patch with UUID: " + alert.Patch.Uuid); + if(string.IsNullOrEmpty(alert.Patch.PatchUrl)) + Results.Add("Missing patch patch-url for patch with UUID: " + alert.Patch.Uuid); + if (string.IsNullOrEmpty(alert.Patch.Description)) + Results.Add("Missing patch description for patch with UUID: " + alert.Patch.Uuid); + if (string.IsNullOrEmpty(alert.Patch.Url)) + Results.Add("Missing patch webpage url for patch with UUID: " + alert.Patch.Uuid); + if (string.IsNullOrEmpty(alert.Patch.Guidance)) + Results.Add("Missing patch guidance for patch with UUID: " + alert.Patch.Uuid); + if (string.IsNullOrEmpty(alert.Patch.TimeStamp.ToString())) + Results.Add("Missing patch timestamp for patch with UUID: " + alert.Patch.Uuid); + } + + public override string Description + { + get { return "Verify core patch details"; } + } + } +} diff --git a/CFUValidator/Validators/PatchURLValidator.cs b/CFUValidator/Validators/PatchURLValidator.cs new file mode 100644 index 000000000..01174acf8 --- /dev/null +++ b/CFUValidator/Validators/PatchURLValidator.cs @@ -0,0 +1,104 @@ +/* Copyright (c) Citrix Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Net; +using XenAdmin.Alerts; + +namespace CFUValidator.Validators +{ + class PatchURLValidator : AlertFeatureValidator + { + private readonly BackgroundWorker workerThread; + public PatchURLValidator(List alerts) : base(alerts) + { + workerThread = new BackgroundWorker(); + workerThread.DoWork += CheckAllPatchURLs; + workerThread.RunWorkerCompleted += RunWorkerCompletedMethod; + } + + private bool isComplete; + + public override void Validate() + { + isComplete = false; + ConsoleSpinner spinner = new ConsoleSpinner(); + workerThread.RunWorkerAsync(); + + while(!isComplete) + spinner.Turn(); + + } + + private void RunWorkerCompletedMethod(object sender, RunWorkerCompletedEventArgs e) + { + isComplete = true; + } + + private void CheckAllPatchURLs(object sender, DoWorkEventArgs e) + { + foreach (XenServerPatchAlert alert in alerts) + { + if(String.IsNullOrEmpty(alert.Patch.PatchUrl)) + { + Results.Add(String.Format("Patch '{0}' URL is missing", alert.Patch.Name)); + continue; + } + + HttpWebResponse response = null; + try + { + WebRequest request = WebRequest.Create(alert.Patch.PatchUrl); + request.Method = "HEAD"; + response = (HttpWebResponse)request.GetResponse(); + if (response == null || response.StatusCode != HttpStatusCode.OK) + Results.Add(String.Format("Patch '{0}' URL '{1}' is invalid", alert.Patch.Name, alert.Patch.PatchUrl)); + } + catch(WebException ex) + { + Results.Add(String.Format("Patch '{0}' URL '{1}' failed: {2}", alert.Patch.Name, alert.Patch.PatchUrl, ex.Message)); + } + finally + { + if(response != null) + response.Close(); + } + } + } + + public override string Description + { + get { return "Checking the patch URLs return a suitable http response"; } + } + } +} diff --git a/CFUValidator/Validators/ZipContentsValidator.cs b/CFUValidator/Validators/ZipContentsValidator.cs new file mode 100644 index 000000000..31de8ddfe --- /dev/null +++ b/CFUValidator/Validators/ZipContentsValidator.cs @@ -0,0 +1,98 @@ +/* Copyright (c) Citrix Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +using System; +using System.Linq; +using System.Collections.Generic; +using System.IO; +using XenAdmin.Actions; +using XenAdmin.Alerts; +using XenCenterLib.Archive; + +namespace CFUValidator.Validators +{ + class ZipContentsValidator : AlertFeatureValidator + { + public ZipContentsValidator(List alerts) : base(alerts){} + + public override void Validate() + { + foreach (XenServerPatchAlert alert in alerts.OrderBy(a=>a.Patch.Name)) + { + DownloadPatchFile(alert); + } + + } + + public override string Description + { + get { return "Downloading and checking the contents of the zip files in the patch"; } + } + + private string NewTempPath() + { + return Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); + } + + private void DownloadPatchFile(XenServerPatchAlert patch) + { + if(string.IsNullOrEmpty(patch.Patch.PatchUrl)) + { + Results.Add("Patch conatined no URL: " + patch.Patch.Name); + return; + } + + string tempFileName = NewTempPath(); + DownloadAndUnzipXenServerPatchAction action = new DownloadAndUnzipXenServerPatchAction(patch.Patch.Name, + new Uri(patch.Patch.PatchUrl), + tempFileName); + try + { + Status = "Download and unzip patch " + patch.Patch.Name; + + ConsoleSpinner spinner = new ConsoleSpinner(); + action.RunAsync(); + while(!action.IsCompleted) + { + spinner.Turn(action.PercentComplete); + } + + if(!action.Succeeded) + Results.Add("Patch download and unzip unsuccessful: " + action.Exception.Message); + } + catch (Exception ex) + { + Results.Add("Patch download error: " + ex.Message); + } + + } + } +} diff --git a/CFUValidator/app.config b/CFUValidator/app.config new file mode 100644 index 000000000..2e71eabc1 --- /dev/null +++ b/CFUValidator/app.config @@ -0,0 +1,3 @@ + + + diff --git a/XenAdmin.sln b/XenAdmin.sln index 5db56b26a..06e583414 100644 --- a/XenAdmin.sln +++ b/XenAdmin.sln @@ -1,8 +1,6 @@  -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2013 -VisualStudioVersion = 12.0.40629.0 -MinimumVisualStudioVersion = 10.0.40219.1 +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XenAdmin", "XenAdmin\XenAdmin.csproj", "{70BDA4BC-F062-4302-8ACD-A15D8BF31D65}" ProjectSection(ProjectDependencies) = postProject {6CE6A8FF-CF49-46B6-BEA4-6464A2F0A4D7} = {6CE6A8FF-CF49-46B6-BEA4-6464A2F0A4D7} @@ -12,7 +10,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CommandLib", "CommandLib\Co EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "xva_verify", "xva_verify\xva_verify.csproj", "{2A70D7E7-EAB2-4C36-B3F4-85B79D2384B5}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "splash", "splash\splash.vcxproj", "{AFB19C9D-DD63-478B-A4A3-8452CBD0B9AB}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Splash", "splash\splash.vcxproj", "{AFB19C9D-DD63-478B-A4A3-8452CBD0B9AB}" ProjectSection(ProjectDependencies) = postProject {70BDA4BC-F062-4302-8ACD-A15D8BF31D65} = {70BDA4BC-F062-4302-8ACD-A15D8BF31D65} EndProjectSection @@ -29,6 +27,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XenOvfApi", "XenOvfApi\XenO EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XenOvfTransport", "XenOvfTransport\XenOvfTransport.csproj", "{9F7E6285-5CBF-41B4-8CB9-AB06DFF90DC0}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CFUValidator", "CFUValidator\CFUValidator.csproj", "{39308480-78C3-40B4-924D-06914F343ACD}" +EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XenServerHealthCheck", "XenServerHealthCheck\XenServerHealthCheck.csproj", "{DEB3208D-1153-407C-8C99-0D8899BE25A5}" EndProject Global @@ -145,6 +145,16 @@ Global {9F7E6285-5CBF-41B4-8CB9-AB06DFF90DC0}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU {9F7E6285-5CBF-41B4-8CB9-AB06DFF90DC0}.Release|Mixed Platforms.Build.0 = Release|Any CPU {9F7E6285-5CBF-41B4-8CB9-AB06DFF90DC0}.Release|Win32.ActiveCfg = Release|Any CPU + {39308480-78C3-40B4-924D-06914F343ACD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {39308480-78C3-40B4-924D-06914F343ACD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {39308480-78C3-40B4-924D-06914F343ACD}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {39308480-78C3-40B4-924D-06914F343ACD}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {39308480-78C3-40B4-924D-06914F343ACD}.Debug|Win32.ActiveCfg = Debug|Any CPU + {39308480-78C3-40B4-924D-06914F343ACD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {39308480-78C3-40B4-924D-06914F343ACD}.Release|Any CPU.Build.0 = Release|Any CPU + {39308480-78C3-40B4-924D-06914F343ACD}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {39308480-78C3-40B4-924D-06914F343ACD}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {39308480-78C3-40B4-924D-06914F343ACD}.Release|Win32.ActiveCfg = Release|Any CPU {DEB3208D-1153-407C-8C99-0D8899BE25A5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {DEB3208D-1153-407C-8C99-0D8899BE25A5}.Debug|Any CPU.Build.0 = Debug|Any CPU {DEB3208D-1153-407C-8C99-0D8899BE25A5}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU From 999e074e2aeb4eac1e14e20fcc1956ee3c9b01cd Mon Sep 17 00:00:00 2001 From: Ji Jiang Date: Tue, 6 Feb 2018 09:52:39 +0000 Subject: [PATCH 2/3] CP-26880: Resurrect XC legacy CFU validator It will be used in XenRT automated testing of CFU Signed-off-by: Ji Jiang --- CFUValidator/CFUValidator.cs | 20 ++++++++++--------- .../XenCenterUpdateDecorator.cs | 12 +++++++---- .../XenServerUpdateDecorator.cs | 11 ++++++---- ...nativeUrlDownloadUpdatesXmlSourceAction.cs | 2 +- .../Updates/ReadFromFileUpdatesXmlSource.cs | 2 +- .../Validators/ZipContentsValidator.cs | 5 +++-- 6 files changed, 31 insertions(+), 21 deletions(-) diff --git a/CFUValidator/CFUValidator.cs b/CFUValidator/CFUValidator.cs index 6a4e06ed7..a3e366d0d 100644 --- a/CFUValidator/CFUValidator.cs +++ b/CFUValidator/CFUValidator.cs @@ -115,10 +115,10 @@ namespace CFUValidator SetupMocks(xenServerPatches, xenServerVersions); Status = "Determining XenCenter update required..."; - var xcupdateAlert = XenAdmin.Core.Updates.NewXenCenterUpdateAlert(xenCenterVersions, new Version(ServerVersion)); + var xcupdateAlerts = XenAdmin.Core.Updates.NewXenCenterUpdateAlerts(xenCenterVersions, new Version(ServerVersion)); Status = "Determining XenServer update required..."; - var updateAlert = XenAdmin.Core.Updates.NewXenServerVersionAlert(xenServerVersions); + var updateAlerts = XenAdmin.Core.Updates.NewXenServerVersionAlerts(xenServerVersions).Where(alert => !alert.CanIgnore).ToList(); Status = "Determining patches required..."; var patchAlerts = XenAdmin.Core.Updates.NewXenServerPatchAlerts(xenServerVersions, xenServerPatches).Where(alert => !alert.CanIgnore).ToList(); @@ -135,7 +135,7 @@ namespace CFUValidator RunValidators(validators); Status = "Generating summary..."; - GeneratePatchSummary(patchAlerts, validators, updateAlert, xcupdateAlert); + GeneratePatchSummary(patchAlerts, validators, updateAlerts, xcupdateAlerts); } private void CheckProvidedVersionNumber(List xenServerVersions) @@ -196,11 +196,11 @@ namespace CFUValidator } private void GeneratePatchSummary(List alerts, List validators, - XenServerVersionAlert updateAlert, XenCenterUpdateAlert xcupdateAlert) + List updateAlerts, List xcupdateAlerts) { OuputComponent oc = new OutputTextOuputComponent(XmlLocation, ServerVersion); - XenCenterUpdateDecorator xcud = new XenCenterUpdateDecorator(oc, xcupdateAlert); - XenServerUpdateDecorator xsud = new XenServerUpdateDecorator(xcud, updateAlert); + XenCenterUpdateDecorator xcud = new XenCenterUpdateDecorator(oc, xcupdateAlerts); + XenServerUpdateDecorator xsud = new XenServerUpdateDecorator(xcud, updateAlerts); PatchAlertDecorator pad = new PatchAlertDecorator(xsud, alerts); AlertFeatureValidatorDecorator afdCoreFields = new AlertFeatureValidatorDecorator(pad, validators.First(v => v is CorePatchDetailsValidator), @@ -240,19 +240,21 @@ namespace CFUValidator private void SetupMocks(List xenServerPatches, List xenServerVersions) { - Mock master = mom.NewXenObject(id); + Mock master = mom.NewXenObject(id); Mock pool = mom.NewXenObject(id); XenRef masterRef = new XenRef("ref"); pool.Setup(p => p.master).Returns(masterRef); + pool.Setup(p => p.other_config).Returns(new Dictionary()); mom.MockCacheFor(id).Setup(c => c.Resolve(It.IsAny>())).Returns(pool.Object); mom.MockConnectionFor(id).Setup(c => c.Resolve(masterRef)).Returns(master.Object); + mom.MockConnectionFor(id).Setup(c => c.IsConnected).Returns(true); master.Setup(h => h.software_version).Returns(new Dictionary()); - master.Setup(h => h.ProductVersion).Returns(ServerVersion); + master.Setup(h => h.ProductVersion()).Returns(ServerVersion); master.Setup(h => h.AppliedPatches()).Returns(GenerateMockPoolPatches(xenServerPatches)); //Currently build number will be referenced first so if it's present hook it up string buildNumber = xenServerVersions.First(v => v.Version.ToString() == ServerVersion).BuildNumber; - master.Setup(h=>h.BuildNumberRaw).Returns(buildNumber); + master.Setup(h=>h.BuildNumberRaw()).Returns(buildNumber); } private List GenerateMockPoolPatches(List xenServerPatches) diff --git a/CFUValidator/OutputDecorators/XenCenterUpdateDecorator.cs b/CFUValidator/OutputDecorators/XenCenterUpdateDecorator.cs index b7f26a56c..dc927a28e 100644 --- a/CFUValidator/OutputDecorators/XenCenterUpdateDecorator.cs +++ b/CFUValidator/OutputDecorators/XenCenterUpdateDecorator.cs @@ -30,6 +30,7 @@ */ using System; +using System.Collections.Generic; using System.Text; using XenAdmin.Alerts; @@ -37,21 +38,24 @@ namespace CFUValidator.OutputDecorators { class XenCenterUpdateDecorator: Decorator { - private readonly XenCenterUpdateAlert alert; + private readonly List alerts; private const string header = "XenCenter updates required:"; private const string updateNotFound = "XenCenter update could not be found"; - public XenCenterUpdateDecorator(OuputComponent ouputComponent, XenCenterUpdateAlert alert) + public XenCenterUpdateDecorator(OuputComponent ouputComponent, List alerts) { SetComponent(ouputComponent); - this.alert = alert; + this.alerts = alerts; } public override StringBuilder Generate() { StringBuilder sb = base.Generate(); sb.AppendLine(header); - sb.AppendLine(alert == null ? updateNotFound : alert.NewVersion.VersionAndLang); + foreach (XenCenterUpdateAlert alert in alerts) + { + sb.AppendLine(alert == null ? updateNotFound : alert.NewVersion.VersionAndLang); + } return sb.AppendLine(String.Empty); } } diff --git a/CFUValidator/OutputDecorators/XenServerUpdateDecorator.cs b/CFUValidator/OutputDecorators/XenServerUpdateDecorator.cs index 2384d8929..40a9310f0 100644 --- a/CFUValidator/OutputDecorators/XenServerUpdateDecorator.cs +++ b/CFUValidator/OutputDecorators/XenServerUpdateDecorator.cs @@ -39,21 +39,24 @@ namespace CFUValidator.OutputDecorators { class XenServerUpdateDecorator : Decorator { - private readonly XenServerVersionAlert alert; + private readonly List alerts; private const string header = "XenServer updates required:"; private const string updateNotFound = "XenServer update could not be found"; - public XenServerUpdateDecorator(OuputComponent ouputComponent, XenServerVersionAlert alert) + public XenServerUpdateDecorator(OuputComponent ouputComponent, List alerts) { SetComponent(ouputComponent); - this.alert = alert; + this.alerts = alerts; } public override StringBuilder Generate() { StringBuilder sb = base.Generate(); sb.AppendLine(header); - sb.AppendLine(alert == null ? updateNotFound : alert.Version.Name); + foreach (XenServerVersionAlert alert in alerts) + { + sb.AppendLine(alert == null ? updateNotFound : alert.Version.Name); + } return sb.AppendLine(String.Empty); } } diff --git a/CFUValidator/Updates/AlternativeUrlDownloadUpdatesXmlSourceAction.cs b/CFUValidator/Updates/AlternativeUrlDownloadUpdatesXmlSourceAction.cs index f5dbdaff6..3946e6a43 100644 --- a/CFUValidator/Updates/AlternativeUrlDownloadUpdatesXmlSourceAction.cs +++ b/CFUValidator/Updates/AlternativeUrlDownloadUpdatesXmlSourceAction.cs @@ -45,7 +45,7 @@ namespace CFUValidator.Updates private readonly string newLocation; public AlternativeUrlDownloadUpdatesXmlSourceAction(string url) - : base(true, true, true, string.Empty, string.Empty) + : base(true, true, true, "CFU", "1", url) { newLocation = url; ErrorRaised = null; diff --git a/CFUValidator/Updates/ReadFromFileUpdatesXmlSource.cs b/CFUValidator/Updates/ReadFromFileUpdatesXmlSource.cs index 536399512..71876e47a 100644 --- a/CFUValidator/Updates/ReadFromFileUpdatesXmlSource.cs +++ b/CFUValidator/Updates/ReadFromFileUpdatesXmlSource.cs @@ -40,7 +40,7 @@ namespace CFUValidator.Updates { private readonly string newLocation; public ReadFromFileUpdatesXmlSource(string location) - : base(true, true, true, string.Empty, string.Empty) + : base(true, true, true, "CFU", "1", location) { newLocation = location; ErrorRaised = null; diff --git a/CFUValidator/Validators/ZipContentsValidator.cs b/CFUValidator/Validators/ZipContentsValidator.cs index 31de8ddfe..5d8aef02a 100644 --- a/CFUValidator/Validators/ZipContentsValidator.cs +++ b/CFUValidator/Validators/ZipContentsValidator.cs @@ -33,6 +33,7 @@ using System; using System.Linq; using System.Collections.Generic; using System.IO; +using XenAdmin; using XenAdmin.Actions; using XenAdmin.Alerts; using XenCenterLib.Archive; @@ -72,8 +73,8 @@ namespace CFUValidator.Validators string tempFileName = NewTempPath(); DownloadAndUnzipXenServerPatchAction action = new DownloadAndUnzipXenServerPatchAction(patch.Patch.Name, - new Uri(patch.Patch.PatchUrl), - tempFileName); + new Uri(patch.Patch.PatchUrl), + tempFileName, false, Branding.Update, Branding.UpdateIso); try { Status = "Download and unzip patch " + patch.Patch.Name; From b5106741362592fd5a86e226cdfe66f9c0a2a3fc Mon Sep 17 00:00:00 2001 From: Ji Jiang Date: Wed, 7 Feb 2018 16:32:19 +0000 Subject: [PATCH 3/3] CA-26880: Fix XenAdmin.sln after revert Signed-off-by: Ji Jiang --- XenAdmin.sln | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/XenAdmin.sln b/XenAdmin.sln index 06e583414..5861b052b 100644 --- a/XenAdmin.sln +++ b/XenAdmin.sln @@ -1,6 +1,8 @@  -Microsoft Visual Studio Solution File, Format Version 11.00 -# Visual Studio 2010 +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0.40629.0 +MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XenAdmin", "XenAdmin\XenAdmin.csproj", "{70BDA4BC-F062-4302-8ACD-A15D8BF31D65}" ProjectSection(ProjectDependencies) = postProject {6CE6A8FF-CF49-46B6-BEA4-6464A2F0A4D7} = {6CE6A8FF-CF49-46B6-BEA4-6464A2F0A4D7} @@ -10,7 +12,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CommandLib", "CommandLib\Co EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "xva_verify", "xva_verify\xva_verify.csproj", "{2A70D7E7-EAB2-4C36-B3F4-85B79D2384B5}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Splash", "splash\splash.vcxproj", "{AFB19C9D-DD63-478B-A4A3-8452CBD0B9AB}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "splash", "splash\splash.vcxproj", "{AFB19C9D-DD63-478B-A4A3-8452CBD0B9AB}" ProjectSection(ProjectDependencies) = postProject {70BDA4BC-F062-4302-8ACD-A15D8BF31D65} = {70BDA4BC-F062-4302-8ACD-A15D8BF31D65} EndProjectSection