CA-292991: Block host joining cluster with cluster network (bonded/unbonded) unless the interface is defined

Signed-off-by: serenc <seren.corbett@citrix.com>
This commit is contained in:
serenc 2018-07-10 11:23:13 +01:00 committed by Mihaela Stoica
parent 0bec35629a
commit 118eca3d61
3 changed files with 84 additions and 0 deletions

View File

@ -24170,6 +24170,24 @@ namespace XenAdmin {
}
}
/// <summary>
/// Looks up a localized string similar to This server needs to have an IP address assigned to one (and only one) of the interfaces that will be part of the bonded cluster network..
/// </summary>
public static string NEWPOOL_IP_COUNT_BOND {
get {
return ResourceManager.GetString("NEWPOOL_IP_COUNT_BOND", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to This server needs to have one (and only one) IP address on the network that will be used for clustering..
/// </summary>
public static string NEWPOOL_IP_COUNT_CLUSTER {
get {
return ResourceManager.GetString("NEWPOOL_IP_COUNT_CLUSTER", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to This server is master of an existing pool.
/// </summary>

View File

@ -8245,6 +8245,12 @@ You should only proceed if you have verified that these settings are correct.</v
<data name="NEWPOOL_HAS_SHARED_STORAGE" xml:space="preserve">
<value>This server has shared storage</value>
</data>
<data name="NEWPOOL_IP_COUNT_BOND" xml:space="preserve">
<value>This server needs to have an IP address assigned to one (and only one) of the interfaces that will be part of the bonded cluster network.</value>
</data>
<data name="NEWPOOL_IP_COUNT_CLUSTER" xml:space="preserve">
<value>This server needs to have one (and only one) IP address on the network that will be used for clustering.</value>
</data>
<data name="NEWPOOL_IS_A_POOL" xml:space="preserve">
<value>This server is master of an existing pool</value>
</data>

View File

@ -34,6 +34,8 @@ using System.Collections.Generic;
using XenAdmin.Network;
using XenAPI;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using XenAdmin.Actions;
namespace XenAdmin.Core
{
@ -71,6 +73,8 @@ namespace XenAdmin.Core
NonCompatibleManagementInterface,
WrongRoleOnMaster,
WrongRoleOnSlave,
WrongNumberOfIpsCluster,
WrongNumberOfIpsBond,
NotConnected,
}
@ -166,6 +170,12 @@ namespace XenAdmin.Core
if (!Helpers.FeatureForbidden(slaveConnection, Host.RestrictManagementOnVLAN) && !HasCompatibleManagementInterface(slaveConnection))
return Reason.NonCompatibleManagementInterface;
bool clusterHostInBond;
if (!HasIpForClusterNetwork(masterConnection, slaveHost, out clusterHostInBond))
{
return clusterHostInBond ? Reason.WrongNumberOfIpsBond : Reason.WrongNumberOfIpsCluster;
}
return Reason.Allowed;
}
@ -227,6 +237,10 @@ namespace XenAdmin.Core
return Messages.NEWPOOL_MASTER_ROLE;
case Reason.WrongRoleOnSlave:
return Messages.NEWPOOL_SLAVE_ROLE;
case Reason.WrongNumberOfIpsCluster:
return Messages.NEWPOOL_IP_COUNT_CLUSTER;
case Reason.WrongNumberOfIpsBond:
return Messages.NEWPOOL_IP_COUNT_BOND;
default:
System.Diagnostics.Trace.Assert(false, "Unknown reason");
return "";
@ -673,5 +687,51 @@ namespace XenAdmin.Core
else
return slaveConnection.Cache.PIFs.Any(p => !p.physical && p.management && p.VLAN != -1);
}
public static bool HasIpForClusterNetwork(IXenConnection masterConnection, Host slaveHost, out bool clusterHostInBond)
{
var clusterHost = masterConnection.Cache.Cluster_hosts.FirstOrDefault();
if (clusterHost == null)
{
clusterHostInBond = false;
return true;
}
var clusterHostPif = clusterHost.Connection.Resolve(clusterHost.PIF);
clusterHostInBond = clusterHostPif.IsBondNIC();
var pifsWithIPAddress = 0;
List<string> ids = new List<string>();
if (clusterHostInBond)
{
List<PIF> slaves = new List<PIF>();
foreach (Bond bond in masterConnection.ResolveAll(clusterHostPif.bond_master_of))
{
slaves.AddRange(masterConnection.ResolveAll(bond.slaves));
}
ids.AddRange(slaves.Select(slave => slave.device));
}
else
{
ids.Add(clusterHostPif.device);
}
foreach (PIF pif in slaveHost.Connection.ResolveAll(slaveHost.PIFs))
{
if (pif.IsManagementInterface(false) && ids.Contains(pif.device))
{
pifsWithIPAddress += 1;
}
}
return pifsWithIPAddress == 1;
}
}
}