// <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.Collections;
    using System.Collections.Generic;
    using System.Linq;

    /// <summary>
    /// ValidatingWebhook describes an admission webhook and the resources and
    /// operations it applies to.
    /// </summary>
    public partial class V1ValidatingWebhook
    {
        /// <summary>
        /// Initializes a new instance of the V1ValidatingWebhook class.
        /// </summary>
        public V1ValidatingWebhook()
        {
            CustomInit();
        }

        /// <summary>
        /// Initializes a new instance of the V1ValidatingWebhook class.
        /// </summary>
        /// <param name="admissionReviewVersions">AdmissionReviewVersions is an
        /// ordered list of preferred `AdmissionReview` versions the Webhook
        /// expects. API server will try to use first version in the list which
        /// it supports. If none of the versions specified in this list
        /// supported by API server, validation will fail for this object. If a
        /// persisted webhook configuration specifies allowed versions and does
        /// not include any versions known to the API Server, calls to the
        /// webhook will fail and be subject to the failure policy.</param>
        /// <param name="clientConfig">ClientConfig defines how to communicate
        /// with the hook. Required</param>
        /// <param name="name">The name of the admission webhook. Name should
        /// be fully qualified, e.g., imagepolicy.kubernetes.io, where
        /// "imagepolicy" is the name of the webhook, and kubernetes.io is the
        /// name of the organization. Required.</param>
        /// <param name="sideEffects">SideEffects states whether this webhook
        /// has side effects. Acceptable values are: None, NoneOnDryRun
        /// (webhooks created via v1beta1 may also specify Some or Unknown).
        /// Webhooks with side effects MUST implement a reconciliation system,
        /// since a request may be rejected by a future step in the admission
        /// chain and the side effects therefore need to be undone. Requests
        /// with the dryRun attribute will be auto-rejected if they match a
        /// webhook with sideEffects == Unknown or Some.</param>
        /// <param name="failurePolicy">FailurePolicy defines how unrecognized
        /// errors from the admission endpoint are handled - allowed values are
        /// Ignore or Fail. Defaults to Fail.</param>
        /// <param name="matchPolicy">matchPolicy defines how the "rules" list
        /// is used to match incoming requests. Allowed values are "Exact" or
        /// "Equivalent".
        ///
        /// - Exact: match a request only if it exactly matches a specified
        /// rule. For example, if deployments can be modified via apps/v1,
        /// apps/v1beta1, and extensions/v1beta1, but "rules" only included
        /// `apiGroups:["apps"], apiVersions:["v1"], resources:
        /// ["deployments"]`, a request to apps/v1beta1 or extensions/v1beta1
        /// would not be sent to the webhook.
        ///
        /// - Equivalent: match a request if modifies a resource listed in
        /// rules, even via another API group or version. For example, if
        /// deployments can be modified via apps/v1, apps/v1beta1, and
        /// extensions/v1beta1, and "rules" only included `apiGroups:["apps"],
        /// apiVersions:["v1"], resources: ["deployments"]`, a request to
        /// apps/v1beta1 or extensions/v1beta1 would be converted to apps/v1
        /// and sent to the webhook.
        ///
        /// Defaults to "Equivalent"</param>
        /// <param name="namespaceSelector">NamespaceSelector decides whether
        /// to run the webhook on an object based on whether the namespace for
        /// that object matches the selector. If the object itself is a
        /// namespace, the matching is performed on object.metadata.labels. If
        /// the object is another cluster scoped resource, it never skips the
        /// webhook.
        ///
        /// For example, to run the webhook on any objects whose namespace is
        /// not associated with "runlevel" of "0" or "1";  you will set the
        /// selector as follows: "namespaceSelector": {
        /// "matchExpressions": [
        /// {
        /// "key": "runlevel",
        /// "operator": "NotIn",
        /// "values": [
        /// "0",
        /// "1"
        /// ]
        /// }
        /// ]
        /// }
        ///
        /// If instead you want to only run the webhook on any objects whose
        /// namespace is associated with the "environment" of "prod" or
        /// "staging"; you will set the selector as follows:
        /// "namespaceSelector": {
        /// "matchExpressions": [
        /// {
        /// "key": "environment",
        /// "operator": "In",
        /// "values": [
        /// "prod",
        /// "staging"
        /// ]
        /// }
        /// ]
        /// }
        ///
        /// See
        /// https://kubernetes.io/docs/concepts/overview/working-with-objects/labels
        /// for more examples of label selectors.
        ///
        /// Default to the empty LabelSelector, which matches
        /// everything.</param>
        /// <param name="objectSelector">ObjectSelector decides whether to run
        /// the webhook based on if the object has matching labels.
        /// objectSelector is evaluated against both the oldObject and
        /// newObject that would be sent to the webhook, and is considered to
        /// match if either object matches the selector. A null object
        /// (oldObject in the case of create, or newObject in the case of
        /// delete) or an object that cannot have labels (like a
        /// DeploymentRollback or a PodProxyOptions object) is not considered
        /// to match. Use the object selector only if the webhook is opt-in,
        /// because end users may skip the admission webhook by setting the
        /// labels. Default to the empty LabelSelector, which matches
        /// everything.</param>
        /// <param name="rules">Rules describes what operations on what
        /// resources/subresources the webhook cares about. The webhook cares
        /// about an operation if it matches _any_ Rule. However, in order to
        /// prevent ValidatingAdmissionWebhooks and MutatingAdmissionWebhooks
        /// from putting the cluster in a state which cannot be recovered from
        /// without completely disabling the plugin,
        /// ValidatingAdmissionWebhooks and MutatingAdmissionWebhooks are never
        /// called on admission requests for ValidatingWebhookConfiguration and
        /// MutatingWebhookConfiguration objects.</param>
        /// <param name="timeoutSeconds">TimeoutSeconds specifies the timeout
        /// for this webhook. After the timeout passes, the webhook call will
        /// be ignored or the API call will fail based on the failure policy.
        /// The timeout value must be between 1 and 30 seconds. Default to 10
        /// seconds.</param>
        public V1ValidatingWebhook(IList<string> admissionReviewVersions, Admissionregistrationv1WebhookClientConfig clientConfig, string name, string sideEffects, string failurePolicy = default(string), string matchPolicy = default(string), V1LabelSelector namespaceSelector = default(V1LabelSelector), V1LabelSelector objectSelector = default(V1LabelSelector), IList<V1RuleWithOperations> rules = default(IList<V1RuleWithOperations>), int? timeoutSeconds = default(int?))
        {
            AdmissionReviewVersions = admissionReviewVersions;
            ClientConfig = clientConfig;
            FailurePolicy = failurePolicy;
            MatchPolicy = matchPolicy;
            Name = name;
            NamespaceSelector = namespaceSelector;
            ObjectSelector = objectSelector;
            Rules = rules;
            SideEffects = sideEffects;
            TimeoutSeconds = timeoutSeconds;
            CustomInit();
        }

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

        /// <summary>
        /// Gets or sets admissionReviewVersions is an ordered list of
        /// preferred `AdmissionReview` versions the Webhook expects. API
        /// server will try to use first version in the list which it supports.
        /// If none of the versions specified in this list supported by API
        /// server, validation will fail for this object. If a persisted
        /// webhook configuration specifies allowed versions and does not
        /// include any versions known to the API Server, calls to the webhook
        /// will fail and be subject to the failure policy.
        /// </summary>
        [JsonProperty(PropertyName = "admissionReviewVersions")]
        public IList<string> AdmissionReviewVersions { get; set; }

        /// <summary>
        /// Gets or sets clientConfig defines how to communicate with the hook.
        /// Required
        /// </summary>
        [JsonProperty(PropertyName = "clientConfig")]
        public Admissionregistrationv1WebhookClientConfig ClientConfig { get; set; }

        /// <summary>
        /// Gets or sets failurePolicy defines how unrecognized errors from the
        /// admission endpoint are handled - allowed values are Ignore or Fail.
        /// Defaults to Fail.
        /// </summary>
        [JsonProperty(PropertyName = "failurePolicy")]
        public string FailurePolicy { get; set; }

        /// <summary>
        /// Gets or sets matchPolicy defines how the "rules" list is used to
        /// match incoming requests. Allowed values are "Exact" or
        /// "Equivalent".
        ///
        /// - Exact: match a request only if it exactly matches a specified
        /// rule. For example, if deployments can be modified via apps/v1,
        /// apps/v1beta1, and extensions/v1beta1, but "rules" only included
        /// `apiGroups:["apps"], apiVersions:["v1"], resources:
        /// ["deployments"]`, a request to apps/v1beta1 or extensions/v1beta1
        /// would not be sent to the webhook.
        ///
        /// - Equivalent: match a request if modifies a resource listed in
        /// rules, even via another API group or version. For example, if
        /// deployments can be modified via apps/v1, apps/v1beta1, and
        /// extensions/v1beta1, and "rules" only included `apiGroups:["apps"],
        /// apiVersions:["v1"], resources: ["deployments"]`, a request to
        /// apps/v1beta1 or extensions/v1beta1 would be converted to apps/v1
        /// and sent to the webhook.
        ///
        /// Defaults to "Equivalent"
        /// </summary>
        [JsonProperty(PropertyName = "matchPolicy")]
        public string MatchPolicy { get; set; }

        /// <summary>
        /// Gets or sets the name of the admission webhook. Name should be
        /// fully qualified, e.g., imagepolicy.kubernetes.io, where
        /// "imagepolicy" is the name of the webhook, and kubernetes.io is the
        /// name of the organization. Required.
        /// </summary>
        [JsonProperty(PropertyName = "name")]
        public string Name { get; set; }

        /// <summary>
        /// Gets or sets namespaceSelector decides whether to run the webhook
        /// on an object based on whether the namespace for that object matches
        /// the selector. If the object itself is a namespace, the matching is
        /// performed on object.metadata.labels. If the object is another
        /// cluster scoped resource, it never skips the webhook.
        ///
        /// For example, to run the webhook on any objects whose namespace is
        /// not associated with "runlevel" of "0" or "1";  you will set the
        /// selector as follows: "namespaceSelector": {
        /// "matchExpressions": [
        /// {
        /// "key": "runlevel",
        /// "operator": "NotIn",
        /// "values": [
        /// "0",
        /// "1"
        /// ]
        /// }
        /// ]
        /// }
        ///
        /// If instead you want to only run the webhook on any objects whose
        /// namespace is associated with the "environment" of "prod" or
        /// "staging"; you will set the selector as follows:
        /// "namespaceSelector": {
        /// "matchExpressions": [
        /// {
        /// "key": "environment",
        /// "operator": "In",
        /// "values": [
        /// "prod",
        /// "staging"
        /// ]
        /// }
        /// ]
        /// }
        ///
        /// See
        /// https://kubernetes.io/docs/concepts/overview/working-with-objects/labels
        /// for more examples of label selectors.
        ///
        /// Default to the empty LabelSelector, which matches everything.
        /// </summary>
        [JsonProperty(PropertyName = "namespaceSelector")]
        public V1LabelSelector NamespaceSelector { get; set; }

        /// <summary>
        /// Gets or sets objectSelector decides whether to run the webhook
        /// based on if the object has matching labels. objectSelector is
        /// evaluated against both the oldObject and newObject that would be
        /// sent to the webhook, and is considered to match if either object
        /// matches the selector. A null object (oldObject in the case of
        /// create, or newObject in the case of delete) or an object that
        /// cannot have labels (like a DeploymentRollback or a PodProxyOptions
        /// object) is not considered to match. Use the object selector only if
        /// the webhook is opt-in, because end users may skip the admission
        /// webhook by setting the labels. Default to the empty LabelSelector,
        /// which matches everything.
        /// </summary>
        [JsonProperty(PropertyName = "objectSelector")]
        public V1LabelSelector ObjectSelector { get; set; }

        /// <summary>
        /// Gets or sets rules describes what operations on what
        /// resources/subresources the webhook cares about. The webhook cares
        /// about an operation if it matches _any_ Rule. However, in order to
        /// prevent ValidatingAdmissionWebhooks and MutatingAdmissionWebhooks
        /// from putting the cluster in a state which cannot be recovered from
        /// without completely disabling the plugin,
        /// ValidatingAdmissionWebhooks and MutatingAdmissionWebhooks are never
        /// called on admission requests for ValidatingWebhookConfiguration and
        /// MutatingWebhookConfiguration objects.
        /// </summary>
        [JsonProperty(PropertyName = "rules")]
        public IList<V1RuleWithOperations> Rules { get; set; }

        /// <summary>
        /// Gets or sets sideEffects states whether this webhook has side
        /// effects. Acceptable values are: None, NoneOnDryRun (webhooks
        /// created via v1beta1 may also specify Some or Unknown). Webhooks
        /// with side effects MUST implement a reconciliation system, since a
        /// request may be rejected by a future step in the admission chain and
        /// the side effects therefore need to be undone. Requests with the
        /// dryRun attribute will be auto-rejected if they match a webhook with
        /// sideEffects == Unknown or Some.
        /// </summary>
        [JsonProperty(PropertyName = "sideEffects")]
        public string SideEffects { get; set; }

        /// <summary>
        /// Gets or sets timeoutSeconds specifies the timeout for this webhook.
        /// After the timeout passes, the webhook call will be ignored or the
        /// API call will fail based on the failure policy. The timeout value
        /// must be between 1 and 30 seconds. Default to 10 seconds.
        /// </summary>
        [JsonProperty(PropertyName = "timeoutSeconds")]
        public int? TimeoutSeconds { get; set; }

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