public void Validate(ClusterDefinition clusterDefinition) { Covenant.Requires <ArgumentNullException>(clusterDefinition != null); HostXvaUri = HostXvaUri ?? defaultHostXvaUri; TemplateName = TemplateName ?? defaultTemplate; StorageRepository = StorageRepository ?? defaultStorageRepository; OsdStorageRepository = OsdStorageRepository ?? defaultStorageRepository; if (string.IsNullOrEmpty(HostXvaUri) || !Uri.TryCreate(HostXvaUri, UriKind.Absolute, out Uri uri)) { throw new ClusterDefinitionException($"[{nameof(XenServerOptions)}.{nameof(HostXvaUri)}] is required when deploying to XenServer."); } if (string.IsNullOrEmpty(StorageRepository)) { throw new ClusterDefinitionException($"[{nameof(XenServerOptions)}.{nameof(StorageRepository)}] is required when deploying to XenServer."); } if (string.IsNullOrEmpty(OsdStorageRepository)) { OsdStorageRepository = StorageRepository; } clusterDefinition.ValidatePrivateNodeAddresses(); // Private node IP addresses must be assigned and valid. clusterDefinition.Hosting.ValidateHypervisor(clusterDefinition, remoteHypervisors: true); // Hypervisor options must be valid. }
public void Validate(ClusterDefinition clusterDefinition) { Covenant.Requires <ArgumentNullException>(clusterDefinition != null); if (string.IsNullOrEmpty(HostVhdxUri) || !Uri.TryCreate(HostVhdxUri, UriKind.Absolute, out Uri uri)) { throw new ClusterDefinitionException($"[{nameof(LocalHyperVOptions)}.{nameof(HostVhdxUri)}] is required when deploying to Hyper-V."); } clusterDefinition.ValidatePrivateNodeAddresses(); // Private node IP addresses must be assigned and valid. clusterDefinition.Hosting.ValidateHypervisor(clusterDefinition, remoteHypervisors: false); // Hypervisor options must be valid. }
/// <summary> /// Validates the options and also ensures that all <c>null</c> properties are /// initialized to their default values. /// </summary> /// <param name="clusterDefinition">The cluster definition.</param> /// <exception cref="ClusterDefinitionException">Thrown if the definition is not valid.</exception> public void Validate(ClusterDefinition clusterDefinition) { Covenant.Requires <ArgumentNullException>(clusterDefinition != null, nameof(clusterDefinition)); var xenServerHostingOptionsPrefix = $"{nameof(ClusterDefinition.Hosting)}.{nameof(ClusterDefinition.Hosting.XenServer)}"; StorageRepository = StorageRepository ?? defaultStorageRepository; if (string.IsNullOrEmpty(StorageRepository)) { throw new ClusterDefinitionException($"[{xenServerHostingOptionsPrefix}.{nameof(StorageRepository)}] is required when deploying to XenServer."); } clusterDefinition.ValidatePrivateNodeAddresses(); // Private node IP addresses must be assigned and valid. }
/// <summary> /// Validates the options and also ensures that all <c>null</c> properties are /// initialized to their default values. /// </summary> /// <param name="clusterDefinition">The cluster definition.</param> /// <exception cref="ClusterDefinitionException">Thrown if the definition is not valid.</exception> public void Validate(ClusterDefinition clusterDefinition) { Covenant.Requires <ArgumentNullException>(clusterDefinition != null, nameof(clusterDefinition)); clusterDefinition.ValidatePrivateNodeAddresses(); // Private node IP addresses must be assigned and valid. }
/// <summary> /// Validates the options and also ensures that all <c>null</c> properties are /// initialized to their default values. /// </summary> /// <param name="clusterDefinition">The cluster definition.</param> /// <exception cref="ClusterDefinitionException">Thrown if the definition is not valid.</exception> public void Validate(ClusterDefinition clusterDefinition) { Covenant.Requires <ArgumentNullException>(clusterDefinition != null, nameof(clusterDefinition)); if (NeonDesktopBuiltIn) { UseInternalSwitch = true; // neonDESKTOP built-in clusters always use the internal switch. // Ensure that cluster has only one control-plane node and set its // address to the reserved IP. if (clusterDefinition.NodeDefinitions.Count != 1 || !clusterDefinition.NodeDefinitions.Values.First().IsControlPane) { throw new ClusterDefinitionException("The neonDESKTOP built-in cluster must include only one node and that must be a [control-plane]."); } clusterDefinition.NodeDefinitions.Values.First().Address = NeonDesktopNodeAddress.ToString(); } if (UseInternalSwitch) { if (!NeonDesktopBuiltIn) { // Ensure that no node addresses for a user defined cluster conflict with the // reserved addresses in the internal subnet. var reservedAddresses = new string[] { NeonKubeInternalSubnet.FirstAddress.ToString(), NeonKubeInternalGateway.ToString(), NeonDesktopNodeAddress.ToString(), NeonKubeInternalSubnet.LastAddress.ToString() }; foreach (var reservedAddress in reservedAddresses) { foreach (var nodeDefinition in clusterDefinition.SortedNodes) { if (nodeDefinition.Address == reservedAddress) { throw new ClusterDefinitionException($"Node [{nodeDefinition.Name}]'s address [{nodeDefinition.Address}] conflicts with the reserved [{reservedAddress}]."); } } } } // Ensure that the cluster network subnet and gateway options are set to the correct // internal switch values. if (clusterDefinition.Network.PremiseSubnet != NeonKubeInternalSubnet.ToString()) { throw new ClusterDefinitionException($"[{nameof(ClusterDefinition.Network)}.{nameof(NetworkOptions.PremiseSubnet)} must be set to [{NeonKubeInternalSubnet}] for the clusters deployed to the internal Hyper-V switch."); } if (clusterDefinition.Network.Gateway != NeonKubeInternalGateway.ToString()) { throw new ClusterDefinitionException($"[{nameof(ClusterDefinition.Network)}.{nameof(NetworkOptions.Gateway)} must be set to [{NeonKubeInternalGateway}] for the clusters deployed to the internal Hyper-V switch."); } if (NeonDesktopBuiltIn) { // Ensure that the cluster includes only one node and that it's address // set to the second to last address in the private subnet. if (clusterDefinition.NodeDefinitions.Count != 1) { throw new ClusterDefinitionException("neonDESKTOP clusters may only provision a single node."); } if (clusterDefinition.NodeDefinitions.First().Value.Address != NeonDesktopNodeAddress.ToString()) { throw new ClusterDefinitionException($"neonDESKTOP cluster node address must be set to [{NeonKubeInternalSubnet}] (not [{clusterDefinition.NodeDefinitions.First().Value.Address}])."); } } else { // Ensure that no user cluster node definition uses the reserved neonDESKTOP address. if (clusterDefinition.NodeDefinitions.Values.Any(nodeDefinition => nodeDefinition.Address == NeonDesktopNodeAddress.ToString())) { throw new ClusterDefinitionException($"The [{NeonDesktopNodeAddress}] address may not be assigned to a user cluster; that's reserved for neonDESKTOP."); } } } clusterDefinition.ValidatePrivateNodeAddresses(); // Private node IP addresses must be assigned and valid. }