diff --git a/XenModel/Messages.Designer.cs b/XenModel/Messages.Designer.cs index d82e8f530..5648dcd1e 100755 --- a/XenModel/Messages.Designer.cs +++ b/XenModel/Messages.Designer.cs @@ -24170,6 +24170,24 @@ namespace XenAdmin { } } + /// + /// 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.. + /// + public static string NEWPOOL_IP_COUNT_BOND { + get { + return ResourceManager.GetString("NEWPOOL_IP_COUNT_BOND", resourceCulture); + } + } + + /// + /// 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.. + /// + public static string NEWPOOL_IP_COUNT_CLUSTER { + get { + return ResourceManager.GetString("NEWPOOL_IP_COUNT_CLUSTER", resourceCulture); + } + } + /// /// Looks up a localized string similar to This server is master of an existing pool. /// diff --git a/XenModel/Messages.resx b/XenModel/Messages.resx index 73671da11..c9219351d 100755 --- a/XenModel/Messages.resx +++ b/XenModel/Messages.resx @@ -8245,6 +8245,12 @@ You should only proceed if you have verified that these settings are correct. This server has shared storage + + 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. + + + This server needs to have one (and only one) IP address on the network that will be used for clustering. + This server is master of an existing pool diff --git a/XenModel/PoolJoinRules.cs b/XenModel/PoolJoinRules.cs index 28c8c8085..38486675e 100644 --- a/XenModel/PoolJoinRules.cs +++ b/XenModel/PoolJoinRules.cs @@ -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 ids = new List(); + + if (clusterHostInBond) + { + + List slaves = new List(); + + 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; + + } } }