// <auto-generated>
// Code generated by Microsoft (R) AutoRest Code Generator.
// Changes may cause incorrect behavior and will be lost if the code is
// regenerated.
// </auto-generated>

namespace k8s.Models
{
    using Microsoft.Rest;
    using Newtonsoft.Json;
    using System.Linq;

    /// <summary>
    /// TopologySpreadConstraint specifies how to spread matching pods among
    /// the given topology.
    /// </summary>
    public partial class V1TopologySpreadConstraint
    {
        /// <summary>
        /// Initializes a new instance of the V1TopologySpreadConstraint class.
        /// </summary>
        public V1TopologySpreadConstraint()
        {
            CustomInit();
        }

        /// <summary>
        /// Initializes a new instance of the V1TopologySpreadConstraint class.
        /// </summary>
        /// <param name="maxSkew">MaxSkew describes the degree to which pods
        /// may be unevenly distributed. When
        /// `whenUnsatisfiable=DoNotSchedule`, it is the maximum permitted
        /// difference between the number of matching pods in the target
        /// topology and the global minimum. For example, in a 3-zone cluster,
        /// MaxSkew is set to 1, and pods with the same labelSelector spread as
        /// 1/1/0: | zone1 | zone2 | zone3 | |   P   |   P   |       | - if
        /// MaxSkew is 1, incoming pod can only be scheduled to zone3 to become
        /// 1/1/1; scheduling it onto zone1(zone2) would make the
        /// ActualSkew(2-0) on zone1(zone2) violate MaxSkew(1). - if MaxSkew is
        /// 2, incoming pod can be scheduled onto any zone. When
        /// `whenUnsatisfiable=ScheduleAnyway`, it is used to give higher
        /// precedence to topologies that satisfy it. It's a required field.
        /// Default value is 1 and 0 is not allowed.</param>
        /// <param name="topologyKey">TopologyKey is the key of node labels.
        /// Nodes that have a label with this key and identical values are
        /// considered to be in the same topology. We consider each &lt;key,
        /// value&gt; as a "bucket", and try to put balanced number of pods
        /// into each bucket. It's a required field.</param>
        /// <param name="whenUnsatisfiable">WhenUnsatisfiable indicates how to
        /// deal with a pod if it doesn't satisfy the spread constraint. -
        /// DoNotSchedule (default) tells the scheduler not to schedule it. -
        /// ScheduleAnyway tells the scheduler to schedule the pod in any
        /// location,
        /// but giving higher precedence to topologies that would help reduce
        /// the
        /// skew.
        /// A constraint is considered "Unsatisfiable" for an incoming pod if
        /// and only if every possible node assigment for that pod would
        /// violate "MaxSkew" on some topology. For example, in a 3-zone
        /// cluster, MaxSkew is set to 1, and pods with the same labelSelector
        /// spread as 3/1/1: | zone1 | zone2 | zone3 | | P P P |   P   |   P
        /// | If WhenUnsatisfiable is set to DoNotSchedule, incoming pod can
        /// only be scheduled to zone2(zone3) to become 3/2/1(3/1/2) as
        /// ActualSkew(2-1) on zone2(zone3) satisfies MaxSkew(1). In other
        /// words, the cluster can still be imbalanced, but scheduler won't
        /// make it *more* imbalanced. It's a required field.</param>
        /// <param name="labelSelector">LabelSelector is used to find matching
        /// pods. Pods that match this label selector are counted to determine
        /// the number of pods in their corresponding topology domain.</param>
        public V1TopologySpreadConstraint(int maxSkew, string topologyKey, string whenUnsatisfiable, V1LabelSelector labelSelector = default(V1LabelSelector))
        {
            LabelSelector = labelSelector;
            MaxSkew = maxSkew;
            TopologyKey = topologyKey;
            WhenUnsatisfiable = whenUnsatisfiable;
            CustomInit();
        }

        /// <summary>
        /// An initialization method that performs custom operations like setting defaults
        /// </summary>
        partial void CustomInit();

        /// <summary>
        /// Gets or sets labelSelector is used to find matching pods. Pods that
        /// match this label selector are counted to determine the number of
        /// pods in their corresponding topology domain.
        /// </summary>
        [JsonProperty(PropertyName = "labelSelector")]
        public V1LabelSelector LabelSelector { get; set; }

        /// <summary>
        /// Gets or sets maxSkew describes the degree to which pods may be
        /// unevenly distributed. When `whenUnsatisfiable=DoNotSchedule`, it is
        /// the maximum permitted difference between the number of matching
        /// pods in the target topology and the global minimum. For example, in
        /// a 3-zone cluster, MaxSkew is set to 1, and pods with the same
        /// labelSelector spread as 1/1/0: | zone1 | zone2 | zone3 | |   P   |
        /// P   |       | - if MaxSkew is 1, incoming pod can only be scheduled
        /// to zone3 to become 1/1/1; scheduling it onto zone1(zone2) would
        /// make the ActualSkew(2-0) on zone1(zone2) violate MaxSkew(1). - if
        /// MaxSkew is 2, incoming pod can be scheduled onto any zone. When
        /// `whenUnsatisfiable=ScheduleAnyway`, it is used to give higher
        /// precedence to topologies that satisfy it. It's a required field.
        /// Default value is 1 and 0 is not allowed.
        /// </summary>
        [JsonProperty(PropertyName = "maxSkew")]
        public int MaxSkew { get; set; }

        /// <summary>
        /// Gets or sets topologyKey is the key of node labels. Nodes that have
        /// a label with this key and identical values are considered to be in
        /// the same topology. We consider each &amp;lt;key, value&amp;gt; as a
        /// "bucket", and try to put balanced number of pods into each bucket.
        /// It's a required field.
        /// </summary>
        [JsonProperty(PropertyName = "topologyKey")]
        public string TopologyKey { get; set; }

        /// <summary>
        /// Gets or sets whenUnsatisfiable indicates how to deal with a pod if
        /// it doesn't satisfy the spread constraint. - DoNotSchedule (default)
        /// tells the scheduler not to schedule it. - ScheduleAnyway tells the
        /// scheduler to schedule the pod in any location,
        /// but giving higher precedence to topologies that would help reduce
        /// the
        /// skew.
        /// A constraint is considered "Unsatisfiable" for an incoming pod if
        /// and only if every possible node assigment for that pod would
        /// violate "MaxSkew" on some topology. For example, in a 3-zone
        /// cluster, MaxSkew is set to 1, and pods with the same labelSelector
        /// spread as 3/1/1: | zone1 | zone2 | zone3 | | P P P |   P   |   P
        /// | If WhenUnsatisfiable is set to DoNotSchedule, incoming pod can
        /// only be scheduled to zone2(zone3) to become 3/2/1(3/1/2) as
        /// ActualSkew(2-1) on zone2(zone3) satisfies MaxSkew(1). In other
        /// words, the cluster can still be imbalanced, but scheduler won't
        /// make it *more* imbalanced. It's a required field.
        /// </summary>
        [JsonProperty(PropertyName = "whenUnsatisfiable")]
        public string WhenUnsatisfiable { get; set; }

        /// <summary>
        /// Validate the object.
        /// </summary>
        /// <exception cref="ValidationException">
        /// Thrown if validation fails
        /// </exception>
        public virtual void Validate()
        {
            if (TopologyKey == null)
            {
                throw new ValidationException(ValidationRules.CannotBeNull, "TopologyKey");
            }
            if (WhenUnsatisfiable == null)
            {
                throw new ValidationException(ValidationRules.CannotBeNull, "WhenUnsatisfiable");
            }
        }
    }
}
