Merge commit 'b1440b3e194ac7dbd2aabc458fb0659f99bfeb45' into development

This commit is contained in:
Alexander Schulz 2020-03-11 14:52:47 +01:00
commit a1e829bc44
8 changed files with 20 additions and 298 deletions

View File

@ -92,7 +92,7 @@ namespace XenAdmin.Dialogs
/// May be null, in which case Program.MainWindow is used.</param>
/// <param name="initiateMasterSearch">If true, if connection to the master fails we will start trying to connect to
/// each remembered slave in turn.</param>
internal void BeginConnect(Form owner, bool initiateMasterSearch)
internal bool BeginConnect(Form owner, bool initiateMasterSearch)
{
if (connection is XenConnection conn)
{
@ -107,8 +107,11 @@ namespace XenAdmin.Dialogs
Show(GetOwnerForm());
Focus();
return true;
}
}
return false;
}
private void RegisterEventHandlers()

View File

@ -64,15 +64,6 @@ namespace XenAdmin.Network
bool AcceptCertificate = false;
HttpWebRequest webreq = (HttpWebRequest)sender;
if (webreq.Address.Host == InvisibleMessages.ACTIVATION_SERVER)
{
// Strict checking on the activation server certificate.
// Also, this ensures that it doesn't get added to the user settings
// through Settings.AddCertificate or Settings.ReplaceCertificate below.
log.Debug("SslPolicyErrors is set to None, exiting validation");
return sslPolicyErrors == SslPolicyErrors.None;
}
//This allows to run tests without MainWindow
if (Program.MainWindow == null) return true;

View File

@ -70,9 +70,12 @@ namespace XenAdmin.Network
dlg.Focus();
return;
}
dlg = new ConnectingToServerDialog(connection);
connectionDialogs.Add(connection, dlg);
dlg.BeginConnect(owner, initiateMasterSearch);
if (!dlg.BeginConnect(owner, initiateMasterSearch) && connection != null)
connectionDialogs.Remove(connection);
}
else
((XenConnection)connection).BeginConnect(initiateMasterSearch, PromptForNewPassword);

View File

@ -30,10 +30,8 @@
*/
using System;
using System.Collections.Generic;
using System.IO;
using XenAPI;
using XenAdmin.Actions.HostActions;
namespace XenAdmin.Actions
{
@ -43,14 +41,11 @@ namespace XenAdmin.Actions
private readonly String Filepath;
private readonly bool ActivateFreeLicense;
public ApplyLicenseAction(Host host, string filepath, bool activateFreeLicense = false)
public ApplyLicenseAction(Host host, string filepath)
: base(host.Connection, string.Format(Messages.APPLYLICENSE_TITLE, host.Name()), Messages.APPLYLICENSE_PREP)
{
this.Host = host;
this.Filepath = filepath;
this.ActivateFreeLicense = activateFreeLicense;
}
protected override void Run()
@ -69,22 +64,11 @@ namespace XenAdmin.Actions
string encodedContent = Convert.ToBase64String(File.ReadAllBytes(Filepath));
// PR-1102: catch the host's license data, before applying the new one, so it can be sent later to the licensing server
LicensingHelper.LicenseDataStruct previousLicenseData = new LicensingHelper.LicenseDataStruct(this.Host);
this.Description = string.Format(Messages.APPLYLICENSE_APPLYING, Filepath);
log.DebugFormat("Applying license to server {0}", this.Host.Name());
RelatedTask = XenAPI.Host.async_license_apply(this.Session, this.Host.opaque_ref, encodedContent);
Description = string.Format(Messages.APPLYLICENSE_APPLYING, Filepath);
log.DebugFormat("Applying license to server {0}", Host.Name());
RelatedTask = Host.async_license_apply(Session, Host.opaque_ref, encodedContent);
PollToCompletion();
this.Description = Messages.APPLYLICENSE_APPLIED;
// PR-1102: send licensing data to the activation server
Dictionary<Host, LicensingHelper.LicenseDataStruct> hosts = new Dictionary<Host, LicensingHelper.LicenseDataStruct>();
hosts.Add(this.Host, previousLicenseData);
if (ActivateFreeLicense)
LicensingHelper.SendActivationData(hosts);
else
LicensingHelper.SendLicenseEditionData(hosts, "");
Description = Messages.APPLYLICENSE_APPLIED;
}
}
}

View File

@ -36,8 +36,6 @@ using XenAPI;
using XenAdmin.Alerts;
using System.ComponentModel;
using System.Threading;
using XenAdmin.Core;
using XenAdmin.Actions.HostActions;
namespace XenAdmin.Actions
{
@ -97,15 +95,12 @@ namespace XenAdmin.Actions
d.Add("port", licenseServerPort);
}
XenAPI.Host.set_license_server(host.Connection.Session, host.opaque_ref, d);
Host.set_license_server(host.Connection.Session, host.opaque_ref, d);
}
protected override void Run()
{
// PR-1102: hosts that have been updated, plus the previous edition information - this data will be sent to the licensing server
Dictionary<Host, LicensingHelper.LicenseDataStruct> updatedHosts = new Dictionary<Host, LicensingHelper.LicenseDataStruct>();
this.Description = Messages.LICENSE_UPDATING_LICENSES;
Description = Messages.LICENSE_UPDATING_LICENSES;
foreach (IXenObject xo in xos)
{
Connection = xo.Connection;
@ -118,9 +113,9 @@ namespace XenAdmin.Actions
Host host = null;
Pool pool = null;
if(xo is Host)
if (xo is Host)
host = xo as Host;
if(xo is Pool)
if (xo is Pool)
{
pool = xo as Pool;
host = xo.Connection.Resolve(pool.master);
@ -144,7 +139,7 @@ namespace XenAdmin.Actions
try
{
if(pool != null)
if (pool != null)
pool.Connection.Cache.Hosts.ToList().ForEach(h=>SetLicenseServer(h, _licenseServerAddress, _licenseServerPort));
else
SetLicenseServer(host, _licenseServerAddress, _licenseServerPort);
@ -179,21 +174,14 @@ namespace XenAdmin.Actions
Alert.RegisterAlertCollectionChanged(alertsChangeHandler);
// PR-1102: catch the host's license data, before applying the new one, so it can be sent later to the licensing server
LicensingHelper.LicenseDataStruct previousLicenseData = new LicensingHelper.LicenseDataStruct(host);
if(xo is Host && host != null)
if (xo is Host && host != null)
{
Host.apply_edition(host.Connection.Session, host.opaque_ref, host.GetEditionText(_edition), false);
// PR-1102: populate the list of updated hosts
updatedHosts.Add(host, previousLicenseData);
}
if (xo is Pool)
{
Pool.apply_edition(xo.Connection.Session, pool.opaque_ref, xo.Connection.Cache.Hosts.First().GetEditionText(_edition));
xo.Connection.Cache.Hosts.ToList().ForEach(h => updatedHosts.Add(h, previousLicenseData));
}
Description = Messages.APPLYLICENSE_UPDATED;
@ -224,18 +212,11 @@ namespace XenAdmin.Actions
}
}
// PR-1102: Send licensing data to the activation server
if (updatedHosts.Count > 0)
{
LicensingHelper.SendLicenseEditionData(updatedHosts, updatedHosts.Keys.First().GetEditionText(_edition));
}
if (LicenseFailures.Count > 0)
{
string exceptionText = LicenseFailures.Count == 1 ? string.Format(Messages.LICENSE_ERROR_1, LicenseFailures[0].Host.Name()) : string.Format(Messages.LICENSE_ERROR_MANY, LicenseFailures.Count, new List<IXenObject>(xos).Count);
if (DoOnLicensingFailure != null)
DoOnLicensingFailure(LicenseFailures, exceptionText);
DoOnLicensingFailure?.Invoke(LicenseFailures, exceptionText);
throw new InvalidOperationException(exceptionText);
}
}

View File

@ -1,212 +0,0 @@
/* 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.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Xml;
using CookComputing.XmlRpc;
using XenAdmin.Core;
using XenAPI;
namespace XenAdmin.Actions.HostActions
{
public static class LicensingHelper
{
#region Send license data to activation server
/// <summary>
/// Send license information to the activation server after assigning or releasing a paid license.
/// This task will run on a separate thread.
/// </summary>
/// <param name="hosts">Pass in a Dictionary containing the hosts and their previous license data</param>
/// <param name="currentEdition">Pass in the current license edition</param>
public static void SendLicenseEditionData(Dictionary<XenAPI.Host, LicenseDataStruct> hosts, string currentEdition)
{
// Supply the state information required by the task.
SendLicenseDataHelper sendLicenseDataHelper = new SendLicenseDataHelper(hosts, "apply_license", currentEdition, true);
// start a separate thread
Thread thread = new Thread(new ThreadStart(sendLicenseDataHelper.ThreadProc));
thread.Name = "Process licensing data for assigning or releasing a license";
thread.IsBackground = true;
thread.Start();
}
/// <summary>
/// Send license information to the activation server after activating a free license.
/// In this case both previous and current editions are "free"
/// This task will run on a separate thread.
/// </summary>
/// <param name="hosts">Pass in a Dictionary containing the hosts and their previous license data</param>
public static void SendActivationData(Dictionary<XenAPI.Host, LicenseDataStruct> hosts)
{
// Supply the state information required by the task.
SendLicenseDataHelper sendLicenseDataHelper = new SendLicenseDataHelper(hosts, "activation", hosts.Keys.First().GetEditionText(XenAPI.Host.Edition.Free), true);
// start a separate thread
Thread thread = new Thread(new ThreadStart(sendLicenseDataHelper.ThreadProc));
thread.Name = "Process licensing data for activating a free license)";
thread.IsBackground = true;
thread.Start();
}
public struct LicenseDataStruct
{
public string Edition;
public string ExpiryDate;
public LicenseDataStruct(string edition, string expiryDate)
{
Edition = edition;
ExpiryDate = expiryDate;
}
public LicenseDataStruct(XenAPI.Host host)
{
Edition = host.edition;
ExpiryDate = host.license_params.ContainsKey("expiry") ? host.license_params["expiry"] : "";
}
}
private class SendLicenseDataHelper
{
public Dictionary<XenAPI.Host, LicenseDataStruct> Hosts;
public string LicensingAction;
public string CurrentEdition;
public bool IncludeSKU;
public SendLicenseDataHelper(Dictionary<XenAPI.Host, LicenseDataStruct> hosts, string licensingAction, string currentEdition, bool includeSKU)
{
Hosts = hosts;
LicensingAction = licensingAction;
CurrentEdition = currentEdition;
IncludeSKU = includeSKU;
}
public void ThreadProc()
{
string licensingData;
try
{
// build the xml
using (MemoryStream ms = new MemoryStream())
{
Encoding Utf8 = new UTF8Encoding(false);
XmlWriterSettings settings = new XmlWriterSettings();
settings.OmitXmlDeclaration = true;
settings.Encoding = Utf8;
XmlWriter writer = XmlWriter.Create(ms, settings);
writer.WriteStartDocument();
writer.WriteStartElement(LicensingAction);
foreach (XenAPI.Host host in Hosts.Keys)
{
ProduceXmlForHost(host, Hosts[host], writer);
}
writer.WriteEndElement();
writer.WriteEndDocument();
writer.Close();
licensingData = Utf8.GetString(ms.ToArray());
}
// send the xml
ActivationProxy proxy = XmlRpcProxyGen.Create<ActivationProxy>();
proxy.Url = string.Format(InvisibleMessages.ACTIVATION_URL, InvisibleMessages.ACTIVATION_SERVER);
proxy.Timeout = 30 * 1000;
proxy.UseIndentation = false;
proxy.UserAgent = Session.UserAgent;
proxy.KeepAlive = true;
proxy.Proxy = Session.Proxy;
// response is the transaction id of this call to the activation service
string response = proxy.process_reactivation_request(licensingData);
}
catch (Exception)
{
}
}
private void ProduceXmlForHost(XenAPI.Host host, LicenseDataStruct previousLicenseData, XmlWriter writer)
{
// wait for host to be updated
for (int i = 0; i < 100 &&
Helper.AreEqual2(host.license_params["expiry"], previousLicenseData.ExpiryDate) &&
Helper.AreEqual2(host.edition, previousLicenseData.Edition); i++)
{
Thread.Sleep(100);
}
writer.WriteStartElement("host");
writer.WriteAttributeString("uuid", host.uuid);
foreach (KeyValuePair<String, String> kvp in host.software_version)
{
writer.WriteStartElement("software_version_element");
writer.WriteAttributeString("key", kvp.Key);
writer.WriteAttributeString("value", kvp.Value);
writer.WriteEndElement();
}
// edition information
if (IncludeSKU)
{
string newEdition;
if (String.IsNullOrEmpty(CurrentEdition))
{
newEdition = host.edition;
}
else
{
newEdition = CurrentEdition;
}
writer.WriteStartElement("SKU");
writer.WriteAttributeString("from", previousLicenseData.Edition);
writer.WriteAttributeString("to", newEdition);
writer.WriteEndElement();
}
// license expiry information
writer.WriteStartElement("license_expiry_date");
writer.WriteAttributeString("from", previousLicenseData.ExpiryDate);
writer.WriteAttributeString("to", host.license_params["expiry"]);
writer.WriteEndElement();
writer.WriteEndElement();
}
}
#endregion
}
}

View File

@ -63,33 +63,6 @@ namespace XenAdmin {
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die ähnelt.
/// </summary>
public static string ACTIVATION_FORM_URL {
get {
return ResourceManager.GetString("ACTIVATION_FORM_URL", resourceCulture);
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die ähnelt.
/// </summary>
public static string ACTIVATION_SERVER {
get {
return ResourceManager.GetString("ACTIVATION_SERVER", resourceCulture);
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die ähnelt.
/// </summary>
public static string ACTIVATION_URL {
get {
return ResourceManager.GetString("ACTIVATION_URL", resourceCulture);
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die https://xcp-ng.org ähnelt.
/// </summary>
public static string COMMUNITY_URL {
get {
return ResourceManager.GetString("COMMUNITY_URL", resourceCulture);

View File

@ -252,7 +252,6 @@
<Compile Include="Actions\Host\GetServerLocalTimeAction.cs" />
<Compile Include="Actions\Host\GetSystemStatusCapabilities.cs" />
<Compile Include="Actions\Host\HostPowerOnAction.cs" />
<Compile Include="Actions\Host\LicensingHelper.cs" />
<Compile Include="Actions\Host\SavePowerOnSettingsAction.cs" />
<Compile Include="Actions\Host\VMsWhichCanBeMigratedAction.cs" />
<Compile Include="Actions\Network\CreateChinAction.cs" />