Exemplo n.º 1
0
        /// <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));

            switch (Environment)
            {
            case HostingEnvironment.Aws:

                if (Aws == null)
                {
                    throw new ClusterDefinitionException($"[{nameof(ClusterDefinition.Hosting)}.{nameof(Aws)}] must be initialized when cloud provider is [{Environment}].");
                }

                Aws.Validate(clusterDefinition);

                Cloud = Cloud ?? new CloudOptions();
                Cloud.Validate(clusterDefinition);
                break;

            case HostingEnvironment.Azure:

                if (Azure == null)
                {
                    throw new ClusterDefinitionException($"[{nameof(ClusterDefinition.Hosting)}.{nameof(Azure)}] must be initialized when cloud provider is [{Environment}].");
                }

                Azure.Validate(clusterDefinition);

                Cloud = Cloud ?? new CloudOptions();
                Cloud.Validate(clusterDefinition);
                break;

            case HostingEnvironment.BareMetal:

                Machine = Machine ?? new MachineHostingOptions();
                Machine.Validate(clusterDefinition);
                break;

            case HostingEnvironment.Google:

                if (Google == null)
                {
                    throw new ClusterDefinitionException($"[{nameof(ClusterDefinition.Hosting)}.{nameof(Google)}] must be initialized when cloud provider is [{Environment}].");
                }

                Google.Validate(clusterDefinition);

                Cloud = Cloud ?? new CloudOptions();
                Cloud.Validate(clusterDefinition);
                break;

            case HostingEnvironment.HyperV:

                HyperV = HyperV ?? new HyperVHostingOptions();
                HyperV.Validate(clusterDefinition);

                Vm = Vm ?? new VmHostingOptions();
                Vm.Validate(clusterDefinition);
                break;

            case HostingEnvironment.XenServer:

                XenServer = XenServer ?? new XenServerHostingOptions();
                XenServer.Validate(clusterDefinition);

                Cloud = Cloud ?? new CloudOptions();
                Cloud.Validate(clusterDefinition);

                Vm = Vm ?? new VmHostingOptions();
                Vm.Validate(clusterDefinition);
                break;

            default:

                throw new NotImplementedException();
            }
        }
Exemplo n.º 2
0
        public void Validate(ClusterDefinition clusterDefinition)
        {
            Covenant.Requires <ArgumentNullException>(clusterDefinition != null, nameof(clusterDefinition));

            switch (Environment)
            {
            case HostingEnvironments.Aws:

                if (Aws == null)
                {
                    throw new ClusterDefinitionException($"[{nameof(HostingOptions)}.{nameof(Aws)}] must be initialized when cloud provider is [{Environment}].");
                }

                Aws.Validate(clusterDefinition);
                break;

            case HostingEnvironments.Azure:

                if (Azure == null)
                {
                    throw new ClusterDefinitionException($"[{nameof(HostingOptions)}.{nameof(Azure)}] must be initialized when cloud provider is [{Environment}].");
                }

                Azure.Validate(clusterDefinition);
                break;

            case HostingEnvironments.Google:

                if (Google == null)
                {
                    throw new ClusterDefinitionException($"[{nameof(HostingOptions)}.{nameof(Google)}] must be initialized when cloud provider is [{Environment}].");
                }

                Google.Validate(clusterDefinition);
                break;

            case HostingEnvironments.HyperV:

                HyperV = HyperV ?? new HyperVOptions();

                HyperV.Validate(clusterDefinition);
                break;

            case HostingEnvironments.HyperVLocal:

                HyperVDev = HyperVDev ?? new LocalHyperVOptions();

                HyperVDev.Validate(clusterDefinition);
                break;

            case HostingEnvironments.Machine:

                Machine = Machine ?? new MachineOptions();

                Machine.Validate(clusterDefinition);
                break;

            case HostingEnvironments.XenServer:

                XenServer = XenServer ?? new XenServerOptions();

                XenServer.Validate(clusterDefinition);
                break;

            default:

                throw new NotImplementedException();
            }

            if (!string.IsNullOrWhiteSpace(VmNamePrefix))
            {
                if (!ClusterDefinition.IsValidName(VmNamePrefix))
                {
                    throw new ClusterDefinitionException($"[{nameof(HostingOptions)}.{nameof(VmNamePrefix)}={VmNamePrefix}] must include only letters, digits, underscores, or periods.");
                }
            }
        }
Exemplo n.º 3
0
        public void Validate(HiveDefinition hiveDefinition)
        {
            Covenant.Requires <ArgumentNullException>(hiveDefinition != null);

            Labels     = Labels ?? new NodeLabels(this);
            HostGroups = HostGroups ?? new List <string>();

            if (Name == null)
            {
                throw new HiveDefinitionException($"The [{nameof(NodeDefinition)}.{nameof(Name)}] property is required.");
            }

            if (!HiveDefinition.IsValidName(Name))
            {
                throw new HiveDefinitionException($"The [{nameof(NodeDefinition)}.{nameof(Name)}={Name}] property is not valid.  Only letters, numbers, periods, dashes, and underscores are allowed.");
            }

            if (name == "localhost")
            {
                throw new HiveDefinitionException($"The [{nameof(NodeDefinition)}.{nameof(Name)}={Name}] property is not valid.  [localhost] is reserved.");
            }

            if (Name.StartsWith("neon-", StringComparison.InvariantCultureIgnoreCase))
            {
                throw new HiveDefinitionException($"The [{nameof(NodeDefinition)}.{nameof(Name)}={Name}] property is not valid because node names starting with [node-] are reserved.");
            }

            if (Name.Equals(HiveDefinition.VirtualSwarmManagerName, StringComparison.InvariantCultureIgnoreCase))
            {
                throw new HiveDefinitionException($"The [{nameof(NodeDefinition)}.{nameof(Name)}={Name}] property is not valid.  [{HiveDefinition.VirtualSwarmManagerName}] is reserved for targeting Swarm related Ansible tasks.");
            }

            if (hiveDefinition.Hosting.IsOnPremiseProvider)
            {
                if (string.IsNullOrEmpty(PrivateAddress))
                {
                    throw new HiveDefinitionException($"Node [{Name}] requires [{nameof(PrivateAddress)}] when hosting in an on-premise facility.");
                }

                if (!IPAddress.TryParse(PrivateAddress, out var nodeAddress))
                {
                    throw new HiveDefinitionException($"Node [{Name}] has invalid IP address [{PrivateAddress}].");
                }
            }

            if (IsManager && hiveDefinition.Hosting.IsOnPremiseProvider && hiveDefinition.Vpn.Enabled)
            {
                if (!NetHelper.IsValidPort(VpnFrontendPort))
                {
                    throw new HiveDefinitionException($"Manager node [{Name}] has [{nameof(VpnFrontendPort)}={VpnFrontendPort}] which is not a valid network port.");
                }
            }

            Labels.Validate(hiveDefinition);

            foreach (var group in HostGroups)
            {
                if (string.IsNullOrWhiteSpace(group))
                {
                    throw new HiveDefinitionException($"Node [{Name}] assigns an empty group in [{nameof(HostGroups)}].");
                }
                else if (HiveHostGroups.BuiltIn.Contains(group))
                {
                    throw new HiveDefinitionException($"Node [{Name}] assigns the standard [{group}] in [{nameof(HostGroups)}].  Standard groups cannot be explicitly assigned since [neon-cli] handles them automatically.");
                }
                else if (!groupNameRegex.IsMatch(group))
                {
                    throw new HiveDefinitionException($"Node [{Name}] assigns the invalid group [{group}] in [{nameof(HostGroups)}].  Group names must start with a letter and then can be followed by zero or more letters, digits, dashes, and underscores.");
                }
            }

            if (Azure != null)
            {
                Azure.Validate(hiveDefinition, this.Name);
            }

            if (hiveDefinition.Hosting.IsRemoteHypervisorProvider)
            {
                if (string.IsNullOrEmpty(VmHost))
                {
                    throw new HiveDefinitionException($"Node [{Name}] does not specify a hypervisor [{nameof(NodeDefinition)}.{nameof(NodeDefinition.VmHost)}].");
                }
                else if (hiveDefinition.Hosting.VmHosts.FirstOrDefault(h => h.Name.Equals(VmHost, StringComparison.InvariantCultureIgnoreCase)) == null)
                {
                    throw new HiveDefinitionException($"Node [{Name}] references hypervisor [{VmHost}] which is defined in [{nameof(HostingOptions)}={nameof(HostingOptions.VmHosts)}].");
                }
            }

            if (VmMemory != null)
            {
                HiveDefinition.ValidateSize(VmMemory, this.GetType(), nameof(VmMemory));
            }

            if (VmMinimumMemory != null)
            {
                HiveDefinition.ValidateSize(VmMinimumMemory, this.GetType(), nameof(VmMinimumMemory));
            }

            if (VmDisk != null)
            {
                HiveDefinition.ValidateSize(VmDisk, this.GetType(), nameof(VmDisk));
            }
        }
Exemplo n.º 4
0
        public void Validate(HiveDefinition hiveDefinition)
        {
            Covenant.Requires <ArgumentNullException>(hiveDefinition != null);

            switch (Environment)
            {
            case HostingEnvironments.Aws:

                if (Aws == null)
                {
                    throw new HiveDefinitionException($"[{nameof(HostingOptions)}.{nameof(Aws)}] must be initialized when cloud provider is [{Environment}].");
                }

                Aws.Validate(hiveDefinition);
                break;

            case HostingEnvironments.Azure:

                if (Azure == null)
                {
                    throw new HiveDefinitionException($"[{nameof(HostingOptions)}.{nameof(Azure)}] must be initialized when cloud provider is [{Environment}].");
                }

                Azure.Validate(hiveDefinition);
                break;

            case HostingEnvironments.Google:

                if (Google == null)
                {
                    throw new HiveDefinitionException($"[{nameof(HostingOptions)}.{nameof(Google)}] must be initialized when cloud provider is [{Environment}].");
                }

                Google.Validate(hiveDefinition);
                break;

            case HostingEnvironments.HyperV:

                HyperV = HyperV ?? new HyperVOptions();

                HyperV.Validate(hiveDefinition);
                break;

            case HostingEnvironments.HyperVDev:

                LocalHyperV = LocalHyperV ?? new LocalHyperVOptions();

                LocalHyperV.Validate(hiveDefinition);
                break;

            case HostingEnvironments.Machine:

                Machine = Machine ?? new MachineOptions();

                Machine.Validate(hiveDefinition);
                break;

            case HostingEnvironments.XenServer:

                XenServer = XenServer ?? new XenServerOptions();

                XenServer.Validate(hiveDefinition);
                break;

            default:

                throw new NotImplementedException();
            }

            if (IsCloudProvider && !hiveDefinition.Vpn.Enabled)
            {
                // VPN is implicitly enabled when hosting on a cloud.

                hiveDefinition.Vpn.Enabled = true;
            }

            if (!string.IsNullOrWhiteSpace(VmNamePrefix))
            {
                if (!HiveDefinition.IsValidName(VmNamePrefix))
                {
                    throw new HiveDefinitionException($"[{nameof(HostingOptions)}.{nameof(VmNamePrefix)}={VmNamePrefix}] must include only letters, digits, underscores, or periods.");
                }
            }
        }
Exemplo n.º 5
0
        /// <summary>
        /// Validates the node definition.
        /// </summary>
        /// <param name="clusterDefinition">The cluster definition.</param>
        /// <exception cref="ArgumentException">Thrown if the definition is not valid.</exception>
        public void Validate(ClusterDefinition clusterDefinition)
        {
            Covenant.Requires <ArgumentNullException>(clusterDefinition != null, nameof(clusterDefinition));

            Vm = Vm ?? new VmNodeOptions();

            var nodeDefinitionPrefix = $"{nameof(ClusterDefinition.NodeDefinitions)}";

            // Ensure that the labels are wired up to the parent node.

            if (Labels == null)
            {
                Labels = new NodeLabels(this);
            }
            else
            {
                Labels.Node = this;
            }

            if (Name == null)
            {
                throw new ClusterDefinitionException($"The [{nodeDefinitionPrefix}.{nameof(Name)}] property is required.");
            }

            if (!ClusterDefinition.IsValidName(Name))
            {
                throw new ClusterDefinitionException($"The [{nodeDefinitionPrefix}.{nameof(Name)}={Name}] property is not valid.  Only letters, numbers, periods, dashes, and underscores are allowed.");
            }

            if (name == "localhost")
            {
                throw new ClusterDefinitionException($"The [{nodeDefinitionPrefix}.{nameof(Name)}={Name}] property is not valid.  [localhost] is reserved.");
            }

            if (Name.StartsWith("neon-", StringComparison.InvariantCultureIgnoreCase) && !clusterDefinition.IsSpecialNeonCluster)
            {
                throw new ClusterDefinitionException($"The [{nodeDefinitionPrefix}.{nameof(Name)}={Name}] property is not valid because node names starting with [neon-] are reserved.");
            }

            if (name.Equals("cluster", StringComparison.InvariantCultureIgnoreCase))
            {
                // $hack(jefflill):
                //
                // The node name [cluster] is reserved because we want to persist the
                // global cluster log file as [cluster.log] and we don't want this to
                // conflict with any of the node log files.
                //
                // See: KubeConst.ClusterSetupLogName

                throw new ClusterDefinitionException($"The [{nodeDefinitionPrefix}.{nameof(Name)}={Name}] property is not valid because the node name [cluster] is reserved.");
            }

            if (string.IsNullOrEmpty(Role))
            {
                Role = NodeRole.Worker;
            }

            if (!Role.Equals(NodeRole.ControlPlane, StringComparison.InvariantCultureIgnoreCase) && !Role.Equals(NodeRole.Worker, StringComparison.InvariantCultureIgnoreCase))
            {
                throw new ClusterDefinitionException($"[{nodeDefinitionPrefix}.{nameof(Name)}={Name}] has invalid [{nameof(Role)}={Role}].  This must be [{NodeRole.ControlPlane}] or [{NodeRole.Worker}].");
            }

            // We don't need to check the node address for cloud providers.

            if (clusterDefinition.Hosting.IsOnPremiseProvider)
            {
                if (string.IsNullOrEmpty(Address))
                {
                    throw new ClusterDefinitionException($"[{nodeDefinitionPrefix}.{nameof(Name)}={Name}] requires [{nameof(Address)}] when hosting in an on-premise facility.");
                }

                if (!NetHelper.TryParseIPv4Address(Address, out var nodeAddress))
                {
                    throw new ClusterDefinitionException($"[{nodeDefinitionPrefix}.{nameof(Name)}={Name}] has invalid IP address [{Address}].");
                }
            }

            switch (clusterDefinition.Hosting.Environment)
            {
            case HostingEnvironment.Aws:

                Aws = Aws ?? new AwsNodeOptions();
                Aws.Validate(clusterDefinition, this.Name);
                break;

            case HostingEnvironment.Azure:

                Azure = Azure ?? new AzureNodeOptions();
                Azure.Validate(clusterDefinition, this.Name);
                break;

            case HostingEnvironment.BareMetal:

                // No machine options to check at this time.
                break;

            case HostingEnvironment.Google:

                // $todo(jefflill: Implement this
                break;

            case HostingEnvironment.HyperV:
            case HostingEnvironment.XenServer:

                Vm = Vm ?? new VmNodeOptions();
                Vm.Validate(clusterDefinition, this.Name);
                break;

            default:

                throw new NotImplementedException($"Hosting environment [{clusterDefinition.Hosting.Environment}] hosting option check is not implemented.");
            }
        }
Exemplo n.º 6
0
        public void Validate(ClusterDefinition clusterDefinition)
        {
            Covenant.Requires <ArgumentNullException>(clusterDefinition != null);

            // Ensure that the labels are wired up to the parent node.

            if (Labels == null)
            {
                Labels = new NodeLabels(this);
            }
            else
            {
                Labels.Node = this;
            }

            if (Name == null)
            {
                throw new ClusterDefinitionException($"The [{nameof(NodeDefinition)}.{nameof(Name)}] property is required.");
            }

            if (!ClusterDefinition.IsValidName(Name))
            {
                throw new ClusterDefinitionException($"The [{nameof(NodeDefinition)}.{nameof(Name)}={Name}] property is not valid.  Only letters, numbers, periods, dashes, and underscores are allowed.");
            }

            if (name == "localhost")
            {
                throw new ClusterDefinitionException($"The [{nameof(NodeDefinition)}.{nameof(Name)}={Name}] property is not valid.  [localhost] is reserved.");
            }

            if (Name.StartsWith("neon-", StringComparison.InvariantCultureIgnoreCase))
            {
                throw new ClusterDefinitionException($"The [{nameof(NodeDefinition)}.{nameof(Name)}={Name}] property is not valid because node names starting with [node-] are reserved.");
            }

            if (clusterDefinition.Hosting.IsOnPremiseProvider)
            {
                if (string.IsNullOrEmpty(PrivateAddress))
                {
                    throw new ClusterDefinitionException($"Node [{Name}] requires [{nameof(PrivateAddress)}] when hosting in an on-premise facility.");
                }

                if (!IPAddress.TryParse(PrivateAddress, out var nodeAddress))
                {
                    throw new ClusterDefinitionException($"Node [{Name}] has invalid IP address [{PrivateAddress}].");
                }
            }

            if (Azure != null)
            {
                Azure.Validate(clusterDefinition, this.Name);
            }

            if (clusterDefinition.Hosting.IsRemoteHypervisorProvider)
            {
                if (string.IsNullOrEmpty(VmHost))
                {
                    throw new ClusterDefinitionException($"Node [{Name}] does not specify a hypervisor [{nameof(NodeDefinition)}.{nameof(NodeDefinition.VmHost)}].");
                }
                else if (clusterDefinition.Hosting.VmHosts.FirstOrDefault(h => h.Name.Equals(VmHost, StringComparison.InvariantCultureIgnoreCase)) == null)
                {
                    throw new ClusterDefinitionException($"Node [{Name}] references hypervisor [{VmHost}] which is defined in [{nameof(HostingOptions)}={nameof(HostingOptions.VmHosts)}].");
                }
            }

            if (VmMemory != null)
            {
                ClusterDefinition.ValidateSize(VmMemory, this.GetType(), nameof(VmMemory));
            }

            if (VmDisk != null)
            {
                ClusterDefinition.ValidateSize(VmDisk, this.GetType(), nameof(VmDisk));
            }
        }