Merge pull request #1940 from jijiang/REQ648

Resurrect legacy CFU validator
This commit is contained in:
Mihaela Stoica 2018-02-08 14:33:38 +00:00 committed by GitHub
commit a5c1375ead
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 1941 additions and 0 deletions

View File

@ -0,0 +1,281 @@
/* 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<string> InstalledHotfixes { get; set; }
private bool CheckHotfixContents{ get; set; }
public CFUValidator(OptionUsage urlOrFile, string xmlLocation, string serverVersion,
List<string> 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<XenServerPatch> xenServerPatches;
List<XenServerVersion> xenServerVersions;
List<XenCenterVersion> xenCenterVersions;
Status = "Getting check for updates XML from " + XmlLocation + "...";
ReadCheckForUpdatesXML(out xenServerPatches, out xenServerVersions, out xenCenterVersions);
List<string> versionToCheck = GetVersionToCheck(xenServerVersions);
foreach (string ver in versionToCheck)
{
ServerVersion = ver;
RunTestsForGivenServerVersion(xenServerVersions, xenServerPatches, xenCenterVersions);
}
}
private List<string> GetVersionToCheck(List<XenServerVersion> xenServerVersions)
{
if(ServerVersion == CFUCommandLineOptionManager.AllVersions)
return xenServerVersions.ConvertAll(i => i.Version.ToString()).Distinct().ToList();
return new List<string>{ServerVersion};
}
private void RunTestsForGivenServerVersion(List<XenServerVersion> xenServerVersions,
List<XenServerPatch> xenServerPatches,
List<XenCenterVersion> xenCenterVersions)
{
CheckProvidedVersionNumber(xenServerVersions);
Status = String.Format("Generating server {0} mock-ups...", ServerVersion);
SetupMocks(xenServerPatches, xenServerVersions);
Status = "Determining XenCenter update required...";
var xcupdateAlerts = XenAdmin.Core.Updates.NewXenCenterUpdateAlerts(xenCenterVersions, new Version(ServerVersion));
Status = "Determining XenServer update required...";
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();
//Build patch checks list
List<AlertFeatureValidator> validators = new List<AlertFeatureValidator>
{
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, updateAlerts, xcupdateAlerts);
}
private void CheckProvidedVersionNumber(List<XenServerVersion> 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<AlertFeatureValidator> 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<XenServerPatchAlert> alerts, List<AlertFeatureValidator> validators,
List<XenServerVersionAlert> updateAlerts, List<XenCenterUpdateAlert> xcupdateAlerts)
{
OuputComponent oc = new OutputTextOuputComponent(XmlLocation, ServerVersion);
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),
"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<XenServerPatch> patches, out List<XenServerVersion> versions, out List<XenCenterVersion> 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<XenServerPatch> xenServerPatches, List<XenServerVersion> xenServerVersions)
{
Mock<Host> master = mom.NewXenObject<Host>(id);
Mock<Pool> pool = mom.NewXenObject<Pool>(id);
XenRef<Host> masterRef = new XenRef<Host>("ref");
pool.Setup(p => p.master).Returns(masterRef);
pool.Setup(p => p.other_config).Returns(new Dictionary<string, string>());
mom.MockCacheFor(id).Setup(c => c.Resolve(It.IsAny<XenRef<Pool>>())).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<string, string>());
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<Pool_patch> GenerateMockPoolPatches(List<XenServerPatch> xenServerPatches)
{
List<Pool_patch> patches = new List<Pool_patch>();
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<Pool_patch> pp = mom.NewXenObject<Pool_patch>(id);
pp.Setup(p => p.uuid).Returns(match.Uuid);
patches.Add(pp.Object);
}
return patches;
}
}
}

View File

@ -0,0 +1,150 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>9.0.30729</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{39308480-78C3-40B4-924D-06914F343ACD}</ProjectGuid>
<OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>CFUValidator</RootNamespace>
<AssemblyName>CFUValidator</AssemblyName>
<TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<PublishUrl>publish\</PublishUrl>
<Install>true</Install>
<InstallFrom>Disk</InstallFrom>
<UpdateEnabled>false</UpdateEnabled>
<UpdateMode>Foreground</UpdateMode>
<UpdateInterval>7</UpdateInterval>
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
<UpdatePeriodically>false</UpdatePeriodically>
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>0</ApplicationRevision>
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
<IsWebBootstrapper>false</IsWebBootstrapper>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
<FileUpgradeFlags>
</FileUpgradeFlags>
<OldToolsVersion>3.5</OldToolsVersion>
<UpgradeBackupLocation />
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<ItemGroup>
<Reference Include="Moq, Version=4.0.10827.0, Culture=neutral, PublicKeyToken=69f491c39445e920, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Moq.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="CFUValidator.cs" />
<Compile Include="CommandLineOptions\CommandLineArgument.cs" />
<Compile Include="CommandLineOptions\CFUCommandLineOptionManager.cs" />
<Compile Include="CommandLineOptions\CommandLineParser.cs" />
<Compile Include="ConsoleSpinner.cs" />
<Compile Include="OutputDecorators\AlertFeatureValidatorDecorator.cs" />
<Compile Include="OutputDecorators\OuputComponent.cs" />
<Compile Include="OutputDecorators\Decorator.cs" />
<Compile Include="OutputDecorators\PatchAlertDecorator.cs" />
<Compile Include="OutputDecorators\XenCenterUpdateDecorator.cs" />
<Compile Include="OutputDecorators\XenServerUpdateDecorator.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Updates\AlternativeUrlDownloadUpdatesXmlSourceAction.cs" />
<Compile Include="Updates\ReadFromFileUpdatesXmlSource.cs" />
<Compile Include="Updates\ICheckForUpdatesXMLSource.cs" />
<Compile Include="Updates\XmlRetrieverFactory.cs" />
<Compile Include="Validators\AlertFeatureValidator.cs" />
<Compile Include="Validators\CorePatchDetailsValidator.cs" />
<Compile Include="Validators\PatchURLValidator.cs" />
<Compile Include="Validators\ZipContentsValidator.cs" />
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
<Visible>False</Visible>
<ProductName>.NET Framework Client Profile</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.2.0">
<Visible>False</Visible>
<ProductName>.NET Framework 2.0 %28x86%29</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.0">
<Visible>False</Visible>
<ProductName>.NET Framework 3.0 %28x86%29</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1</ProductName>
<Install>true</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
<Visible>False</Visible>
<ProductName>Windows Installer 3.1</ProductName>
<Install>true</Install>
</BootstrapperPackage>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\XenAdminTests\XenAdminTests.csproj">
<Project>{21B9482C-D255-40D5-ABA7-C8F00F99547C}</Project>
<Name>XenAdminTests</Name>
</ProjectReference>
<ProjectReference Include="..\XenAdmin\XenAdmin.csproj">
<Project>{70BDA4BC-F062-4302-8ACD-A15D8BF31D65}</Project>
<Name>XenAdmin</Name>
</ProjectReference>
<ProjectReference Include="..\XenCenterLib\XenCenterLib.csproj">
<Project>{9861DFA1-B41F-432D-A43F-226257DEBBB9}</Project>
<Name>XenCenterLib</Name>
</ProjectReference>
<ProjectReference Include="..\XenModel\XenModel.csproj">
<Project>{B306FC59-4441-4A5F-9F54-D3F68D4EE38D}</Project>
<Name>XenModel</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@ -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<CommandLineArgument> clas;
public CFUCommandLineOptionManager(List<CommandLineArgument> clas)
{
this.clas = clas;
}
//Not to be called from inside this class to keep IoC
public static List<CommandLineArgument> EmptyArguments
{
get
{
return new List<CommandLineArgument>
{
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', "<URL to extract XML from> Cannot be used with -f flag"),
new CommandLineArgument( OptionUsage.File, 'f', "<File name to extract XML from> Cannot be used with -u flag" ),
new CommandLineArgument( OptionUsage.ServerVersion, 's', "<Server version to test> eg. 6.0.2" ),
new CommandLineArgument( OptionUsage.Hotfix, 'p', "<List of patches/hotfixes that server has> 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<string> InstalledHotfixes
{
get
{
CommandLineArgument cla = clas.First(c => c.Usage == OptionUsage.Hotfix);
if (!cla.IsActiveOption)
return new List<string>();
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();
}
}
}
}

View File

@ -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<string> Options { get; set; }
public string Description { get; private set; }
public bool IsActiveOption { get; set; }
}
}

View File

@ -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<CommandLineArgument> ParsedArguments { get; private set; }
public CommandLineParser(string[] args, List<CommandLineArgument> 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;
}
}
}
}
}

View File

@ -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){}
}
}
}

View File

@ -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);
}
}
}

View File

@ -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();
}
}
}

View File

@ -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; }
}
}
}

View File

@ -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<XenServerPatchAlert> 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<XenServerPatchAlert> 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));
}
}
}
}

View File

@ -0,0 +1,62 @@
/* 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.Text;
using XenAdmin.Alerts;
namespace CFUValidator.OutputDecorators
{
class XenCenterUpdateDecorator: Decorator
{
private readonly List<XenCenterUpdateAlert> alerts;
private const string header = "XenCenter updates required:";
private const string updateNotFound = "XenCenter update could not be found";
public XenCenterUpdateDecorator(OuputComponent ouputComponent, List<XenCenterUpdateAlert> alerts)
{
SetComponent(ouputComponent);
this.alerts = alerts;
}
public override StringBuilder Generate()
{
StringBuilder sb = base.Generate();
sb.AppendLine(header);
foreach (XenCenterUpdateAlert alert in alerts)
{
sb.AppendLine(alert == null ? updateNotFound : alert.NewVersion.VersionAndLang);
}
return sb.AppendLine(String.Empty);
}
}
}

View File

@ -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;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using XenAdmin.Alerts;
namespace CFUValidator.OutputDecorators
{
class XenServerUpdateDecorator : Decorator
{
private readonly List<XenServerVersionAlert> alerts;
private const string header = "XenServer updates required:";
private const string updateNotFound = "XenServer update could not be found";
public XenServerUpdateDecorator(OuputComponent ouputComponent, List<XenServerVersionAlert> alerts)
{
SetComponent(ouputComponent);
this.alerts = alerts;
}
public override StringBuilder Generate()
{
StringBuilder sb = base.Generate();
sb.AppendLine(header);
foreach (XenServerVersionAlert alert in alerts)
{
sb.AppendLine(alert == null ? updateNotFound : alert.Version.Name);
}
return sb.AppendLine(String.Empty);
}
}
}

88
CFUValidator/Program.cs Normal file
View File

@ -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);
}
}
}

View File

@ -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")]

View File

@ -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, "CFU", "1", url)
{
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; }
}
}

View File

@ -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<XenServerPatch> XenServerPatches { get; }
List<XenServerVersion> XenServerVersions{ get; }
List<XenCenterVersion> XenCenterVersions { get; }
bool IsCompleted { get; }
void RunAsync();
int PercentComplete { get; }
Exception ErrorRaised { get; }
}
}

View File

@ -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, "CFU", "1", location)
{
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; }
}
}

View File

@ -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");
}
}
}

View File

@ -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<XenServerPatchAlert> alerts;
protected AlertFeatureValidator(List<XenServerPatchAlert> alerts)
{
this.alerts = alerts;
Results = new List<string>();
}
public abstract void Validate();
public abstract string Description { get; }
public List<string> 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();
}
}
}
}

View File

@ -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<XenServerPatchAlert> 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"; }
}
}
}

View File

@ -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<XenServerPatchAlert> 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"; }
}
}
}

View File

@ -0,0 +1,99 @@
/* 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;
using XenAdmin.Actions;
using XenAdmin.Alerts;
using XenCenterLib.Archive;
namespace CFUValidator.Validators
{
class ZipContentsValidator : AlertFeatureValidator
{
public ZipContentsValidator(List<XenServerPatchAlert> 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, false, Branding.Update, Branding.UpdateIso);
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);
}
}
}
}

3
CFUValidator/app.config Normal file
View File

@ -0,0 +1,3 @@
<?xml version="1.0"?>
<configuration>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6"/></startup></configuration>

View File

@ -29,6 +29,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 +147,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