# generated by datamodel-codegen:
#   timestamp: 2024-04-28T19:06:26+00:00
#   k8s version: v1.30.0

from __future__ import annotations

from datetime import datetime
from typing import List, Optional, Union

from pydantic import BaseModel, Field

from ...apimachinery.pkg.apis.meta import v1


class CrossVersionObjectReference(BaseModel):
    apiVersion: Optional[str] = Field(
        default=None, description="apiVersion is the API version of the referent"
    )
    kind: str = Field(
        ...,
        description=(
            "kind is the kind of the referent; More info:"
            " https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds"
        ),
    )
    name: str = Field(
        ...,
        description=(
            "name is the name of the referent; More info:"
            " https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names"
        ),
    )


class HPAScalingPolicy(BaseModel):
    periodSeconds: int = Field(
        ...,
        description=(
            "periodSeconds specifies the window of time for which the policy should"
            " hold true. PeriodSeconds must be greater than zero and less than or equal"
            " to 1800 (30 min)."
        ),
    )
    type: str = Field(..., description="type is used to specify the scaling policy.")
    value: int = Field(
        ...,
        description=(
            "value contains the amount of change which is permitted by the policy. It"
            " must be greater than zero"
        ),
    )


class HPAScalingRules(BaseModel):
    policies: Optional[List[HPAScalingPolicy]] = Field(
        default=None,
        description=(
            "policies is a list of potential scaling polices which can be used during"
            " scaling. At least one policy must be specified, otherwise the"
            " HPAScalingRules will be discarded as invalid"
        ),
    )
    selectPolicy: Optional[str] = Field(
        default=None,
        description=(
            "selectPolicy is used to specify which policy should be used. If not set,"
            " the default value Max is used."
        ),
    )
    stabilizationWindowSeconds: Optional[int] = Field(
        default=None,
        description=(
            "stabilizationWindowSeconds is the number of seconds for which past"
            " recommendations should be considered while scaling up or scaling down."
            " StabilizationWindowSeconds must be greater than or equal to zero and less"
            " than or equal to 3600 (one hour). If not set, use the default values: -"
            " For scale up: 0 (i.e. no stabilization is done). - For scale down: 300"
            " (i.e. the stabilization window is 300 seconds long)."
        ),
    )


class HorizontalPodAutoscalerBehavior(BaseModel):
    scaleDown: Optional[HPAScalingRules] = Field(
        default=None,
        description=(
            "scaleDown is scaling policy for scaling Down. If not set, the default"
            " value is to allow to scale down to minReplicas pods, with a 300 second"
            " stabilization window (i.e., the highest recommendation for the last"
            " 300sec is used)."
        ),
    )
    scaleUp: Optional[HPAScalingRules] = Field(
        default=None,
        description=(
            "scaleUp is scaling policy for scaling Up. If not set, the default value is"
            " the higher of:\n  * increase no more than 4 pods per 60 seconds\n  *"
            " double the number of pods per 60 seconds\nNo stabilization is used."
        ),
    )


class HorizontalPodAutoscalerCondition(BaseModel):
    lastTransitionTime: Optional[datetime] = Field(
        default=None,
        description=(
            "lastTransitionTime is the last time the condition transitioned from one"
            " status to another"
        ),
    )
    message: Optional[str] = Field(
        default=None,
        description=(
            "message is a human-readable explanation containing details about the"
            " transition"
        ),
    )
    reason: Optional[str] = Field(
        default=None,
        description="reason is the reason for the condition's last transition.",
    )
    status: str = Field(
        ..., description="status is the status of the condition (True, False, Unknown)"
    )
    type: str = Field(..., description="type describes the current condition")


class MetricTarget(BaseModel):
    averageUtilization: Optional[int] = Field(
        default=None,
        description=(
            "averageUtilization is the target value of the average of the resource"
            " metric across all relevant pods, represented as a percentage of the"
            " requested value of the resource for the pods. Currently only valid for"
            " Resource metric source type"
        ),
    )
    averageValue: Optional[Union[str, float]] = Field(
        default=None,
        description=(
            "averageValue is the target value of the average of the metric across all"
            " relevant pods (as a quantity)"
        ),
    )
    type: str = Field(
        ...,
        description=(
            "type represents whether the metric type is Utilization, Value, or"
            " AverageValue"
        ),
    )
    value: Optional[Union[str, float]] = Field(
        default=None,
        description="value is the target value of the metric (as a quantity).",
    )


class MetricValueStatus(BaseModel):
    averageUtilization: Optional[int] = Field(
        default=None,
        description=(
            "currentAverageUtilization is the current value of the average of the"
            " resource metric across all relevant pods, represented as a percentage of"
            " the requested value of the resource for the pods."
        ),
    )
    averageValue: Optional[Union[str, float]] = Field(
        default=None,
        description=(
            "averageValue is the current value of the average of the metric across all"
            " relevant pods (as a quantity)"
        ),
    )
    value: Optional[Union[str, float]] = Field(
        default=None,
        description="value is the current value of the metric (as a quantity).",
    )


class ResourceMetricSource(BaseModel):
    name: str = Field(..., description="name is the name of the resource in question.")
    target: MetricTarget = Field(
        ..., description="target specifies the target value for the given metric"
    )


class ResourceMetricStatus(BaseModel):
    current: MetricValueStatus = Field(
        ..., description="current contains the current value for the given metric"
    )
    name: str = Field(..., description="name is the name of the resource in question.")


class ContainerResourceMetricSource(BaseModel):
    container: str = Field(
        ...,
        description=(
            "container is the name of the container in the pods of the scaling target"
        ),
    )
    name: str = Field(..., description="name is the name of the resource in question.")
    target: MetricTarget = Field(
        ..., description="target specifies the target value for the given metric"
    )


class ContainerResourceMetricStatus(BaseModel):
    container: str = Field(
        ...,
        description=(
            "container is the name of the container in the pods of the scaling target"
        ),
    )
    current: MetricValueStatus = Field(
        ..., description="current contains the current value for the given metric"
    )
    name: str = Field(..., description="name is the name of the resource in question.")


class MetricIdentifier(BaseModel):
    name: str = Field(..., description="name is the name of the given metric")
    selector: Optional[v1.LabelSelector] = Field(
        default=None,
        description=(
            "selector is the string-encoded form of a standard kubernetes label"
            " selector for the given metric When set, it is passed as an additional"
            " parameter to the metrics server for more specific metrics scoping. When"
            " unset, just the metricName will be used to gather metrics."
        ),
    )


class ObjectMetricSource(BaseModel):
    describedObject: CrossVersionObjectReference = Field(
        ...,
        description=(
            "describedObject specifies the descriptions of a object,such as kind,name"
            " apiVersion"
        ),
    )
    metric: MetricIdentifier = Field(
        ..., description="metric identifies the target metric by name and selector"
    )
    target: MetricTarget = Field(
        ..., description="target specifies the target value for the given metric"
    )


class ObjectMetricStatus(BaseModel):
    current: MetricValueStatus = Field(
        ..., description="current contains the current value for the given metric"
    )
    describedObject: CrossVersionObjectReference = Field(
        ...,
        description=(
            "DescribedObject specifies the descriptions of a object,such as kind,name"
            " apiVersion"
        ),
    )
    metric: MetricIdentifier = Field(
        ..., description="metric identifies the target metric by name and selector"
    )


class PodsMetricSource(BaseModel):
    metric: MetricIdentifier = Field(
        ..., description="metric identifies the target metric by name and selector"
    )
    target: MetricTarget = Field(
        ..., description="target specifies the target value for the given metric"
    )


class PodsMetricStatus(BaseModel):
    current: MetricValueStatus = Field(
        ..., description="current contains the current value for the given metric"
    )
    metric: MetricIdentifier = Field(
        ..., description="metric identifies the target metric by name and selector"
    )


class ExternalMetricSource(BaseModel):
    metric: MetricIdentifier = Field(
        ..., description="metric identifies the target metric by name and selector"
    )
    target: MetricTarget = Field(
        ..., description="target specifies the target value for the given metric"
    )


class ExternalMetricStatus(BaseModel):
    current: MetricValueStatus = Field(
        ..., description="current contains the current value for the given metric"
    )
    metric: MetricIdentifier = Field(
        ..., description="metric identifies the target metric by name and selector"
    )


class MetricSpec(BaseModel):
    containerResource: Optional[ContainerResourceMetricSource] = Field(
        default=None,
        description=(
            "containerResource refers to a resource metric (such as those specified in"
            " requests and limits) known to Kubernetes describing a single container in"
            " each pod of the current scale target (e.g. CPU or memory). Such metrics"
            " are built in to Kubernetes, and have special scaling options on top of"
            ' those available to normal per-pod metrics using the "pods" source. This'
            " is an alpha feature and can be enabled by the HPAContainerMetrics feature"
            " flag."
        ),
    )
    external: Optional[ExternalMetricSource] = Field(
        default=None,
        description=(
            "external refers to a global metric that is not associated with any"
            " Kubernetes object. It allows autoscaling based on information coming from"
            " components running outside of cluster (for example length of queue in"
            " cloud messaging service, or QPS from loadbalancer running outside of"
            " cluster)."
        ),
    )
    object: Optional[ObjectMetricSource] = Field(
        default=None,
        description=(
            "object refers to a metric describing a single kubernetes object (for"
            " example, hits-per-second on an Ingress object)."
        ),
    )
    pods: Optional[PodsMetricSource] = Field(
        default=None,
        description=(
            "pods refers to a metric describing each pod in the current scale target"
            " (for example, transactions-processed-per-second).  The values will be"
            " averaged together before being compared to the target value."
        ),
    )
    resource: Optional[ResourceMetricSource] = Field(
        default=None,
        description=(
            "resource refers to a resource metric (such as those specified in requests"
            " and limits) known to Kubernetes describing each pod in the current scale"
            " target (e.g. CPU or memory). Such metrics are built in to Kubernetes, and"
            " have special scaling options on top of those available to normal per-pod"
            ' metrics using the "pods" source.'
        ),
    )
    type: str = Field(
        ...,
        description=(
            "type is the type of metric source.  It should be one of"
            ' "ContainerResource", "External", "Object", "Pods" or "Resource", each'
            ' mapping to a matching field in the object. Note: "ContainerResource" type'
            " is available on when the feature-gate HPAContainerMetrics is enabled"
        ),
    )


class MetricStatus(BaseModel):
    containerResource: Optional[ContainerResourceMetricStatus] = Field(
        default=None,
        description=(
            "container resource refers to a resource metric (such as those specified in"
            " requests and limits) known to Kubernetes describing a single container in"
            " each pod in the current scale target (e.g. CPU or memory). Such metrics"
            " are built in to Kubernetes, and have special scaling options on top of"
            ' those available to normal per-pod metrics using the "pods" source.'
        ),
    )
    external: Optional[ExternalMetricStatus] = Field(
        default=None,
        description=(
            "external refers to a global metric that is not associated with any"
            " Kubernetes object. It allows autoscaling based on information coming from"
            " components running outside of cluster (for example length of queue in"
            " cloud messaging service, or QPS from loadbalancer running outside of"
            " cluster)."
        ),
    )
    object: Optional[ObjectMetricStatus] = Field(
        default=None,
        description=(
            "object refers to a metric describing a single kubernetes object (for"
            " example, hits-per-second on an Ingress object)."
        ),
    )
    pods: Optional[PodsMetricStatus] = Field(
        default=None,
        description=(
            "pods refers to a metric describing each pod in the current scale target"
            " (for example, transactions-processed-per-second).  The values will be"
            " averaged together before being compared to the target value."
        ),
    )
    resource: Optional[ResourceMetricStatus] = Field(
        default=None,
        description=(
            "resource refers to a resource metric (such as those specified in requests"
            " and limits) known to Kubernetes describing each pod in the current scale"
            " target (e.g. CPU or memory). Such metrics are built in to Kubernetes, and"
            " have special scaling options on top of those available to normal per-pod"
            ' metrics using the "pods" source.'
        ),
    )
    type: str = Field(
        ...,
        description=(
            'type is the type of metric source.  It will be one of "ContainerResource",'
            ' "External", "Object", "Pods" or "Resource", each corresponds to a'
            ' matching field in the object. Note: "ContainerResource" type is available'
            " on when the feature-gate HPAContainerMetrics is enabled"
        ),
    )


class HorizontalPodAutoscalerSpec(BaseModel):
    behavior: Optional[HorizontalPodAutoscalerBehavior] = Field(
        default=None,
        description=(
            "behavior configures the scaling behavior of the target in both Up and Down"
            " directions (scaleUp and scaleDown fields respectively). If not set, the"
            " default HPAScalingRules for scale up and scale down are used."
        ),
    )
    maxReplicas: int = Field(
        ...,
        description=(
            "maxReplicas is the upper limit for the number of replicas to which the"
            " autoscaler can scale up. It cannot be less that minReplicas."
        ),
    )
    metrics: Optional[List[MetricSpec]] = Field(
        default=None,
        description=(
            "metrics contains the specifications for which to use to calculate the"
            " desired replica count (the maximum replica count across all metrics will"
            " be used).  The desired replica count is calculated multiplying the ratio"
            " between the target value and the current value by the current number of"
            " pods.  Ergo, metrics used must decrease as the pod count is increased,"
            " and vice-versa.  See the individual metric source types for more"
            " information about how each type of metric must respond. If not set, the"
            " default metric will be set to 80% average CPU utilization."
        ),
    )
    minReplicas: Optional[int] = Field(
        default=None,
        description=(
            "minReplicas is the lower limit for the number of replicas to which the"
            " autoscaler can scale down.  It defaults to 1 pod.  minReplicas is allowed"
            " to be 0 if the alpha feature gate HPAScaleToZero is enabled and at least"
            " one Object or External metric is configured.  Scaling is active as long"
            " as at least one metric value is available."
        ),
    )
    scaleTargetRef: CrossVersionObjectReference = Field(
        ...,
        description=(
            "scaleTargetRef points to the target resource to scale, and is used to the"
            " pods for which metrics should be collected, as well as to actually change"
            " the replica count."
        ),
    )


class HorizontalPodAutoscalerStatus(BaseModel):
    conditions: Optional[List[HorizontalPodAutoscalerCondition]] = Field(
        default=None,
        description=(
            "conditions is the set of conditions required for this autoscaler to scale"
            " its target, and indicates whether or not those conditions are met."
        ),
    )
    currentMetrics: Optional[List[MetricStatus]] = Field(
        default=None,
        description=(
            "currentMetrics is the last read state of the metrics used by this"
            " autoscaler."
        ),
    )
    currentReplicas: Optional[int] = Field(
        default=None,
        description=(
            "currentReplicas is current number of replicas of pods managed by this"
            " autoscaler, as last seen by the autoscaler."
        ),
    )
    desiredReplicas: int = Field(
        ...,
        description=(
            "desiredReplicas is the desired number of replicas of pods managed by this"
            " autoscaler, as last calculated by the autoscaler."
        ),
    )
    lastScaleTime: Optional[datetime] = Field(
        default=None,
        description=(
            "lastScaleTime is the last time the HorizontalPodAutoscaler scaled the"
            " number of pods, used by the autoscaler to control how often the number of"
            " pods is changed."
        ),
    )
    observedGeneration: Optional[int] = Field(
        default=None,
        description=(
            "observedGeneration is the most recent generation observed by this"
            " autoscaler."
        ),
    )


class HorizontalPodAutoscaler(BaseModel):
    apiVersion: Optional[str] = Field(
        default="autoscaling/v2",
        description=(
            "APIVersion defines the versioned schema of this representation of an"
            " object. Servers should convert recognized schemas to the latest internal"
            " value, and may reject unrecognized values. More info:"
            " https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources"
        ),
    )
    kind: Optional[str] = Field(
        default="HorizontalPodAutoscaler",
        description=(
            "Kind is a string value representing the REST resource this object"
            " represents. Servers may infer this from the endpoint the client submits"
            " requests to. Cannot be updated. In CamelCase. More info:"
            " https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds"
        ),
    )
    metadata: Optional[v1.ObjectMeta] = Field(
        default=None,
        description=(
            "metadata is the standard object metadata. More info:"
            " https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata"
        ),
    )
    spec: Optional[HorizontalPodAutoscalerSpec] = Field(
        default=None,
        description=(
            "spec is the specification for the behaviour of the autoscaler. More info:"
            " https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status."
        ),
    )
    status: Optional[HorizontalPodAutoscalerStatus] = Field(
        default=None,
        description="status is the current information about the autoscaler.",
    )


class HorizontalPodAutoscalerList(BaseModel):
    apiVersion: Optional[str] = Field(
        default="autoscaling/v2",
        description=(
            "APIVersion defines the versioned schema of this representation of an"
            " object. Servers should convert recognized schemas to the latest internal"
            " value, and may reject unrecognized values. More info:"
            " https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources"
        ),
    )
    items: List[HorizontalPodAutoscaler] = Field(
        ..., description="items is the list of horizontal pod autoscaler objects."
    )
    kind: Optional[str] = Field(
        default="HorizontalPodAutoscalerList",
        description=(
            "Kind is a string value representing the REST resource this object"
            " represents. Servers may infer this from the endpoint the client submits"
            " requests to. Cannot be updated. In CamelCase. More info:"
            " https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds"
        ),
    )
    metadata: Optional[v1.ListMeta] = Field(
        default=None, description="metadata is the standard list metadata."
    )
